[sunxi-dev] Adjusted patchset. Tested on H3, H5, A64, A83T, H6, ... focused only on basic features such as dvfs, hdmi, ... Kernel sources are switched to @megous and many patches were taken from @anarsoul branch, mostly regarding Pinebook/A64 which will take some time to get upstream. It's a mess which will be eventually sorted out or merged up.

This commit is contained in:
Igor Pecovnik 2018-11-15 14:43:32 +01:00
parent cfd8a89568
commit 8edf8c56a8
217 changed files with 36176 additions and 4728 deletions

View file

@ -4,8 +4,8 @@ BOARDFAMILY="sun50iw2"
BOOTCONFIG="orangepi_pc2_defconfig" BOOTCONFIG="orangepi_pc2_defconfig"
MODULES="" MODULES=""
MODULES_NEXT="" MODULES_NEXT=""
CPUMIN="408000" CPUMIN="120000"
CPUMAX="1296000" CPUMAX="1400000"
# #
KERNEL_TARGET="next,dev" KERNEL_TARGET="next,dev"
CLI_TARGET="stretch,bionic:next" CLI_TARGET="stretch,bionic:next"

View file

@ -4,8 +4,8 @@ BOARDFAMILY="sun50iw2"
BOOTCONFIG="orangepi_prime_defconfig" BOOTCONFIG="orangepi_prime_defconfig"
MODULES="" MODULES=""
MODULES_NEXT="" MODULES_NEXT=""
CPUMIN="408000" CPUMIN="120000"
CPUMAX="1296000" CPUMAX="1400000"
# #
KERNEL_TARGET="next,dev" KERNEL_TARGET="next,dev"
CLI_TARGET="stretch:next" CLI_TARGET="stretch:next"

View file

@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/arm 4.19.1 Kernel Configuration # Linux/arm 4.19.2 Kernel Configuration
# #
# #
@ -569,7 +569,6 @@ CONFIG_CRYPTO_GHASH_ARM_CE=m
# CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set # CONFIG_CRYPTO_CRCT10DIF_ARM_CE is not set
# CONFIG_CRYPTO_CRC32_ARM_CE is not set # CONFIG_CRYPTO_CRC32_ARM_CE is not set
# CONFIG_CRYPTO_CHACHA20_NEON is not set # CONFIG_CRYPTO_CHACHA20_NEON is not set
# CONFIG_CRYPTO_SPECK_NEON is not set
CONFIG_VIRTUALIZATION=y CONFIG_VIRTUALIZATION=y
# CONFIG_VHOST_NET is not set # CONFIG_VHOST_NET is not set
# CONFIG_VHOST_SCSI is not set # CONFIG_VHOST_SCSI is not set
@ -771,6 +770,8 @@ CONFIG_NET_KEY=y
# CONFIG_NET_KEY_MIGRATE is not set # CONFIG_NET_KEY_MIGRATE is not set
# CONFIG_XDP_SOCKETS is not set # CONFIG_XDP_SOCKETS is not set
CONFIG_INET=y CONFIG_INET=y
CONFIG_WIREGUARD=m
# CONFIG_WIREGUARD_DEBUG is not set
CONFIG_IP_MULTICAST=y CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_FIB_TRIE_STATS=y
@ -3098,6 +3099,7 @@ CONFIG_CLOCK_THERMAL=y
# ACPI INT340X thermal drivers # ACPI INT340X thermal drivers
# #
CONFIG_SUN50I_H6_THS=m CONFIG_SUN50I_H6_THS=m
CONFIG_SUN8I_THS=m
CONFIG_GENERIC_ADC_THERMAL=m CONFIG_GENERIC_ADC_THERMAL=m
CONFIG_WATCHDOG=y CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_CORE=y
@ -3723,6 +3725,7 @@ CONFIG_VIDEO_RJ54N1=m
# CONFIG_VIDEO_SMIAPP is not set # CONFIG_VIDEO_SMIAPP is not set
CONFIG_VIDEO_ET8EK8=m CONFIG_VIDEO_ET8EK8=m
# CONFIG_VIDEO_S5C73M3 is not set # CONFIG_VIDEO_S5C73M3 is not set
CONFIG_VIDEO_HM5065=m
# #
# Flash devices # Flash devices
@ -3993,8 +3996,10 @@ CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100 CONFIG_DRM_FBDEV_OVERALLOC=100
CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y
# CONFIG_DRM_DP_CEC is not set # CONFIG_DRM_DP_CEC is not set
CONFIG_DRM_TTM=m
CONFIG_DRM_GEM_CMA_HELPER=y CONFIG_DRM_GEM_CMA_HELPER=y
CONFIG_DRM_KMS_CMA_HELPER=y CONFIG_DRM_KMS_CMA_HELPER=y
CONFIG_DRM_SCHED=m
# #
# I2C encoder or helper chips # I2C encoder or helper chips
@ -4063,7 +4068,6 @@ CONFIG_DRM_PANEL_BRIDGE=y
# #
# Display Interface Bridges # Display Interface Bridges
# #
# CONFIG_DRM_ANALOGIX_ANX78XX is not set
# CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CDNS_DSI is not set
# CONFIG_DRM_DUMB_VGA_DAC is not set # CONFIG_DRM_DUMB_VGA_DAC is not set
# CONFIG_DRM_LVDS_ENCODER is not set # CONFIG_DRM_LVDS_ENCODER is not set
@ -4076,6 +4080,9 @@ CONFIG_DRM_PANEL_BRIDGE=y
# CONFIG_DRM_THINE_THC63LVD1024 is not set # CONFIG_DRM_THINE_THC63LVD1024 is not set
# CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_TOSHIBA_TC358767 is not set
# CONFIG_DRM_TI_TFP410 is not set # CONFIG_DRM_TI_TFP410 is not set
CONFIG_DRM_ANALOGIX_DP_I2C=m
# CONFIG_DRM_ANALOGIX_ANX78XX is not set
CONFIG_DRM_ANALOGIX_ANX6345=m
# CONFIG_DRM_I2C_ADV7511 is not set # CONFIG_DRM_I2C_ADV7511 is not set
CONFIG_DRM_DW_HDMI=y CONFIG_DRM_DW_HDMI=y
# CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set # CONFIG_DRM_DW_HDMI_AHB_AUDIO is not set
@ -4094,6 +4101,7 @@ CONFIG_TINYDRM_MI0283QT=m
# CONFIG_TINYDRM_ST7735R is not set # CONFIG_TINYDRM_ST7735R is not set
# CONFIG_DRM_PL111 is not set # CONFIG_DRM_PL111 is not set
# CONFIG_DRM_TVE200 is not set # CONFIG_DRM_TVE200 is not set
CONFIG_DRM_LIMA=m
# CONFIG_DRM_LEGACY is not set # CONFIG_DRM_LEGACY is not set
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
@ -4254,9 +4262,11 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
# #
CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SUN4I_CODEC=m
CONFIG_SND_SUN8I_CODEC=m CONFIG_SND_SUN8I_CODEC=m
CONFIG_SND_AC100_CODEC=m
CONFIG_SND_SUN8I_CODEC_ANALOG=m CONFIG_SND_SUN8I_CODEC_ANALOG=m
CONFIG_SND_SUN4I_I2S=m CONFIG_SND_SUN4I_I2S=m
CONFIG_SND_SUN4I_SPDIF=m CONFIG_SND_SUN4I_SPDIF=m
CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m
# CONFIG_SND_SOC_XTFPGA_I2S is not set # CONFIG_SND_SOC_XTFPGA_I2S is not set
# CONFIG_ZX_TDM is not set # CONFIG_ZX_TDM is not set
CONFIG_SND_SOC_I2C_AND_SPI=m CONFIG_SND_SOC_I2C_AND_SPI=m
@ -4879,6 +4889,7 @@ CONFIG_LEDS_REGULATOR=m
CONFIG_LEDS_SYSCON=y CONFIG_LEDS_SYSCON=y
CONFIG_LEDS_MLXREG=m CONFIG_LEDS_MLXREG=m
CONFIG_LEDS_USER=y CONFIG_LEDS_USER=y
CONFIG_LEDS_AXP20X=m
# #
# LED Triggers # LED Triggers
@ -5735,7 +5746,7 @@ CONFIG_RESET_SUNXI=y
CONFIG_GENERIC_PHY=y CONFIG_GENERIC_PHY=y
CONFIG_PHY_SUN4I_USB=y CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_SUN50I_USB3=y CONFIG_PHY_SUN50I_USB3=m
# CONFIG_BCM_KONA_USB2_PHY is not set # CONFIG_BCM_KONA_USB2_PHY is not set
# CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_HSIC is not set
# CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_PHY_PXA_28NM_USB2 is not set
@ -5764,7 +5775,7 @@ CONFIG_ARM_PMU=y
# CONFIG_ANDROID is not set # CONFIG_ANDROID is not set
CONFIG_DAX=m CONFIG_DAX=m
CONFIG_NVMEM=y CONFIG_NVMEM=y
CONFIG_NVMEM_SUNXI_SID=m CONFIG_NVMEM_SUNXI_SID=y
# #
# HW tracing support # HW tracing support
@ -6232,7 +6243,6 @@ CONFIG_CRYPTO_CHACHA20=m
CONFIG_CRYPTO_SEED=m CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_SM4=m CONFIG_CRYPTO_SM4=m
CONFIG_CRYPTO_SPECK=m
CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_TWOFISH_COMMON=m CONFIG_CRYPTO_TWOFISH_COMMON=m

View file

@ -1,6 +1,6 @@
# #
# Automatically generated file; DO NOT EDIT. # Automatically generated file; DO NOT EDIT.
# Linux/arm64 4.19.1 Kernel Configuration # Linux/arm64 4.19.2 Kernel Configuration
# #
# #
@ -481,7 +481,6 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
CONFIG_CRYPTO_CHACHA20_NEON=y CONFIG_CRYPTO_CHACHA20_NEON=y
CONFIG_CRYPTO_AES_ARM64_BS=y CONFIG_CRYPTO_AES_ARM64_BS=y
# CONFIG_CRYPTO_SPECK_NEON is not set
# #
# General architecture-dependent options # General architecture-dependent options
@ -751,6 +750,8 @@ CONFIG_XFRM_IPCOMP=m
CONFIG_NET_KEY=m CONFIG_NET_KEY=m
# CONFIG_NET_KEY_MIGRATE is not set # CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y CONFIG_INET=y
CONFIG_WIREGUARD=m
# CONFIG_WIREGUARD_DEBUG is not set
CONFIG_IP_MULTICAST=y CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_FIB_TRIE_STATS=y
@ -2065,6 +2066,7 @@ CONFIG_USB_VL600=m
CONFIG_USB_NET_CH9200=m CONFIG_USB_NET_CH9200=m
CONFIG_WLAN=y CONFIG_WLAN=y
CONFIG_WLAN_VENDOR_ADMTEK=y CONFIG_WLAN_VENDOR_ADMTEK=y
CONFIG_RTL8189ES=m
CONFIG_ATH_COMMON=m CONFIG_ATH_COMMON=m
CONFIG_WLAN_VENDOR_ATH=y CONFIG_WLAN_VENDOR_ATH=y
# CONFIG_ATH_DEBUG is not set # CONFIG_ATH_DEBUG is not set
@ -2161,10 +2163,12 @@ CONFIG_RT2X00_LIB_LEDS=y
CONFIG_WLAN_VENDOR_REALTEK=y CONFIG_WLAN_VENDOR_REALTEK=y
CONFIG_RTL8187=m CONFIG_RTL8187=m
CONFIG_RTL8187_LEDS=y CONFIG_RTL8187_LEDS=y
CONFIG_RTL8189FS=m
CONFIG_RTL_CARDS=m CONFIG_RTL_CARDS=m
# CONFIG_RTL8192CU is not set # CONFIG_RTL8192CU is not set
CONFIG_RTL8XXXU=m CONFIG_RTL8XXXU=m
CONFIG_RTL8XXXU_UNTESTED=y CONFIG_RTL8XXXU_UNTESTED=y
CONFIG_RTL8723CS=m
# CONFIG_WLAN_VENDOR_RSI is not set # CONFIG_WLAN_VENDOR_RSI is not set
# CONFIG_WLAN_VENDOR_ST is not set # CONFIG_WLAN_VENDOR_ST is not set
# CONFIG_WLAN_VENDOR_TI is not set # CONFIG_WLAN_VENDOR_TI is not set
@ -2918,6 +2922,7 @@ CONFIG_THERMAL_EMULATION=y
# ACPI INT340X thermal drivers # ACPI INT340X thermal drivers
# #
CONFIG_SUN50I_H6_THS=m CONFIG_SUN50I_H6_THS=m
CONFIG_SUN8I_THS=m
# CONFIG_QCOM_SPMI_TEMP_ALARM is not set # CONFIG_QCOM_SPMI_TEMP_ALARM is not set
CONFIG_GENERIC_ADC_THERMAL=m CONFIG_GENERIC_ADC_THERMAL=m
CONFIG_WATCHDOG=y CONFIG_WATCHDOG=y
@ -2969,7 +2974,7 @@ CONFIG_BCMA_BLOCKIO=y
# #
CONFIG_MFD_CORE=y CONFIG_MFD_CORE=y
# CONFIG_MFD_ACT8945A is not set # CONFIG_MFD_ACT8945A is not set
CONFIG_MFD_SUN4I_GPADC=m CONFIG_MFD_SUN4I_GPADC=y
# CONFIG_MFD_AS3711 is not set # CONFIG_MFD_AS3711 is not set
# CONFIG_MFD_AS3722 is not set # CONFIG_MFD_AS3722 is not set
# CONFIG_PMIC_ADP5520 is not set # CONFIG_PMIC_ADP5520 is not set
@ -3641,8 +3646,10 @@ CONFIG_DRM_FBDEV_EMULATION=y
CONFIG_DRM_FBDEV_OVERALLOC=100 CONFIG_DRM_FBDEV_OVERALLOC=100
CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y
# CONFIG_DRM_DP_CEC is not set # CONFIG_DRM_DP_CEC is not set
CONFIG_DRM_TTM=m
CONFIG_DRM_GEM_CMA_HELPER=y CONFIG_DRM_GEM_CMA_HELPER=y
CONFIG_DRM_KMS_CMA_HELPER=y CONFIG_DRM_KMS_CMA_HELPER=y
CONFIG_DRM_SCHED=m
# #
# I2C encoder or helper chips # I2C encoder or helper chips
@ -3706,7 +3713,6 @@ CONFIG_DRM_PANEL_BRIDGE=y
# #
# Display Interface Bridges # Display Interface Bridges
# #
CONFIG_DRM_ANALOGIX_ANX78XX=m
CONFIG_DRM_CDNS_DSI=m CONFIG_DRM_CDNS_DSI=m
# CONFIG_DRM_DUMB_VGA_DAC is not set # CONFIG_DRM_DUMB_VGA_DAC is not set
# CONFIG_DRM_LVDS_ENCODER is not set # CONFIG_DRM_LVDS_ENCODER is not set
@ -3719,6 +3725,9 @@ CONFIG_DRM_SII9234=m
CONFIG_DRM_THINE_THC63LVD1024=m CONFIG_DRM_THINE_THC63LVD1024=m
# CONFIG_DRM_TOSHIBA_TC358767 is not set # CONFIG_DRM_TOSHIBA_TC358767 is not set
# CONFIG_DRM_TI_TFP410 is not set # CONFIG_DRM_TI_TFP410 is not set
CONFIG_DRM_ANALOGIX_DP_I2C=m
CONFIG_DRM_ANALOGIX_ANX78XX=m
CONFIG_DRM_ANALOGIX_ANX6345=m
# CONFIG_DRM_I2C_ADV7511 is not set # CONFIG_DRM_I2C_ADV7511 is not set
CONFIG_DRM_DW_HDMI=y CONFIG_DRM_DW_HDMI=y
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
@ -3729,6 +3738,7 @@ CONFIG_DRM_DW_HDMI_CEC=m
# CONFIG_DRM_MXSFB is not set # CONFIG_DRM_MXSFB is not set
# CONFIG_DRM_TINYDRM is not set # CONFIG_DRM_TINYDRM is not set
# CONFIG_DRM_PL111 is not set # CONFIG_DRM_PL111 is not set
CONFIG_DRM_LIMA=m
# CONFIG_DRM_LEGACY is not set # CONFIG_DRM_LEGACY is not set
CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
@ -3892,9 +3902,12 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y
# Allwinner SoC Audio support # Allwinner SoC Audio support
# #
CONFIG_SND_SUN4I_CODEC=m CONFIG_SND_SUN4I_CODEC=m
CONFIG_SND_SUN8I_CODEC=m
CONFIG_SND_SUN8I_CODEC_ANALOG=m CONFIG_SND_SUN8I_CODEC_ANALOG=m
CONFIG_SND_SUN50I_CODEC_ANALOG=m
CONFIG_SND_SUN4I_I2S=m CONFIG_SND_SUN4I_I2S=m
CONFIG_SND_SUN4I_SPDIF=m CONFIG_SND_SUN4I_SPDIF=m
CONFIG_SND_SUN8I_ADDA_PR_REGMAP=m
# CONFIG_SND_SOC_XTFPGA_I2S is not set # CONFIG_SND_SOC_XTFPGA_I2S is not set
# CONFIG_ZX_TDM is not set # CONFIG_ZX_TDM is not set
CONFIG_SND_SOC_I2C_AND_SPI=m CONFIG_SND_SOC_I2C_AND_SPI=m
@ -4477,6 +4490,7 @@ CONFIG_LEDS_REGULATOR=m
CONFIG_LEDS_SYSCON=y CONFIG_LEDS_SYSCON=y
CONFIG_LEDS_MLXREG=m CONFIG_LEDS_MLXREG=m
CONFIG_LEDS_USER=y CONFIG_LEDS_USER=y
CONFIG_LEDS_AXP20X=m
# #
# LED Triggers # LED Triggers
@ -4845,6 +4859,7 @@ CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
CONFIG_FSL_ERRATUM_A008585=y CONFIG_FSL_ERRATUM_A008585=y
# CONFIG_HISILICON_ERRATUM_161010101 is not set # CONFIG_HISILICON_ERRATUM_161010101 is not set
# CONFIG_ARM64_ERRATUM_858921 is not set # CONFIG_ARM64_ERRATUM_858921 is not set
CONFIG_SUN50I_A64_UNSTABLE_TIMER=y
# CONFIG_ARM_TIMER_SP804 is not set # CONFIG_ARM_TIMER_SP804 is not set
CONFIG_MAILBOX=y CONFIG_MAILBOX=y
CONFIG_ARM_MHU=y CONFIG_ARM_MHU=y
@ -5846,7 +5861,6 @@ CONFIG_CRYPTO_CHACHA20=y
# CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SEED is not set
CONFIG_CRYPTO_SERPENT=y CONFIG_CRYPTO_SERPENT=y
CONFIG_CRYPTO_SM4=m CONFIG_CRYPTO_SM4=m
# CONFIG_CRYPTO_SPECK is not set
# CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_TEA is not set
CONFIG_CRYPTO_TWOFISH=y CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRYPTO_TWOFISH_COMMON=y CONFIG_CRYPTO_TWOFISH_COMMON=y

View file

@ -5,7 +5,7 @@ OVERLAY_PREFIX='sun50i-h6'
BOOTENV_FILE='sun50iw2-next.txt' BOOTENV_FILE='sun50iw2-next.txt'
[[ -z $CPUMIN ]] && CPUMIN=480000 [[ -z $CPUMIN ]] && CPUMIN=480000
[[ -z $CPUMAX ]] && CPUMAX=1510000 [[ -z $CPUMAX ]] && CPUMAX=1810000
GOVERNOR=ondemand GOVERNOR=ondemand
ASOUND_STATE='asound.state.sun50iw2-dev' ASOUND_STATE='asound.state.sun50iw2-dev'
@ -26,17 +26,19 @@ BOOTSCRIPT='boot-sun50i-next.cmd:boot.cmd'
case $BRANCH in case $BRANCH in
dev) dev)
KERNELSOURCE='https://github.com/Icenowy/linux' KERNELSOURCE='https://github.com/Icenowy/linux'
KERNELBRANCH='branch:h6-integrate-2-ugly' KERNELBRANCH='branch:h6-integrate-2-ugly'
KERNELDIR=$MAINLINE_KERNEL_DIR KERNELDIR=$MAINLINE_KERNEL_DIR
KERNEL_USE_GCC='> 7.0' KERNEL_USE_GCC='> 7.0'
KERNELPATCHDIR='sunxi-dev-h6' KERNELPATCHDIR='sunxi-dev-h6'
#KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
KERNELSOURCE="https://github.com/megous/linux"
#KERNELBRANCH='branch:linux-4.19.y'
KERNELBRANCH="branch:orange-pi-4.19"
KERNELPATCHDIR='sunxi-dev'
KERNELDIR=$MAINLINE_KERNEL_DIR
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
KERNELBRANCH='branch:linux-4.19.y'
KERNELDIR=$MAINLINE_KERNEL_DIR
KERNEL_USE_GCC='> 7.0'
KERNELPATCHDIR='sunxi-dev'
;; ;;
esac esac

View file

@ -45,12 +45,13 @@ case $BRANCH in
ATF_USE_GCC='> 6.3' ATF_USE_GCC='> 6.3'
ATF_TARGET_MAP='PLAT=sun50iw1p1 DEBUG=1 bl31;;build/sun50iw1p1/debug/bl31.bin' ATF_TARGET_MAP='PLAT=sun50iw1p1 DEBUG=1 bl31;;build/sun50iw1p1/debug/bl31.bin'
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE #KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
KERNELBRANCH='branch:linux-4.19.y' KERNELSOURCE="https://github.com/megous/linux"
#KERNELBRANCH='branch:linux-4.19.y'
KERNELBRANCH="branch:orange-pi-4.19"
KERNELDIR=$MAINLINE_KERNEL_DIR KERNELDIR=$MAINLINE_KERNEL_DIR
KERNEL_USE_GCC='> 7.0'
KERNELPATCHDIR='sunxi-dev' KERNELPATCHDIR='sunxi-dev'
KERNEL_USE_GCC='> 7.0'
;; ;;
esac esac

View file

@ -36,10 +36,12 @@ case $BRANCH in
dev) dev)
KERNELSOURCE=$MAINLINE_KERNEL_SOURCE #KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
KERNELBRANCH='branch:linux-4.19.y' KERNELSOURCE="https://github.com/megous/linux"
#KERNELBRANCH='branch:linux-4.19.y'
KERNELBRANCH="branch:orange-pi-4.19"
KERNELDIR=$MAINLINE_KERNEL_DIR KERNELDIR=$MAINLINE_KERNEL_DIR
KERNELPATCHDIR='sunxi-dev'
KERNEL_USE_GCC='> 7.0' KERNEL_USE_GCC='> 7.0'
;; ;;

View file

@ -480,6 +480,15 @@ prepare_partitions()
[[ -f $SDCARD/boot/armbianEnv.txt ]] && rm $SDCARD/boot/armbianEnv.txt [[ -f $SDCARD/boot/armbianEnv.txt ]] && rm $SDCARD/boot/armbianEnv.txt
fi fi
# if we have a headless device, set console to serial
if [[ $BUILD_DESKTOP == "no" ]]; then
if grep -lq "^console=" $SDCARD/boot/armbianEnv.txt; then
sed -i "s/console=.*/console=serial/" $SDCARD/boot/armbianEnv.txt
else
echo "console=serial" >> $SDCARD/boot/armbianEnv.txt
fi
fi
# recompile .cmd to .scr if boot.cmd exists # recompile .cmd to .scr if boot.cmd exists
[[ -f $SDCARD/boot/boot.cmd ]] && \ [[ -f $SDCARD/boot/boot.cmd ]] && \
mkimage -C none -A arm -T script -d $SDCARD/boot/boot.cmd $SDCARD/boot/boot.scr > /dev/null 2>&1 mkimage -C none -A arm -T script -d $SDCARD/boot/boot.cmd $SDCARD/boot/boot.scr > /dev/null 2>&1

View file

@ -1,17 +0,0 @@
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index d7c803c3..9ab2d1e2 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -59,6 +59,12 @@
opp-microvolt = <1060000>;
clock-latency-ns = <244144>; /* 8 32k periods */
};
+
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1160000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
};
cpus {

View file

@ -1,125 +0,0 @@
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 65f4e2a4..9eb2043c 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -339,6 +339,12 @@ $(INSTALL_TARGETS):
%.dtb: | scripts
$(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
+%.dtbo: | scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
+
+%.scr: | scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@
+
PHONY += dtbs dtbs_install
dtbs: prepare scripts
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
index 3c79f859..4e5c1d59 100644
--- a/arch/arm/boot/.gitignore
+++ b/arch/arm/boot/.gitignore
@@ -3,3 +3,5 @@ zImage
xipImage
bootpImage
uImage
+*.dtb*
+*.scr
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index f839ecd9..9788f16d 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -121,6 +121,12 @@ zinstall install:
%.dtb: scripts
$(Q)$(MAKE) $(build)=$(boot)/dts $(boot)/dts/$@
+%.dtbo: | scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts MACHINE=$(MACHINE) $(boot)/dts/$@
+
+%.scr: | scripts
+ $(Q)$(MAKE) $(build)=$(boot)/dts ARCH=$(ARCH) $(boot)/dts/$@
+
PHONY += dtbs dtbs_install
dtbs: prepare scripts
diff --git a/arch/arm64/boot/dts/.gitignore b/arch/arm64/boot/dts/.gitignore
index b60ed208..4bec63b6 100644
--- a/arch/arm64/boot/dts/.gitignore
+++ b/arch/arm64/boot/dts/.gitignore
@@ -0,0 +1,2 @@
+*.dtb*
+*.scr
diff --git a/scripts/Makefile.dtbinst b/scripts/Makefile.dtbinst
index 34614a48..8a8313d6 100644
--- a/scripts/Makefile.dtbinst
+++ b/scripts/Makefile.dtbinst
@@ -20,6 +20,9 @@ include scripts/Kbuild.include
include $(src)/Makefile
dtbinst-files := $(sort $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS), $(dtb-)))
+dtboinst-files := $(dtbo-y)
+script-files := $(scr-y)
+readme-files := $(dtbotxt-y)
dtbinst-dirs := $(subdir-y) $(subdir-m)
# Helper targets for Installing DTBs into the boot directory
@@ -31,10 +34,19 @@ install-dir = $(patsubst $(dtbinst_root)%,$(INSTALL_DTBS_PATH)%,$(obj))
$(dtbinst-files): %.dtb: $(obj)/%.dtb
$(call cmd,dtb_install,$(install-dir))
+$(dtboinst-files): %.dtbo: $(obj)/%.dtbo
+ $(call cmd,dtb_install,$(install-dir))
+
+$(script-files): %.scr: $(obj)/%.scr
+ $(call cmd,dtb_install,$(install-dir))
+
+$(readme-files): %: $(src)/%
+ $(call cmd,dtb_install,$(install-dir))
+
$(dtbinst-dirs):
$(Q)$(MAKE) $(dtbinst)=$(obj)/$@
-PHONY += $(dtbinst-files) $(dtbinst-dirs)
-__dtbs_install: $(dtbinst-files) $(dtbinst-dirs)
+PHONY += $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs)
+__dtbs_install: $(dtbinst-files) $(dtboinst-files) $(script-files) $(readme-files) $(dtbinst-dirs)
.PHONY: $(PHONY)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index 58c05e5d..2b95dda9 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -278,6 +278,9 @@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
# ---------------------------------------------------------------------------
DTC ?= $(objtree)/scripts/dtc/dtc
+# Overlay support
+DTC_FLAGS += -@ -Wno-unit_address_format -Wno-simple_bus_reg
+
# Disable noisy checks by default
ifeq ($(KBUILD_ENABLE_EXTRA_GCC_CHECKS),)
DTC_FLAGS += -Wno-unit_address_vs_reg \
@@ -324,6 +327,23 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
$(obj)/%.dtb: $(src)/%.dts FORCE
$(call if_changed_dep,dtc)
+quiet_cmd_dtco = DTCO $@
+cmd_dtco = mkdir -p $(dir ${dtc-tmp}) ; \
+ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
+ $(DTC) -O dtb -o $@ -b 0 \
+ -i $(dir $<) $(DTC_FLAGS) \
+ -d $(depfile).dtc.tmp $(dtc-tmp) ; \
+ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
+
+$(obj)/%.dtbo: $(src)/%.dts FORCE
+ $(call if_changed_dep,dtco)
+
+quiet_cmd_scr = MKIMAGE $@
+cmd_scr = mkimage -C none -A $(ARCH) -T script -d $< $@
+
+$(obj)/%.scr: $(src)/%.scr-cmd FORCE
+ $(call if_changed,scr)
+
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
# Bzip2

View file

@ -1,326 +0,0 @@
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index bc07ad3..e9da9cf 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -113,6 +113,13 @@ config OF_OVERLAY
While this option is selected automatically when needed, you can
enable it manually to improve device tree unit test coverage.
+config OF_CONFIGFS
+ bool "Device Tree Overlay ConfigFS interface"
+ select CONFIGFS_FS
+ depends on OF_OVERLAY
+ help
+ Enable a simple user-space driven DT overlay interface.
+
config OF_NUMA
bool
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index d7efd9d..a06cc35 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o
obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o
obj-$(CONFIG_OF_RESOLVE) += resolver.o
obj-$(CONFIG_OF_OVERLAY) += overlay.o
+obj-$(CONFIG_OF_CONFIGFS) += configfs.o
obj-$(CONFIG_OF_NUMA) += of_numa.o
obj-$(CONFIG_OF_UNITTEST) += unittest-data/
diff --git a/drivers/of/configfs.c b/drivers/of/configfs.c
new file mode 100644
index 0000000..68f889d
--- /dev/null
+++ b/drivers/of/configfs.c
@@ -0,0 +1,277 @@
+/*
+ * Configfs entries for device-tree
+ *
+ * Copyright (C) 2013 - Pantelis Antoniou <panto@antoniou-consulting.com>
+ *
+ * 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/ctype.h>
+#include <linux/cpu.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/configfs.h>
+#include <linux/types.h>
+#include <linux/stat.h>
+#include <linux/limits.h>
+#include <linux/file.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/sizes.h>
+
+#include "of_private.h"
+
+struct cfs_overlay_item {
+ struct config_item item;
+
+ char path[PATH_MAX];
+
+ const struct firmware *fw;
+ struct device_node *overlay;
+ int ov_id;
+
+ void *dtbo;
+ int dtbo_size;
+};
+
+static inline struct cfs_overlay_item *to_cfs_overlay_item(
+ struct config_item *item)
+{
+ return item ? container_of(item, struct cfs_overlay_item, item) : NULL;
+}
+
+static ssize_t cfs_overlay_item_path_show(struct config_item *item,
+ char *page)
+{
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
+ return sprintf(page, "%s\n", overlay->path);
+}
+
+static ssize_t cfs_overlay_item_path_store(struct config_item *item,
+ const char *page, size_t count)
+{
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
+ const char *p = page;
+ char *s;
+ int err;
+
+ /* if it's set do not allow changes */
+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
+ return -EPERM;
+
+ /* copy to path buffer (and make sure it's always zero terminated */
+ count = snprintf(overlay->path, sizeof(overlay->path) - 1, "%s", p);
+ overlay->path[sizeof(overlay->path) - 1] = '\0';
+
+ /* strip trailing newlines */
+ s = overlay->path + strlen(overlay->path);
+ while (s > overlay->path && *--s == '\n')
+ *s = '\0';
+
+ pr_debug("%s: path is '%s'\n", __func__, overlay->path);
+
+ err = request_firmware(&overlay->fw, overlay->path, NULL);
+ if (err != 0)
+ goto out_err;
+
+ err = of_overlay_fdt_apply((void *)overlay->fw->data,
+ (u32)overlay->fw->size, &overlay->ov_id);
+ if (err != 0)
+ goto out_err;
+
+ return count;
+
+out_err:
+
+ release_firmware(overlay->fw);
+ overlay->fw = NULL;
+
+ overlay->path[0] = '\0';
+ return err;
+}
+
+static ssize_t cfs_overlay_item_status_show(struct config_item *item,
+ char *page)
+{
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
+
+ return sprintf(page, "%s\n",
+ overlay->ov_id > 0 ? "applied" : "unapplied");
+}
+
+CONFIGFS_ATTR(cfs_overlay_item_, path);
+CONFIGFS_ATTR_RO(cfs_overlay_item_, status);
+
+static struct configfs_attribute *cfs_overlay_attrs[] = {
+ &cfs_overlay_item_attr_path,
+ &cfs_overlay_item_attr_status,
+ NULL,
+};
+
+ssize_t cfs_overlay_item_dtbo_read(struct config_item *item,
+ void *buf, size_t max_count)
+{
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
+
+ pr_debug("%s: buf=%p max_count=%zu\n", __func__,
+ buf, max_count);
+
+ if (overlay->dtbo == NULL)
+ return 0;
+
+ /* copy if buffer provided */
+ if (buf != NULL) {
+ /* the buffer must be large enough */
+ if (overlay->dtbo_size > max_count)
+ return -ENOSPC;
+
+ memcpy(buf, overlay->dtbo, overlay->dtbo_size);
+ }
+
+ return overlay->dtbo_size;
+}
+
+ssize_t cfs_overlay_item_dtbo_write(struct config_item *item,
+ const void *buf, size_t count)
+{
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
+ int err;
+
+ /* if it's set do not allow changes */
+ if (overlay->path[0] != '\0' || overlay->dtbo_size > 0)
+ return -EPERM;
+
+ /* copy the contents */
+ overlay->dtbo = kmemdup(buf, count, GFP_KERNEL);
+ if (overlay->dtbo == NULL)
+ return -ENOMEM;
+
+ overlay->dtbo_size = count;
+
+ err = of_overlay_fdt_apply(overlay->dtbo, overlay->dtbo_size,
+ &overlay->ov_id);
+ if (err != 0)
+ goto out_err;
+
+ return count;
+
+out_err:
+ kfree(overlay->dtbo);
+ overlay->dtbo = NULL;
+ overlay->dtbo_size = 0;
+ overlay->ov_id = 0;
+
+ return err;
+}
+
+CONFIGFS_BIN_ATTR(cfs_overlay_item_, dtbo, NULL, SZ_1M);
+
+static struct configfs_bin_attribute *cfs_overlay_bin_attrs[] = {
+ &cfs_overlay_item_attr_dtbo,
+ NULL,
+};
+
+static void cfs_overlay_release(struct config_item *item)
+{
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
+
+ if (overlay->ov_id > 0)
+ of_overlay_remove(&overlay->ov_id);
+ if (overlay->fw)
+ release_firmware(overlay->fw);
+ /* kfree with NULL is safe */
+ kfree(overlay->dtbo);
+ kfree(overlay);
+}
+
+static struct configfs_item_operations cfs_overlay_item_ops = {
+ .release = cfs_overlay_release,
+};
+
+static struct config_item_type cfs_overlay_type = {
+ .ct_item_ops = &cfs_overlay_item_ops,
+ .ct_attrs = cfs_overlay_attrs,
+ .ct_bin_attrs = cfs_overlay_bin_attrs,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct config_item *cfs_overlay_group_make_item(
+ struct config_group *group, const char *name)
+{
+ struct cfs_overlay_item *overlay;
+
+ overlay = kzalloc(sizeof(*overlay), GFP_KERNEL);
+ if (!overlay)
+ return ERR_PTR(-ENOMEM);
+
+ config_item_init_type_name(&overlay->item, name, &cfs_overlay_type);
+ return &overlay->item;
+}
+
+static void cfs_overlay_group_drop_item(struct config_group *group,
+ struct config_item *item)
+{
+ struct cfs_overlay_item *overlay = to_cfs_overlay_item(item);
+
+ config_item_put(&overlay->item);
+}
+
+static struct configfs_group_operations overlays_ops = {
+ .make_item = cfs_overlay_group_make_item,
+ .drop_item = cfs_overlay_group_drop_item,
+};
+
+static struct config_item_type overlays_type = {
+ .ct_group_ops = &overlays_ops,
+ .ct_owner = THIS_MODULE,
+};
+
+static struct configfs_group_operations of_cfs_ops = {
+ /* empty - we don't allow anything to be created */
+};
+
+static struct config_item_type of_cfs_type = {
+ .ct_group_ops = &of_cfs_ops,
+ .ct_owner = THIS_MODULE,
+};
+
+struct config_group of_cfs_overlay_group;
+
+static struct configfs_subsystem of_cfs_subsys = {
+ .su_group = {
+ .cg_item = {
+ .ci_namebuf = "device-tree",
+ .ci_type = &of_cfs_type,
+ },
+ },
+ .su_mutex = __MUTEX_INITIALIZER(of_cfs_subsys.su_mutex),
+};
+
+static int __init of_cfs_init(void)
+{
+ int ret;
+
+ pr_info("%s\n", __func__);
+
+ config_group_init(&of_cfs_subsys.su_group);
+ config_group_init_type_name(&of_cfs_overlay_group, "overlays",
+ &overlays_type);
+ configfs_add_default_group(&of_cfs_overlay_group,
+ &of_cfs_subsys.su_group);
+
+ ret = configfs_register_subsystem(&of_cfs_subsys);
+ if (ret != 0) {
+ pr_err("%s: failed to register subsys\n", __func__);
+ goto out;
+ }
+ pr_info("%s: OK\n", __func__);
+out:
+ return ret;
+}
+late_initcall(of_cfs_init);
diff --git a/drivers/of/fdt_address.c b/drivers/of/fdt_address.c
index dca8f9b..ec7e167 100644
--- a/drivers/of/fdt_address.c
+++ b/drivers/of/fdt_address.c
@@ -161,7 +161,7 @@ static int __init fdt_translate_one(const void *blob, int parent,
* that can be mapped to a cpu physical address). This is not really specified
* that way, but this is traditionally the way IBM at least do things
*/
-static u64 __init fdt_translate_address(const void *blob, int node_offset)
+u64 __init fdt_translate_address(const void *blob, int node_offset)
{
int parent, len;
const struct of_bus *bus, *pbus;

View file

@ -1,275 +0,0 @@
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index 3040c3074..712e1cf5f
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts
new file mode 100644
index 000000000..385015396
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts
@@ -0,0 +1,258 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (c) 2018 Armbian
+ */
+
+/dts-v1/;
+
+#include "sun50i-h6.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Orange Pi One+";
+ compatible = "xunlong,orangepi-one-plus", "allwinner,sun50i-h6";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pwr {
+ label = "orangepi:red:pwr";
+ gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ status {
+ label = "orangepi:green:status";
+ gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_gmac_3v3: gmac-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc-gmac-3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ startup-delay-us = <100000>;
+ enable-active-high;
+ gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>; /* PD6 */
+ vin-supply = <&reg_aldo2>;
+ };
+
+ reg_vcc3v3: vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_vcc1v8: vcc1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_usb_vbus: vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <100000>;
+ gpio = <&r_pio 0 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdca>;
+};
+
+&usb2phy {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci3 {
+ status = "okay";
+};
+
+
+&emac {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ext_rgmii_pins>;
+ phy-mode = "rgmii";
+ phy-handle = <&ext_rgmii_phy>;
+ phy-supply = <&reg_gmac_3v3>;
+ allwinner,rx-delay-ps = <200>;
+ allwinner,tx-delay-ps = <200>;
+ status = "disabled";
+};
+
+&dwc3 {
+ status = "okay";
+};
+
+&mdio {
+ ext_rgmii_phy: ethernet-phy@1 {
+ compatible = "ethernet-phy-ieee802.3-c22";
+ reg = <1>;
+ };
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci3 {
+ status = "okay";
+};
+
+&r_i2c {
+ status = "okay";
+
+ axp805: pmic@36 {
+ compatible = "x-powers,axp805", "x-powers,axp806";
+ reg = <0x36>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ x-powers,master-mode;
+
+ regulators {
+ reg_aldo1: aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-pl";
+ };
+
+ reg_aldo2: aldo2 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-ac200";
+ };
+
+ reg_aldo3: aldo3 {
+ /* This regulator is connected with CLDO1 */
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3-1";
+ };
+
+ reg_bldo1: bldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-ddr-bias-pll";
+ };
+
+ reg_bldo2: bldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-efuse-emmc-pcie-hdmi";
+ };
+
+ reg_bldo3: bldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-wifi-io";
+ };
+
+ bldo4 {
+ /* unused */
+ };
+
+ reg_cldo1: cldo1 {
+ /* This regulator is connected with ALDO3 */
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3-2";
+ };
+
+ reg_cldo2: cldo2 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-1";
+ };
+
+ reg_cldo3: cldo3 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-2";
+ };
+
+ reg_dcdca: dcdca {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1160000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ reg_dcdcc: dcdcc {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1080000>;
+ regulator-name = "vdd-gpu";
+ };
+
+ reg_dcdcd: dcdcd {
+ regulator-always-on;
+ regulator-min-microvolt = <960000>;
+ regulator-max-microvolt = <960000>;
+ regulator-name = "vdd-sys";
+ };
+
+ reg_dcdce: dcdce {
+ regulator-always-on;
+ regulator-min-microvolt = <1400000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vcc-dram";
+ };
+
+ sw {
+ /* unused */
+ };
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_ph_pins>;
+ status = "okay";
+};
+
+&usb2otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usb2phy {
+ usb0_vbus-supply = <&reg_usb_vbus>;
+ usb1_vbus-supply = <&reg_usb_vbus>;
+ status = "okay";
+};

View file

@ -1,287 +0,0 @@
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
index a9797d233..4972f2901
--- a/arch/arm64/boot/dts/allwinner/Makefile
+++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-lite2.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb
dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts
new file mode 100644
index 000000000..b9aff606e
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-lite2.dts
@@ -0,0 +1,269 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h6.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ model = "Orange Pi Lite 2";
+ compatible = "pine64,pine-h64", "allwinner,sun50i-h6";
+
+ aliases {
+ serial0 = &uart0;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ pwr {
+ label = "orangepi:red:pwr";
+ gpios = <&r_pio 0 4 GPIO_ACTIVE_HIGH>;
+ default-state = "on";
+ };
+
+ status {
+ label = "orangepi:green:status";
+ gpios = <&r_pio 0 7 GPIO_ACTIVE_HIGH>;
+ };
+ };
+
+ reg_vcc3v3: vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ reg_vcc1v8: vcc1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ reg_usb_vbus: vbus {
+ compatible = "regulator-fixed";
+ regulator-name = "usb-vbus";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ startup-delay-us = <100000>;
+ gpio = <&r_pio 0 5 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ wifi_pwrseq: wifi_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ clocks = <&rtc 1>;
+ clock-names = "ext_clock";
+ reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */
+ post-power-on-delay-ms = <200>;
+ };
+};
+
+&cpu0 {
+ cpu-supply = <&reg_dcdca>;
+};
+
+&dwc3 {
+ status = "okay";
+};
+
+&ehci0 {
+ status = "okay";
+};
+
+&ehci3 {
+ status = "okay";
+};
+
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&reg_cldo2>;
+ vqmmc-supply = <&reg_bldo3>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ bus-width = <4>;
+ non-removable;
+ status = "okay";
+
+ ap6255: sdio_wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ interrupt-parent = <&r_pio>;
+ interrupts = <1 0 IRQ_TYPE_LEVEL_LOW>; /* PM0 */
+ interrupt-names = "host-wake";
+ };
+};
+
+&mmc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc2_pins>;
+ vmmc-supply = <&reg_vcc3v3>;
+ vqmmc-supply = <&reg_bldo3>;
+ non-removable;
+ cap-mmc-hw-reset;
+ status = "okay";
+};
+
+&ohci0 {
+ status = "okay";
+};
+
+&ohci3 {
+ status = "okay";
+};
+
+&r_i2c {
+ pinctrl-names = "default";
+ pinctrl-0 = <&r_i2c_pins>;
+ status = "okay";
+
+ axp805: pmic@36 {
+ compatible = "x-powers,axp805", "x-powers,axp806";
+ reg = <0x36>;
+ interrupt-parent = <&r_intc>;
+ interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ x-powers,self-working-mode;
+
+ regulators {
+ reg_aldo1: aldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-pl";
+ };
+
+ reg_aldo2: aldo2 {
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-ac200";
+ };
+
+ reg_aldo3: aldo3 {
+ /* This regulator is connected with CLDO1 */
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3-1";
+ };
+
+ reg_bldo1: bldo1 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-ddr-bias-pll";
+ };
+
+ reg_bldo2: bldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-efuse-emmc-pcie-hdmi";
+ };
+
+ reg_bldo3: bldo3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-name = "vcc-wifi-io";
+ };
+
+ bldo4 {
+ /* unused */
+ };
+
+ reg_cldo1: cldo1 {
+ /* This regulator is connected with ALDO3 */
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-3v3-2";
+ };
+
+ reg_cldo2: cldo2 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-1";
+ };
+
+ reg_cldo3: cldo3 {
+ regulator-always-on;
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-name = "vcc-wifi-2";
+ };
+
+ reg_dcdca: dcdca {
+ regulator-always-on;
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1160000>;
+ regulator-name = "vdd-cpu";
+ };
+
+ reg_dcdcc: dcdcc {
+ regulator-min-microvolt = <810000>;
+ regulator-max-microvolt = <1080000>;
+ regulator-name = "vdd-gpu";
+ };
+
+ reg_dcdcd: dcdcd {
+ regulator-always-on;
+ regulator-min-microvolt = <960000>;
+ regulator-max-microvolt = <960000>;
+ regulator-name = "vdd-sys";
+ };
+
+ reg_dcdce: dcdce {
+ regulator-always-on;
+ regulator-min-microvolt = <1400000>;
+ regulator-max-microvolt = <1400000>;
+ regulator-name = "vcc-dram";
+ };
+
+ sw {
+ /* unused */
+ };
+ };
+ };
+};
+
+&uart0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart0_ph_pins>;
+ status = "okay";
+};
+
+&usb2otg {
+ dr_mode = "host";
+ status = "okay";
+};
+
+&usb2phy {
+ usb0_vbus-supply = <&reg_usb_vbus>;
+ usb3_vbus-supply = <&reg_usb_vbus>;
+ status = "okay";
+};
+
+&usb3phy {
+ phy-supply = <&reg_usb_vbus>;
+ status = "okay";
+};

View file

@ -1,19 +0,0 @@
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index bec8c4a..cd278d5 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -253,6 +253,14 @@
bias-pull-up;
};
+ mmc1_pins: mmc1-pins {
+ pins = "PG0", "PG1", "PG2", "PG3",
+ "PG4", "PG5";
+ function = "mmc1";
+ drive-strength = <30>;
+ bias-pull-up;
+ };
+
mmc2_pins: mmc2-pins {
pins = "PC1", "PC4", "PC5", "PC6",
"PC7", "PC8", "PC9", "PC10",

View file

@ -1,35 +0,0 @@
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index bec8c4a..73ed36d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -124,6 +124,13 @@
clock-output-names = "osc32k";
};
+ ext_osc32k: ext_osc32k_clk {
+ #clock-cells = <0>;
+ compatible = "fixed-clock";
+ clock-frequency = <32768>;
+ clock-output-names = "ext_osc32k";
+ };
+
psci {
compatible = "arm,psci-0.2";
method = "smc";
@@ -511,6 +526,16 @@
#reset-cells = <1>;
};
+ rtc: rtc@7000000 {
+ compatible = "allwinner,sun6i-a31-rtc";
+ reg = <0x07000000 0x54>;
+ interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ clock-output-names = "rtc-osc32k", "rtc-osc32k-out";
+ clocks = <&ext_osc32k>;
+ #clock-cells = <1>;
+ };
+
r_intc: interrupt-controller@7021000 {
compatible = "allwinner,sun50i-h6-r-intc",
"allwinner,sun6i-a31-r-intc";

View file

@ -1,221 +0,0 @@
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 90c9a8a..3c79b90 100755
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -29,6 +29,27 @@ create_package() {
# in case we are in a restrictive umask environment like 0077
chmod -R a+rX "$pdir"
+ # Create preinstall and post install script to remove dtb
+ if [[ "$1" == *dtb* ]]; then
+ echo "if [ -d /boot/dtb-$version ]; then mv /boot/dtb-$version /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/preinst
+ echo "if [ -d /boot/dtb.old ]; then rm -rf /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst
+ echo "if [ -d /boot/dtb ]; then mv /boot/dtb /boot/dtb.old; fi" >> $pdir/DEBIAN/preinst
+ echo "exit 0" >> $pdir/DEBIAN/preinst
+ chmod 775 $pdir/DEBIAN/preinst
+
+ echo "if [ -d /boot/dtb-$version.old ]; then rm -rf /boot/dtb-$version.old; fi" >> $pdir/DEBIAN/postinst
+ echo "ln -sf dtb-$version /boot/dtb > /dev/null 2>&1 || mv /boot/dtb-$version /boot/dtb" >> $pdir/DEBIAN/postinst
+ echo "exit 0" >> $pdir/DEBIAN/postinst
+ chmod 775 $pdir/DEBIAN/postinst
+ fi
+
+ # Create postinstall script for headers
+ if [[ "$1" == *headers* ]]; then
+ echo "cd /usr/src/linux-headers-$version; echo \"Compiling headers - please wait ...\"; find -type f -exec touch {} +;make -s scripts >/dev/null 2>&1" >> $pdir/DEBIAN/postinst
+ echo "exit 0" >> $pdir/DEBIAN/postinst
+ chmod 775 $pdir/DEBIAN/postinst
+ fi
+
# Create the package
dpkg-gencontrol -p$pname -P"$pdir"
dpkg --build "$pdir" ..
@@ -39,9 +60,11 @@ tmpdir="$objtree/debian/tmp"
kernel_headers_dir="$objtree/debian/hdrtmp"
libc_headers_dir="$objtree/debian/headertmp"
dbg_dir="$objtree/debian/dbgtmp"
-packagename=linux-image-$version
-kernel_headers_packagename=linux-headers-$version
-libc_headers_packagename=linux-libc-dev
+dtb_dir="$objtree/debian/dtbtmp"
+packagename=linux-image-dev"$LOCALVERSION"
+kernel_headers_packagename=linux-headers-dev"$LOCALVERSION"
+dtb_packagename=linux-dtb-dev"$LOCALVERSION"
+libc_headers_packagename=linux-libc-dev-dev"$LOCALVERSION"
dbg_packagename=$packagename-dbg
if [ "$ARCH" = "um" ] ; then
@@ -52,6 +75,15 @@ fi
# XXX: have each arch Makefile export a variable of the canonical image install
# path instead
case $ARCH in
+aarch64|arm64)
+ image_name=Image
+ installed_image_path="boot/vmlinuz-$version"
+
+ ;;
+arm*)
+ image_name=zImage
+ installed_image_path="boot/vmlinuz-$version"
+ ;;
um)
installed_image_path="usr/bin/linux-$version"
;;
@@ -65,7 +97,9 @@ esac
BUILD_DEBUG="$(grep -s '^CONFIG_DEBUG_INFO=y' $KCONFIG_CONFIG || true)"
# Setup the directory structure
-rm -rf "$tmpdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" $objtree/debian/files
+rm -rf "$tmpdir" "$kernel_headers_dir" "$libc_headers_dir" "$dbg_dir" "$dtb_dir" $objtree/debian/files
+mkdir -m 755 -p "$dtb_dir/DEBIAN"
+mkdir -p "$dtb_dir/boot/dtb-$version" "$dtb_dir/usr/share/doc/$dtb_packagename"
mkdir -m 755 -p "$tmpdir/DEBIAN"
mkdir -p "$tmpdir/lib" "$tmpdir/boot"
mkdir -p "$kernel_headers_dir/lib/modules/$version/"
@@ -118,6 +152,11 @@ if grep -q '^CONFIG_MODULES=y' $KCONFIG_CONFIG ; then
fi
fi
+if grep -q '^CONFIG_OF=y' $KCONFIG_CONFIG ; then
+ #mkdir -p "$tmpdir/boot/dtb"
+ INSTALL_DTBS_PATH="$dtb_dir/boot/dtb-$version" $MAKE KBUILD_SRC= dtbs_install
+fi
+
if [ "$ARCH" != "um" ]; then
$MAKE headers_check KBUILD_SRC=
$MAKE headers_install KBUILD_SRC= INSTALL_HDR_PATH="$libc_headers_dir/usr"
@@ -137,7 +176,7 @@ fi
for script in postinst postrm preinst prerm ; do
mkdir -p "$tmpdir$debhookdir/$script.d"
cat <<EOF > "$tmpdir/DEBIAN/$script"
-#!/bin/sh
+#!/bin/bash
set -e
@@ -153,9 +192,60 @@ EOF
chmod 755 "$tmpdir/DEBIAN/$script"
done
+##
+## Create sym link to kernel image
+##
+sed -e "s/set -e//g" -i $tmpdir/DEBIAN/postinst
+sed -e "s/exit 0//g" -i $tmpdir/DEBIAN/postinst
+cat >> $tmpdir/DEBIAN/postinst <<EOT
+if [ "\$(grep nand /proc/partitions)" != "" ] && [ "\$(grep mmc /proc/partitions)" = "" ]; then
+ mkimage -A arm -O linux -T kernel -C none -a "0x40008000" -e "0x40008000" -n "Linux kernel" -d /$installed_image_path /boot/uImage > /dev/null 2>&1
+ cp /boot/uImage /tmp/uImage
+ sync
+ mountpoint -q /boot || mount /boot
+ cp /tmp/uImage /boot/uImage
+ rm -f /$installed_image_path
+else
+ ln -sf $(basename $installed_image_path) /boot/$image_name || mv /$installed_image_path /boot/$image_name
+fi
+touch /boot/.next
+exit 0
+EOT
+
+##
+## FAT install workaround
+##
+sed -e "s/set -e//g" -i $tmpdir/DEBIAN/preinst
+sed -e "s/exit 0//g" -i $tmpdir/DEBIAN/preinst
+cat >> $tmpdir/DEBIAN/preinst <<EOT
+# exit if we are running chroot
+if [ "\$(stat -c %d:%i /)" != "\$(stat -c %d:%i /proc/1/root/.)" ]; then exit 0; fi
+
+check_and_unmount (){
+ boot_device=\$(mountpoint -d /boot)
+
+ for file in /dev/* ; do
+ CURRENT_DEVICE=\$(printf "%d:%d" \$(stat --printf="0x%t 0x%T" \$file))
+ if [[ "\$CURRENT_DEVICE" = "\$boot_device" ]]; then
+ boot_partition=\$file
+ break
+ fi
+ done
+
+ bootfstype=\$(blkid -s TYPE -o value \$boot_partition)
+ if [ "\$bootfstype" = "vfat" ]; then
+ umount /boot
+ rm -f /boot/System.map* /boot/config* /boot/vmlinuz* /boot/$image_name /boot/uImage
+ fi
+}
+mountpoint -q /boot && check_and_unmount
+EOT
+echo "exit 0" >> $tmpdir/DEBIAN/preinst
+
# Build kernel header package
(cd $srctree; find . -name Makefile\* -o -name Kconfig\* -o -name \*.pl) > "$objtree/debian/hdrsrcfiles"
(cd $srctree; find arch/*/include include scripts -type f -o -type l) >> "$objtree/debian/hdrsrcfiles"
+(cd $srctree; find security/*/include -type f) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find arch/$SRCARCH -name module.lds -o -name Kbuild.platforms -o -name Platform) >> "$objtree/debian/hdrsrcfiles"
(cd $srctree; find $(find arch/$SRCARCH -name include -o -name scripts -type d) -type f) >> "$objtree/debian/hdrsrcfiles"
if grep -q '^CONFIG_STACK_VALIDATION=y' $KCONFIG_CONFIG ; then
@@ -167,15 +257,19 @@ if grep -q '^CONFIG_GCC_PLUGINS=y' $KCONFIG_CONFIG ; then
fi
destdir=$kernel_headers_dir/usr/src/linux-headers-$version
mkdir -p "$destdir"
+(cd $destdir; patch -p1 < /tmp/headers-debian-byteshift.patch)
(cd $srctree; tar -c -f - -T -) < "$objtree/debian/hdrsrcfiles" | (cd $destdir; tar -xf -)
(cd $objtree; tar -c -f - -T -) < "$objtree/debian/hdrobjfiles" | (cd $destdir; tar -xf -)
(cd $objtree; cp $KCONFIG_CONFIG $destdir/.config) # copy .config manually to be where it's expected to be
ln -sf "/usr/src/linux-headers-$version" "$kernel_headers_dir/lib/modules/$version/build"
rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
+(cd $destdir; make M=scripts clean)
+
if [ "$ARCH" != "um" ]; then
create_package "$kernel_headers_packagename" "$kernel_headers_dir"
- create_package "$libc_headers_packagename" "$libc_headers_dir"
+ # create_package "$libc_headers_packagename" "$libc_headers_dir"
+ create_package "$dtb_packagename" "$dtb_dir"
fi
create_package "$packagename" "$tmpdir"
diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian
index 6adb3a1..00e12eb 100755
--- a/scripts/package/mkdebian
+++ b/scripts/package/mkdebian
@@ -61,10 +61,12 @@ else
packageversion=$version-$revision
fi
sourcename=$KDEB_SOURCENAME
-packagename=linux-image-$version
-kernel_headers_packagename=linux-headers-$version
+packagename=linux-image-dev$LOCALVERSION
+kernel_headers_packagename=linux-headers-dev$LOCALVERSION
+dtb_packagename=linux-dtb-dev$LOCALVERSION
dbg_packagename=$packagename-dbg
debarch=
+image_name=
set_debarch
if [ "$ARCH" = "um" ] ; then
@@ -168,6 +170,11 @@ Architecture: $debarch
Description: Linux kernel debugging symbols for $version
This package will come in handy if you need to debug the kernel. It provides
all the necessary debug symbols for the kernel and its modules.
+
+Package: $dtb_packagename
+Architecture: $debarch
+Description: Linux DTB, version $version
+ This package contains device blobs from the Linux kernel, version $version
EOF
cat <<EOF > debian/rules
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
index f839ecd9..cd276162 100644
--- a/arch/arm64/Makefile
+++ b/arch/arm64/Makefile
@@ -103,7 +103,7 @@ core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
# Default target when executing plain make
boot := arch/arm64/boot
-KBUILD_IMAGE := $(boot)/Image.gz
+KBUILD_IMAGE := $(boot)/Image
KBUILD_DTBS := dtbs
all: Image.gz $(KBUILD_DTBS)

View file

@ -0,0 +1,229 @@
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 44097a3e0..a0cbdbb2c 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -756,6 +756,14 @@ config LEDS_NIC78BX
To compile this driver as a module, choose M here: the module
will be called leds-nic78bx.
+config LEDS_AXP20X
+ tristate "LED support for AXP20X-like PMICs (AXP813, ...)"
+ depends on LEDS_CLASS && MFD_AXP20X
+ help
+ This option enables support for on-chip LED drivers on
+ AXP20X-like PMICs.
+
+
comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 420b5d2cf..a8149fb6e 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_LEDS_MT6323) += leds-mt6323.o
obj-$(CONFIG_LEDS_LM3692X) += leds-lm3692x.o
obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o
obj-$(CONFIG_LEDS_LM3601X) += leds-lm3601x.o
+obj-$(CONFIG_LEDS_AXP20X) += leds-axp20x.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o
diff --git a/drivers/leds/leds-axp20x.c b/drivers/leds/leds-axp20x.c
new file mode 100644
index 000000000..de33c1d83
--- /dev/null
+++ b/drivers/leds/leds-axp20x.c
@@ -0,0 +1,138 @@
+/*
+ * LED Driver for X-Powers AXP813 PMIC.
+ *
+ * Copyright(c) 2017 Ondrej Jirman <megous@megous.com>
+ *
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/mfd/axp20x.h>
+
+#define AXP813_CHGLED_CTRL_MASK BIT(3)
+#define AXP813_CHGLED_CTRL_CHARGER BIT(3)
+#define AXP813_CHGLED_CTRL_USER 0
+
+#define AXP813_CHGLED_USER_STATE_MASK GENMASK(5, 4)
+#define AXP813_CHGLED_USER_STATE_OFFSET 4
+#define AXP813_CHGLED_USER_STATE_OFF 0
+#define AXP813_CHGLED_USER_STATE_BLINK_SLOW 1
+#define AXP813_CHGLED_USER_STATE_BLINK_FAST 2
+#define AXP813_CHGLED_USER_STATE_ON 3
+
+struct axp20x_led {
+ struct led_classdev cdev;
+ struct regmap *regmap;
+};
+
+static int axp20x_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct axp20x_led *led =
+ container_of(led_cdev, struct axp20x_led, cdev);
+ unsigned int val;
+
+ val = value == LED_OFF ? AXP813_CHGLED_USER_STATE_OFF :
+ AXP813_CHGLED_USER_STATE_ON;
+
+ return regmap_update_bits(led->regmap, AXP20X_OFF_CTRL,
+ AXP813_CHGLED_USER_STATE_MASK,
+ val << AXP813_CHGLED_USER_STATE_OFFSET);
+
+}
+
+static int axp20x_led_probe(struct platform_device *pdev)
+{
+ struct axp20x_dev *axp20x;
+ struct axp20x_led *led;
+ int ret;
+
+ if (!of_device_is_available(pdev->dev.of_node))
+ return -ENODEV;
+
+ axp20x = dev_get_drvdata(pdev->dev.parent);
+ if (!axp20x)
+ return -EINVAL;
+
+ led = devm_kzalloc(&pdev->dev,
+ sizeof(struct axp20x_led),
+ GFP_KERNEL);
+ if (!led)
+ return -ENOMEM;
+
+ led->regmap = axp20x->regmap;
+
+ led->cdev.name = "chgled";
+ led->cdev.brightness_set_blocking = axp20x_led_set;
+ led->cdev.brightness = LED_OFF;
+ led->cdev.max_brightness = 1;
+
+ ret = led_classdev_register(pdev->dev.parent, &led->cdev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to register led %s\n",
+ led->cdev.name);
+ return ret;
+ }
+
+ ret = regmap_update_bits(led->regmap, AXP20X_OFF_CTRL,
+ AXP813_CHGLED_CTRL_MASK,
+ AXP813_CHGLED_CTRL_USER);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to enable user cnotrol\n");
+ }
+
+ ret = axp20x_led_set(&led->cdev, led->cdev.brightness);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to init led %s\n",
+ led->cdev.name);
+ }
+
+ platform_set_drvdata(pdev, led);
+ return 0;
+}
+
+static int axp20x_led_remove(struct platform_device *pdev)
+{
+ struct axp20x_led *led = platform_get_drvdata(pdev);
+
+ axp20x_led_set(&led->cdev, LED_OFF);
+
+ regmap_update_bits(led->regmap, AXP20X_OFF_CTRL,
+ AXP813_CHGLED_CTRL_MASK,
+ AXP813_CHGLED_CTRL_CHARGER);
+
+ led_classdev_unregister(&led->cdev);
+
+ return 0;
+}
+
+static const struct of_device_id axp20x_leds_of_match[] = {
+ { .compatible = "x-powers,axp813-leds", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, axp20x_leds_of_match);
+
+static struct platform_driver axp20x_led_driver = {
+ .driver = {
+ .name = "axp20x-leds",
+ .of_match_table = axp20x_leds_of_match,
+ },
+ .probe = axp20x_led_probe,
+ .remove = axp20x_led_remove,
+};
+
+module_platform_driver(axp20x_led_driver);
+
+MODULE_AUTHOR("Ondrej Jirman <megous@megous.com>");
+MODULE_DESCRIPTION("LED driver for AXP813 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-axp20x");
diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
index 0be511dd9..a9bdf3cdd 100644
--- a/drivers/mfd/axp20x.c
+++ b/drivers/mfd/axp20x.c
@@ -24,6 +24,7 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
+#include <linux/regulator/userspace-consumer.h>
#include <linux/mfd/axp20x.h>
#include <linux/mfd/core.h>
#include <linux/of_device.h>
@@ -130,6 +131,7 @@ static const struct regmap_range axp288_volatile_ranges[] = {
regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT),
regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
+ regmap_reg_range(AXP22X_CHRG_CTRL3, AXP22X_CHRG_CTRL3),
regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
regmap_reg_range(AXP22X_GPIO_STATE, AXP22X_GPIO_STATE),
@@ -762,6 +764,16 @@ static const struct mfd_cell axp809_cells[] = {
},
};
+static struct regulator_bulk_data vcc_vb = {
+ .supply = "vcc-vb",
+};
+
+static struct regulator_userspace_consumer_data vcc_vb_data = {
+ .name = "vcc-vb",
+ .num_supplies = 1,
+ .supplies = &vcc_vb,
+};
+
static const struct mfd_cell axp813_cells[] = {
{
.name = "axp221-pek",
@@ -778,6 +790,16 @@ static const struct mfd_cell axp813_cells[] = {
}, {
.name = "axp20x-battery-power-supply",
.of_compatible = "x-powers,axp813-battery-power-supply",
+ }, {
+ .name = "axp20x-usb-power-supply",
+ .of_compatible = "x-powers,axp813-usb-power-supply",
+ }, {
+ .name = "axp20x-leds",
+ .of_compatible = "x-powers,axp813-leds",
+ }, {
+ .name = "reg-userspace-consumer",
+ .platform_data = &vcc_vb_data,
+ .pdata_size = sizeof(vcc_vb_data),
},
};

View file

@ -0,0 +1,24 @@
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 586ce53fc..e72c24470 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -590,19 +590,6 @@
};
};
- ths: ths@1c25000 {
- #thermal-sensor-cells = <0>;
- compatible = "allwinner,sun8i-h3-ths";
- reg = <0x01c25000 0x400>,
- <0x01c14234 0x4>;
- reg-names = "ths", "calibration";
- interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&ccu RST_BUS_THS>;
- reset-names = "ahb";
- clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
- clock-names = "ahb", "ths";
- };
-
timer@1c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0xa0>;

View file

@ -0,0 +1,346 @@
From 6eb4890e1b83490864f18d3926182069e54a4dfb Mon Sep 17 00:00:00 2001
From: Ondrej Jirman <megous@megous.com>
Date: Sun, 12 Nov 2017 23:09:14 +0100
Subject: [PATCH] sound: soc: ac100-codec: Initial implementation
This driver provides AC100 codec controls.
Note: This does not yet provide anything, it's just a skeleton
for a future driver.
Signed-off-by: Ondrej Jirman <megous@megous.com>
---
sound/soc/sunxi/Kconfig | 11 ++
sound/soc/sunxi/Makefile | 1 +
sound/soc/sunxi/ac100-codec.c | 291 ++++++++++++++++++++++++++++++++++
3 files changed, 303 insertions(+)
create mode 100644 sound/soc/sunxi/ac100-codec.c
diff --git a/sound/soc/sunxi/Kconfig b/sound/soc/sunxi/Kconfig
index 22408bc2d6ec6..e276cc94a8c5e 100644
--- a/sound/soc/sunxi/Kconfig
+++ b/sound/soc/sunxi/Kconfig
@@ -20,6 +20,17 @@ config SND_SUN8I_CODEC
Say Y or M if you want to add sun8i digital audio codec support.
+config SND_AC100_CODEC
+ tristate "Allwinner (X-Powers) AC100 audio codec"
+ depends on OF
+ depends on MACH_SUN8I || COMPILE_TEST
+ select REGMAP_MMIO
+ help
+ This option enables the audio codec support for Allwinner (X-Powers)
+ AC100 chip.
+
+ Say Y or M if you want to add AC100 audio codec support.
+
config SND_SUN8I_CODEC_ANALOG
tristate "Allwinner sun8i Codec Analog Controls Support"
depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
diff --git a/sound/soc/sunxi/Makefile b/sound/soc/sunxi/Makefile
index 4a9ef67386caf..83461fdbfaa2a 100644
--- a/sound/soc/sunxi/Makefile
+++ b/sound/soc/sunxi/Makefile
@@ -4,3 +4,4 @@ obj-$(CONFIG_SND_SUN4I_I2S) += sun4i-i2s.o
obj-$(CONFIG_SND_SUN4I_SPDIF) += sun4i-spdif.o
obj-$(CONFIG_SND_SUN8I_CODEC_ANALOG) += sun8i-codec-analog.o
obj-$(CONFIG_SND_SUN8I_CODEC) += sun8i-codec.o
+obj-$(CONFIG_SND_AC100_CODEC) += ac100-codec.o
diff --git a/sound/soc/sunxi/ac100-codec.c b/sound/soc/sunxi/ac100-codec.c
new file mode 100644
index 0000000000000..d5438815be754
--- /dev/null
+++ b/sound/soc/sunxi/ac100-codec.c
@@ -0,0 +1,291 @@
+/*
+ * This driver supports the controls for X-Powers (Allwinner)
+ * AC100 audio codec. This codec is co-packaged with AXP81x PMICs.
+ *
+ * (C) Copyright 2017 Ondrej Jirman <megous@megous.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/mfd/ac100.h>
+
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+/*
+ * Reasearch
+ * ---------
+ *
+ * Features:
+ * 2 A/D
+ * 2 D/A
+ * 2 I2S/PCM #1 and #2
+ * 1 PCM mono #3 muxable with I2S #2
+ * 3 mic inputs (mic #2 and #3 exclusively muxable at input)
+ * 1 line in (directly or through amp)
+ * 1 aux input
+ * all input signals mixable directly into output (bypass AD/DA)
+ *
+ * outputs:
+ * HPOUTL - headphone left
+ * HPOUTR - headphone right
+ * LINEOUT - line out differential
+ * EAROUT - earpeiece differential
+ * SPKOUT1 - SPOL left speaker differnetial
+ * SPKOUT2 - SPOR right speaker differnetial
+ *
+ * Power up:
+ * LDOIN - 1.5-3.3V external power
+ * AVCC - analog power 3V
+ * CPVDD - 1.8V
+ * VDD-IO1 - power for I2S #1 and #2 1.8/3V
+ * VDD-IO2 - power for I2S #3 1.8/3V
+ * VCC-RTC - power for RTC 1.8/3V
+ *
+ * Clocks: page 28
+ * SYSCLK must be 24576000 Hz (48kHz) or 22579200 Hz (44.1kHz)
+ * - Source I2S1CLK/MCLK1
+ * - If SRC# module is used SYSCLK must be generated by PLL
+ *
+ * A/D:
+ * ADC_APC_CTRL B15 B11 enable/disable A/D to save power
+ * ADC_APC_CTRL B14-12 B10-8 volume control for A/D
+ * ADC_DIG_CTRL B15 enable/disable digital A/D to save power
+ * ADDA_FS_I2S1 ADDA_FS_I2S2 - select sample rate
+ *
+ * D/A:
+ * OMIXER_DACA_CTRL B15-14 enable/disable D/A channels
+ * DAC_DIG_CTRL B15 enable/disable digital D/A
+ *
+ * Mixer:
+ * - 2 channels DAC Output mixers
+ * - inputs:
+ * - LINEINL/R
+ * - AXIL/R
+ * - MIC1P/N,MIC2P/N
+ * - Stereo DAC output
+ * - 2 channels ADC Record mixers
+ * - inputs:
+ * - LINEINL/R
+ * - AXIL/R
+ * - MIC1P/N,MIC2P/N
+ * - Stereo DAC output
+ * - Digital mixers
+ * - avaliable on:
+ * - before stereo DAC - DAC_MXR_SRC
+ * - I2S1 output - I2S1_MXR_SRC
+ * - I2S2 output - I2S2_MXR_SRC
+ * - Analogue inputs
+ * - LINEINL/R - 1 ch. mono
+ * - can be mixed into ADC record mixer or DAC output mixer
+ * - -9dB to 12dB in 1.5dB step by LINEIN_DIFF_PREG
+ * - AXIL/R - 2 ch. stereo
+ * - can be mixed into ADC record mixer or DAC output mixer
+ * - programmable volume level adj. and mute
+ * - -9dB to 12dB in 1.5dB steps by AXI_PREG
+ * - MIC1P/N - has preamp
+ * - MIC2P/N - has preamp
+ * - MIC3P/N - has preamp muxed with MIC2 (sel by ADC_SRCBST_CTRL B7)
+ * - can be mixed into ADC record mixer or DAC output mixer
+ * - preamps enable at ADC_SRCBST_CTRL B15 and B11
+ * - preamp gain at MIC1BOOST MIC2BOOST
+ * - Analogue outputs:
+ * - HPOUTL/R, HPOUTFB - 2ch. headphones
+ * - sources output mixer or directly from DAC
+ * - sel HPOUT_CTRL B15 B14
+ * - mute HPOUT_CTRL B13 B12
+ * - power amp
+ * - powerdown/up HPOUT_CTRL B11
+ * - volume HP_VOL[5:0] - 64dB range in 1dB step from 0dB to -62dB
+ * - mute by using 0 for HP_VOL[5:0]
+ * - DC offset cancellation (POP noise) HP_DCRM_EN
+ * - This bit must be set 0xf before headphone PA enabled, and this bit
+ * must be set 0x0 before headphone PA disabled.
+ * - zero cross to prevent noise/clicsk on volume change ZCROSS_EN
+ * - SPOLP/N, SPORP/N 2 ch. speakers (mono/stereo)
+ * - source for SPOLP
+ * - left output mixer or (left+right) output mixer
+ * - source for SPORP
+ * - right output mixer or (left+right) output mixer
+ * - volume 43.5dB rang in 1.5dB step from -43.5dB to 0dB
+ * - amp enable SPKOUT_CTRL B11 B7
+ * - EAROUTP/N - 1 ch earpeice
+ * - source left DAC, right DAC, left output mixer or right output mixer
+ * - volume ERPOUT_CTRL[4:0] 43.5dB range in 1.5dB step from -43.5dB to 0dB
+ * - power amp enable ERPOUT_CTRL B5
+ * - LINEOUTP/N - 1ch line out
+ * - source MIC1 preamp, MIC2 preamp, left output mix or right output mix
+ * - volume 10.5dB range in 1.5dB step from -4.5dB to 6dB
+ * - out buffer power up/down LOUT_CTRL B4
+ *
+ * Jack insert detection:
+ * - HBIAS current detection
+ * - 5bit ADC sample rate 16/32/64/128Hz
+ * - HMIC_STATUS[12:8] - ADC value
+ * - 2 thresholds TH1 for plug connection, TH2 for key press
+ * - can periodically trigger interrupts during key press (HBIAS above TH2)
+ *
+ * Interrupts:
+ * - FALLING_EDGE
+ * - for:
+ * - KEYDOWN
+ * - KEYUP
+ * - PLUG_IN
+ * - PLUG_OUT
+ * - HMIC_DATA
+ *
+ * High Pass Filter:
+ * - remove DC offset, can be disabled
+ *
+ * AGC:
+ * - automatic gain control before ADC input channels
+ * - params:
+ * - attack, decay time - 32/fs to 2^15*32/fs
+ * - target gain - 1dB to 30dB relative to a full-scale signal
+ * - noise threshold - 30dB to 90dB of full-scale (mute if input below this level)
+ * - max gain 0dB to 40dB in steps of 0.5dB
+ * - hysteresis - for noise detection in terms of signal level
+ * - debounce time - hysteresis for noise det in terms of time
+ * - also provides some output flags:
+ * - noise threshold reached
+ * - current gain
+ * - agc saturated (gain could get higher for the given input, but limited by
+ * params)
+ * - adc saturated - clipping at ADC input stage
+ *
+ * DRC:
+ * - dynamic range control for digital playback path
+ * - energy filter
+ * - compressor
+ * - smooth filter
+ * - can be disabled
+ */
+
+#define AC100_HMIC_DATA_MASK GENMASK(12, 8)
+#define AC100_HMIC_DATA_OFF 8
+#define AC100_HMIC_PULLOUT_PENDING BIT(4)
+#define AC100_HMIC_PLUGIN_PENDING BIT(3)
+#define AC100_HMIC_KEYUP_PENDING BIT(2)
+#define AC100_HMIC_KEYDOWN_PENDING BIT(1)
+#define AC100_HMIC_DATA_PENDING BIT(0)
+
+struct ac100_codec {
+ struct device *dev;
+ struct regmap *regmap;
+ int irq;
+};
+
+static irqreturn_t ac100_codec_irq(int irq, void *data)
+{
+ struct ac100_codec *codec = data;
+ unsigned int val = 0;
+ int ret;
+
+ /* read status */
+ ret = regmap_read(codec->regmap, AC100_HMIC_STATUS, &val);
+ if (ret)
+ return IRQ_HANDLED;
+
+ if (val & AC100_HMIC_PULLOUT_PENDING) {
+ dev_info(codec->dev, "IRQ: Pull out");
+ }
+
+ if (val & AC100_HMIC_PLUGIN_PENDING) {
+ dev_info(codec->dev, "IRQ: Plug in");
+ }
+
+ if (val & AC100_HMIC_KEYUP_PENDING) {
+ dev_info(codec->dev, "IRQ: Key up");
+ }
+
+ if (val & AC100_HMIC_KEYDOWN_PENDING) {
+ dev_info(codec->dev, "IRQ: Key down");
+ }
+
+ if (val & AC100_HMIC_DATA_PENDING) {
+ dev_info(codec->dev, "IRQ: Data");
+ }
+
+ /* clear status */
+ ret = regmap_write(codec->regmap, AC100_HMIC_STATUS, 0);
+ if (ret)
+ return IRQ_HANDLED;
+
+ return IRQ_HANDLED;
+}
+
+static int ac100_codec_probe(struct platform_device *pdev)
+{
+ struct ac100_dev *ac100 = dev_get_drvdata(pdev->dev.parent);
+ struct ac100_codec *codec;
+ int ret;
+
+ codec = devm_kzalloc(&pdev->dev, sizeof(*codec), GFP_KERNEL);
+ if (!codec)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, codec);
+ codec->dev = &pdev->dev;
+ codec->regmap = ac100->regmap;
+
+ codec->irq = platform_get_irq(pdev, 0);
+ if (codec->irq < 0) {
+ dev_err(&pdev->dev, "No IRQ resource\n");
+ return codec->irq;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, codec->irq, NULL,
+ ac100_codec_irq,
+ IRQF_SHARED | IRQF_ONESHOT,
+ dev_name(&pdev->dev), codec);
+ if (ret) {
+ dev_err(&pdev->dev, "Could not request IRQ\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int ac100_codec_remove(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct ac100_codec *codec = snd_soc_card_get_drvdata(card);
+
+ return 0;
+}
+
+static const struct of_device_id ac100_codec_of_match[] = {
+ { .compatible = "x-powers,ac100-codec" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, ac100_codec_of_match);
+
+static struct platform_driver ac100_codec_driver = {
+ .driver = {
+ .name = "ac100-codec",
+ .of_match_table = ac100_codec_of_match,
+ },
+ .probe = ac100_codec_probe,
+ .remove = ac100_codec_remove,
+};
+module_platform_driver(ac100_codec_driver);
+
+MODULE_DESCRIPTION("X-Powers AC100 codec driver");
+MODULE_AUTHOR("Ondrej Jirman <megous@megous.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ac100-codec");

View file

@ -0,0 +1,46 @@
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
index 67e2246a6..e37d779f8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
@@ -55,7 +55,6 @@
clocks = <&ccu CLK_CPUX>;
clock-names = "cpu";
operating-points-v2 = <&cpu0_opp_table>;
- clock-frequency = <1200000000>;
#cooling-cells = <2>;
cooling-min-level = <0>;
cooling-max-level = <15>;
@@ -67,7 +66,6 @@
reg = <1>;
enable-method = "psci";
operating-points-v2 = <&cpu0_opp_table>;
- clock-frequency = <1200000000>;
};
cpu@2 {
@@ -76,7 +74,6 @@
reg = <2>;
enable-method = "psci";
operating-points-v2 = <&cpu0_opp_table>;
- clock-frequency = <1200000000>;
};
cpu@3 {
@@ -85,10 +82,16 @@
reg = <3>;
enable-method = "psci";
operating-points-v2 = <&cpu0_opp_table>;
- clock-frequency = <1200000000>;
};
};
+ reg_cpu_fallback: reg_cpu_fallback {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd-cpux-dummy";
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1100000>;
+ };
+
psci {
compatible = "arm,psci-0.2";
method = "smc";

View file

@ -0,0 +1,52 @@
From a5b709a81ad9a5e2e6e4be6a696711ad7f35ad57 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Thu, 9 Feb 2017 00:18:56 +0800
Subject: [PATCH 001/146] arm64: allwinner: a64: enable Wi-Fi for Pine64
The Wi-Fi modules of Pine64 is powered via DLDO4 and ELDO1 (the latter
one provides I/O voltage).
Add device node for it.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
.../boot/dts/allwinner/sun50i-a64-pine64.dts | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 1b9b92e541d2..d06b5b88f60e 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -62,6 +62,11 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+ wifi_pwrseq: wifi_pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&r_pio 0 2 GPIO_ACTIVE_LOW>; /* PL2 */
+ };
};
&ehci0 {
@@ -109,6 +114,17 @@
status = "okay";
};
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&reg_dldo4>;
+ vqmmc-supply = <&reg_eldo1>;
+ mmc-pwrseq = <&wifi_pwrseq>;
+ non-removable;
+ bus-width = <4>;
+ status = "okay";
+};
+
&ohci0 {
status = "okay";
};
--
2.17.1

View file

@ -0,0 +1,72 @@
From fa666ec858630bad5d3bf2952c96460302065102 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Sat, 6 May 2017 19:29:44 +0800
Subject: [PATCH 002/146] arm64: allwinner: a64: add Mali device node
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 41 +++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index d3daf90a8715..0f69f3593975 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -157,6 +157,20 @@
compatible = "linux,spdif-dit";
};
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ cma: linux,cma {
+ compatible = "shared-dma-pool";
+ reusable;
+ size = <0x4000000>;
+ alignment = <0x2000>;
+ linux,cma-default;
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13
@@ -664,6 +678,33 @@
};
};
+ mali: gpu@1c40000 {
+ compatible = "allwinner,sun50i-a64-mali",
+ "allwinner,sun7i-a20-mali", "arm,mali-400";
+ reg = <0x01c40000 0x10000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "gp",
+ "gpmmu",
+ "pp0",
+ "ppmmu0",
+ "pp1",
+ "ppmmu1",
+ "pmu";
+ clocks = <&ccu CLK_BUS_GPU>, <&ccu CLK_GPU>;
+ clock-names = "bus", "core";
+ resets = <&ccu RST_BUS_GPU>;
+ memory-region = <&cma>;
+
+ assigned-clocks = <&ccu CLK_GPU>;
+ assigned-clock-rates = <384000000>;
+ };
+
gic: interrupt-controller@1c81000 {
compatible = "arm,gic-400";
reg = <0x01c81000 0x1000>,
--
2.17.1

View file

@ -0,0 +1,35 @@
From 98800eeb2244387e821f4af8d21ccf2deaf18da0 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Mon, 21 Aug 2017 23:02:32 +0800
Subject: [PATCH 003/146] net: stmmac: dwmac-sun8i: support RGMII modes with
PHY internal delay
Some boards uses a PHY with internal delay with an Allwinner SoC.
Support these PHY modes in the driver.
As the driver has no configuration registers for these modes, just treat
them as ordinary RGMII.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index f9a61f90cfbc..3c18f4a9dd6c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -933,6 +933,9 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
/* default */
break;
case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
reg |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII;
break;
case PHY_INTERFACE_MODE_RMII:
--
2.17.1

View file

@ -0,0 +1,35 @@
From e89cb84d23d2537cd1b256afdd0fe880648ee1a9 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Mon, 21 Aug 2017 23:08:08 +0800
Subject: [PATCH 004/146] arm64: allwinner: a64: disable the RTL8211E internal
RX delay on Pine64+
Some Pine64+ boards have a broken RTL8211E PHY, which cannot work
reliably in 1000Base-T mode with default configuration.
A solution is passed to Pine64, which is said to be disabling the
internal RX delay of the PHY.
Enable the hack by set the PHY mode to RGMII-TXID.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
index 24f1aac366d6..ed715426fffc 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
@@ -52,7 +52,7 @@
&emac {
pinctrl-names = "default";
pinctrl-0 = <&rgmii_pins>;
- phy-mode = "rgmii";
+ phy-mode = "rgmii-txid";
phy-handle = <&ext_rgmii_phy>;
status = "okay";
};
--
2.17.1

View file

@ -0,0 +1,50 @@
From ea69ff188dd5d9ac7162f05a22bf299b83a7536e Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Mon, 7 Dec 2015 09:33:28 +0100
Subject: [PATCH 005/146] drm: gem: cma: Export with handle allocator
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/gpu/drm/drm_gem_cma_helper.c | 3 ++-
include/drm/drm_gem_cma_helper.h | 4 ++++
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
index 80a5115c3846..077c61f065d9 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -142,7 +142,7 @@ EXPORT_SYMBOL_GPL(drm_gem_cma_create);
* A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative
* error code on failure.
*/
-static struct drm_gem_cma_object *
+struct drm_gem_cma_object *
drm_gem_cma_create_with_handle(struct drm_file *file_priv,
struct drm_device *drm, size_t size,
uint32_t *handle)
@@ -169,6 +169,7 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
return cma_obj;
}
+EXPORT_SYMBOL_GPL(drm_gem_cma_create_with_handle);
/**
* drm_gem_cma_free_object - free resources associated with a CMA GEM object
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index 19777145cf8e..79f397c91517 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -79,6 +79,10 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma);
/* allocate physical memory */
struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
size_t size);
+struct drm_gem_cma_object *
+drm_gem_cma_create_with_handle(struct drm_file *file_priv,
+ struct drm_device *drm, size_t size,
+ uint32_t *handle);
extern const struct vm_operations_struct drm_gem_cma_vm_ops;
--
2.17.1

View file

@ -0,0 +1,102 @@
From b143de6aef8be007256082e0f89606b7f5e3c757 Mon Sep 17 00:00:00 2001
From: Maxime Ripard <maxime.ripard@free-electrons.com>
Date: Mon, 7 Dec 2015 09:47:34 +0100
Subject: [PATCH 006/146] drm/sun4i: Add GEM allocator
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
drivers/gpu/drm/sun4i/sun4i_drv.c | 27 +++++++++++++++++++++++++++
include/uapi/drm/sun4i_drm.h | 29 +++++++++++++++++++++++++++++
2 files changed, 56 insertions(+)
create mode 100644 include/uapi/drm/sun4i_drm.h
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 8b0cd08034e0..9f5de14fb2fe 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -22,6 +22,8 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_of.h>
+#include <uapi/drm/sun4i_drm.h>
+
#include "sun4i_drv.h"
#include "sun4i_frontend.h"
#include "sun4i_framebuffer.h"
@@ -30,6 +32,27 @@
DEFINE_DRM_GEM_CMA_FOPS(sun4i_drv_fops);
+static int sun4i_gem_create_ioctl(struct drm_device *drm, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_sun4i_gem_create *args = data;
+ struct drm_gem_cma_object *cma_obj;
+ size_t size;
+
+ /* The Mali requires a 64 bytes alignment */
+ size = ALIGN(args->size, 64);
+
+ cma_obj = drm_gem_cma_create_with_handle(file_priv, drm, size,
+ &args->handle);
+
+ return PTR_ERR_OR_ZERO(cma_obj);
+}
+
+static const struct drm_ioctl_desc sun4i_drv_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(SUN4I_GEM_CREATE, sun4i_gem_create_ioctl,
+ DRM_UNLOCKED | DRM_AUTH),
+};
+
static struct drm_driver sun4i_drv_driver = {
.driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_ATOMIC,
@@ -42,6 +65,10 @@ static struct drm_driver sun4i_drv_driver = {
.major = 1,
.minor = 0,
+ /* Custom ioctls */
+ .ioctls = sun4i_drv_ioctls,
+ .num_ioctls = ARRAY_SIZE(sun4i_drv_ioctls),
+
/* GEM Operations */
.dumb_create = drm_gem_cma_dumb_create,
.gem_free_object_unlocked = drm_gem_cma_free_object,
diff --git a/include/uapi/drm/sun4i_drm.h b/include/uapi/drm/sun4i_drm.h
new file mode 100644
index 000000000000..67b9dd4ee594
--- /dev/null
+++ b/include/uapi/drm/sun4i_drm.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 Free Electrons
+ * Copyright (C) 2015 NextThing Co
+ *
+ * Maxime Ripard <maxime.ripard@free-electrons.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef _UAPI_SUN4I_DRM_H_
+#define _UAPI_SUN4I_DRM_H_
+
+#include <drm/drm.h>
+
+struct drm_sun4i_gem_create {
+ __u64 size;
+ __u32 flags;
+ __u32 handle;
+};
+
+#define DRM_SUN4I_GEM_CREATE 0x00
+
+#define DRM_IOCTL_SUN4I_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_SUN4I_GEM_CREATE, \
+ struct drm_sun4i_gem_create)
+
+#endif
--
2.17.1

View file

@ -0,0 +1,96 @@
From 87020e638ad511e0ebe9c72208d2f0192c905812 Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Sun, 3 Dec 2017 11:43:08 -0800
Subject: [PATCH 007/146] Add sopine HDMI sound and WiFi support
---
.../allwinner/sun50i-a64-sopine-baseboard.dts | 18 ++++++++++++
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 29 +++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index c21f2331add6..8161895dde52 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -86,6 +86,10 @@
status = "okay";
};
+&i2s2 {
+ status = "okay";
+};
+
&mdio {
ext_rgmii_phy: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
@@ -93,6 +97,16 @@
};
};
+&mmc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc1_pins>;
+ vmmc-supply = <&reg_dldo4>;
+ vqmmc-supply = <&reg_eldo1>;
+ non-removable;
+ bus-width = <4>;
+ status = "okay";
+};
+
&mmc2 {
pinctrl-names = "default";
pinctrl-0 = <&mmc2_pins>;
@@ -138,6 +152,10 @@
vcc-hdmi-supply = <&reg_dldo1>;
};
+&sound_hdmi {
+ status = "okay";
+};
+
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&uart0_pins_a>;
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 0f69f3593975..0b44018361cb 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -727,6 +727,35 @@
status = "disabled";
};
+ i2s2: i2s@1c22800 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun8i-h3-i2s";
+ reg = <0x01c22800 0x400>;
+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_I2S2>, <&ccu CLK_I2S2>;
+ clock-names = "apb", "mod";
+ dmas = <&dma 27>;
+ resets = <&ccu RST_BUS_I2S2>;
+ dma-names = "tx";
+ status = "disabled";
+ };
+
+ sound_hdmi: sound_hdmi {
+ compatible = "simple-audio-card";
+ simple-audio-card,format = "i2s";
+ simple-audio-card,name = "allwinner,hdmi";
+ simple-audio-card,mclk-fs = <256>;
+ status = "disabled";
+
+ simple-audio-card,codec {
+ sound-dai = <&hdmi>;
+ };
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s2>;
+ };
+ };
+
rtc: rtc@1f00000 {
compatible = "allwinner,sun6i-a31-rtc";
reg = <0x01f00000 0x54>;
--
2.17.1

View file

@ -0,0 +1,39 @@
From 887b96d878bb0e261bc19062dc73d193c75bc56a Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Tue, 26 Dec 2017 15:53:53 -0800
Subject: [PATCH 008/146] arm64: dts: sun50i-a64-pine64: add HDMI audio nodes
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index d06b5b88f60e..8c5dd99cc9ac 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -97,6 +97,10 @@
bias-pull-up;
};
+&i2s2 {
+ status = "okay";
+};
+
&mdio {
ext_rmii_phy1: ethernet-phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
@@ -254,6 +258,10 @@
status = "disabled";
};
+&sound_hdmi {
+ status = "okay";
+};
+
/* On Exp and Euler connectors */
&uart0 {
pinctrl-names = "default";
--
2.17.1

View file

@ -0,0 +1,95 @@
From 92e5c7876cef2b53ed3d1701169fcd93b73e0e33 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sat, 20 Jan 2018 13:25:21 +0100
Subject: [PATCH 009/146] dt-bindings: update the Allwinner GPADC device tree
binding for H3 & A83T
Allwinner H3 features a thermal sensor like the one in A33, but has its
register re-arranged, the clock divider moved to CCU (originally the
clock divider is in ADC) and added a pair of bus clock and reset.
Allwinner A83T features a thermal sensor similar to the H3, the ths clock,
the bus clock and the reset was removed from the CCU. The THS in A83T
has a clock that is directly connected and runs with 24 MHz.
Update the binding document to cover H3 and A83T.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
.../devicetree/bindings/mfd/sun4i-gpadc.txt | 50 +++++++++++++++++--
1 file changed, 47 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
index 86dd8191b04c..f6b939617a6d 100644
--- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
+++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
@@ -4,12 +4,35 @@ The Allwinner SoCs all have an ADC that can also act as a thermal sensor
and sometimes as a touchscreen controller.
Required properties:
- - compatible: "allwinner,sun8i-a33-ths",
+ - compatible: must contain one of the following compatibles:
+ - "allwinner,sun8i-a33-ths"
+ - "allwinner,sun8i-h3-ths"
+ - "allwinner,sun8i-a83t-ths"
- reg: mmio address range of the chip,
- - #thermal-sensor-cells: shall be 0,
+ - #thermal-sensor-cells: shall be 0 or 1,
- #io-channel-cells: shall be 0,
-Example:
+Required properties for the following compatibles:
+ - "allwinner,sun8i-h3-ths"
+ - "allwinner,sun8i-a83t-ths"
+ - interrupts: the sampling interrupt of the ADC,
+
+Required properties for the following compatibles:
+ - "allwinner,sun8i-h3-ths"
+ - clocks: the bus clock and the input clock of the ADC,
+ - clock-names: should be "bus" and "mod",
+ - resets: the bus reset of the ADC,
+
+Optional properties for the following compatibles:
+ - "allwinner,sun8i-h3-ths"
+ - nvmem-cells: A phandle to the calibration data provided by a nvmem device.
+ If unspecified default values shall be used. The size should
+ be 0x4 or 0x8, depending on the amount of CDATA registers.
+ - nvmem-cell-names: Should be "calibration".
+
+Details see: bindings/nvmem/nvmem.txt
+
+Example for A33:
ths: ths@1c25000 {
compatible = "allwinner,sun8i-a33-ths";
reg = <0x01c25000 0x100>;
@@ -17,6 +40,27 @@ Example:
#io-channel-cells = <0>;
};
+Example for H3:
+ ths: thermal-sensor@1c25000 {
+ compatible = "allwinner,sun8i-h3-ths";
+ reg = <0x01c25000 0x400>;
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_THS>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <0>;
+ #io-channel-cells = <0>;
+ };
+
+Example for A83T:
+ ths: thermal-sensor@1f04000 {
+ compatible = "allwinner,sun8i-a83t-ths";
+ reg = <0x01f04000 0x100>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <1>;
+ #io-channel-cells = <0>;
+ };
+
sun4i, sun5i and sun6i SoCs are also supported via the older binding:
sun4i resistive touchscreen controller
--
2.17.1

View file

@ -0,0 +1,56 @@
From ef6a8862ab9440c5d6a73da32be83edc46e2fe94 Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Thu, 14 Sep 2017 22:52:47 +0800
Subject: [PATCH 011/146] iio: adc: sun4i-gpadc-iio: rename A33-specified
registers to contain A33
As the H3 SoC, which is also in sun8i line, has totally different
register map for the thermal sensor (a cut down version of GPADC), we
should rename A23/A33-specified registers to contain A33, in order to
prevent obfuscation with H3 registers. Currently these registers are
only prefixed "SUN8I", not "SUN8I_A33".
Add "_A33" after "SUN8I" on the register names.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Reviewed-by: Chen-Yu Tsai <wens@csie.org>
Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 2 +-
include/linux/mfd/sun4i-gpadc.h | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 04d7147e0110..03804ff9c006 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -88,7 +88,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
- .tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
+ .tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
};
struct sun4i_gpadc_iio {
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index 139872c2e0fe..78d31984a222 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -38,9 +38,9 @@
#define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(3, 0) & BIT(x))
#define SUN6I_GPADC_CTRL1_ADC_CHAN_MASK GENMASK(3, 0)
-/* TP_CTRL1 bits for sun8i SoCs */
-#define SUN8I_GPADC_CTRL1_CHOP_TEMP_EN BIT(8)
-#define SUN8I_GPADC_CTRL1_GPADC_CALI_EN BIT(7)
+/* TP_CTRL1 bits for A33 */
+#define SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN BIT(8)
+#define SUN8I_A33_GPADC_CTRL1_GPADC_CALI_EN BIT(7)
#define SUN4I_GPADC_CTRL2 0x08
--
2.17.1

View file

@ -0,0 +1,237 @@
From 3de3b1512ed5905e9522a4966d238f571825ee70 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sat, 20 Jan 2018 14:03:10 +0100
Subject: [PATCH 012/146] iio: adc: sun4i-gpadc-iio: rework: sampling start/end
code readout reg
For adding newer sensor some basic rework of the code is necessary.
This commit reworks the code and allows the sampling start/end code and
the position of value readout register to be altered. Later the start/end
functions will be used to configure the ths and start/stop the
sampling.
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 87 ++++++++++++++++++++++++++++---
include/linux/mfd/sun4i-gpadc.h | 19 +++++--
2 files changed, 94 insertions(+), 12 deletions(-)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 03804ff9c006..363936b37c5a 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -49,6 +49,18 @@ static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
}
+struct sun4i_gpadc_iio;
+
+/*
+ * Prototypes for these functions, which enable these functions to be
+ * referenced in gpadc_data structures.
+ */
+static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info);
+static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info);
+
+static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info);
+static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info);
+
struct gpadc_data {
int temp_offset;
int temp_scale;
@@ -56,6 +68,13 @@ struct gpadc_data {
unsigned int tp_adc_select;
unsigned int (*adc_chan_select)(unsigned int chan);
unsigned int adc_chan_mask;
+ unsigned int temp_data;
+ int (*sample_start)(struct sun4i_gpadc_iio *info);
+ int (*sample_end)(struct sun4i_gpadc_iio *info);
+ u32 ctrl0_map;
+ u32 ctrl2_map;
+ u32 sensor_en_map;
+ u32 filter_map;
};
static const struct gpadc_data sun4i_gpadc_data = {
@@ -65,6 +84,9 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = &sun4i_gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .sample_start = sun4i_gpadc_sample_start,
+ .sample_end = sun4i_gpadc_sample_end,
};
static const struct gpadc_data sun5i_gpadc_data = {
@@ -74,6 +96,9 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = &sun4i_gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .sample_start = sun4i_gpadc_sample_start,
+ .sample_end = sun4i_gpadc_sample_end,
};
static const struct gpadc_data sun6i_gpadc_data = {
@@ -83,12 +108,18 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = &sun6i_gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .sample_start = sun4i_gpadc_sample_start,
+ .sample_end = sun4i_gpadc_sample_end,
};
static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
+ .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .sample_start = sun4i_gpadc_sample_start,
+ .sample_end = sun4i_gpadc_sample_end,
};
struct sun4i_gpadc_iio {
@@ -277,7 +308,7 @@ static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
if (info->no_irq) {
pm_runtime_get_sync(indio_dev->dev.parent);
- regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val);
+ regmap_read(info->regmap, info->data->temp_data, val);
pm_runtime_mark_last_busy(indio_dev->dev.parent);
pm_runtime_put_autosuspend(indio_dev->dev.parent);
@@ -382,10 +413,8 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
-static int sun4i_gpadc_runtime_suspend(struct device *dev)
+static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info)
{
- struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
-
/* Disable the ADC on IP */
regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
/* Disable temperature sensor on IP */
@@ -394,19 +423,32 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
return 0;
}
-static int sun4i_gpadc_runtime_resume(struct device *dev)
+static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info)
+{
+ /* Disable temperature sensor */
+ regmap_write(info->regmap, SUNXI_THS_CTRL2, 0x0);
+
+ return 0;
+}
+
+static int sun4i_gpadc_runtime_suspend(struct device *dev)
{
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
+ return info->data->sample_end(info);
+}
+
+static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
+{
/* clkin = 6MHz */
regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
SUN4I_GPADC_CTRL0_FS_DIV(7) |
- SUN4I_GPADC_CTRL0_T_ACQ(63));
+ SUNXI_THS_ACQ0(63));
regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en);
regmap_write(info->regmap, SUN4I_GPADC_CTRL3,
- SUN4I_GPADC_CTRL3_FILTER_EN |
- SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
+ SUNXI_THS_FILTER_EN |
+ SUNXI_THS_FILTER_TYPE(1));
/* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */
regmap_write(info->regmap, SUN4I_GPADC_TPR,
SUN4I_GPADC_TPR_TEMP_ENABLE |
@@ -415,6 +457,35 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)
return 0;
}
+static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)
+{
+ u32 value;
+
+ if (info->data->ctrl0_map)
+ regmap_write(info->regmap, SUNXI_THS_CTRL0,
+ info->data->ctrl0_map);
+
+ regmap_write(info->regmap, SUNXI_THS_CTRL2,
+ info->data->ctrl2_map);
+
+ regmap_write(info->regmap, SUNXI_THS_FILTER,
+ info->data->filter_map);
+
+ regmap_read(info->regmap, SUNXI_THS_CTRL2, &value);
+
+ regmap_write(info->regmap, SUNXI_THS_CTRL2,
+ info->data->sensor_en_map | value);
+
+ return 0;
+}
+
+static int sun4i_gpadc_runtime_resume(struct device *dev)
+{
+ struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
+
+ return info->data->sample_start(info);
+}
+
static int sun4i_gpadc_get_temp(void *data, int *temp)
{
struct sun4i_gpadc_iio *info = data;
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index 78d31984a222..39e096c3ddac 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -17,7 +17,6 @@
#define SUN4I_GPADC_CTRL0_ADC_CLK_SELECT BIT(22)
#define SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(x) ((GENMASK(1, 0) & (x)) << 20)
#define SUN4I_GPADC_CTRL0_FS_DIV(x) ((GENMASK(3, 0) & (x)) << 16)
-#define SUN4I_GPADC_CTRL0_T_ACQ(x) (GENMASK(15, 0) & (x))
#define SUN4I_GPADC_CTRL1 0x04
@@ -51,9 +50,6 @@
#define SUN4I_GPADC_CTRL3 0x0c
-#define SUN4I_GPADC_CTRL3_FILTER_EN BIT(2)
-#define SUN4I_GPADC_CTRL3_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
-
#define SUN4I_GPADC_TPR 0x18
#define SUN4I_GPADC_TPR_TEMP_ENABLE BIT(16)
@@ -90,6 +86,21 @@
/* 10s delay before suspending the IP */
#define SUN4I_GPADC_AUTOSUSPEND_DELAY 10000
+/* SUNXI_THS COMMON REGISTERS + DEFINES */
+#define SUNXI_THS_CTRL0 0x00
+#define SUNXI_THS_CTRL2 0x40
+#define SUNXI_THS_FILTER 0x70
+
+#define SUNXI_THS_FILTER_EN BIT(2)
+#define SUNXI_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
+#define SUNXI_THS_ACQ0(x) (GENMASK(15, 0) & (x))
+#define SUNXI_THS_ACQ1(x) (GENMASK(31, 16) & ((x) << 16))
+
+#define SUNXI_THS_TEMP_SENSE_EN0 BIT(0)
+#define SUNXI_THS_TEMP_SENSE_EN1 BIT(1)
+#define SUNXI_THS_TEMP_SENSE_EN2 BIT(2)
+#define SUNXI_THS_TEMP_SENSE_EN3 BIT(3)
+
struct sun4i_gpadc_dev {
struct device *dev;
struct regmap *regmap;
--
2.17.1

View file

@ -0,0 +1,168 @@
From c2d19fecbff6a21b3ab351c7843ae27de0d10b5b Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sun, 21 Jan 2018 22:23:00 +0100
Subject: [PATCH 013/146] iio: adc: sun4i-gpadc-iio: rework: support clocks and
reset
For adding newer sensor some basic rework of the code is necessary.
The SoCs after H3 has newer thermal sensor ADCs, which have two clock
inputs (bus clock and sampling clock) and a reset. The registers are
also re-arranged.
This commit reworks the code, adds the process of the clocks and
resets.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 80 +++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 363936b37c5a..1a80744bd472 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -22,6 +22,7 @@
* shutdown for not being used.
*/
+#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -31,6 +32,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/reset.h>
#include <linux/thermal.h>
#include <linux/delay.h>
@@ -75,6 +77,9 @@ struct gpadc_data {
u32 ctrl2_map;
u32 sensor_en_map;
u32 filter_map;
+ bool has_bus_clk;
+ bool has_bus_rst;
+ bool has_mod_clk;
};
static const struct gpadc_data sun4i_gpadc_data = {
@@ -134,6 +139,9 @@ struct sun4i_gpadc_iio {
atomic_t ignore_temp_data_irq;
const struct gpadc_data *data;
bool no_irq;
+ struct clk *bus_clk;
+ struct clk *mod_clk;
+ struct reset_control *reset;
/* prevents concurrent reads of temperature and ADC */
struct mutex mutex;
struct thermal_zone_device *tzd;
@@ -435,6 +443,12 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
{
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
+ if (info->data->has_mod_clk)
+ clk_disable(info->mod_clk);
+
+ if (info->data->has_bus_clk)
+ clk_disable(info->bus_clk);
+
return info->data->sample_end(info);
}
@@ -483,6 +497,12 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)
{
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
+ if (info->data->has_mod_clk)
+ clk_enable(info->mod_clk);
+
+ if (info->data->has_bus_clk)
+ clk_enable(info->bus_clk);
+
return info->data->sample_start(info);
}
@@ -597,10 +617,61 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
return ret;
}
+ if (info->data->has_bus_rst) {
+ info->reset = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(info->reset)) {
+ ret = PTR_ERR(info->reset);
+ return ret;
+ }
+
+ ret = reset_control_deassert(info->reset);
+ if (ret)
+ return ret;
+ }
+
+ if (info->data->has_bus_clk) {
+ info->bus_clk = devm_clk_get(&pdev->dev, "bus");
+ if (IS_ERR(info->bus_clk)) {
+ ret = PTR_ERR(info->bus_clk);
+ goto assert_reset;
+ }
+
+ ret = clk_prepare_enable(info->bus_clk);
+ if (ret)
+ goto assert_reset;
+ }
+
+ if (info->data->has_mod_clk) {
+ info->mod_clk = devm_clk_get(&pdev->dev, "mod");
+ if (IS_ERR(info->mod_clk)) {
+ ret = PTR_ERR(info->mod_clk);
+ goto disable_bus_clk;
+ }
+
+ /* Running at 6MHz */
+ ret = clk_set_rate(info->mod_clk, 4000000);
+ if (ret)
+ goto disable_bus_clk;
+
+ ret = clk_prepare_enable(info->mod_clk);
+ if (ret)
+ goto disable_bus_clk;
+ }
+
if (IS_ENABLED(CONFIG_THERMAL_OF))
info->sensor_device = &pdev->dev;
return 0;
+
+disable_bus_clk:
+ if (info->data->has_bus_clk)
+ clk_disable_unprepare(info->bus_clk);
+
+assert_reset:
+ if (info->data->has_bus_rst)
+ reset_control_assert(info->reset);
+
+ return ret;
}
static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,
@@ -766,6 +837,15 @@ static int sun4i_gpadc_remove(struct platform_device *pdev)
if (!info->no_irq)
iio_map_array_unregister(indio_dev);
+ if (info->data->has_mod_clk)
+ clk_disable_unprepare(info->mod_clk);
+
+ if (info->data->has_bus_clk)
+ clk_disable_unprepare(info->bus_clk);
+
+ if (info->data->has_bus_rst)
+ reset_control_assert(info->reset);
+
return 0;
}
--
2.17.1

View file

@ -0,0 +1,186 @@
From e684b6faf4b5509f852867cac4830a0274f89211 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sun, 21 Jan 2018 22:26:50 +0100
Subject: [PATCH 014/146] iio: adc: sun4i-gpadc-iio: rework: support multible
sensors
For adding newer sensor some basic rework of the code is necessary.
This patch reworks the driver to be able to handle more than one
thermal sensor. Newer SoC like the A80 have 4 thermal sensors.
Because of this the maximal sensor count value was set to 4.
The sensor_id value is set during sensor registration and is for each
registered sensor indiviual. This makes it able to differntiate the
sensors when the value is read from the register.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 36 ++++++++++++++++++++-----------
include/linux/mfd/sun4i-gpadc.h | 6 ++++++
2 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 1a80744bd472..bff06f2798e8 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -70,7 +70,7 @@ struct gpadc_data {
unsigned int tp_adc_select;
unsigned int (*adc_chan_select)(unsigned int chan);
unsigned int adc_chan_mask;
- unsigned int temp_data;
+ unsigned int temp_data[MAX_SENSOR_COUNT];
int (*sample_start)(struct sun4i_gpadc_iio *info);
int (*sample_end)(struct sun4i_gpadc_iio *info);
u32 ctrl0_map;
@@ -80,6 +80,7 @@ struct gpadc_data {
bool has_bus_clk;
bool has_bus_rst;
bool has_mod_clk;
+ int sensor_count;
};
static const struct gpadc_data sun4i_gpadc_data = {
@@ -89,9 +90,10 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = &sun4i_gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
- .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
static const struct gpadc_data sun5i_gpadc_data = {
@@ -101,9 +103,10 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = &sun4i_gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
- .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
static const struct gpadc_data sun6i_gpadc_data = {
@@ -113,18 +116,20 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = &sun6i_gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
- .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
- .temp_data = SUN4I_GPADC_TEMP_DATA,
+ .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+ .sensor_count = 1,
};
struct sun4i_gpadc_iio {
@@ -142,6 +147,7 @@ struct sun4i_gpadc_iio {
struct clk *bus_clk;
struct clk *mod_clk;
struct reset_control *reset;
+ int sensor_id;
/* prevents concurrent reads of temperature and ADC */
struct mutex mutex;
struct thermal_zone_device *tzd;
@@ -309,14 +315,15 @@ static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
}
-static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
+static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val,
+ int sensor)
{
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
if (info->no_irq) {
pm_runtime_get_sync(indio_dev->dev.parent);
- regmap_read(info->regmap, info->data->temp_data, val);
+ regmap_read(info->regmap, info->data->temp_data[sensor], val);
pm_runtime_mark_last_busy(indio_dev->dev.parent);
pm_runtime_put_autosuspend(indio_dev->dev.parent);
@@ -363,7 +370,7 @@ static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
val);
else
- ret = sun4i_gpadc_temp_read(indio_dev, val);
+ ret = sun4i_gpadc_temp_read(indio_dev, val, 0);
if (ret)
return ret;
@@ -511,7 +518,7 @@ static int sun4i_gpadc_get_temp(void *data, int *temp)
struct sun4i_gpadc_iio *info = data;
int val, scale, offset;
- if (sun4i_gpadc_temp_read(info->indio_dev, &val))
+ if (sun4i_gpadc_temp_read(info->indio_dev, &val, info->sensor_id))
return -ETIMEDOUT;
sun4i_gpadc_temp_scale(info->indio_dev, &scale);
@@ -755,7 +762,7 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
{
struct sun4i_gpadc_iio *info;
struct iio_dev *indio_dev;
- int ret;
+ int ret, i;
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
if (!indio_dev)
@@ -788,9 +795,12 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
if (IS_ENABLED(CONFIG_THERMAL_OF)) {
- info->tzd = thermal_zone_of_sensor_register(info->sensor_device,
- 0, info,
- &sun4i_ts_tz_ops);
+ for (i = 0; i < info->data->sensor_count; i++) {
+ info->sensor_id = i;
+ info->tzd = thermal_zone_of_sensor_register(
+ info->sensor_device,
+ i, info, &sun4i_ts_tz_ops);
+ }
/*
* Do not fail driver probing when failing to register in
* thermal because no thermal DT node is found.
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index 39e096c3ddac..40b4dd9d2405 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -90,6 +90,10 @@
#define SUNXI_THS_CTRL0 0x00
#define SUNXI_THS_CTRL2 0x40
#define SUNXI_THS_FILTER 0x70
+#define SUNXI_THS_TDATA0 0x80
+#define SUNXI_THS_TDATA1 0x84
+#define SUNXI_THS_TDATA2 0x88
+#define SUNXI_THS_TDATA3 0x8c
#define SUNXI_THS_FILTER_EN BIT(2)
#define SUNXI_THS_FILTER_TYPE(x) (GENMASK(1, 0) & (x))
@@ -101,6 +105,8 @@
#define SUNXI_THS_TEMP_SENSE_EN2 BIT(2)
#define SUNXI_THS_TEMP_SENSE_EN3 BIT(3)
+#define MAX_SENSOR_COUNT 4
+
struct sun4i_gpadc_dev {
struct device *dev;
struct regmap *regmap;
--
2.17.1

View file

@ -0,0 +1,166 @@
From 9bb64076c49cf41aaa252ce7b5aa24b93c322bd5 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sun, 21 Jan 2018 22:29:55 +0100
Subject: [PATCH 015/146] iio: adc: sun4i-gpadc-iio: rework: support nvmem
calibration data
This patch reworks the driver to support nvmem calibration cells.
The driver checks if the nvmem calibration is supported and reads out
the nvmem. At the beginning of the startup process the calibration data
is written to the related registers.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 52 +++++++++++++++++++++++++++++++
include/linux/mfd/sun4i-gpadc.h | 2 ++
2 files changed, 54 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index bff06f2798e8..7b12666cdd9e 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -81,6 +82,7 @@ struct gpadc_data {
bool has_bus_rst;
bool has_mod_clk;
int sensor_count;
+ bool supports_nvmem;
};
static const struct gpadc_data sun4i_gpadc_data = {
@@ -94,6 +96,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+ .supports_nvmem = false,
};
static const struct gpadc_data sun5i_gpadc_data = {
@@ -107,6 +110,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+ .supports_nvmem = false,
};
static const struct gpadc_data sun6i_gpadc_data = {
@@ -120,6 +124,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+ .supports_nvmem = false,
};
static const struct gpadc_data sun8i_a33_gpadc_data = {
@@ -130,6 +135,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+ .supports_nvmem = false,
};
struct sun4i_gpadc_iio {
@@ -148,6 +154,8 @@ struct sun4i_gpadc_iio {
struct clk *mod_clk;
struct reset_control *reset;
int sensor_id;
+ u32 calibration_data[2];
+ bool has_calibration_data[2];
/* prevents concurrent reads of temperature and ADC */
struct mutex mutex;
struct thermal_zone_device *tzd;
@@ -459,6 +467,17 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
return info->data->sample_end(info);
}
+static void sunxi_calibrate(struct sun4i_gpadc_iio *info)
+{
+ if (info->has_calibration_data[0])
+ regmap_write(info->regmap, SUNXI_THS_CDATA_0_1,
+ info->calibration_data[0]);
+
+ if (info->has_calibration_data[1])
+ regmap_write(info->regmap, SUNXI_THS_CDATA_2_3,
+ info->calibration_data[1]);
+}
+
static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
{
/* clkin = 6MHz */
@@ -481,6 +500,7 @@ static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)
{
u32 value;
+ sunxi_calibrate(info);
if (info->data->ctrl0_map)
regmap_write(info->regmap, SUNXI_THS_CTRL0,
@@ -602,6 +622,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
struct resource *mem;
void __iomem *base;
int ret;
+ struct nvmem_cell *cell;
+ ssize_t cell_size;
+ u64 *cell_data;
info->data = of_device_get_match_data(&pdev->dev);
if (!info->data)
@@ -616,6 +639,35 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
if (IS_ERR(base))
return PTR_ERR(base);
+ info->has_calibration_data[0] = false;
+ info->has_calibration_data[1] = false;
+
+ if (!info->data->supports_nvmem)
+ goto no_nvmem;
+
+ cell = devm_nvmem_cell_get(&pdev->dev, "calibration");
+ if (IS_ERR(cell)) {
+ if (PTR_ERR(cell) == -EPROBE_DEFER)
+ return PTR_ERR(cell);
+ } else {
+ cell_data = (u64 *)nvmem_cell_read(cell, &cell_size);
+ devm_nvmem_cell_put(&pdev->dev, cell);
+ if (cell_size <= 4) {
+ info->has_calibration_data[0] = true;
+ info->calibration_data[0] = be32_to_cpu(cell_data[0] &
+ GENMASK(31, 0));
+ } else if (cell_size <= 8) {
+ info->has_calibration_data[0] = true;
+ info->calibration_data[0] = be32_to_cpu(cell_data[0] &
+ GENMASK(31, 0));
+ info->has_calibration_data[1] = true;
+ info->calibration_data[1] = be32_to_cpu(
+ (cell_data[0] >> 32) & GENMASK(31, 0));
+ }
+ }
+
+no_nvmem:
+
info->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&sun4i_gpadc_regmap_config);
if (IS_ERR(info->regmap)) {
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index 40b4dd9d2405..c251002431bd 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -90,6 +90,8 @@
#define SUNXI_THS_CTRL0 0x00
#define SUNXI_THS_CTRL2 0x40
#define SUNXI_THS_FILTER 0x70
+#define SUNXI_THS_CDATA_0_1 0x74
+#define SUNXI_THS_CDATA_2_3 0x78
#define SUNXI_THS_TDATA0 0x80
#define SUNXI_THS_TDATA1 0x84
#define SUNXI_THS_TDATA2 0x88
--
2.17.1

View file

@ -0,0 +1,253 @@
From 153c005037601e2ba02f7fb36d8864194d8c98c8 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sun, 21 Jan 2018 11:20:55 +0100
Subject: [PATCH 016/146] iio: adc: sun4i-gpadc-iio: rework: add interrupt
support
This patch rewors the driver to support interrupts for the thermal part
of the sensor.
This is only available for the newer sensor (currently H3 and A83T).
The interrupt will be trigerd on data available and triggers the update
for the thermal sensors. All newer sensors have different amount of
sensors and different interrupts for each device the reset of the
interrupts need to be done different
For the newer sensors is the autosuspend disabled.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 68 ++++++++++++++++++++++++++++---
include/linux/mfd/sun4i-gpadc.h | 33 +++++++++++++++
2 files changed, 95 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 7b12666cdd9e..77e07f042730 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -78,11 +78,14 @@ struct gpadc_data {
u32 ctrl2_map;
u32 sensor_en_map;
u32 filter_map;
+ u32 irq_clear_map;
+ u32 irq_control_map;
bool has_bus_clk;
bool has_bus_rst;
bool has_mod_clk;
int sensor_count;
bool supports_nvmem;
+ bool support_irq;
};
static const struct gpadc_data sun4i_gpadc_data = {
@@ -97,6 +100,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+ .support_irq = false,
};
static const struct gpadc_data sun5i_gpadc_data = {
@@ -111,6 +115,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+ .support_irq = false,
};
static const struct gpadc_data sun6i_gpadc_data = {
@@ -125,6 +130,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+ .support_irq = false,
};
static const struct gpadc_data sun8i_a33_gpadc_data = {
@@ -136,6 +142,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+ .support_irq = false,
};
struct sun4i_gpadc_iio {
@@ -339,6 +346,11 @@ static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val,
return 0;
}
+ if (info->data->support_irq) {
+ regmap_read(info->regmap, info->data->temp_data[sensor], val);
+ return 0;
+ }
+
return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
}
@@ -436,6 +448,17 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static irqreturn_t sunxi_irq_thread(int irq, void *data)
+{
+ struct sun4i_gpadc_iio *info = data;
+
+ regmap_write(info->regmap, SUNXI_THS_STAT, info->data->irq_clear_map);
+
+ thermal_zone_device_update(info->tzd, THERMAL_EVENT_TEMP_SAMPLE);
+
+ return IRQ_HANDLED;
+}
+
static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info)
{
/* Disable the ADC on IP */
@@ -448,6 +471,8 @@ static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info)
static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info)
{
+ /* Disable ths interrupt*/
+ regmap_write(info->regmap, SUNXI_THS_INTC, 0x0);
/* Disable temperature sensor */
regmap_write(info->regmap, SUNXI_THS_CTRL2, 0x0);
@@ -509,9 +534,15 @@ static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)
regmap_write(info->regmap, SUNXI_THS_CTRL2,
info->data->ctrl2_map);
+ regmap_write(info->regmap, SUNXI_THS_STAT,
+ info->data->irq_clear_map);
+
regmap_write(info->regmap, SUNXI_THS_FILTER,
info->data->filter_map);
+ regmap_write(info->regmap, SUNXI_THS_INTC,
+ info->data->irq_control_map);
+
regmap_read(info->regmap, SUNXI_THS_CTRL2, &value);
regmap_write(info->regmap, SUNXI_THS_CTRL2,
@@ -625,12 +656,29 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,
struct nvmem_cell *cell;
ssize_t cell_size;
u64 *cell_data;
+ int irq;
info->data = of_device_get_match_data(&pdev->dev);
if (!info->data)
return -ENODEV;
- info->no_irq = true;
+ if (info->data->support_irq) {
+ /* only the new versions of ths support right now irqs */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ dev_err(&pdev->dev, "failed to get IRQ: %d\n", irq);
+ return irq;
+ }
+
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+ sunxi_irq_thread, IRQF_ONESHOT,
+ dev_name(&pdev->dev), info);
+ if (ret)
+ return ret;
+
+ } else
+ info->no_irq = true;
+
indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels);
indio_dev->channels = sun8i_a33_gpadc_channels;
@@ -840,11 +888,13 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
if (ret)
return ret;
- pm_runtime_set_autosuspend_delay(&pdev->dev,
- SUN4I_GPADC_AUTOSUSPEND_DELAY);
- pm_runtime_use_autosuspend(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
+ if (!info->data->support_irq) {
+ pm_runtime_set_autosuspend_delay(&pdev->dev,
+ SUN4I_GPADC_AUTOSUSPEND_DELAY);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_set_suspended(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ }
if (IS_ENABLED(CONFIG_THERMAL_OF)) {
for (i = 0; i < info->data->sensor_count; i++) {
@@ -865,6 +915,9 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
}
}
+ if (info->data->support_irq)
+ info->data->sample_start(info);
+
ret = devm_iio_device_register(&pdev->dev, indio_dev);
if (ret < 0) {
dev_err(&pdev->dev, "could not register the device\n");
@@ -894,6 +947,9 @@ static int sun4i_gpadc_remove(struct platform_device *pdev)
if (!IS_ENABLED(CONFIG_THERMAL_OF))
return 0;
+ if (info->data->support_irq)
+ info->data->sample_end(info);
+
thermal_zone_of_sensor_unregister(info->sensor_device, info->tzd);
if (!info->no_irq)
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index c251002431bd..ab34a96a7ff3 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -89,6 +89,8 @@
/* SUNXI_THS COMMON REGISTERS + DEFINES */
#define SUNXI_THS_CTRL0 0x00
#define SUNXI_THS_CTRL2 0x40
+#define SUNXI_THS_INTC 0x44
+#define SUNXI_THS_STAT 0x48
#define SUNXI_THS_FILTER 0x70
#define SUNXI_THS_CDATA_0_1 0x74
#define SUNXI_THS_CDATA_2_3 0x78
@@ -107,6 +109,37 @@
#define SUNXI_THS_TEMP_SENSE_EN2 BIT(2)
#define SUNXI_THS_TEMP_SENSE_EN3 BIT(3)
+#define SUNXI_THS_TEMP_PERIOD(x) (GENMASK(31, 12) & ((x) << 12))
+
+#define SUNXI_THS_INTS_ALARM_OFF_2 BIT(14)
+#define SUNXI_THS_INTS_ALARM_OFF_1 BIT(13)
+#define SUNXI_THS_INTS_ALARM_OFF_0 BIT(12)
+#define SUNXI_THS_INTS_TDATA_IRQ_3 BIT(11)
+#define SUNXI_THS_INTS_TDATA_IRQ_2 BIT(10)
+#define SUNXI_THS_INTS_TDATA_IRQ_1 BIT(9)
+#define SUNXI_THS_INTS_TDATA_IRQ_0 BIT(8)
+#define SUNXI_THS_INTS_SHUT_INT_3 BIT(7)
+#define SUNXI_THS_INTS_SHUT_INT_2 BIT(6)
+#define SUNXI_THS_INTS_SHUT_INT_1 BIT(5)
+#define SUNXI_THS_INTS_SHUT_INT_0 BIT(4)
+#define SUNXI_THS_INTS_ALARM_INT_3 BIT(3)
+#define SUNXI_THS_INTS_ALARM_INT_2 BIT(2)
+#define SUNXI_THS_INTS_ALARM_INT_1 BIT(1)
+#define SUNXI_THS_INTS_ALARM_INT_0 BIT(0)
+
+#define SUNXI_THS_INTC_TDATA_IRQ_EN3 BIT(11)
+#define SUNXI_THS_INTC_TDATA_IRQ_EN2 BIT(10)
+#define SUNXI_THS_INTC_TDATA_IRQ_EN1 BIT(9)
+#define SUNXI_THS_INTC_TDATA_IRQ_EN0 BIT(8)
+#define SUNXI_THS_INTC_SHUT_INT_EN3 BIT(7)
+#define SUNXI_THS_INTC_SHUT_INT_EN2 BIT(6)
+#define SUNXI_THS_INTC_SHUT_INT_EN1 BIT(5)
+#define SUNXI_THS_INTC_SHUT_INT_EN0 BIT(4)
+#define SUNXI_THS_INTC_ALARM_INT_EN3 BIT(3)
+#define SUNXI_THS_INTC_ALARM_INT_EN2 BIT(2)
+#define SUNXI_THS_INTC_ALARM_INT_EN1 BIT(1)
+#define SUNXI_THS_INTC_ALARM_INT_EN0 BIT(0)
+
#define MAX_SENSOR_COUNT 4
struct sun4i_gpadc_dev {
--
2.17.1

View file

@ -0,0 +1,67 @@
From 1968a84bd7cfdf60b29a154e682c4239bdfe6cb7 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sun, 21 Jan 2018 23:14:09 +0100
Subject: [PATCH 017/146] iio: adc: sun4i-gpadc-iio: add support for H3 thermal
sensor
This patch adds support for the H3 ths sensor.
The H3 supports interrupts. The interrupt is configured to update the
the sensor values every second. The calibration data is writen at the
begin of the init process.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 77e07f042730..f2e0ec65c53e 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -145,6 +145,31 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.support_irq = false,
};
+static const struct gpadc_data sun8i_h3_ths_data = {
+ .temp_offset = -1791,
+ .temp_scale = -121,
+ .temp_data = {SUNXI_THS_TDATA0, 0, 0, 0},
+ .sample_start = sunxi_ths_sample_start,
+ .sample_end = sunxi_ths_sample_end,
+ .has_bus_clk = true,
+ .has_bus_rst = true,
+ .has_mod_clk = true,
+ .sensor_count = 1,
+ .supports_nvmem = true,
+ .support_irq = true,
+ .ctrl0_map = SUNXI_THS_ACQ0(0xff),
+ .ctrl2_map = SUNXI_THS_ACQ1(0x3f),
+ .sensor_en_map = SUNXI_THS_TEMP_SENSE_EN0,
+ .filter_map = SUNXI_THS_FILTER_EN |
+ SUNXI_THS_FILTER_TYPE(0x2),
+ .irq_clear_map = SUNXI_THS_INTS_ALARM_INT_0 |
+ SUNXI_THS_INTS_SHUT_INT_0 |
+ SUNXI_THS_INTS_TDATA_IRQ_0 |
+ SUNXI_THS_INTS_ALARM_OFF_0,
+ .irq_control_map = SUNXI_THS_INTC_TDATA_IRQ_EN0 |
+ SUNXI_THS_TEMP_PERIOD(0x7),
+};
+
struct sun4i_gpadc_iio {
struct iio_dev *indio_dev;
struct completion completion;
@@ -643,6 +668,10 @@ static const struct of_device_id sun4i_gpadc_of_id[] = {
.compatible = "allwinner,sun8i-a33-ths",
.data = &sun8i_a33_gpadc_data,
},
+ {
+ .compatible = "allwinner,sun8i-h3-ths",
+ .data = &sun8i_h3_ths_data,
+ },
{ /* sentinel */ }
};
--
2.17.1

View file

@ -0,0 +1,75 @@
From 20484f59a26747db157563c9ba13767c21b48efb Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sun, 21 Jan 2018 18:50:11 +0100
Subject: [PATCH 018/146] iio: adc: sun4i-gpadc-iio: add support for A83T
thermal sensor
This patch adds support for the A83T ths sensor.
The A83T does not support interrupts. This seems to be broken.
The calibration data is writen at the begin of the init process.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 38 +++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index f2e0ec65c53e..b8693afcdbea 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -170,6 +170,40 @@ static const struct gpadc_data sun8i_h3_ths_data = {
SUNXI_THS_TEMP_PERIOD(0x7),
};
+static const struct gpadc_data sun8i_a83t_ths_data = {
+ .temp_offset = -2724,
+ .temp_scale = -70,
+ .temp_data = {SUNXI_THS_TDATA0,
+ SUNXI_THS_TDATA1,
+ SUNXI_THS_TDATA2,
+ 0},
+ .sample_start = sunxi_ths_sample_start,
+ .sample_end = sunxi_ths_sample_end,
+ .sensor_count = 3,
+ .supports_nvmem = false,
+ .support_irq = true,
+ .ctrl0_map = SUNXI_THS_ACQ0(0x1f3),
+ .ctrl2_map = SUNXI_THS_ACQ1(0x1f3),
+ .sensor_en_map = SUNXI_THS_TEMP_SENSE_EN0 |
+ SUNXI_THS_TEMP_SENSE_EN1 |
+ SUNXI_THS_TEMP_SENSE_EN2,
+ .filter_map = SUNXI_THS_FILTER_EN |
+ SUNXI_THS_FILTER_TYPE(0x2),
+ .irq_clear_map = SUNXI_THS_INTS_ALARM_INT_0 |
+ SUNXI_THS_INTS_ALARM_INT_1 |
+ SUNXI_THS_INTS_ALARM_INT_2 |
+ SUNXI_THS_INTS_SHUT_INT_0 |
+ SUNXI_THS_INTS_SHUT_INT_1 |
+ SUNXI_THS_INTS_SHUT_INT_2 |
+ SUNXI_THS_INTS_TDATA_IRQ_0 |
+ SUNXI_THS_INTS_TDATA_IRQ_1 |
+ SUNXI_THS_INTS_TDATA_IRQ_2,
+ .irq_control_map = SUNXI_THS_INTC_TDATA_IRQ_EN0 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN1 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN2 |
+ SUNXI_THS_TEMP_PERIOD(0x257),
+};
+
struct sun4i_gpadc_iio {
struct iio_dev *indio_dev;
struct completion completion;
@@ -672,6 +706,10 @@ static const struct of_device_id sun4i_gpadc_of_id[] = {
.compatible = "allwinner,sun8i-h3-ths",
.data = &sun8i_h3_ths_data,
},
+ {
+ .compatible = "allwinner,sun8i-a83t-ths",
+ .data = &sun8i_a83t_ths_data,
+ },
{ /* sentinel */ }
};
--
2.17.1

View file

@ -0,0 +1,39 @@
From f1b96d20375eb192d017999740c0055f2efbf576 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Fri, 26 Jan 2018 01:01:34 +0100
Subject: [PATCH 019/146] arm: dts: sunxi-h3-h5: add support for the thermal
sensor in H3 and H5
As we have gained the support for the thermal sensor in H3 and H5,
we can now add its device nodes to the device tree. The H3 and H5 share
most of its compatible. The compatible and the thermal sensor cells
will be added in an additional patch per device.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sunxi-h3-h5.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index fc6131315c47..8fde0f6c16e4 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -488,6 +488,15 @@
};
};
+ ths: thermal-sensor@1c25000 {
+ reg = <0x01c25000 0x100>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_THS>;
+ #io-channel-cells = <0>;
+ };
+
timer@1c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0xa0>;
--
2.17.1

View file

@ -0,0 +1,30 @@
From e475b475fbab608b805a57c8cc083e7b3da77954 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Fri, 26 Jan 2018 01:07:15 +0100
Subject: [PATCH 020/146] arm: dts: sun8i: h3: add support for the thermal
sensor in H3
This patch adds the missing compatible and the thermal sensor cells.
The H3 has one sensor.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sun8i-h3.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index f0096074a467..5907b54b6e1d 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -216,3 +216,8 @@
&pio {
compatible = "allwinner,sun8i-h3-pinctrl";
};
+
+&ths {
+ compatible = "allwinner,sun8i-h3-ths";
+ #thermal-sensor-cells = <0>;
+};
--
2.17.1

View file

@ -0,0 +1,36 @@
From 16346f511d19e20e12041076f402606b87de0b56 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Fri, 26 Jan 2018 01:10:12 +0100
Subject: [PATCH 021/146] arm: dts: sun8i: h3: add thermal zone to H3
This patch adds the thermal zones to the H3. We have only one sensor and
that is placed in the cpu.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sun8i-h3.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 5907b54b6e1d..d2c85be8a2d0 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -111,6 +111,15 @@
};
};
+ thermal-zones {
+ cpu-thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 0>;
+ };
+ };
+
timer {
compatible = "arm,armv7-timer";
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
--
2.17.1

View file

@ -0,0 +1,34 @@
From 328b1316b4a89f2bf9e451f3cfa41d591962c44e Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Tue, 23 Jan 2018 10:57:37 +0100
Subject: [PATCH 022/146] arm: dts: sun8i: h3: enable H3 sid controller
This patch enables the the sid controller in the H3. It can be used
for thermal calibration data.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sun8i-h3.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index d2c85be8a2d0..791a9406c671 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -111,6 +111,13 @@
};
};
+ soc {
+ sid: eeprom@1c14000 {
+ compatible = "allwinner,sun8i-h3-sid";
+ reg = <0x01c14000 0x400>;
+ };
+ };
+
thermal-zones {
cpu-thermal {
/* milliseconds */
--
2.17.1

View file

@ -0,0 +1,38 @@
From 4d9df1fab6b1601612b7b4380f83d3c4560c671e Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Fri, 26 Jan 2018 01:15:17 +0100
Subject: [PATCH 023/146] arm: dts: sun8i: a83t: add support for the thermal
sensor in A83T
As we have gained the support for the thermal sensor in A83T,
we can now add its device nodes to the device tree.
The A83T seems to have a broken IRQ 31, thus we use here IRQ 41.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sun8i-a83t.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 00a02b037320..6bdfcc7a1ac3 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -757,6 +757,14 @@
clocks = <&osc24M>;
};
+ ths: thermal-sensor@1f04000 {
+ compatible = "allwinner,sun8i-a83t-ths";
+ reg = <0x01f04000 0x100>;
+ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+ #thermal-sensor-cells = <1>;
+ #io-channel-cells = <0>;
+ };
+
watchdog@1c20ca0 {
compatible = "allwinner,sun6i-a31-wdt";
reg = <0x01c20ca0 0x20>;
--
2.17.1

View file

@ -0,0 +1,46 @@
From 5bcffafbbcc98a66101d02d37ba6beca3f52068e Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Fri, 26 Jan 2018 01:17:14 +0100
Subject: [PATCH 024/146] arm: dts: sun8i: a83t: add thermal zone to A83T
This patch adds the thermal zones to the A83T. Sensor 0 is located in the
cpu cluster 0. Sensor 1 is located in cluster 1 and Sensor 3 is located
in the gpu.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sun8i-a83t.dtsi | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 6bdfcc7a1ac3..ec22157419b6 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -1033,4 +1033,24 @@
#size-cells = <0>;
};
};
+
+ thermal-zones {
+ cpu0_thermal: cpu0-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&ths 0>;
+ };
+
+ cpu1_thermal: cpu1-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&ths 1>;
+ };
+
+ gpu_thermal: gpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&ths 2>;
+ };
+ };
};
--
2.17.1

View file

@ -0,0 +1,26 @@
From f79548364ea767853c5a95f1db2407219f06572a Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Wed, 24 Jan 2018 22:35:13 +0100
Subject: [PATCH 026/146] iio: adc: Kconfig: enable A80, A64 and H5 for THS
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 4a754921fb6f..c77aec60a364 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -723,7 +723,7 @@ config STX104
config SUN4I_GPADC
tristate "Support for the Allwinner SoCs GPADC"
depends on IIO
- depends on MFD_SUN4I_GPADC || MACH_SUN8I
+ depends on MFD_SUN4I_GPADC || MACH_SUN8I || MACH_SUN50I || MACH_SUN9I
depends on THERMAL || !THERMAL_OF
select REGMAP_IRQ
help
--
2.17.1

View file

@ -0,0 +1,79 @@
From 46f1130b5286457e519c296a4b683747deb983cb Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Wed, 24 Jan 2018 16:58:30 +0100
Subject: [PATCH 027/146] iio: adc: sun4i-gpadc-iio: add support for H5 thermal
sensor
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds support for the H5 ths sensor.
The H5 supports interrupts. The interrupt is configured to update
the sensor values every second. The sensor is except the scale/offset
values and an additional sensor for the gpu the same. A temperatur higer
than 70°C needs an other formula. Since the operating temperatures maximum
is 70°C this case was neglegted.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 36 +++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index b8693afcdbea..40529a197335 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -204,6 +204,38 @@ static const struct gpadc_data sun8i_a83t_ths_data = {
SUNXI_THS_TEMP_PERIOD(0x257),
};
+static const struct gpadc_data sun50i_h5_ths_data = {
+ .temp_offset = -1872,
+ .temp_scale = -119,
+ .temp_data = {SUNXI_THS_TDATA0,
+ SUNXI_THS_TDATA1, 0, 0},
+ .sample_start = sunxi_ths_sample_start,
+ .sample_end = sunxi_ths_sample_end,
+ .has_bus_clk = true,
+ .has_bus_rst = true,
+ .has_mod_clk = true,
+ .sensor_count = 2,
+ .supports_nvmem = false,
+ .support_irq = true,
+ .ctrl0_map = SUNXI_THS_ACQ0(0x1f3),
+ .ctrl2_map = SUNXI_THS_ACQ1(0x1f3),
+ .sensor_en_map = SUNXI_THS_TEMP_SENSE_EN0 |
+ SUNXI_THS_TEMP_SENSE_EN1,
+ .filter_map = SUNXI_THS_FILTER_EN |
+ SUNXI_THS_FILTER_TYPE(0x2),
+ .irq_clear_map = SUNXI_THS_INTS_ALARM_INT_0 |
+ SUNXI_THS_INTS_ALARM_INT_1 |
+ SUNXI_THS_INTS_SHUT_INT_0 |
+ SUNXI_THS_INTS_SHUT_INT_1 |
+ SUNXI_THS_INTS_TDATA_IRQ_0 |
+ SUNXI_THS_INTS_TDATA_IRQ_1 |
+ SUNXI_THS_INTS_ALARM_OFF_0 |
+ SUNXI_THS_INTS_ALARM_OFF_1,
+ .irq_control_map = SUNXI_THS_INTC_TDATA_IRQ_EN0 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN1 |
+ SUNXI_THS_TEMP_PERIOD(0x3a),
+};
+
struct sun4i_gpadc_iio {
struct iio_dev *indio_dev;
struct completion completion;
@@ -710,6 +742,10 @@ static const struct of_device_id sun4i_gpadc_of_id[] = {
.compatible = "allwinner,sun8i-a83t-ths",
.data = &sun8i_a83t_ths_data,
},
+ {
+ .compatible = "allwinner,sun50i-h5-ths",
+ .data = &sun50i_h5_ths_data,
+ },
{ /* sentinel */ }
};
--
2.17.1

View file

@ -0,0 +1,86 @@
From 413a3bde03c061d4b5affe25ad75f4dfe6e3282b Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Wed, 24 Jan 2018 17:28:02 +0100
Subject: [PATCH 028/146] iio: adc: sun4i-gpadc-iio: add support for A80
thermal sensor
This patch adds support for the A80 ths sensor.
The A80 has 4 sensors and supports interrupts. The interrupt is configured to update
the sensor values every second. The A80 shares some registers with the
integrated GPADC. ACQ0 must be set in the GPADC register with the offset
0x00. In fact the GPADC and the THS use the same register base and also
the same clocks and resets.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 46 +++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 40529a197335..7ab175f0bd40 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -236,6 +236,48 @@ static const struct gpadc_data sun50i_h5_ths_data = {
SUNXI_THS_TEMP_PERIOD(0x3a),
};
+static const struct gpadc_data sun9i_a80_ths_data = {
+ .temp_offset = -2794,
+ .temp_scale = -67,
+ .temp_data = {SUNXI_THS_TDATA0,
+ SUNXI_THS_TDATA1,
+ SUNXI_THS_TDATA2,
+ SUNXI_THS_TDATA3},
+ .sample_start = sunxi_ths_sample_start,
+ .sample_end = sunxi_ths_sample_end,
+ .has_bus_clk = true,
+ .has_bus_rst = true,
+ .has_mod_clk = true,
+ .sensor_count = 4,
+ .supports_nvmem = false,
+ .support_irq = true,
+ .ctrl0_map = SUNXI_THS_ACQ0(0x1f3),
+ .ctrl2_map = SUNXI_THS_TEMP_SENSE_EN0 |
+ SUNXI_THS_TEMP_SENSE_EN1 |
+ SUNXI_THS_TEMP_SENSE_EN2 |
+ SUNXI_THS_TEMP_SENSE_EN3 |
+ SUNXI_THS_ACQ1(0x1f3),
+ .filter_map = SUNXI_THS_FILTER_EN |
+ SUNXI_THS_FILTER_TYPE(0x2),
+ .irq_clear_map = SUNXI_THS_INTS_ALARM_INT_0 |
+ SUNXI_THS_INTS_ALARM_INT_1 |
+ SUNXI_THS_INTS_ALARM_INT_2 |
+ SUNXI_THS_INTS_ALARM_INT_3 |
+ SUNXI_THS_INTS_SHUT_INT_0 |
+ SUNXI_THS_INTS_SHUT_INT_1 |
+ SUNXI_THS_INTS_SHUT_INT_2 |
+ SUNXI_THS_INTS_SHUT_INT_3 |
+ SUNXI_THS_INTS_TDATA_IRQ_0 |
+ SUNXI_THS_INTS_TDATA_IRQ_1 |
+ SUNXI_THS_INTS_TDATA_IRQ_2 |
+ SUNXI_THS_INTS_TDATA_IRQ_3,
+ .irq_control_map = SUNXI_THS_INTC_TDATA_IRQ_EN0 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN1 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN2 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN3 |
+ SUNXI_THS_TEMP_PERIOD(0x3a),
+};
+
struct sun4i_gpadc_iio {
struct iio_dev *indio_dev;
struct completion completion;
@@ -746,6 +788,10 @@ static const struct of_device_id sun4i_gpadc_of_id[] = {
.compatible = "allwinner,sun50i-h5-ths",
.data = &sun50i_h5_ths_data,
},
+ {
+ .compatible = "allwinner,sun9i-a80-ths",
+ .data = &sun9i_a80_ths_data,
+ },
{ /* sentinel */ }
};
--
2.17.1

View file

@ -0,0 +1,87 @@
From 5a1eb96e482c276f8bc81c18696748ecb20b3656 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Wed, 24 Jan 2018 17:41:45 +0100
Subject: [PATCH 029/146] iio: adc: sun4i-gpadc-iio: add support for A64
thermal sensor
This patch adds support for the A64 ths sensor.
The A64 supports interrupts. The interrupt is configured to update
the sensor values every second.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 50 +++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index 7ab175f0bd40..fdfa01bad325 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -278,6 +278,52 @@ static const struct gpadc_data sun9i_a80_ths_data = {
SUNXI_THS_TEMP_PERIOD(0x3a),
};
+static const struct gpadc_data sun50i_a64_ths_data = {
+ .temp_offset = -2170,
+ .temp_scale = -117,
+ .temp_data = {SUNXI_THS_TDATA0,
+ SUNXI_THS_TDATA1,
+ SUNXI_THS_TDATA2,
+ 0},
+ .sample_start = sunxi_ths_sample_start,
+ .sample_end = sunxi_ths_sample_end,
+ .has_bus_clk = true,
+ .has_bus_rst = true,
+ .has_mod_clk = true,
+ .sensor_count = 3,
+ .supports_nvmem = false,
+ .support_irq = true,
+
+ /* The final sample period is calculated as follows:
+ * (THERMAL_PER + 1) * 4096 / 24MHz * 2^(FILTER_TYPE + 1)
+ *
+ * This results to about 1Hz with these settings.
+ */
+ .ctrl0_map = SUNXI_THS_ACQ0(0xff),
+ .ctrl2_map = SUNXI_THS_TEMP_SENSE_EN0 |
+ SUNXI_THS_TEMP_SENSE_EN1 |
+ SUNXI_THS_TEMP_SENSE_EN2 |
+ SUNXI_THS_ACQ1(0x3f),
+ .filter_map = SUNXI_THS_FILTER_EN |
+ SUNXI_THS_FILTER_TYPE(0x1),
+ .irq_clear_map = SUNXI_THS_INTS_ALARM_INT_0 |
+ SUNXI_THS_INTS_ALARM_INT_1 |
+ SUNXI_THS_INTS_ALARM_INT_2 |
+ SUNXI_THS_INTS_SHUT_INT_0 |
+ SUNXI_THS_INTS_SHUT_INT_1 |
+ SUNXI_THS_INTS_SHUT_INT_2 |
+ SUNXI_THS_INTS_TDATA_IRQ_0 |
+ SUNXI_THS_INTS_TDATA_IRQ_1 |
+ SUNXI_THS_INTS_TDATA_IRQ_2 |
+ SUNXI_THS_INTS_ALARM_OFF_0 |
+ SUNXI_THS_INTS_ALARM_OFF_1 |
+ SUNXI_THS_INTS_ALARM_OFF_2,
+ .irq_control_map = SUNXI_THS_INTC_TDATA_IRQ_EN0 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN1 |
+ SUNXI_THS_INTC_TDATA_IRQ_EN2 |
+ SUNXI_THS_TEMP_PERIOD(0x7),
+};
+
struct sun4i_gpadc_iio {
struct iio_dev *indio_dev;
struct completion completion;
@@ -792,6 +838,10 @@ static const struct of_device_id sun4i_gpadc_of_id[] = {
.compatible = "allwinner,sun9i-a80-ths",
.data = &sun9i_a80_ths_data,
},
+ {
+ .compatible = "allwinner,sun50i-a64-ths",
+ .data = &sun50i_a64_ths_data,
+ },
{ /* sentinel */ }
};
--
2.17.1

View file

@ -0,0 +1,30 @@
From e6e2d489bd4776f62a962ad8f511d862a1864f80 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Fri, 26 Jan 2018 01:40:38 +0100
Subject: [PATCH 030/146] arm64: dts: allwinner: h5: add support for the
thermal sensor in H5
This patch adds the missing compatible and the thermal sensor cells.
The H5 has two sensors.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
index 62d646baac3c..ee12490203b8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
@@ -129,3 +129,8 @@
<GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
compatible = "allwinner,sun50i-h5-pinctrl";
};
+
+&ths {
+ compatible = "allwinner,sun50i-h5-ths";
+ #thermal-sensor-cells = <1>;
+};
--
2.17.1

View file

@ -0,0 +1,43 @@
From b3ec6c1e145347ad88b14fcab39080c5af9410ef Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Fri, 26 Jan 2018 01:42:16 +0100
Subject: [PATCH 031/146] arm64: dts: allwinner: h5: add termal zone to H5
This patch adds the termal zones to the H5. Sensor 0 is located in the
cpu. Sensor 1 is located in the gpu.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
index ee12490203b8..849c3d8a50bb 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h5.dtsi
@@ -81,6 +81,22 @@
method = "smc";
};
+ thermal-zones {
+ cpu-thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 0>;
+ };
+
+ gpu-thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 1>;
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13
--
2.17.1

View file

@ -0,0 +1,42 @@
From 4990f2559d012df5c225df7cda3c29d60d3263b7 Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sat, 27 Jan 2018 21:30:16 +0100
Subject: [PATCH 032/146] arm: dts: sun9i: a80: add support for the thermal
sensor in A80
As we have gained the support for the thermal sensor in A80,
we can now add its device nodes to the device tree.
The clocks and the resets are shared between the GPADC and the THS
sensor.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sun9i-a80.dtsi | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 25591d6883ef..9411831d04aa 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -913,6 +913,17 @@
#reset-cells = <1>;
};
+ ths: thermal-sensor@6004C00 {
+ compatible = "allwinner,sun9i-a80-ths";
+ reg = <0x06004C00 0x100>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_GPADC>, <&ccu CLK_GPADC>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_GPADC>;
+ #thermal-sensor-cells = <1>;
+ #io-channel-cells = <0>;
+ };
+
timer@6000c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x06000c00 0xa0>;
--
2.17.1

View file

@ -0,0 +1,54 @@
From 559d5cc47ffd71a47da77424e251a8d21250cabb Mon Sep 17 00:00:00 2001
From: Philipp Rossak <embed3d@gmail.com>
Date: Sat, 27 Jan 2018 21:39:09 +0100
Subject: [PATCH 033/146] arm: dts: sun9i: a80: add thermal zone to A80
This patch adds the thermal zones to the A80.
Sensor 0 is located besides the big CPU, sensor 1 is located besides the
DRAM, sensor 2 is located besides the GPU and sensor 3 is located besides
the small CPU.
Signed-off-by: Philipp Rossak <embed3d@gmail.com>
---
arch/arm/boot/dts/sun9i-a80.dtsi | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 9411831d04aa..6c52b33dad84 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -1221,4 +1221,30 @@
#size-cells = <0>;
};
};
+
+ thermal-zones {
+ cpu0_thermal: cpu0-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&ths 0>;
+ };
+
+ dram_thermal: dram-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&ths 1>;
+ };
+
+ gpu_thermal: gpu-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&ths 2>;
+ };
+
+ cpu2_thermal: cpu2-thermal {
+ polling-delay-passive = <1000>;
+ polling-delay = <5000>;
+ thermal-sensors = <&ths 3>;
+ };
+ };
};
--
2.17.1

View file

@ -0,0 +1,62 @@
From ff4436bd3de240a1d0796d4c6f8bd676ff0925e1 Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Mon, 23 Apr 2018 23:24:41 -0700
Subject: [PATCH 034/146] dts: a64 ths
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 0b44018361cb..0eb482eb58b7 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -171,6 +171,27 @@
};
};
+ thermal-zones {
+ cpu_thermal: cpu0-thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 0>;
+ };
+ gpu0_thermal: gpu0-thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 1>;
+ };
+ gpu1_thermal: gpu1-thermal {
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 2>;
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13
@@ -536,6 +557,17 @@
status = "disabled";
};
+ ths: thermal-sensor@1c25000 {
+ compatible = "allwinner,sun50i-a64-ths";
+ reg = <0x01c25000 0x100>;
+ interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
+ clock-names = "bus", "mod";
+ resets = <&ccu RST_BUS_THS>;
+ #io-channel-cells = <0>;
+ #thermal-sensor-cells = <1>;
+ };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
--
2.17.1

View file

@ -0,0 +1,73 @@
From 5afd98f6db25b34a96bfc7544681dbf40896c1fd Mon Sep 17 00:00:00 2001
From: Icenowy Zheng <icenowy@aosc.io>
Date: Sat, 23 Sep 2017 08:15:29 +0800
Subject: [PATCH 035/146] clk: sunxi-ng: add mux and pll notifiers for A64 CPU
clock
The A64 PLL_CPU clock has the same instability if some factor changed
without the PLL gated like other SoCs with sun6i-style CCU, e.g. A33,
H3.
Add the mux and pll notifiers for A64 CPU clock to workaround the
problem.
Fixes: c6a0637460c2 ("clk: sunxi-ng: Add A64 clocks")
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
---
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 28 ++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index ee9c12cf3f08..1fe3c3fbc9bc 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -896,11 +896,26 @@ static const struct sunxi_ccu_desc sun50i_a64_ccu_desc = {
.num_resets = ARRAY_SIZE(sun50i_a64_ccu_resets),
};
+static struct ccu_pll_nb sun50i_a64_pll_cpu_nb = {
+ .common = &pll_cpux_clk.common,
+ /* copy from pll_cpux_clk */
+ .enable = BIT(31),
+ .lock = BIT(28),
+};
+
+static struct ccu_mux_nb sun50i_a64_cpu_nb = {
+ .common = &cpux_clk.common,
+ .cm = &cpux_clk.mux,
+ .delay_us = 1, /* > 8 clock cycles at 24 MHz */
+ .bypass_index = 1, /* index of 24 MHz oscillator */
+};
+
static int sun50i_a64_ccu_probe(struct platform_device *pdev)
{
struct resource *res;
void __iomem *reg;
u32 val;
+ int ret;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
reg = devm_ioremap_resource(&pdev->dev, res);
@@ -914,7 +929,18 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
- return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+ ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+ if (ret)
+ return ret;
+
+ /* Gate then ungate PLL CPU after any rate changes */
+ ccu_pll_notifier_register(&sun50i_a64_pll_cpu_nb);
+
+ /* Reparent CPU during PLL CPU rate changes */
+ ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+ &sun50i_a64_cpu_nb);
+
+ return 0;
}
static const struct of_device_id sun50i_a64_ccu_ids[] = {
--
2.17.1

View file

@ -0,0 +1,31 @@
From a6b5eb09bddbd0c331f41fefa2fd2f71a2cf9455 Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Tue, 24 Apr 2018 22:21:10 -0700
Subject: [PATCH 036/146] sun4i-gpadc-iio: ignore zero samples to avoid force
poweroff when reading first sample
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
drivers/iio/adc/sun4i-gpadc-iio.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c
index fdfa01bad325..68256e73a4d2 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -751,6 +751,12 @@ static int sun4i_gpadc_get_temp(void *data, int *temp)
if (sun4i_gpadc_temp_read(info->indio_dev, &val, info->sensor_id))
return -ETIMEDOUT;
+ /* Ignore first sample which is always zero. 0 is either too
+ * cold or too hot, so we can safely ignore it
+ */
+ if (val == 0)
+ return -ETIMEDOUT;
+
sun4i_gpadc_temp_scale(info->indio_dev, &scale);
sun4i_gpadc_temp_offset(info->indio_dev, &offset);
--
2.17.1

View file

@ -0,0 +1,251 @@
From b07dd371b1a1203a013f91da750259f7a2467fce Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Tue, 24 Apr 2018 22:21:27 -0700
Subject: [PATCH 037/146] a64 dvfs wip
Changed: Igor
---
.../boot/dts/allwinner/sun50i-a64-pine64.dts | 4 +
.../dts/allwinner/sun50i-a64-pinebook.dts | 4 +
.../allwinner/sun50i-a64-sopine-baseboard.dts | 4 +
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 111 ++++++++++++++++--
drivers/clk/sunxi-ng/ccu-sun50i-a64.h | 1 -
include/dt-bindings/clock/sun50i-a64-ccu.h | 1 +
6 files changed, 112 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index 8c5dd99cc9ac..cdf5169f2a1a 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -69,6 +69,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
index 897e60cbe38d..b3698a8bb1d3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
@@ -66,6 +66,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
phys = <&usbphy 0>;
phy-names = "usb";
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index 8161895dde52..dc728b3b5556 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -69,6 +69,10 @@
};
};
+&cpu0 {
+ cpu-supply = <&reg_dcdc2>;
+};
+
&ehci0 {
status = "okay";
};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 0eb482eb58b7..62b880f68d6a 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -49,6 +49,7 @@
#include <dt-bindings/reset/sun50i-a64-ccu.h>
#include <dt-bindings/reset/sun8i-de2.h>
#include <dt-bindings/reset/sun8i-r-ccu.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
interrupt-parent = <&gic>;
@@ -79,6 +80,47 @@
};
};
+ cpu0_opp_table: opp_table0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-120000000 {
+ opp-hz = /bits/ 64 <120000000>;
+ opp-microvolt = <1040000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ opp-648000000 {
+ opp-hz = /bits/ 64 <648000000>;
+ opp-microvolt = <1040000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ opp-816000000 {
+ opp-hz = /bits/ 64 <816000000>;
+ opp-microvolt = <1100000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ opp-912000000 {
+ opp-hz = /bits/ 64 <912000000>;
+ opp-microvolt = <1120000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ opp-960000000 {
+ opp-hz = /bits/ 64 <960000000>;
+ opp-microvolt = <1160000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ opp-1008000000 {
+ opp-hz = /bits/ 64 <1008000000>;
+ opp-microvolt = <1200000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ opp-1056000000 {
+ opp-hz = /bits/ 64 <1056000000>;
+ opp-microvolt = <1240000>;
+ clock-latency-ns = <244144>; /* 8 32k periods */
+ };
+ };
+
cpus {
#address-cells = <1>;
#size-cells = <0>;
@@ -88,6 +135,10 @@
device_type = "cpu";
reg = <0>;
enable-method = "psci";
+ clocks = <&ccu CLK_CPUX>;
+ clock-names = "cpu";
+ operating-points-v2 = <&cpu0_opp_table>;
+ #cooling-cells = <2>;
};
cpu1: cpu@1 {
@@ -95,6 +146,7 @@
device_type = "cpu";
reg = <1>;
enable-method = "psci";
+ operating-points-v2 = <&cpu0_opp_table>;
};
cpu2: cpu@2 {
@@ -102,6 +154,7 @@
device_type = "cpu";
reg = <2>;
enable-method = "psci";
+ operating-points-v2 = <&cpu0_opp_table>;
};
cpu3: cpu@3 {
@@ -109,6 +162,7 @@
device_type = "cpu";
reg = <3>;
enable-method = "psci";
+ operating-points-v2 = <&cpu0_opp_table>;
};
};
@@ -173,22 +227,55 @@
thermal-zones {
cpu_thermal: cpu0-thermal {
- /* milliseconds */
- polling-delay-passive = <250>;
- polling-delay = <1000>;
- thermal-sensors = <&ths 0>;
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 0>;
+
+ cooling-maps {
+ map0 {
+ trip = <&cpu_alert0>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ map1 {
+ trip = <&cpu_alert1>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ trips {
+ cpu_alert0: cpu_alert0 {
+ /* milliCelsius */
+ temperature = <75000>;
+ hysteresis = <2000>;
+ type = "passive";
+ };
+
+ cpu_alert1: cpu_alert1 {
+ /* milliCelsius */
+ temperature = <90000>;
+ hysteresis = <2000>;
+ type = "hot";
+ };
+
+ cpu_crit: cpu_crit {
+ /* milliCelsius */
+ temperature = <110000>;
+ hysteresis = <2000>;
+ type = "critical";
+ };
+ };
};
gpu0_thermal: gpu0-thermal {
- /* milliseconds */
- polling-delay-passive = <250>;
- polling-delay = <1000>;
- thermal-sensors = <&ths 1>;
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 1>;
};
gpu1_thermal: gpu1-thermal {
- /* milliseconds */
- polling-delay-passive = <250>;
- polling-delay = <1000>;
- thermal-sensors = <&ths 2>;
+ /* milliseconds */
+ polling-delay-passive = <250>;
+ polling-delay = <1000>;
+ thermal-sensors = <&ths 2>;
};
};
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
index 061b6fbb4f95..91f79512cee4 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
@@ -43,7 +43,6 @@
#define CLK_PLL_HSIC 18
#define CLK_PLL_DE 19
#define CLK_PLL_DDR1 20
-#define CLK_CPUX 21
#define CLK_AXI 22
#define CLK_APB 23
#define CLK_AHB1 24
diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h
index d66432c6e675..d7f42dd22663 100644
--- a/include/dt-bindings/clock/sun50i-a64-ccu.h
+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h
@@ -45,6 +45,7 @@
#define CLK_PLL_PERIPH0 11
+#define CLK_CPUX 21
#define CLK_BUS_MIPI_DSI 28
#define CLK_BUS_CE 29
#define CLK_BUS_DMA 30
--
2.17.1

View file

@ -0,0 +1,64 @@
From eca91d4d36d78c3176480742532b247fd3d72fe0 Mon Sep 17 00:00:00 2001
From: Simon Shields <simon@lineageos.org>
Date: Sat, 13 Jan 2018 14:17:26 +1100
Subject: [PATCH 038/146] ARM: dts: add gpu node to exynos4
v2 (Qiang Yu):
add vender string to exynos4 mali gpu
Based off a similar commit for the Samsung Mali driver by
Tobias Jakobi <tjakobi@math.uni-bielefeld.de>
Signed-off-by: Simon Shields <simon@lineageos.org>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
arch/arm/boot/dts/exynos4.dtsi | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index 6085e92ac2d7..362461657136 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -730,6 +730,39 @@
status = "disabled";
};
+ gpu: gpu@13000000 {
+ compatible = "samsung,exynos4-mali", "arm,mali-400";
+ reg = <0x13000000 0x30000>;
+ power-domains = <&pd_g3d>;
+
+ /*
+ * Propagate VPLL output clock to SCLK_G3D and
+ * ensure that the DIV_G3D divider is 1.
+ */
+ assigned-clocks = <&clock CLK_MOUT_G3D1>, <&clock CLK_MOUT_G3D>,
+ <&clock CLK_FOUT_VPLL>, <&clock CLK_SCLK_G3D>;
+ assigned-clock-parents = <&clock CLK_SCLK_VPLL>,
+ <&clock CLK_MOUT_G3D1>;
+ assigned-clock-rates = <0>, <0>, <160000000>, <160000000>;
+
+ clocks = <&clock CLK_SCLK_G3D>, <&clock CLK_G3D>;
+ clock-names = "bus", "core";
+
+ interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "ppmmu0", "ppmmu1", "ppmmu2", "ppmmu3",
+ "gpmmu", "pp0", "pp1", "pp2", "pp3", "gp";
+ status = "disabled";
+ };
+
tmu: tmu@100c0000 {
interrupt-parent = <&combiner>;
reg = <0x100C0000 0x100>;
--
2.17.1

View file

@ -0,0 +1,29 @@
From 93a9dff30ace06dceba2a84eb709433d5e08c7bc Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Wed, 21 Mar 2018 14:58:02 +0800
Subject: [PATCH 039/146] dt-bindings: add switch-delay property for
mali-utgard
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
index 63cd91176a68..3e2590162d4f 100644
--- a/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
+++ b/Documentation/devicetree/bindings/gpu/arm,mali-utgard.txt
@@ -58,6 +58,10 @@ Optional properties:
A power domain consumer specifier as defined in
Documentation/devicetree/bindings/power/power_domain.txt
+ - switch-delay:
+ This value is the number of Mali clock cycles it takes to
+ enable the power gates and turn on the power mesh.
+
Vendor-specific bindings
------------------------
--
2.17.1

View file

@ -0,0 +1,215 @@
From e59461ae51787ed4ba778ca32b6bde432552da96 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 14 May 2018 20:53:38 +0800
Subject: [PATCH 042/146] drm/lima: add lima uapi header
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
include/uapi/drm/lima_drm.h | 195 ++++++++++++++++++++++++++++++++++++
1 file changed, 195 insertions(+)
create mode 100644 include/uapi/drm/lima_drm.h
diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h
new file mode 100644
index 000000000000..9df95e46fb2c
--- /dev/null
+++ b/include/uapi/drm/lima_drm.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_DRM_H__
+#define __LIMA_DRM_H__
+
+#include "drm.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define LIMA_INFO_GPU_MALI400 0x00
+#define LIMA_INFO_GPU_MALI450 0x01
+
+struct drm_lima_info {
+ __u32 gpu_id; /* out */
+ __u32 num_pp; /* out */
+ __u64 va_start; /* out */
+ __u64 va_end; /* out */
+};
+
+struct drm_lima_gem_create {
+ __u32 size; /* in */
+ __u32 flags; /* in */
+ __u32 handle; /* out */
+ __u32 pad;
+};
+
+struct drm_lima_gem_info {
+ __u32 handle; /* in */
+ __u32 pad;
+ __u64 offset; /* out */
+};
+
+#define LIMA_VA_OP_MAP 1
+#define LIMA_VA_OP_UNMAP 2
+
+struct drm_lima_gem_va {
+ __u32 handle; /* in */
+ __u32 op; /* in */
+ __u32 flags; /* in */
+ __u32 va; /* in */
+};
+
+#define LIMA_SUBMIT_BO_READ 0x01
+#define LIMA_SUBMIT_BO_WRITE 0x02
+
+struct drm_lima_gem_submit_bo {
+ __u32 handle; /* in */
+ __u32 flags; /* in */
+};
+
+#define LIMA_SUBMIT_DEP_FENCE 0x00
+#define LIMA_SUBMIT_DEP_SYNC_FD 0x01
+
+struct drm_lima_gem_submit_dep_fence {
+ __u32 type;
+ __u32 ctx;
+ __u32 pipe;
+ __u32 seq;
+};
+
+struct drm_lima_gem_submit_dep_sync_fd {
+ __u32 type;
+ __u32 fd;
+};
+
+union drm_lima_gem_submit_dep {
+ __u32 type;
+ struct drm_lima_gem_submit_dep_fence fence;
+ struct drm_lima_gem_submit_dep_sync_fd sync_fd;
+};
+
+#define LIMA_GP_FRAME_REG_NUM 6
+
+struct drm_lima_gp_frame {
+ __u32 frame[LIMA_GP_FRAME_REG_NUM];
+};
+
+#define LIMA_PP_FRAME_REG_NUM 23
+#define LIMA_PP_WB_REG_NUM 12
+
+struct drm_lima_m400_pp_frame {
+ __u32 frame[LIMA_PP_FRAME_REG_NUM];
+ __u32 num_pp;
+ __u32 wb[3 * LIMA_PP_WB_REG_NUM];
+ __u32 plbu_array_address[4];
+ __u32 fragment_stack_address[4];
+};
+
+struct drm_lima_m450_pp_frame {
+ __u32 frame[LIMA_PP_FRAME_REG_NUM];
+ __u32 _pad;
+ __u32 wb[3 * LIMA_PP_WB_REG_NUM];
+ __u32 dlbu_regs[4];
+ __u32 fragment_stack_address[8];
+};
+
+#define LIMA_PIPE_GP 0x00
+#define LIMA_PIPE_PP 0x01
+
+#define LIMA_SUBMIT_FLAG_EXPLICIT_FENCE (1 << 0)
+#define LIMA_SUBMIT_FLAG_SYNC_FD_OUT (1 << 1)
+
+struct drm_lima_gem_submit_in {
+ __u32 ctx;
+ __u32 pipe;
+ __u32 nr_bos;
+ __u32 frame_size;
+ __u64 bos;
+ __u64 frame;
+ __u64 deps;
+ __u32 nr_deps;
+ __u32 flags;
+};
+
+struct drm_lima_gem_submit_out {
+ __u32 fence;
+ __u32 done;
+ __u32 sync_fd;
+ __u32 _pad;
+};
+
+union drm_lima_gem_submit {
+ struct drm_lima_gem_submit_in in;
+ struct drm_lima_gem_submit_out out;
+};
+
+struct drm_lima_wait_fence {
+ __u32 ctx; /* in */
+ __u32 pipe; /* in */
+ __u64 timeout_ns; /* in */
+ __u32 seq; /* in */
+ __u32 _pad;
+};
+
+#define LIMA_GEM_WAIT_READ 0x01
+#define LIMA_GEM_WAIT_WRITE 0x02
+
+struct drm_lima_gem_wait {
+ __u32 handle; /* in */
+ __u32 op; /* in */
+ __u64 timeout_ns; /* in */
+};
+
+#define LIMA_CTX_OP_CREATE 1
+#define LIMA_CTX_OP_FREE 2
+
+struct drm_lima_ctx {
+ __u32 op; /* in */
+ __u32 id; /* in/out */
+};
+
+#define DRM_LIMA_INFO 0x00
+#define DRM_LIMA_GEM_CREATE 0x01
+#define DRM_LIMA_GEM_INFO 0x02
+#define DRM_LIMA_GEM_VA 0x03
+#define DRM_LIMA_GEM_SUBMIT 0x04
+#define DRM_LIMA_WAIT_FENCE 0x05
+#define DRM_LIMA_GEM_WAIT 0x06
+#define DRM_LIMA_CTX 0x07
+
+#define DRM_IOCTL_LIMA_INFO DRM_IOR(DRM_COMMAND_BASE + DRM_LIMA_INFO, struct drm_lima_info)
+#define DRM_IOCTL_LIMA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_CREATE, struct drm_lima_gem_create)
+#define DRM_IOCTL_LIMA_GEM_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_INFO, struct drm_lima_gem_info)
+#define DRM_IOCTL_LIMA_GEM_VA DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_VA, struct drm_lima_gem_va)
+#define DRM_IOCTL_LIMA_GEM_SUBMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_SUBMIT, union drm_lima_gem_submit)
+#define DRM_IOCTL_LIMA_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_WAIT_FENCE, struct drm_lima_wait_fence)
+#define DRM_IOCTL_LIMA_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_WAIT, struct drm_lima_gem_wait)
+#define DRM_IOCTL_LIMA_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_CTX, struct drm_lima_ctx)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __LIMA_DRM_H__ */
--
2.17.1

View file

@ -0,0 +1,325 @@
From 68dcb878e43a65cc7129d7a1535da3b133e0e446 Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Mon, 14 May 2018 21:14:31 +0800
Subject: [PATCH 043/146] drm/lima: add mali 4xx GPU hardware regs
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_regs.h | 304 +++++++++++++++++++++++++++++++
1 file changed, 304 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_regs.h
diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h
new file mode 100644
index 000000000000..ea4a37d69b98
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_regs.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2010-2017 ARM Limited. All rights reserved.
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * This program is free software and is provided to you under
+ * the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation, and any use by
+ * you of this program is subject to the terms of such GNU
+ * licence.
+ *
+ * A copy of the licence is included with the program, and
+ * can also be obtained from Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __LIMA_REGS_H__
+#define __LIMA_REGS_H__
+
+/* PMU regs */
+#define LIMA_PMU_POWER_UP 0x00
+#define LIMA_PMU_POWER_DOWN 0x04
+#define LIMA_PMU_POWER_GP0_MASK (1 << 0)
+#define LIMA_PMU_POWER_L2_MASK (1 << 1)
+#define LIMA_PMU_POWER_PP_MASK(i) (1 << (2 + i))
+
+/*
+ * On Mali450 each block automatically starts up its corresponding L2
+ * and the PPs are not fully independent controllable.
+ * Instead PP0, PP1-3 and PP4-7 can be turned on or off.
+ */
+#define LIMA450_PMU_POWER_PP0_MASK BIT(1)
+#define LIMA450_PMU_POWER_PP13_MASK BIT(2)
+#define LIMA450_PMU_POWER_PP47_MASK BIT(3)
+
+#define LIMA_PMU_STATUS 0x08
+#define LIMA_PMU_INT_MASK 0x0C
+#define LIMA_PMU_INT_RAWSTAT 0x10
+#define LIMA_PMU_INT_CLEAR 0x18
+#define LIMA_PMU_INT_CMD_MASK (1 << 0)
+#define LIMA_PMU_SW_DELAY 0x1C
+
+/* L2 cache regs */
+#define LIMA_L2_CACHE_SIZE 0x0004
+#define LIMA_L2_CACHE_STATUS 0x0008
+#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY (1 << 0)
+#define LIMA_L2_CACHE_STATUS_DATA_BUSY (1 << 1)
+#define LIMA_L2_CACHE_COMMAND 0x0010
+#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL (1 << 0)
+#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014
+#define LIMA_L2_CACHE_MAX_READS 0x0018
+#define LIMA_L2_CACHE_ENABLE 0x001C
+#define LIMA_L2_CACHE_ENABLE_ACCESS (1 << 0)
+#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE (1 << 1)
+#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020
+#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024
+#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028
+#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C
+
+/* GP regs */
+#define LIMA_GP_VSCL_START_ADDR 0x00
+#define LIMA_GP_VSCL_END_ADDR 0x04
+#define LIMA_GP_PLBUCL_START_ADDR 0x08
+#define LIMA_GP_PLBUCL_END_ADDR 0x0c
+#define LIMA_GP_PLBU_ALLOC_START_ADDR 0x10
+#define LIMA_GP_PLBU_ALLOC_END_ADDR 0x14
+#define LIMA_GP_CMD 0x20
+#define LIMA_GP_CMD_START_VS (1 << 0)
+#define LIMA_GP_CMD_START_PLBU (1 << 1)
+#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC (1 << 4)
+#define LIMA_GP_CMD_RESET (1 << 5)
+#define LIMA_GP_CMD_FORCE_HANG (1 << 6)
+#define LIMA_GP_CMD_STOP_BUS (1 << 9)
+#define LIMA_GP_CMD_SOFT_RESET (1 << 10)
+#define LIMA_GP_INT_RAWSTAT 0x24
+#define LIMA_GP_INT_CLEAR 0x28
+#define LIMA_GP_INT_MASK 0x2C
+#define LIMA_GP_INT_STAT 0x30
+#define LIMA_GP_IRQ_VS_END_CMD_LST (1 << 0)
+#define LIMA_GP_IRQ_PLBU_END_CMD_LST (1 << 1)
+#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM (1 << 2)
+#define LIMA_GP_IRQ_VS_SEM_IRQ (1 << 3)
+#define LIMA_GP_IRQ_PLBU_SEM_IRQ (1 << 4)
+#define LIMA_GP_IRQ_HANG (1 << 5)
+#define LIMA_GP_IRQ_FORCE_HANG (1 << 6)
+#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT (1 << 7)
+#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT (1 << 8)
+#define LIMA_GP_IRQ_WRITE_BOUND_ERR (1 << 9)
+#define LIMA_GP_IRQ_SYNC_ERROR (1 << 10)
+#define LIMA_GP_IRQ_AXI_BUS_ERROR (1 << 11)
+#define LIMA_GP_IRQ_AXI_BUS_STOPPED (1 << 12)
+#define LIMA_GP_IRQ_VS_INVALID_CMD (1 << 13)
+#define LIMA_GP_IRQ_PLB_INVALID_CMD (1 << 14)
+#define LIMA_GP_IRQ_RESET_COMPLETED (1 << 19)
+#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW (1 << 20)
+#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW (1 << 21)
+#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22)
+#define LIMA_GP_WRITE_BOUND_LOW 0x34
+#define LIMA_GP_PERF_CNT_0_ENABLE 0x3C
+#define LIMA_GP_PERF_CNT_1_ENABLE 0x40
+#define LIMA_GP_PERF_CNT_0_SRC 0x44
+#define LIMA_GP_PERF_CNT_1_SRC 0x48
+#define LIMA_GP_PERF_CNT_0_VALUE 0x4C
+#define LIMA_GP_PERF_CNT_1_VALUE 0x50
+#define LIMA_GP_PERF_CNT_0_LIMIT 0x54
+#define LIMA_GP_STATUS 0x68
+#define LIMA_GP_STATUS_VS_ACTIVE (1 << 1)
+#define LIMA_GP_STATUS_BUS_STOPPED (1 << 2)
+#define LIMA_GP_STATUS_PLBU_ACTIVE (1 << 3)
+#define LIMA_GP_STATUS_BUS_ERROR (1 << 6)
+#define LIMA_GP_STATUS_WRITE_BOUND_ERR (1 << 8)
+#define LIMA_GP_VERSION 0x6C
+#define LIMA_GP_VSCL_START_ADDR_READ 0x80
+#define LIMA_GP_PLBCL_START_ADDR_READ 0x84
+#define LIMA_GP_CONTR_AXI_BUS_ERROR_STAT 0x94
+
+#define LIMA_GP_IRQ_MASK_ALL \
+ ( \
+ LIMA_GP_IRQ_VS_END_CMD_LST | \
+ LIMA_GP_IRQ_PLBU_END_CMD_LST | \
+ LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \
+ LIMA_GP_IRQ_VS_SEM_IRQ | \
+ LIMA_GP_IRQ_PLBU_SEM_IRQ | \
+ LIMA_GP_IRQ_HANG | \
+ LIMA_GP_IRQ_FORCE_HANG | \
+ LIMA_GP_IRQ_PERF_CNT_0_LIMIT | \
+ LIMA_GP_IRQ_PERF_CNT_1_LIMIT | \
+ LIMA_GP_IRQ_WRITE_BOUND_ERR | \
+ LIMA_GP_IRQ_SYNC_ERROR | \
+ LIMA_GP_IRQ_AXI_BUS_ERROR | \
+ LIMA_GP_IRQ_AXI_BUS_STOPPED | \
+ LIMA_GP_IRQ_VS_INVALID_CMD | \
+ LIMA_GP_IRQ_PLB_INVALID_CMD | \
+ LIMA_GP_IRQ_RESET_COMPLETED | \
+ LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \
+ LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \
+ LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
+
+#define LIMA_GP_IRQ_MASK_ERROR \
+ ( \
+ LIMA_GP_IRQ_PLBU_OUT_OF_MEM | \
+ LIMA_GP_IRQ_FORCE_HANG | \
+ LIMA_GP_IRQ_WRITE_BOUND_ERR | \
+ LIMA_GP_IRQ_SYNC_ERROR | \
+ LIMA_GP_IRQ_AXI_BUS_ERROR | \
+ LIMA_GP_IRQ_VS_INVALID_CMD | \
+ LIMA_GP_IRQ_PLB_INVALID_CMD | \
+ LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW | \
+ LIMA_GP_IRQ_SEMAPHORE_OVERFLOW | \
+ LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
+
+#define LIMA_GP_IRQ_MASK_USED \
+ ( \
+ LIMA_GP_IRQ_VS_END_CMD_LST | \
+ LIMA_GP_IRQ_PLBU_END_CMD_LST | \
+ LIMA_GP_IRQ_MASK_ERROR)
+
+/* PP regs */
+#define LIMA_PP_FRAME 0x0000
+#define LIMA_PP_RSW 0x0004
+#define LIMA_PP_STACK 0x0030
+#define LIMA_PP_STACK_SIZE 0x0034
+#define LIMA_PP_ORIGIN_OFFSET_X 0x0040
+#define LIMA_PP_WB(i) (0x0100 * (i + 1))
+#define LIMA_PP_WB_SOURCE_SELECT 0x0000
+#define LIMA_PP_WB_SOURCE_ADDR 0x0004
+
+#define LIMA_PP_VERSION 0x1000
+#define LIMA_PP_CURRENT_REND_LIST_ADDR 0x1004
+#define LIMA_PP_STATUS 0x1008
+#define LIMA_PP_STATUS_RENDERING_ACTIVE (1 << 0)
+#define LIMA_PP_STATUS_BUS_STOPPED (1 << 4)
+#define LIMA_PP_CTRL 0x100c
+#define LIMA_PP_CTRL_STOP_BUS (1 << 0)
+#define LIMA_PP_CTRL_FLUSH_CACHES (1 << 3)
+#define LIMA_PP_CTRL_FORCE_RESET (1 << 5)
+#define LIMA_PP_CTRL_START_RENDERING (1 << 6)
+#define LIMA_PP_CTRL_SOFT_RESET (1 << 7)
+#define LIMA_PP_INT_RAWSTAT 0x1020
+#define LIMA_PP_INT_CLEAR 0x1024
+#define LIMA_PP_INT_MASK 0x1028
+#define LIMA_PP_INT_STATUS 0x102c
+#define LIMA_PP_IRQ_END_OF_FRAME (1 << 0)
+#define LIMA_PP_IRQ_END_OF_TILE (1 << 1)
+#define LIMA_PP_IRQ_HANG (1 << 2)
+#define LIMA_PP_IRQ_FORCE_HANG (1 << 3)
+#define LIMA_PP_IRQ_BUS_ERROR (1 << 4)
+#define LIMA_PP_IRQ_BUS_STOP (1 << 5)
+#define LIMA_PP_IRQ_CNT_0_LIMIT (1 << 6)
+#define LIMA_PP_IRQ_CNT_1_LIMIT (1 << 7)
+#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR (1 << 8)
+#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND (1 << 9)
+#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW (1 << 10)
+#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW (1 << 11)
+#define LIMA_PP_IRQ_RESET_COMPLETED (1 << 12)
+#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044
+#define LIMA_PP_BUS_ERROR_STATUS 0x1050
+#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080
+#define LIMA_PP_PERF_CNT_0_SRC 0x1084
+#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088
+#define LIMA_PP_PERF_CNT_0_VALUE 0x108c
+#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0
+#define LIMA_PP_PERF_CNT_1_SRC 0x10a4
+#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8
+#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac
+#define LIMA_PP_PERFMON_CONTR 0x10b0
+#define LIMA_PP_PERFMON_BASE 0x10b4
+
+#define LIMA_PP_IRQ_MASK_ALL \
+ ( \
+ LIMA_PP_IRQ_END_OF_FRAME | \
+ LIMA_PP_IRQ_END_OF_TILE | \
+ LIMA_PP_IRQ_HANG | \
+ LIMA_PP_IRQ_FORCE_HANG | \
+ LIMA_PP_IRQ_BUS_ERROR | \
+ LIMA_PP_IRQ_BUS_STOP | \
+ LIMA_PP_IRQ_CNT_0_LIMIT | \
+ LIMA_PP_IRQ_CNT_1_LIMIT | \
+ LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \
+ LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \
+ LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \
+ LIMA_PP_IRQ_CALL_STACK_OVERFLOW | \
+ LIMA_PP_IRQ_RESET_COMPLETED)
+
+#define LIMA_PP_IRQ_MASK_ERROR \
+ ( \
+ LIMA_PP_IRQ_FORCE_HANG | \
+ LIMA_PP_IRQ_BUS_ERROR | \
+ LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR | \
+ LIMA_PP_IRQ_INVALID_PLIST_COMMAND | \
+ LIMA_PP_IRQ_CALL_STACK_UNDERFLOW | \
+ LIMA_PP_IRQ_CALL_STACK_OVERFLOW)
+
+#define LIMA_PP_IRQ_MASK_USED \
+ ( \
+ LIMA_PP_IRQ_END_OF_FRAME | \
+ LIMA_PP_IRQ_MASK_ERROR)
+
+/* MMU regs */
+#define LIMA_MMU_DTE_ADDR 0x0000
+#define LIMA_MMU_STATUS 0x0004
+#define LIMA_MMU_STATUS_PAGING_ENABLED (1 << 0)
+#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE (1 << 1)
+#define LIMA_MMU_STATUS_STALL_ACTIVE (1 << 2)
+#define LIMA_MMU_STATUS_IDLE (1 << 3)
+#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY (1 << 4)
+#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE (1 << 5)
+#define LIMA_MMU_STATUS_BUS_ID(x) ((x >> 6) & 0x1F)
+#define LIMA_MMU_COMMAND 0x0008
+#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00
+#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01
+#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02
+#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03
+#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04
+#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05
+#define LIMA_MMU_COMMAND_HARD_RESET 0x06
+#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C
+#define LIMA_MMU_ZAP_ONE_LINE 0x0010
+#define LIMA_MMU_INT_RAWSTAT 0x0014
+#define LIMA_MMU_INT_CLEAR 0x0018
+#define LIMA_MMU_INT_MASK 0x001C
+#define LIMA_MMU_INT_PAGE_FAULT 0x01
+#define LIMA_MMU_INT_READ_BUS_ERROR 0x02
+#define LIMA_MMU_INT_STATUS 0x0020
+
+#define LIMA_VM_FLAG_PRESENT (1 << 0)
+#define LIMA_VM_FLAG_READ_PERMISSION (1 << 1)
+#define LIMA_VM_FLAG_WRITE_PERMISSION (1 << 2)
+#define LIMA_VM_FLAG_OVERRIDE_CACHE (1 << 3)
+#define LIMA_VM_FLAG_WRITE_CACHEABLE (1 << 4)
+#define LIMA_VM_FLAG_WRITE_ALLOCATE (1 << 5)
+#define LIMA_VM_FLAG_WRITE_BUFFERABLE (1 << 6)
+#define LIMA_VM_FLAG_READ_CACHEABLE (1 << 7)
+#define LIMA_VM_FLAG_READ_ALLOCATE (1 << 8)
+#define LIMA_VM_FLAG_MASK 0x1FF
+
+#define LIMA_VM_FLAGS_CACHE ( \
+ LIMA_VM_FLAG_PRESENT | \
+ LIMA_VM_FLAG_READ_PERMISSION | \
+ LIMA_VM_FLAG_WRITE_PERMISSION | \
+ LIMA_VM_FLAG_OVERRIDE_CACHE | \
+ LIMA_VM_FLAG_WRITE_CACHEABLE | \
+ LIMA_VM_FLAG_WRITE_BUFFERABLE | \
+ LIMA_VM_FLAG_READ_CACHEABLE | \
+ LIMA_VM_FLAG_READ_ALLOCATE )
+
+#define LIMA_VM_FLAGS_UNCACHE ( \
+ LIMA_VM_FLAG_PRESENT | \
+ LIMA_VM_FLAG_READ_PERMISSION | \
+ LIMA_VM_FLAG_WRITE_PERMISSION )
+
+/* DLBU regs */
+#define LIMA_DLBU_MASTER_TLLIST_PHYS_ADDR 0x0000
+#define LIMA_DLBU_MASTER_TLLIST_VADDR 0x0004
+#define LIMA_DLBU_TLLIST_VBASEADDR 0x0008
+#define LIMA_DLBU_FB_DIM 0x000C
+#define LIMA_DLBU_TLLIST_CONF 0x0010
+#define LIMA_DLBU_START_TILE_POS 0x0014
+#define LIMA_DLBU_PP_ENABLE_MASK 0x0018
+
+/* BCAST regs */
+#define LIMA_BCAST_BROADCAST_MASK 0x0
+#define LIMA_BCAST_INTERRUPT_MASK 0x4
+
+#endif
--
2.17.1

View file

@ -0,0 +1,573 @@
From 3cce83eb3e3b54e3ffc668724722736cf7a72055 Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Mon, 14 May 2018 21:32:02 +0800
Subject: [PATCH 044/146] drm/lima: add lima core driver
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
---
drivers/gpu/drm/lima/lima_drv.c | 466 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_drv.h | 77 ++++++
2 files changed, 543 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_drv.c
create mode 100644 drivers/gpu/drm/lima/lima_drv.h
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
new file mode 100644
index 000000000000..4df24a6cfff3
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -0,0 +1,466 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/log2.h>
+#include <drm/drm_prime.h>
+#include <drm/lima_drm.h>
+
+#include "lima_drv.h"
+#include "lima_gem.h"
+#include "lima_gem_prime.h"
+#include "lima_vm.h"
+
+int lima_sched_timeout_ms = 0;
+int lima_sched_max_tasks = 32;
+int lima_max_mem = -1;
+
+MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms (0 = no timeout (default))");
+module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444);
+
+MODULE_PARM_DESC(sched_max_tasks, "max queued task num in a context (default 32)");
+module_param_named(sched_max_tasks, lima_sched_max_tasks, int, 0444);
+
+MODULE_PARM_DESC(max_mem, "Max memory size in MB can be used (<0 = auto)");
+module_param_named(max_mem, lima_max_mem, int, 0444);
+
+static int lima_ioctl_info(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_info *info = data;
+ struct lima_device *ldev = to_lima_dev(dev);
+
+ switch (ldev->id) {
+ case lima_gpu_mali400:
+ info->gpu_id = LIMA_INFO_GPU_MALI400;
+ break;
+ case lima_gpu_mali450:
+ info->gpu_id = LIMA_INFO_GPU_MALI450;
+ break;
+ default:
+ return -ENODEV;
+ }
+ info->num_pp = ldev->pipe[lima_pipe_pp].num_processor;
+ info->va_start = ldev->va_start;
+ info->va_end = ldev->va_end;
+ return 0;
+}
+
+static int lima_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_gem_create *args = data;
+
+ if (args->flags)
+ return -EINVAL;
+
+ if (args->size == 0)
+ return -EINVAL;
+
+ return lima_gem_create_handle(dev, file, args->size, args->flags, &args->handle);
+}
+
+static int lima_ioctl_gem_info(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_gem_info *args = data;
+
+ return lima_gem_mmap_offset(file, args->handle, &args->offset);
+}
+
+static int lima_ioctl_gem_va(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_gem_va *args = data;
+
+ switch (args->op) {
+ case LIMA_VA_OP_MAP:
+ return lima_gem_va_map(file, args->handle, args->flags, args->va);
+ case LIMA_VA_OP_UNMAP:
+ return lima_gem_va_unmap(file, args->handle, args->va);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int lima_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_gem_submit_in *args = data;
+ struct lima_device *ldev = to_lima_dev(dev);
+ struct lima_drm_priv *priv = file->driver_priv;
+ struct drm_lima_gem_submit_bo *bos;
+ struct ttm_validate_buffer *vbs;
+ union drm_lima_gem_submit_dep *deps = NULL;
+ struct lima_sched_pipe *pipe;
+ struct lima_sched_task *task;
+ struct lima_ctx *ctx;
+ struct lima_submit submit = {0};
+ int err = 0, size;
+
+ if (args->pipe >= lima_pipe_num || args->nr_bos == 0)
+ return -EINVAL;
+
+ if (args->flags & ~(LIMA_SUBMIT_FLAG_EXPLICIT_FENCE |
+ LIMA_SUBMIT_FLAG_SYNC_FD_OUT))
+ return -EINVAL;
+
+ pipe = ldev->pipe + args->pipe;
+ if (args->frame_size != pipe->frame_size)
+ return -EINVAL;
+
+ size = args->nr_bos * (sizeof(*submit.bos) + sizeof(*submit.vbs)) +
+ args->nr_deps * sizeof(*submit.deps);
+ bos = kzalloc(size, GFP_KERNEL);
+ if (!bos)
+ return -ENOMEM;
+
+ size = args->nr_bos * sizeof(*submit.bos);
+ if (copy_from_user(bos, u64_to_user_ptr(args->bos), size)) {
+ err = -EFAULT;
+ goto out0;
+ }
+
+ vbs = (void *)bos + size;
+
+ if (args->nr_deps) {
+ deps = (void *)vbs + args->nr_bos * sizeof(*submit.vbs);
+ size = args->nr_deps * sizeof(*submit.deps);
+ if (copy_from_user(deps, u64_to_user_ptr(args->deps), size)) {
+ err = -EFAULT;
+ goto out0;
+ }
+ }
+
+ task = kmem_cache_zalloc(pipe->task_slab, GFP_KERNEL);
+ if (!task) {
+ err = -ENOMEM;
+ goto out0;
+ }
+
+ task->frame = task + 1;
+ if (copy_from_user(task->frame, u64_to_user_ptr(args->frame), args->frame_size)) {
+ err = -EFAULT;
+ goto out1;
+ }
+
+ err = pipe->task_validate(pipe, task);
+ if (err)
+ goto out1;
+
+ ctx = lima_ctx_get(&priv->ctx_mgr, args->ctx);
+ if (!ctx) {
+ err = -ENOENT;
+ goto out1;
+ }
+
+ submit.pipe = args->pipe;
+ submit.bos = bos;
+ submit.vbs = vbs;
+ submit.nr_bos = args->nr_bos;
+ submit.task = task;
+ submit.ctx = ctx;
+ submit.deps = deps;
+ submit.nr_deps = args->nr_deps;
+ submit.flags = args->flags;
+
+ err = lima_gem_submit(file, &submit);
+ if (!err) {
+ struct drm_lima_gem_submit_out *out = data;
+ out->fence = submit.fence;
+ out->done = submit.done;
+ out->sync_fd = submit.sync_fd;
+ }
+
+ lima_ctx_put(ctx);
+out1:
+ if (err)
+ kmem_cache_free(pipe->task_slab, task);
+out0:
+ kfree(bos);
+ return err;
+}
+
+static int lima_wait_fence(struct dma_fence *fence, u64 timeout_ns)
+{
+ signed long ret;
+
+ if (!timeout_ns)
+ ret = dma_fence_is_signaled(fence) ? 0 : -EBUSY;
+ else {
+ unsigned long timeout = lima_timeout_to_jiffies(timeout_ns);
+
+ /* must use long for result check because in 64bit arch int
+ * will overflow if timeout is too large and get <0 result
+ */
+ ret = dma_fence_wait_timeout(fence, true, timeout);
+ if (ret == 0)
+ ret = timeout ? -ETIMEDOUT : -EBUSY;
+ else if (ret > 0)
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int lima_ioctl_wait_fence(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_wait_fence *args = data;
+ struct lima_drm_priv *priv = file->driver_priv;
+ struct dma_fence *fence;
+ int err = 0;
+
+ fence = lima_ctx_get_native_fence(&priv->ctx_mgr, args->ctx,
+ args->pipe, args->seq);
+ if (IS_ERR(fence))
+ return PTR_ERR(fence);
+
+ if (fence) {
+ err = lima_wait_fence(fence, args->timeout_ns);
+ dma_fence_put(fence);
+ }
+
+ return err;
+}
+
+static int lima_ioctl_gem_wait(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_gem_wait *args = data;
+
+ if (!(args->op & (LIMA_GEM_WAIT_READ|LIMA_GEM_WAIT_WRITE)))
+ return -EINVAL;
+
+ return lima_gem_wait(file, args->handle, args->op, args->timeout_ns);
+}
+
+static int lima_ioctl_ctx(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_ctx *args = data;
+ struct lima_drm_priv *priv = file->driver_priv;
+ struct lima_device *ldev = to_lima_dev(dev);
+
+ if (args->op == LIMA_CTX_OP_CREATE)
+ return lima_ctx_create(ldev, &priv->ctx_mgr, &args->id);
+ else if (args->op == LIMA_CTX_OP_FREE)
+ return lima_ctx_free(&priv->ctx_mgr, args->id);
+
+ return -EINVAL;
+}
+
+static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file)
+{
+ int err;
+ struct lima_drm_priv *priv;
+ struct lima_device *ldev = to_lima_dev(dev);
+
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ priv->vm = lima_vm_create(ldev);
+ if (!priv->vm) {
+ err = -ENOMEM;
+ goto err_out0;
+ }
+
+ lima_ctx_mgr_init(&priv->ctx_mgr);
+
+ file->driver_priv = priv;
+ return 0;
+
+err_out0:
+ kfree(priv);
+ return err;
+}
+
+static void lima_drm_driver_preclose(struct drm_device *dev, struct drm_file *file)
+{
+ struct lima_drm_priv *priv = file->driver_priv;
+
+ lima_ctx_mgr_fini(&priv->ctx_mgr);
+}
+
+static void lima_drm_driver_postclose(struct drm_device *dev, struct drm_file *file)
+{
+ struct lima_drm_priv *priv = file->driver_priv;
+
+ lima_vm_put(priv->vm);
+ kfree(priv);
+}
+
+static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = {
+ DRM_IOCTL_DEF_DRV(LIMA_INFO, lima_ioctl_info, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_GEM_CREATE, lima_ioctl_gem_create, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_GEM_INFO, lima_ioctl_gem_info, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_GEM_VA, lima_ioctl_gem_va, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_GEM_SUBMIT, lima_ioctl_gem_submit, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_WAIT_FENCE, lima_ioctl_wait_fence, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_GEM_WAIT, lima_ioctl_gem_wait, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_CTX, lima_ioctl_ctx, DRM_AUTH|DRM_RENDER_ALLOW),
+};
+
+static const struct file_operations lima_drm_driver_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .mmap = lima_gem_mmap,
+};
+
+static struct drm_driver lima_drm_driver = {
+ .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_PRIME,
+ .open = lima_drm_driver_open,
+ .preclose = lima_drm_driver_preclose,
+ .postclose = lima_drm_driver_postclose,
+ .ioctls = lima_drm_driver_ioctls,
+ .num_ioctls = ARRAY_SIZE(lima_drm_driver_ioctls),
+ .fops = &lima_drm_driver_fops,
+ .gem_free_object_unlocked = lima_gem_free_object,
+ .gem_open_object = lima_gem_object_open,
+ .gem_close_object = lima_gem_object_close,
+ .name = "lima",
+ .desc = "lima DRM",
+ .date = "20170325",
+ .major = 1,
+ .minor = 0,
+ .patchlevel = 0,
+
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_import_sg_table = lima_gem_prime_import_sg_table,
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .gem_prime_export = drm_gem_prime_export,
+ .gem_prime_res_obj = lima_gem_prime_res_obj,
+ .gem_prime_get_sg_table = lima_gem_prime_get_sg_table,
+};
+
+static int lima_pdev_probe(struct platform_device *pdev)
+{
+ struct lima_device *ldev;
+ struct drm_device *ddev;
+ int err;
+
+ ldev = devm_kzalloc(&pdev->dev, sizeof(*ldev), GFP_KERNEL);
+ if (!ldev)
+ return -ENOMEM;
+
+ ldev->pdev = pdev;
+ ldev->dev = &pdev->dev;
+ ldev->id = (enum lima_gpu_id)of_device_get_match_data(&pdev->dev);
+
+ platform_set_drvdata(pdev, ldev);
+
+ /* Allocate and initialize the DRM device. */
+ ddev = drm_dev_alloc(&lima_drm_driver, &pdev->dev);
+ if (IS_ERR(ddev))
+ return PTR_ERR(ddev);
+
+ ddev->dev_private = ldev;
+ ldev->ddev = ddev;
+
+ err = lima_device_init(ldev);
+ if (err) {
+ dev_err(&pdev->dev, "Fatal error during GPU init\n");
+ goto err_out0;
+ }
+
+ /*
+ * Register the DRM device with the core and the connectors with
+ * sysfs.
+ */
+ err = drm_dev_register(ddev, 0);
+ if (err < 0)
+ goto err_out1;
+
+ return 0;
+
+err_out1:
+ lima_device_fini(ldev);
+err_out0:
+ drm_dev_unref(ddev);
+ return err;
+}
+
+static int lima_pdev_remove(struct platform_device *pdev)
+{
+ struct lima_device *ldev = platform_get_drvdata(pdev);
+ struct drm_device *ddev = ldev->ddev;
+
+ drm_dev_unregister(ddev);
+ lima_device_fini(ldev);
+ drm_dev_unref(ddev);
+ return 0;
+}
+
+static const struct of_device_id dt_match[] = {
+ { .compatible = "arm,mali-400", .data = (void *)lima_gpu_mali400 },
+ { .compatible = "arm,mali-450", .data = (void *)lima_gpu_mali450 },
+ {}
+};
+MODULE_DEVICE_TABLE(of, dt_match);
+
+static struct platform_driver lima_platform_driver = {
+ .probe = lima_pdev_probe,
+ .remove = lima_pdev_remove,
+ .driver = {
+ .name = "lima",
+ .of_match_table = dt_match,
+ },
+};
+
+static void lima_check_module_param(void)
+{
+ if (lima_sched_max_tasks < 4)
+ lima_sched_max_tasks = 4;
+ else
+ lima_sched_max_tasks = roundup_pow_of_two(lima_sched_max_tasks);
+
+ if (lima_max_mem < 32)
+ lima_max_mem = -1;
+}
+
+static int __init lima_init(void)
+{
+ int ret;
+
+ lima_check_module_param();
+ ret = lima_sched_slab_init();
+ if (ret)
+ return ret;
+
+ ret = platform_driver_register(&lima_platform_driver);
+ if (ret)
+ lima_sched_slab_fini();
+
+ return ret;
+}
+module_init(lima_init);
+
+static void __exit lima_exit(void)
+{
+ platform_driver_unregister(&lima_platform_driver);
+ lima_sched_slab_fini();
+}
+module_exit(lima_exit);
+
+MODULE_AUTHOR("Lima Project Developers");
+MODULE_DESCRIPTION("Lima DRM Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h
new file mode 100644
index 000000000000..2f5f51da21db
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_drv.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_DRV_H__
+#define __LIMA_DRV_H__
+
+#include <drm/drmP.h>
+#include <drm/ttm/ttm_execbuf_util.h>
+
+#include "lima_ctx.h"
+
+extern int lima_sched_timeout_ms;
+extern int lima_sched_max_tasks;
+extern int lima_max_mem;
+
+struct lima_vm;
+struct lima_bo;
+struct lima_sched_task;
+
+struct drm_lima_gem_submit_bo;
+
+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+
+struct lima_drm_priv {
+ struct lima_vm *vm;
+ struct lima_ctx_mgr ctx_mgr;
+};
+
+struct lima_submit {
+ struct lima_ctx *ctx;
+ int pipe;
+ u32 flags;
+
+ struct drm_lima_gem_submit_bo *bos;
+ struct ttm_validate_buffer *vbs;
+ u32 nr_bos;
+
+ struct ttm_validate_buffer vm_pd_vb;
+ struct ww_acquire_ctx ticket;
+ struct list_head duplicates;
+ struct list_head validated;
+
+ union drm_lima_gem_submit_dep *deps;
+ u32 nr_deps;
+
+ struct lima_sched_task *task;
+
+ uint32_t fence;
+ uint32_t done;
+ int sync_fd;
+};
+
+static inline struct lima_drm_priv *
+to_lima_drm_priv(struct drm_file *file)
+{
+ return file->driver_priv;
+}
+
+#endif
--
2.17.1

View file

@ -0,0 +1,573 @@
From 1656622231f4fc9ba6260ad1c0a44e574793a04c Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Mon, 14 May 2018 21:41:53 +0800
Subject: [PATCH 045/146] drm/lima: add GPU device functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Simon Shields <simon@lineageos.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_device.c | 407 +++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_device.h | 136 ++++++++++
2 files changed, 543 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_device.c
create mode 100644 drivers/gpu/drm/lima/lima_device.h
diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c
new file mode 100644
index 000000000000..a6c3905a0c85
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_device.c
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include "lima_device.h"
+#include "lima_gp.h"
+#include "lima_pp.h"
+#include "lima_mmu.h"
+#include "lima_pmu.h"
+#include "lima_l2_cache.h"
+#include "lima_dlbu.h"
+#include "lima_bcast.h"
+#include "lima_vm.h"
+
+struct lima_ip_desc {
+ char *name;
+ char *irq_name;
+ bool must_have[lima_gpu_num];
+ int offset[lima_gpu_num];
+
+ int (*init)(struct lima_ip *);
+ void (*fini)(struct lima_ip *);
+};
+
+#define LIMA_IP_DESC(ipname, mst0, mst1, off0, off1, func, irq) \
+ [lima_ip_##ipname] = { \
+ .name = #ipname, \
+ .irq_name = irq, \
+ .must_have = { \
+ [lima_gpu_mali400] = mst0, \
+ [lima_gpu_mali450] = mst1, \
+ }, \
+ .offset = { \
+ [lima_gpu_mali400] = off0, \
+ [lima_gpu_mali450] = off1, \
+ }, \
+ .init = lima_##func##_init, \
+ .fini = lima_##func##_fini, \
+ }
+
+static struct lima_ip_desc lima_ip_desc[lima_ip_num] = {
+ LIMA_IP_DESC(pmu, false, false, 0x02000, 0x02000, pmu, "pmu"),
+ LIMA_IP_DESC(l2_cache0, true, true, 0x01000, 0x10000, l2_cache, NULL),
+ LIMA_IP_DESC(l2_cache1, false, true, -1, 0x01000, l2_cache, NULL),
+ LIMA_IP_DESC(l2_cache2, false, false, -1, 0x11000, l2_cache, NULL),
+ LIMA_IP_DESC(gp, true, true, 0x00000, 0x00000, gp, "gp"),
+ LIMA_IP_DESC(pp0, true, true, 0x08000, 0x08000, pp, "pp0"),
+ LIMA_IP_DESC(pp1, false, false, 0x0A000, 0x0A000, pp, "pp1"),
+ LIMA_IP_DESC(pp2, false, false, 0x0C000, 0x0C000, pp, "pp2"),
+ LIMA_IP_DESC(pp3, false, false, 0x0E000, 0x0E000, pp, "pp3"),
+ LIMA_IP_DESC(pp4, false, false, -1, 0x28000, pp, "pp4"),
+ LIMA_IP_DESC(pp5, false, false, -1, 0x2A000, pp, "pp5"),
+ LIMA_IP_DESC(pp6, false, false, -1, 0x2C000, pp, "pp6"),
+ LIMA_IP_DESC(pp7, false, false, -1, 0x2E000, pp, "pp7"),
+ LIMA_IP_DESC(gpmmu, true, true, 0x03000, 0x03000, mmu, "gpmmu"),
+ LIMA_IP_DESC(ppmmu0, true, true, 0x04000, 0x04000, mmu, "ppmmu0"),
+ LIMA_IP_DESC(ppmmu1, false, false, 0x05000, 0x05000, mmu, "ppmmu1"),
+ LIMA_IP_DESC(ppmmu2, false, false, 0x06000, 0x06000, mmu, "ppmmu2"),
+ LIMA_IP_DESC(ppmmu3, false, false, 0x07000, 0x07000, mmu, "ppmmu3"),
+ LIMA_IP_DESC(ppmmu4, false, false, -1, 0x1C000, mmu, "ppmmu4"),
+ LIMA_IP_DESC(ppmmu5, false, false, -1, 0x1D000, mmu, "ppmmu5"),
+ LIMA_IP_DESC(ppmmu6, false, false, -1, 0x1E000, mmu, "ppmmu6"),
+ LIMA_IP_DESC(ppmmu7, false, false, -1, 0x1F000, mmu, "ppmmu7"),
+ LIMA_IP_DESC(dlbu, false, true, -1, 0x14000, dlbu, NULL),
+ LIMA_IP_DESC(bcast, false, true, -1, 0x13000, bcast, NULL),
+ LIMA_IP_DESC(pp_bcast, false, true, -1, 0x16000, pp_bcast, "pp"),
+ LIMA_IP_DESC(ppmmu_bcast, false, true, -1, 0x15000, mmu, NULL),
+};
+
+const char *lima_ip_name(struct lima_ip *ip)
+{
+ return lima_ip_desc[ip->id].name;
+}
+
+static int lima_clk_init(struct lima_device *dev)
+{
+ int err;
+ unsigned long bus_rate, gpu_rate;
+
+ dev->clk_bus = devm_clk_get(dev->dev, "bus");
+ if (IS_ERR(dev->clk_bus)) {
+ dev_err(dev->dev, "get bus clk failed %ld\n", PTR_ERR(dev->clk_bus));
+ return PTR_ERR(dev->clk_bus);
+ }
+
+ dev->clk_gpu = devm_clk_get(dev->dev, "core");
+ if (IS_ERR(dev->clk_gpu)) {
+ dev_err(dev->dev, "get core clk failed %ld\n", PTR_ERR(dev->clk_gpu));
+ return PTR_ERR(dev->clk_gpu);
+ }
+
+ bus_rate = clk_get_rate(dev->clk_bus);
+ dev_info(dev->dev, "bus rate = %lu\n", bus_rate);
+
+ gpu_rate = clk_get_rate(dev->clk_gpu);
+ dev_info(dev->dev, "mod rate = %lu", gpu_rate);
+
+ if ((err = clk_prepare_enable(dev->clk_bus)))
+ return err;
+ if ((err = clk_prepare_enable(dev->clk_gpu)))
+ goto error_out0;
+
+ dev->reset = devm_reset_control_get_optional(dev->dev, NULL);
+ if (IS_ERR(dev->reset)) {
+ err = PTR_ERR(dev->reset);
+ goto error_out1;
+ } else if (dev->reset != NULL) {
+ if ((err = reset_control_deassert(dev->reset)))
+ goto error_out1;
+ }
+
+ return 0;
+
+error_out1:
+ clk_disable_unprepare(dev->clk_gpu);
+error_out0:
+ clk_disable_unprepare(dev->clk_bus);
+ return err;
+}
+
+static void lima_clk_fini(struct lima_device *dev)
+{
+ if (dev->reset != NULL)
+ reset_control_assert(dev->reset);
+ clk_disable_unprepare(dev->clk_gpu);
+ clk_disable_unprepare(dev->clk_bus);
+}
+
+static int lima_regulator_init(struct lima_device *dev)
+{
+ int ret;
+ dev->regulator = devm_regulator_get_optional(dev->dev, "mali");
+ if (IS_ERR(dev->regulator)) {
+ ret = PTR_ERR(dev->regulator);
+ dev->regulator = NULL;
+ if (ret == -ENODEV)
+ return 0;
+ dev_err(dev->dev, "failed to get regulator: %ld\n", PTR_ERR(dev->regulator));
+ return ret;
+ }
+
+ ret = regulator_enable(dev->regulator);
+ if (ret < 0) {
+ dev_err(dev->dev, "failed to enable regulator: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void lima_regulator_fini(struct lima_device *dev)
+{
+ if (dev->regulator)
+ regulator_disable(dev->regulator);
+}
+
+static int lima_init_ip(struct lima_device *dev, int index)
+{
+ struct lima_ip_desc *desc = lima_ip_desc + index;
+ struct lima_ip *ip = dev->ip + index;
+ int offset = desc->offset[dev->id];
+ bool must = desc->must_have[dev->id];
+ int err;
+
+ if (offset < 0)
+ return 0;
+
+ ip->dev = dev;
+ ip->id = index;
+ ip->iomem = dev->iomem + offset;
+ if (desc->irq_name) {
+ err = platform_get_irq_byname(dev->pdev, desc->irq_name);
+ if (err < 0)
+ goto out;
+ ip->irq = err;
+ }
+
+ err = desc->init(ip);
+ if (!err) {
+ ip->present = true;
+ return 0;
+ }
+
+out:
+ return must ? err : 0;
+}
+
+static void lima_fini_ip(struct lima_device *ldev, int index)
+{
+ struct lima_ip_desc *desc = lima_ip_desc + index;
+ struct lima_ip *ip = ldev->ip + index;
+
+ if (ip->present)
+ desc->fini(ip);
+}
+
+static int lima_init_gp_pipe(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp;
+ int err;
+
+ if ((err = lima_sched_pipe_init(pipe, "gp")))
+ return err;
+
+ pipe->l2_cache[pipe->num_l2_cache++] = dev->ip + lima_ip_l2_cache0;
+ pipe->mmu[pipe->num_mmu++] = dev->ip + lima_ip_gpmmu;
+ pipe->processor[pipe->num_processor++] = dev->ip + lima_ip_gp;
+
+ if ((err = lima_gp_pipe_init(dev))) {
+ lima_sched_pipe_fini(pipe);
+ return err;
+ }
+
+ return 0;
+}
+
+static void lima_fini_gp_pipe(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp;
+
+ lima_gp_pipe_fini(dev);
+ lima_sched_pipe_fini(pipe);
+}
+
+static int lima_init_pp_pipe(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ int err, i;
+
+ if ((err = lima_sched_pipe_init(pipe, "pp")))
+ return err;
+
+ for (i = 0; i < LIMA_SCHED_PIPE_MAX_PROCESSOR; i++) {
+ struct lima_ip *pp = dev->ip + lima_ip_pp0 + i;
+ struct lima_ip *ppmmu = dev->ip + lima_ip_ppmmu0 + i;
+ struct lima_ip *l2_cache;
+
+ if (dev->id == lima_gpu_mali400)
+ l2_cache = dev->ip + lima_ip_l2_cache0;
+ else
+ l2_cache = dev->ip + lima_ip_l2_cache1 + (i >> 2);
+
+ if (pp->present && ppmmu->present && l2_cache->present) {
+ pipe->mmu[pipe->num_mmu++] = ppmmu;
+ pipe->processor[pipe->num_processor++] = pp;
+ if (!pipe->l2_cache[i >> 2])
+ pipe->l2_cache[pipe->num_l2_cache++] = l2_cache;
+ }
+ }
+
+ if (dev->ip[lima_ip_bcast].present) {
+ pipe->bcast_processor = dev->ip + lima_ip_pp_bcast;
+ pipe->bcast_mmu = dev->ip + lima_ip_ppmmu_bcast;
+ }
+
+ if ((err = lima_pp_pipe_init(dev))) {
+ lima_sched_pipe_fini(pipe);
+ return err;
+ }
+
+ return 0;
+}
+
+static void lima_fini_pp_pipe(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+
+ lima_pp_pipe_fini(dev);
+ lima_sched_pipe_fini(pipe);
+}
+
+int lima_device_init(struct lima_device *ldev)
+{
+ int err, i;
+ struct resource *res;
+
+ dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32));
+
+ err = lima_clk_init(ldev);
+ if (err) {
+ dev_err(ldev->dev, "clk init fail %d\n", err);
+ return err;
+ }
+
+ if ((err = lima_regulator_init(ldev))) {
+ dev_err(ldev->dev, "regulator init fail %d\n", err);
+ goto err_out0;
+ }
+
+ err = lima_ttm_init(ldev);
+ if (err)
+ goto err_out1;
+
+ ldev->empty_vm = lima_vm_create(ldev);
+ if (!ldev->empty_vm) {
+ err = -ENOMEM;
+ goto err_out2;
+ }
+
+ ldev->va_start = 0;
+ if (ldev->id == lima_gpu_mali450) {
+ ldev->va_end = LIMA_VA_RESERVE_START;
+ ldev->dlbu_cpu = dma_alloc_wc(
+ ldev->dev, LIMA_PAGE_SIZE,
+ &ldev->dlbu_dma, GFP_KERNEL);
+ if (!ldev->dlbu_cpu) {
+ err = -ENOMEM;
+ goto err_out3;
+ }
+ }
+ else
+ ldev->va_end = LIMA_VA_RESERVE_END;
+
+ res = platform_get_resource(ldev->pdev, IORESOURCE_MEM, 0);
+ ldev->iomem = devm_ioremap_resource(ldev->dev, res);
+ if (IS_ERR(ldev->iomem)) {
+ dev_err(ldev->dev, "fail to ioremap iomem\n");
+ err = PTR_ERR(ldev->iomem);
+ goto err_out4;
+ }
+
+ for (i = 0; i < lima_ip_num; i++) {
+ err = lima_init_ip(ldev, i);
+ if (err)
+ goto err_out5;
+ }
+
+ err = lima_init_gp_pipe(ldev);
+ if (err)
+ goto err_out5;
+
+ err = lima_init_pp_pipe(ldev);
+ if (err)
+ goto err_out6;
+
+ if (ldev->id == lima_gpu_mali450) {
+ lima_dlbu_enable(ldev);
+ lima_bcast_enable(ldev);
+ }
+
+ return 0;
+
+err_out6:
+ lima_fini_gp_pipe(ldev);
+err_out5:
+ while (--i >= 0)
+ lima_fini_ip(ldev, i);
+err_out4:
+ if (ldev->dlbu_cpu)
+ dma_free_wc(ldev->dev, LIMA_PAGE_SIZE,
+ ldev->dlbu_cpu, ldev->dlbu_dma);
+err_out3:
+ lima_vm_put(ldev->empty_vm);
+err_out2:
+ lima_ttm_fini(ldev);
+err_out1:
+ lima_regulator_fini(ldev);
+err_out0:
+ lima_clk_fini(ldev);
+ return err;
+}
+
+void lima_device_fini(struct lima_device *ldev)
+{
+ int i;
+
+ lima_fini_pp_pipe(ldev);
+ lima_fini_gp_pipe(ldev);
+
+ for (i = lima_ip_num - 1; i >= 0; i--)
+ lima_fini_ip(ldev, i);
+
+ if (ldev->dlbu_cpu)
+ dma_free_wc(ldev->dev, LIMA_PAGE_SIZE,
+ ldev->dlbu_cpu, ldev->dlbu_dma);
+
+ lima_vm_put(ldev->empty_vm);
+
+ lima_ttm_fini(ldev);
+
+ lima_regulator_fini(ldev);
+
+ lima_clk_fini(ldev);
+}
diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h
new file mode 100644
index 000000000000..6c9c26b9e122
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_device.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_DEVICE_H__
+#define __LIMA_DEVICE_H__
+
+#include <drm/drm_device.h>
+
+#include "lima_sched.h"
+#include "lima_ttm.h"
+
+enum lima_gpu_id {
+ lima_gpu_mali400 = 0,
+ lima_gpu_mali450,
+ lima_gpu_num,
+};
+
+enum lima_ip_id {
+ lima_ip_pmu,
+ lima_ip_gpmmu,
+ lima_ip_ppmmu0,
+ lima_ip_ppmmu1,
+ lima_ip_ppmmu2,
+ lima_ip_ppmmu3,
+ lima_ip_ppmmu4,
+ lima_ip_ppmmu5,
+ lima_ip_ppmmu6,
+ lima_ip_ppmmu7,
+ lima_ip_gp,
+ lima_ip_pp0,
+ lima_ip_pp1,
+ lima_ip_pp2,
+ lima_ip_pp3,
+ lima_ip_pp4,
+ lima_ip_pp5,
+ lima_ip_pp6,
+ lima_ip_pp7,
+ lima_ip_l2_cache0,
+ lima_ip_l2_cache1,
+ lima_ip_l2_cache2,
+ lima_ip_dlbu,
+ lima_ip_bcast,
+ lima_ip_pp_bcast,
+ lima_ip_ppmmu_bcast,
+ lima_ip_num,
+};
+
+struct lima_device;
+
+struct lima_ip {
+ struct lima_device *dev;
+ enum lima_ip_id id;
+ bool present;
+
+ void __iomem *iomem;
+ int irq;
+
+ union {
+ /* pmu */
+ unsigned switch_delay;
+ /* gp/pp */
+ bool async_reset;
+ /* l2 cache */
+ spinlock_t lock;
+ } data;
+};
+
+enum lima_pipe_id {
+ lima_pipe_gp,
+ lima_pipe_pp,
+ lima_pipe_num,
+};
+
+struct lima_device {
+ struct device *dev;
+ struct drm_device *ddev;
+ struct platform_device *pdev;
+
+ enum lima_gpu_id id;
+ int num_pp;
+
+ void __iomem *iomem;
+ struct clk *clk_bus;
+ struct clk *clk_gpu;
+ struct reset_control *reset;
+ struct regulator *regulator;
+
+ struct lima_ip ip[lima_ip_num];
+ struct lima_sched_pipe pipe[lima_pipe_num];
+
+ struct lima_mman mman;
+
+ struct lima_vm *empty_vm;
+ uint64_t va_start;
+ uint64_t va_end;
+
+ u32 *dlbu_cpu;
+ dma_addr_t dlbu_dma;
+};
+
+static inline struct lima_device *
+to_lima_dev(struct drm_device *dev)
+{
+ return dev->dev_private;
+}
+
+static inline struct lima_device *
+ttm_to_lima_dev(struct ttm_bo_device *dev)
+{
+ return container_of(dev, struct lima_device, mman.bdev);
+}
+
+int lima_device_init(struct lima_device *ldev);
+void lima_device_fini(struct lima_device *ldev);
+
+const char *lima_ip_name(struct lima_ip *ip);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,144 @@
From 399e0d92074e30643eee980e744b6cac64bef7a2 Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Mon, 14 May 2018 21:47:28 +0800
Subject: [PATCH 046/146] drm/lima: add PMU related functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_pmu.c | 85 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_pmu.h | 30 ++++++++++++
2 files changed, 115 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_pmu.c
create mode 100644 drivers/gpu/drm/lima/lima_pmu.h
diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c
new file mode 100644
index 000000000000..255a64e9f265
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_pmu.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_pmu.h"
+#include "lima_regs.h"
+
+#define pmu_write(reg, data) writel(data, ip->iomem + LIMA_PMU_##reg)
+#define pmu_read(reg) readl(ip->iomem + LIMA_PMU_##reg)
+
+static int lima_pmu_wait_cmd(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ u32 stat, timeout;
+
+ for (timeout = 1000000; timeout > 0; timeout--) {
+ stat = pmu_read(INT_RAWSTAT);
+ if (stat & LIMA_PMU_INT_CMD_MASK)
+ break;
+ }
+
+ if (!timeout) {
+ dev_err(dev->dev, "timeout wait pmd cmd\n");
+ return -ETIMEDOUT;
+ }
+
+ pmu_write(INT_CLEAR, LIMA_PMU_INT_CMD_MASK);
+ return 0;
+}
+
+int lima_pmu_init(struct lima_ip *ip)
+{
+ int err;
+ u32 stat;
+ struct lima_device *dev = ip->dev;
+ struct device_node *np = dev->dev->of_node;
+
+ /* If this value is too low, when in high GPU clk freq,
+ * GPU will be in unstable state. */
+ if (of_property_read_u32(np, "switch-delay", &ip->data.switch_delay))
+ ip->data.switch_delay = 0xff;
+
+ pmu_write(INT_MASK, 0);
+ pmu_write(SW_DELAY, ip->data.switch_delay);
+
+ /* status reg 1=off 0=on */
+ stat = pmu_read(STATUS);
+
+ /* power up all ip */
+ if (stat) {
+ pmu_write(POWER_UP, stat);
+ err = lima_pmu_wait_cmd(ip);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+void lima_pmu_fini(struct lima_ip *ip)
+{
+
+}
diff --git a/drivers/gpu/drm/lima/lima_pmu.h b/drivers/gpu/drm/lima/lima_pmu.h
new file mode 100644
index 000000000000..fb68a7059a37
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_pmu.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_PMU_H__
+#define __LIMA_PMU_H__
+
+struct lima_ip;
+
+int lima_pmu_init(struct lima_ip *ip);
+void lima_pmu_fini(struct lima_ip *ip);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,158 @@
From 821cfa3044859b50d6d2f2f1fdbd1761bb53099b Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 14 May 2018 22:03:24 +0800
Subject: [PATCH 047/146] drm/lima: add L2 cache functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_l2_cache.c | 98 ++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_l2_cache.h | 32 +++++++++
2 files changed, 130 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.c
create mode 100644 drivers/gpu/drm/lima/lima_l2_cache.h
diff --git a/drivers/gpu/drm/lima/lima_l2_cache.c b/drivers/gpu/drm/lima/lima_l2_cache.c
new file mode 100644
index 000000000000..a9b85de5c51a
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_l2_cache.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_l2_cache.h"
+#include "lima_regs.h"
+
+#define l2_cache_write(reg, data) writel(data, ip->iomem + LIMA_L2_CACHE_##reg)
+#define l2_cache_read(reg) readl(ip->iomem + LIMA_L2_CACHE_##reg)
+
+static int lima_l2_cache_wait_idle(struct lima_ip *ip)
+{
+ int timeout;
+ struct lima_device *dev = ip->dev;
+
+ for (timeout = 100000; timeout > 0; timeout--) {
+ if (!(l2_cache_read(STATUS) & LIMA_L2_CACHE_STATUS_COMMAND_BUSY))
+ break;
+ }
+ if (!timeout) {
+ dev_err(dev->dev, "l2 cache wait command timeout\n");
+ return -ETIMEDOUT;
+ }
+ return 0;
+}
+
+int lima_l2_cache_flush(struct lima_ip *ip)
+{
+ int ret;
+
+ spin_lock(&ip->data.lock);
+ l2_cache_write(COMMAND, LIMA_L2_CACHE_COMMAND_CLEAR_ALL);
+ ret = lima_l2_cache_wait_idle(ip);
+ spin_unlock(&ip->data.lock);
+ return ret;
+}
+
+int lima_l2_cache_init(struct lima_ip *ip)
+{
+ int i, err;
+ u32 size;
+ struct lima_device *dev = ip->dev;
+
+ /* l2_cache2 only exists when one of PP4-7 present */
+ if (ip->id == lima_ip_l2_cache2) {
+ for (i = lima_ip_pp4; i <= lima_ip_pp7; i++) {
+ if (dev->ip[i].present)
+ break;
+ }
+ if (i > lima_ip_pp7)
+ return -ENODEV;
+ }
+
+ spin_lock_init(&ip->data.lock);
+
+ size = l2_cache_read(SIZE);
+ dev_info(dev->dev, "l2 cache %uK, %u-way, %ubyte cache line, %ubit external bus\n",
+ 1 << (((size >> 16) & 0xff) - 10),
+ 1 << ((size >> 8) & 0xff),
+ 1 << (size & 0xff),
+ 1 << ((size >> 24) & 0xff));
+
+ err = lima_l2_cache_flush(ip);
+ if (err)
+ return err;
+
+ l2_cache_write(ENABLE, LIMA_L2_CACHE_ENABLE_ACCESS | LIMA_L2_CACHE_ENABLE_READ_ALLOCATE);
+ l2_cache_write(MAX_READS, 0x1c);
+
+ return 0;
+}
+
+void lima_l2_cache_fini(struct lima_ip *ip)
+{
+
+}
diff --git a/drivers/gpu/drm/lima/lima_l2_cache.h b/drivers/gpu/drm/lima/lima_l2_cache.h
new file mode 100644
index 000000000000..4a35725bf38d
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_l2_cache.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_L2_CACHE_H__
+#define __LIMA_L2_CACHE_H__
+
+struct lima_ip;
+
+int lima_l2_cache_init(struct lima_ip *ip);
+void lima_l2_cache_fini(struct lima_ip *ip);
+
+int lima_l2_cache_flush(struct lima_ip *ip);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,358 @@
From ddd7da175a64f80b659132f6d9e0fac616d6bf6d Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 14 May 2018 22:05:37 +0800
Subject: [PATCH 048/146] drm/lima: add GP related functions
GP is a processor for OpenGL vertex shader
processing.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_gp.c | 293 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_gp.h | 34 ++++
2 files changed, 327 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_gp.c
create mode 100644 drivers/gpu/drm/lima/lima_gp.h
diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c
new file mode 100644
index 000000000000..8fb49986418a
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gp.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <drm/lima_drm.h>
+
+#include "lima_device.h"
+#include "lima_gp.h"
+#include "lima_regs.h"
+
+#define gp_write(reg, data) writel(data, ip->iomem + LIMA_GP_##reg)
+#define gp_read(reg) readl(ip->iomem + LIMA_GP_##reg)
+
+static irqreturn_t lima_gp_irq_handler(int irq, void *data)
+{
+ struct lima_ip *ip = data;
+ struct lima_device *dev = ip->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp;
+ u32 state = gp_read(INT_STAT);
+ u32 status = gp_read(STATUS);
+ bool done = false;
+
+ /* for shared irq case */
+ if (!state)
+ return IRQ_NONE;
+
+ if (state & LIMA_GP_IRQ_MASK_ERROR) {
+ dev_err(dev->dev, "gp error irq state=%x status=%x\n",
+ state, status);
+
+ /* mask all interrupts before hard reset */
+ gp_write(INT_MASK, 0);
+
+ pipe->error = true;
+ done = true;
+ }
+ else {
+ bool valid = state & (LIMA_GP_IRQ_VS_END_CMD_LST |
+ LIMA_GP_IRQ_PLBU_END_CMD_LST);
+ bool active = status & (LIMA_GP_STATUS_VS_ACTIVE |
+ LIMA_GP_STATUS_PLBU_ACTIVE);
+ done = valid && !active;
+ }
+
+ gp_write(INT_CLEAR, state);
+
+ if (done)
+ lima_sched_pipe_task_done(pipe);
+
+ return IRQ_HANDLED;
+}
+
+static void lima_gp_soft_reset_async(struct lima_ip *ip)
+{
+ if (ip->data.async_reset)
+ return;
+
+ gp_write(INT_MASK, 0);
+ gp_write(INT_CLEAR, LIMA_GP_IRQ_RESET_COMPLETED);
+ gp_write(CMD, LIMA_GP_CMD_SOFT_RESET);
+ ip->data.async_reset = true;
+}
+
+static int lima_gp_soft_reset_async_wait(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int timeout;
+
+ if (!ip->data.async_reset)
+ return 0;
+
+ for (timeout = 1000; timeout > 0; timeout--) {
+ if (gp_read(INT_RAWSTAT) & LIMA_GP_IRQ_RESET_COMPLETED)
+ break;
+ }
+ if (!timeout) {
+ dev_err(dev->dev, "gp soft reset time out\n");
+ return -ETIMEDOUT;
+ }
+
+ gp_write(INT_CLEAR, LIMA_GP_IRQ_MASK_ALL);
+ gp_write(INT_MASK, LIMA_GP_IRQ_MASK_USED);
+
+ ip->data.async_reset = false;
+ return 0;
+}
+
+static int lima_gp_task_validate(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ struct drm_lima_gp_frame *frame = task->frame;
+ u32 *f = frame->frame;
+ (void)pipe;
+
+ if (f[LIMA_GP_VSCL_START_ADDR >> 2] >
+ f[LIMA_GP_VSCL_END_ADDR >> 2] ||
+ f[LIMA_GP_PLBUCL_START_ADDR >> 2] >
+ f[LIMA_GP_PLBUCL_END_ADDR >> 2] ||
+ f[LIMA_GP_PLBU_ALLOC_START_ADDR >> 2] >
+ f[LIMA_GP_PLBU_ALLOC_END_ADDR >> 2])
+ return -EINVAL;
+
+ if (f[LIMA_GP_VSCL_START_ADDR >> 2] ==
+ f[LIMA_GP_VSCL_END_ADDR >> 2] &&
+ f[LIMA_GP_PLBUCL_START_ADDR >> 2] ==
+ f[LIMA_GP_PLBUCL_END_ADDR >> 2])
+ return -EINVAL;
+
+ return 0;
+}
+
+static void lima_gp_task_run(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ struct lima_ip *ip = pipe->processor[0];
+ struct drm_lima_gp_frame *frame = task->frame;
+ u32 *f = frame->frame;
+ u32 cmd = 0;
+ int i;
+
+ if (f[LIMA_GP_VSCL_START_ADDR >> 2] !=
+ f[LIMA_GP_VSCL_END_ADDR >> 2])
+ cmd |= LIMA_GP_CMD_START_VS;
+ if (f[LIMA_GP_PLBUCL_START_ADDR >> 2] !=
+ f[LIMA_GP_PLBUCL_END_ADDR >> 2])
+ cmd |= LIMA_GP_CMD_START_PLBU;
+
+ /* before any hw ops, wait last success task async soft reset */
+ lima_gp_soft_reset_async_wait(ip);
+
+ for (i = 0; i < LIMA_GP_FRAME_REG_NUM; i++)
+ writel(f[i], ip->iomem + LIMA_GP_VSCL_START_ADDR + i * 4);
+
+ gp_write(CMD, LIMA_GP_CMD_UPDATE_PLBU_ALLOC);
+ gp_write(CMD, cmd);
+}
+
+static int lima_gp_hard_reset(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int timeout;
+
+ gp_write(PERF_CNT_0_LIMIT, 0xC0FFE000);
+ gp_write(INT_MASK, 0);
+ gp_write(CMD, LIMA_GP_CMD_RESET);
+ for (timeout = 1000; timeout > 0; timeout--) {
+ gp_write(PERF_CNT_0_LIMIT, 0xC01A0000);
+ if (gp_read(PERF_CNT_0_LIMIT) == 0xC01A0000)
+ break;
+ }
+ if (!timeout) {
+ dev_err(dev->dev, "gp hard reset timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ gp_write(PERF_CNT_0_LIMIT, 0);
+ gp_write(INT_CLEAR, LIMA_GP_IRQ_MASK_ALL);
+ gp_write(INT_MASK, LIMA_GP_IRQ_MASK_USED);
+ return 0;
+}
+
+static void lima_gp_task_fini(struct lima_sched_pipe *pipe)
+{
+ lima_gp_soft_reset_async(pipe->processor[0]);
+}
+
+static void lima_gp_task_error(struct lima_sched_pipe *pipe)
+{
+ lima_gp_hard_reset(pipe->processor[0]);
+}
+
+static void lima_gp_task_mmu_error(struct lima_sched_pipe *pipe)
+{
+ lima_sched_pipe_task_done(pipe);
+}
+
+static void lima_gp_print_version(struct lima_ip *ip)
+{
+ u32 version, major, minor;
+ char *name;
+
+ version = gp_read(VERSION);
+ major = (version >> 8) & 0xFF;
+ minor = version & 0xFF;
+ switch (version >> 16) {
+ case 0xA07:
+ name = "mali200";
+ break;
+ case 0xC07:
+ name = "mali300";
+ break;
+ case 0xB07:
+ name = "mali400";
+ break;
+ case 0xD07:
+ name = "mali450";
+ break;
+ default:
+ name = "unknow";
+ break;
+ }
+ dev_info(ip->dev->dev, "%s - %s version major %d minor %d\n",
+ lima_ip_name(ip), name, major, minor);
+}
+
+static struct kmem_cache *lima_gp_task_slab = NULL;
+static int lima_gp_task_slab_refcnt = 0;
+
+int lima_gp_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int err;
+
+ lima_gp_print_version(ip);
+
+ ip->data.async_reset = false;
+ lima_gp_soft_reset_async(ip);
+ err = lima_gp_soft_reset_async_wait(ip);
+ if (err)
+ return err;
+
+ err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler, 0,
+ lima_ip_name(ip), ip);
+ if (err) {
+ dev_err(dev->dev, "gp %s fail to request irq\n",
+ lima_ip_name(ip));
+ return err;
+ }
+
+ return 0;
+}
+
+void lima_gp_fini(struct lima_ip *ip)
+{
+
+}
+
+int lima_gp_pipe_init(struct lima_device *dev)
+{
+ int frame_size = sizeof(struct drm_lima_gp_frame);
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_gp;
+
+ if (!lima_gp_task_slab) {
+ lima_gp_task_slab = kmem_cache_create(
+ "lima_gp_task", sizeof(struct lima_sched_task) + frame_size,
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!lima_gp_task_slab)
+ return -ENOMEM;
+ }
+ lima_gp_task_slab_refcnt++;
+
+ pipe->frame_size = frame_size;
+ pipe->task_slab = lima_gp_task_slab;
+
+ pipe->task_validate = lima_gp_task_validate;
+ pipe->task_run = lima_gp_task_run;
+ pipe->task_fini = lima_gp_task_fini;
+ pipe->task_error = lima_gp_task_error;
+ pipe->task_mmu_error = lima_gp_task_mmu_error;
+
+ return 0;
+}
+
+void lima_gp_pipe_fini(struct lima_device *dev)
+{
+ if (!--lima_gp_task_slab_refcnt) {
+ kmem_cache_destroy(lima_gp_task_slab);
+ lima_gp_task_slab = NULL;
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h
new file mode 100644
index 000000000000..8354911e50ce
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gp.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_GP_H__
+#define __LIMA_GP_H__
+
+struct lima_ip;
+struct lima_device;
+
+int lima_gp_init(struct lima_ip *ip);
+void lima_gp_fini(struct lima_ip *ip);
+
+int lima_gp_pipe_init(struct lima_device *dev);
+void lima_gp_pipe_fini(struct lima_device *dev);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,487 @@
From f3a488deb6ebf451b0a1f928e5692ea3d1af4410 Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Mon, 14 May 2018 22:10:48 +0800
Subject: [PATCH 049/146] drm/lima: add PP related functions
PP is a processor used for OpenGL fragment shader
processing.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_pp.c | 418 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_pp.h | 37 +++
2 files changed, 455 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_pp.c
create mode 100644 drivers/gpu/drm/lima/lima_pp.h
diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
new file mode 100644
index 000000000000..371d6b70c271
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_pp.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include <drm/lima_drm.h>
+
+#include "lima_device.h"
+#include "lima_pp.h"
+#include "lima_dlbu.h"
+#include "lima_bcast.h"
+#include "lima_vm.h"
+#include "lima_regs.h"
+
+#define pp_write(reg, data) writel(data, ip->iomem + LIMA_PP_##reg)
+#define pp_read(reg) readl(ip->iomem + LIMA_PP_##reg)
+
+static void lima_pp_handle_irq(struct lima_ip *ip, u32 state)
+{
+ struct lima_device *dev = ip->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+
+ if (state & LIMA_PP_IRQ_MASK_ERROR) {
+ u32 status = pp_read(STATUS);
+
+ dev_err(dev->dev, "pp error irq state=%x status=%x\n",
+ state, status);
+
+ pipe->error = true;
+
+ /* mask all interrupts before hard reset */
+ pp_write(INT_MASK, 0);
+ }
+
+ pp_write(INT_CLEAR, state);
+}
+
+static irqreturn_t lima_pp_irq_handler(int irq, void *data)
+{
+ struct lima_ip *ip = data;
+ struct lima_device *dev = ip->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ u32 state = pp_read(INT_STATUS);
+
+ /* for shared irq case */
+ if (!state)
+ return IRQ_NONE;
+
+ lima_pp_handle_irq(ip, state);
+
+ if (atomic_dec_and_test(&pipe->task))
+ lima_sched_pipe_task_done(pipe);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data)
+{
+ int i;
+ irqreturn_t ret = IRQ_NONE;
+ struct lima_ip *pp_bcast = data;
+ struct lima_device *dev = pp_bcast->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *ip = pipe->processor[i];
+ u32 status, state;
+
+ if (pipe->done & (1 << i))
+ continue;
+
+ /* status read first in case int state change in the middle
+ * which may miss the interrupt handling */
+ status = pp_read(STATUS);
+ state = pp_read(INT_STATUS);
+
+ if (state) {
+ lima_pp_handle_irq(ip, state);
+ ret = IRQ_HANDLED;
+ }
+ else {
+ if (status & LIMA_PP_STATUS_RENDERING_ACTIVE)
+ continue;
+ }
+
+ pipe->done |= (1 << i);
+ if (atomic_dec_and_test(&pipe->task))
+ lima_sched_pipe_task_done(pipe);
+ }
+
+ return ret;
+}
+
+static void lima_pp_soft_reset_async(struct lima_ip *ip)
+{
+ if (ip->data.async_reset)
+ return;
+
+ pp_write(INT_MASK, 0);
+ pp_write(INT_RAWSTAT, LIMA_PP_IRQ_MASK_ALL);
+ pp_write(CTRL, LIMA_PP_CTRL_SOFT_RESET);
+ ip->data.async_reset = true;
+}
+
+static int lima_pp_soft_reset_async_wait_one(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int timeout;
+
+ for (timeout = 1000; timeout > 0; timeout--) {
+ if (!(pp_read(STATUS) & LIMA_PP_STATUS_RENDERING_ACTIVE) &&
+ pp_read(INT_RAWSTAT) == LIMA_PP_IRQ_RESET_COMPLETED)
+ break;
+ }
+ if (!timeout) {
+ dev_err(dev->dev, "pp %s reset time out\n", lima_ip_name(ip));
+ return -ETIMEDOUT;
+ }
+
+ pp_write(INT_CLEAR, LIMA_PP_IRQ_MASK_ALL);
+ pp_write(INT_MASK, LIMA_PP_IRQ_MASK_USED);
+ return 0;
+}
+
+static int lima_pp_soft_reset_async_wait(struct lima_ip *ip)
+{
+ int i, err = 0;
+
+ if (!ip->data.async_reset)
+ return 0;
+
+ if (ip->id == lima_ip_pp_bcast) {
+ struct lima_device *dev = ip->dev;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ for (i = 0; i < pipe->num_processor; i++)
+ err |= lima_pp_soft_reset_async_wait_one(pipe->processor[i]);
+ }
+ else
+ err = lima_pp_soft_reset_async_wait_one(ip);
+
+ ip->data.async_reset = false;
+ return err;
+}
+
+static void lima_pp_start_task(struct lima_ip *ip, u32 *frame, u32 *wb,
+ bool skip_stack_addr)
+{
+ int i, j, n = 0;
+
+ for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++) {
+ if (skip_stack_addr && i * 4 == LIMA_PP_STACK)
+ continue;
+
+ writel(frame[i], ip->iomem + LIMA_PP_FRAME + i * 4);
+ }
+
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < LIMA_PP_WB_REG_NUM; j++)
+ writel(wb[n++], ip->iomem + LIMA_PP_WB(i) + j * 4);
+ }
+
+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
+}
+
+static int lima_pp_hard_reset(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int timeout;
+
+ pp_write(PERF_CNT_0_LIMIT, 0xC0FFE000);
+ pp_write(INT_MASK, 0);
+ pp_write(CTRL, LIMA_PP_CTRL_FORCE_RESET);
+ for (timeout = 1000; timeout > 0; timeout--) {
+ pp_write(PERF_CNT_0_LIMIT, 0xC01A0000);
+ if (pp_read(PERF_CNT_0_LIMIT) == 0xC01A0000)
+ break;
+ }
+ if (!timeout) {
+ dev_err(dev->dev, "pp hard reset timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ pp_write(PERF_CNT_0_LIMIT, 0);
+ pp_write(INT_CLEAR, LIMA_PP_IRQ_MASK_ALL);
+ pp_write(INT_MASK, LIMA_PP_IRQ_MASK_USED);
+ return 0;
+}
+
+static void lima_pp_print_version(struct lima_ip *ip)
+{
+ u32 version, major, minor;
+ char *name;
+
+ version = pp_read(VERSION);
+ major = (version >> 8) & 0xFF;
+ minor = version & 0xFF;
+ switch (version >> 16) {
+ case 0xC807:
+ name = "mali200";
+ break;
+ case 0xCE07:
+ name = "mali300";
+ break;
+ case 0xCD07:
+ name = "mali400";
+ break;
+ case 0xCF07:
+ name = "mali450";
+ break;
+ default:
+ name = "unknow";
+ break;
+ }
+ dev_info(ip->dev->dev, "%s - %s version major %d minor %d\n",
+ lima_ip_name(ip), name, major, minor);
+}
+
+int lima_pp_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int err;
+
+ lima_pp_print_version(ip);
+
+ ip->data.async_reset = false;
+ lima_pp_soft_reset_async(ip);
+ err = lima_pp_soft_reset_async_wait(ip);
+ if (err)
+ return err;
+
+ err = devm_request_irq(dev->dev, ip->irq, lima_pp_irq_handler,
+ IRQF_SHARED, lima_ip_name(ip), ip);
+ if (err) {
+ dev_err(dev->dev, "pp %s fail to request irq\n",
+ lima_ip_name(ip));
+ return err;
+ }
+
+ return 0;
+}
+
+void lima_pp_fini(struct lima_ip *ip)
+{
+
+}
+
+int lima_pp_bcast_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int err;
+
+ err = devm_request_irq(dev->dev, ip->irq, lima_pp_bcast_irq_handler,
+ IRQF_SHARED, lima_ip_name(ip), ip);
+ if (err) {
+ dev_err(dev->dev, "pp %s fail to request irq\n",
+ lima_ip_name(ip));
+ return err;
+ }
+
+ return 0;
+}
+
+void lima_pp_bcast_fini(struct lima_ip *ip)
+{
+
+}
+
+static int lima_pp_task_validate(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ if (!pipe->bcast_processor) {
+ struct drm_lima_m400_pp_frame *f = task->frame;
+
+ if (f->num_pp > pipe->num_processor)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void lima_pp_task_run(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ if (pipe->bcast_processor) {
+ struct drm_lima_m450_pp_frame *frame = task->frame;
+ struct lima_device *dev = pipe->bcast_processor->dev;
+ int i;
+
+ pipe->done = 0;
+ atomic_set(&pipe->task, pipe->num_processor);
+
+ frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU;
+ lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs);
+
+ lima_pp_soft_reset_async_wait(pipe->bcast_processor);
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *ip = pipe->processor[i];
+ pp_write(STACK, frame->fragment_stack_address[i]);
+ }
+
+ lima_pp_start_task(pipe->bcast_processor, frame->frame,
+ frame->wb, true);
+ }
+ else {
+ struct drm_lima_m400_pp_frame *frame = task->frame;
+ int i;
+
+ atomic_set(&pipe->task, frame->num_pp);
+
+ for (i = 0; i < frame->num_pp; i++) {
+ frame->frame[LIMA_PP_FRAME >> 2] =
+ frame->plbu_array_address[i];
+ frame->frame[LIMA_PP_STACK >> 2] =
+ frame->fragment_stack_address[i];
+
+ lima_pp_soft_reset_async_wait(pipe->processor[i]);
+
+ lima_pp_start_task(pipe->processor[i], frame->frame,
+ frame->wb, false);
+ }
+ }
+}
+
+static void lima_pp_task_fini(struct lima_sched_pipe *pipe)
+{
+ if (pipe->bcast_processor)
+ lima_pp_soft_reset_async(pipe->bcast_processor);
+ else {
+ int i;
+ for (i = 0; i < pipe->num_processor; i++)
+ lima_pp_soft_reset_async(pipe->processor[i]);
+ }
+}
+
+static void lima_pp_task_error(struct lima_sched_pipe *pipe)
+{
+ int i;
+
+ if (pipe->bcast_processor)
+ lima_bcast_disable(pipe->bcast_processor->dev);
+
+ for (i = 0; i < pipe->num_processor; i++)
+ lima_pp_hard_reset(pipe->processor[i]);
+
+ if (pipe->bcast_processor)
+ lima_bcast_enable(pipe->bcast_processor->dev);
+}
+
+static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
+{
+ if (atomic_dec_and_test(&pipe->task))
+ lima_sched_pipe_task_done(pipe);
+}
+
+static struct kmem_cache *lima_pp_task_slab = NULL;
+static int lima_pp_task_slab_refcnt = 0;
+
+int lima_pp_pipe_init(struct lima_device *dev)
+{
+ int frame_size;
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+
+ if (dev->id == lima_gpu_mali400)
+ frame_size = sizeof(struct drm_lima_m400_pp_frame);
+ else
+ frame_size = sizeof(struct drm_lima_m450_pp_frame);
+
+ if (!lima_pp_task_slab) {
+ lima_pp_task_slab = kmem_cache_create(
+ "lima_pp_task", sizeof(struct lima_sched_task) + frame_size,
+ 0, SLAB_HWCACHE_ALIGN, NULL);
+ if (!lima_pp_task_slab)
+ return -ENOMEM;
+ }
+ lima_pp_task_slab_refcnt++;
+
+ pipe->frame_size = frame_size;
+ pipe->task_slab = lima_pp_task_slab;
+
+ pipe->task_validate = lima_pp_task_validate;
+ pipe->task_run = lima_pp_task_run;
+ pipe->task_fini = lima_pp_task_fini;
+ pipe->task_error = lima_pp_task_error;
+ pipe->task_mmu_error = lima_pp_task_mmu_error;
+
+ return 0;
+}
+
+void lima_pp_pipe_fini(struct lima_device *dev)
+{
+ if (!--lima_pp_task_slab_refcnt) {
+ kmem_cache_destroy(lima_pp_task_slab);
+ lima_pp_task_slab = NULL;
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h
new file mode 100644
index 000000000000..4bd1d9fcbcdf
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_pp.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_PP_H__
+#define __LIMA_PP_H__
+
+struct lima_ip;
+struct lima_device;
+
+int lima_pp_init(struct lima_ip *ip);
+void lima_pp_fini(struct lima_ip *ip);
+
+int lima_pp_bcast_init(struct lima_ip *ip);
+void lima_pp_bcast_fini(struct lima_ip *ip);
+
+int lima_pp_pipe_init(struct lima_device *dev);
+void lima_pp_pipe_fini(struct lima_device *dev);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,218 @@
From ae47294de5185d599b64565ff1ca2d47277eecec Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Mon, 14 May 2018 22:13:51 +0800
Subject: [PATCH 050/146] drm/lima: add MMU related functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_mmu.c | 154 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_mmu.h | 34 +++++++
2 files changed, 188 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_mmu.c
create mode 100644 drivers/gpu/drm/lima/lima_mmu.h
diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c
new file mode 100644
index 000000000000..22ac4db07849
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_mmu.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_mmu.h"
+#include "lima_vm.h"
+#include "lima_object.h"
+#include "lima_regs.h"
+
+#define mmu_write(reg, data) writel(data, ip->iomem + LIMA_MMU_##reg)
+#define mmu_read(reg) readl(ip->iomem + LIMA_MMU_##reg)
+
+#define lima_mmu_send_command(command, condition) \
+({ \
+ int __timeout, __ret = 0; \
+ \
+ mmu_write(COMMAND, command); \
+ for (__timeout = 1000; __timeout > 0; __timeout--) { \
+ if (condition) \
+ break; \
+ } \
+ if (!__timeout) { \
+ dev_err(dev->dev, "mmu command %x timeout\n", command); \
+ __ret = -ETIMEDOUT; \
+ } \
+ __ret; \
+})
+
+static irqreturn_t lima_mmu_irq_handler(int irq, void *data)
+{
+ struct lima_ip *ip = data;
+ struct lima_device *dev = ip->dev;
+ u32 status = mmu_read(INT_STATUS);
+ struct lima_sched_pipe *pipe;
+
+ /* for shared irq case */
+ if (!status)
+ return IRQ_NONE;
+
+ if (status & LIMA_MMU_INT_PAGE_FAULT) {
+ u32 fault = mmu_read(PAGE_FAULT_ADDR);
+ dev_err(dev->dev, "mmu page fault at 0x%x from bus id %d of type %s on %s\n",
+ fault, LIMA_MMU_STATUS_BUS_ID(status),
+ status & LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE ? "write" : "read",
+ lima_ip_name(ip));
+ }
+
+ if (status & LIMA_MMU_INT_READ_BUS_ERROR) {
+ dev_err(dev->dev, "mmu %s irq bus error\n", lima_ip_name(ip));
+ }
+
+ /* mask all interrupts before resume */
+ mmu_write(INT_MASK, 0);
+ mmu_write(INT_CLEAR, status);
+
+ pipe = dev->pipe + (ip->id == lima_ip_gpmmu ? lima_pipe_gp : lima_pipe_pp);
+ lima_sched_pipe_mmu_error(pipe);
+
+ return IRQ_HANDLED;
+}
+
+int lima_mmu_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ int err;
+
+ if (ip->id == lima_ip_ppmmu_bcast)
+ return 0;
+
+ mmu_write(DTE_ADDR, 0xCAFEBABE);
+ if (mmu_read(DTE_ADDR) != 0xCAFEB000) {
+ dev_err(dev->dev, "mmu %s dte write test fail\n", lima_ip_name(ip));
+ return -EIO;
+ }
+
+ err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, mmu_read(DTE_ADDR) == 0);
+ if (err)
+ return err;
+
+ err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler,
+ IRQF_SHARED, lima_ip_name(ip), ip);
+ if (err) {
+ dev_err(dev->dev, "mmu %s fail to request irq\n", lima_ip_name(ip));
+ return err;
+ }
+
+ mmu_write(INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
+ mmu_write(DTE_ADDR, *lima_bo_get_pages(dev->empty_vm->pd));
+ return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
+ mmu_read(STATUS) & LIMA_MMU_STATUS_PAGING_ENABLED);
+}
+
+void lima_mmu_fini(struct lima_ip *ip)
+{
+
+}
+
+void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm)
+{
+ struct lima_device *dev = ip->dev;
+
+ lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_STALL,
+ mmu_read(STATUS) & LIMA_MMU_STATUS_STALL_ACTIVE);
+
+ if (vm)
+ mmu_write(DTE_ADDR, *lima_bo_get_pages(vm->pd));
+
+ /* flush the TLB */
+ mmu_write(COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE);
+
+ lima_mmu_send_command(LIMA_MMU_COMMAND_DISABLE_STALL,
+ !(mmu_read(STATUS) & LIMA_MMU_STATUS_STALL_ACTIVE));
+}
+
+void lima_mmu_page_fault_resume(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+ u32 status = mmu_read(STATUS);
+
+ if (status & LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE) {
+ dev_info(dev->dev, "mmu resume\n");
+
+ mmu_write(INT_MASK, 0);
+ mmu_write(DTE_ADDR, 0xCAFEBABE);
+ lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET, mmu_read(DTE_ADDR) == 0);
+ mmu_write(INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
+ mmu_write(DTE_ADDR, *lima_bo_get_pages(dev->empty_vm->pd));
+ lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
+ mmu_read(STATUS) & LIMA_MMU_STATUS_PAGING_ENABLED);
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h
new file mode 100644
index 000000000000..9930521ddfa1
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_mmu.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_MMU_H__
+#define __LIMA_MMU_H__
+
+struct lima_ip;
+struct lima_vm;
+
+int lima_mmu_init(struct lima_ip *ip);
+void lima_mmu_fini(struct lima_ip *ip);
+
+void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm);
+void lima_mmu_page_fault_resume(struct lima_ip *ip);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,131 @@
From 7fe721b0e0c72de29b4cfe9b3d6aa80a64f1603d Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 14 May 2018 22:17:43 +0800
Subject: [PATCH 051/146] drm/lima: add BCAST related function
BCAST is a hardware module to broadcast register
read/write for PPs. It can also merge IRQs from
different PPs into one IRQ.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_bcast.c | 65 +++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_bcast.h | 34 ++++++++++++++++
2 files changed, 99 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_bcast.c
create mode 100644 drivers/gpu/drm/lima/lima_bcast.h
diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c
new file mode 100644
index 000000000000..32012a61ea6a
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_bcast.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_bcast.h"
+#include "lima_regs.h"
+
+#define bcast_write(reg, data) writel(data, ip->iomem + LIMA_BCAST_##reg)
+#define bcast_read(reg) readl(ip->iomem + LIMA_BCAST_##reg)
+
+void lima_bcast_enable(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ struct lima_ip *ip = dev->ip + lima_ip_bcast;
+ int i, mask = 0;
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *pp = pipe->processor[i];
+ mask |= 1 << (pp->id - lima_ip_pp0);
+ }
+
+ bcast_write(BROADCAST_MASK, (mask << 16) | mask);
+ bcast_write(INTERRUPT_MASK, mask);
+}
+
+void lima_bcast_disable(struct lima_device *dev)
+{
+ struct lima_ip *ip = dev->ip + lima_ip_bcast;
+
+ bcast_write(BROADCAST_MASK, 0);
+ bcast_write(INTERRUPT_MASK, 0);
+}
+
+int lima_bcast_init(struct lima_ip *ip)
+{
+ return 0;
+}
+
+void lima_bcast_fini(struct lima_ip *ip)
+{
+
+}
+
diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h
new file mode 100644
index 000000000000..abafd4f613c7
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_bcast.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __LIMA_BCAST_H__
+#define __LIMA_BCAST_H__
+
+struct lima_ip;
+
+int lima_bcast_init(struct lima_ip *ip);
+void lima_bcast_fini(struct lima_ip *ip);
+
+void lima_bcast_enable(struct lima_device *dev);
+void lima_bcast_disable(struct lima_device *dev);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,142 @@
From ec275c7f186f53de7bf00ced46c8f0bbb3338e8d Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 14 May 2018 22:21:19 +0800
Subject: [PATCH 052/146] drm/lima: add DLBU related functions
DLBU is used to balance load among PPs.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_dlbu.c | 75 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_dlbu.h | 37 ++++++++++++++++
2 files changed, 112 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_dlbu.c
create mode 100644 drivers/gpu/drm/lima/lima_dlbu.h
diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c
new file mode 100644
index 000000000000..5281dd3c0417
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_dlbu.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/io.h>
+#include <linux/device.h>
+
+#include "lima_device.h"
+#include "lima_dlbu.h"
+#include "lima_vm.h"
+#include "lima_regs.h"
+
+#define dlbu_write(reg, data) writel(data, ip->iomem + LIMA_DLBU_##reg)
+#define dlbu_read(reg) readl(ip->iomem + LIMA_DLBU_##reg)
+
+void lima_dlbu_enable(struct lima_device *dev)
+{
+ struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ struct lima_ip *ip = dev->ip + lima_ip_dlbu;
+ int i, mask = 0;
+
+ for (i = 0; i < pipe->num_processor; i++) {
+ struct lima_ip *pp = pipe->processor[i];
+ mask |= 1 << (pp->id - lima_ip_pp0);
+ }
+
+ dlbu_write(PP_ENABLE_MASK, mask);
+}
+
+void lima_dlbu_disable(struct lima_device *dev)
+{
+ struct lima_ip *ip = dev->ip + lima_ip_dlbu;
+ dlbu_write(PP_ENABLE_MASK, 0);
+}
+
+void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg)
+{
+ dlbu_write(TLLIST_VBASEADDR, reg[0]);
+ dlbu_write(FB_DIM, reg[1]);
+ dlbu_write(TLLIST_CONF, reg[2]);
+ dlbu_write(START_TILE_POS, reg[3]);
+}
+
+int lima_dlbu_init(struct lima_ip *ip)
+{
+ struct lima_device *dev = ip->dev;
+
+ dlbu_write(MASTER_TLLIST_PHYS_ADDR, dev->dlbu_dma | 1);
+ dlbu_write(MASTER_TLLIST_VADDR, LIMA_VA_RESERVE_DLBU);
+
+ return 0;
+}
+
+void lima_dlbu_fini(struct lima_ip *ip)
+{
+
+}
diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h
new file mode 100644
index 000000000000..4521a5dda9e0
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_dlbu.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __LIMA_DLBU_H__
+#define __LIMA_DLBU_H__
+
+struct lima_ip;
+struct lima_device;
+
+void lima_dlbu_enable(struct lima_device *dev);
+void lima_dlbu_disable(struct lima_device *dev);
+
+void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg);
+
+int lima_dlbu_init(struct lima_ip *ip);
+void lima_dlbu_fini(struct lima_ip *ip);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,414 @@
From 643a121d5e299aef668f8a87a7858b7f52e735d6 Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Mon, 14 May 2018 22:24:16 +0800
Subject: [PATCH 053/146] drm/lima: add GPU virtual memory space handing
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
drivers/gpu/drm/lima/lima_vm.c | 312 +++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_vm.h | 73 ++++++++
2 files changed, 385 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_vm.c
create mode 100644 drivers/gpu/drm/lima/lima_vm.h
diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
new file mode 100644
index 000000000000..00a3f6b59a33
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/interval_tree_generic.h>
+
+#include "lima_device.h"
+#include "lima_vm.h"
+#include "lima_object.h"
+#include "lima_regs.h"
+
+struct lima_bo_va_mapping {
+ struct list_head list;
+ struct rb_node rb;
+ uint32_t start;
+ uint32_t last;
+ uint32_t __subtree_last;
+};
+
+struct lima_bo_va {
+ struct list_head list;
+ unsigned ref_count;
+
+ struct list_head mapping;
+
+ struct lima_vm *vm;
+};
+
+#define LIMA_PDE(va) (va >> 22)
+#define LIMA_PTE(va) ((va & 0x3FFFFF) >> 12)
+
+#define START(node) ((node)->start)
+#define LAST(node) ((node)->last)
+
+INTERVAL_TREE_DEFINE(struct lima_bo_va_mapping, rb, uint32_t, __subtree_last,
+ START, LAST, static, lima_vm_it)
+
+#undef START
+#undef LAST
+
+static void lima_vm_unmap_page_table(struct lima_vm *vm, u32 start, u32 end)
+{
+ u32 addr;
+
+ for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) {
+ u32 pde = LIMA_PDE(addr);
+ u32 pte = LIMA_PTE(addr);
+ u32 *pt;
+
+ pt = lima_bo_kmap(vm->pt[pde]);
+ pt[pte] = 0;
+ }
+}
+
+static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma,
+ u32 start, u32 end)
+{
+ u64 addr;
+ int err, i = 0;
+
+ for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) {
+ u32 pde = LIMA_PDE(addr);
+ u32 pte = LIMA_PTE(addr);
+ u32 *pd, *pt;
+
+ if (vm->pt[pde])
+ pt = lima_bo_kmap(vm->pt[pde]);
+ else {
+ vm->pt[pde] = lima_bo_create(
+ vm->dev, LIMA_PAGE_SIZE, 0, ttm_bo_type_kernel,
+ NULL, vm->pd->tbo.resv);
+ if (IS_ERR(vm->pt[pde])) {
+ err = PTR_ERR(vm->pt[pde]);
+ goto err_out;
+ }
+
+ pt = lima_bo_kmap(vm->pt[pde]);
+ if (IS_ERR(pt)) {
+ err = PTR_ERR(pt);
+ goto err_out;
+ }
+
+ pd = lima_bo_kmap(vm->pd);
+ pd[pde] = *lima_bo_get_pages(vm->pt[pde]) | LIMA_VM_FLAG_PRESENT;
+ }
+
+ pt[pte] = dma[i++] | LIMA_VM_FLAGS_CACHE;
+ }
+
+ return 0;
+
+err_out:
+ if (addr != start)
+ lima_vm_unmap_page_table(vm, start, addr - 1);
+ return err;
+}
+
+static struct lima_bo_va *
+lima_vm_bo_find(struct lima_vm *vm, struct lima_bo *bo)
+{
+ struct lima_bo_va *bo_va, *ret = NULL;
+
+ list_for_each_entry(bo_va, &bo->va, list) {
+ if (bo_va->vm == vm) {
+ ret = bo_va;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start)
+{
+ int err;
+ struct lima_bo_va_mapping *it, *mapping;
+ u32 end = start + bo->gem.size - 1;
+ dma_addr_t *pages_dma = lima_bo_get_pages(bo);
+ struct lima_bo_va *bo_va;
+
+ it = lima_vm_it_iter_first(&vm->va, start, end);
+ if (it) {
+ dev_dbg(bo->gem.dev->dev, "lima vm map va overlap %x-%x %x-%x\n",
+ start, end, it->start, it->last);
+ return -EINVAL;
+ }
+
+ mapping = kmalloc(sizeof(*mapping), GFP_KERNEL);
+ if (!mapping)
+ return -ENOMEM;
+ mapping->start = start;
+ mapping->last = end;
+
+ err = lima_vm_map_page_table(vm, pages_dma, start, end);
+ if (err) {
+ kfree(mapping);
+ return err;
+ }
+
+ lima_vm_it_insert(mapping, &vm->va);
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ list_add_tail(&mapping->list, &bo_va->mapping);
+
+ return 0;
+}
+
+static void lima_vm_unmap(struct lima_vm *vm,
+ struct lima_bo_va_mapping *mapping)
+{
+ lima_vm_it_remove(mapping, &vm->va);
+
+ lima_vm_unmap_page_table(vm, mapping->start, mapping->last);
+
+ list_del(&mapping->list);
+ kfree(mapping);
+}
+
+int lima_vm_bo_unmap(struct lima_vm *vm, struct lima_bo *bo, u32 start)
+{
+ struct lima_bo_va *bo_va;
+ struct lima_bo_va_mapping *mapping;
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ list_for_each_entry(mapping, &bo_va->mapping, list) {
+ if (mapping->start == start) {
+ lima_vm_unmap(vm, mapping);
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo)
+{
+ struct lima_bo_va *bo_va;
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ if (bo_va) {
+ bo_va->ref_count++;
+ return 0;
+ }
+
+ bo_va = kmalloc(sizeof(*bo_va), GFP_KERNEL);
+ if (!bo_va)
+ return -ENOMEM;
+
+ bo_va->vm = vm;
+ bo_va->ref_count = 1;
+ INIT_LIST_HEAD(&bo_va->mapping);
+ list_add_tail(&bo_va->list, &bo->va);
+ return 0;
+}
+
+int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo)
+{
+ struct lima_bo_va *bo_va;
+ struct lima_bo_va_mapping *mapping, *tmp;
+
+ bo_va = lima_vm_bo_find(vm, bo);
+ if (--bo_va->ref_count > 0)
+ return 0;
+
+ list_for_each_entry_safe(mapping, tmp, &bo_va->mapping, list) {
+ lima_vm_unmap(vm, mapping);
+ }
+ list_del(&bo_va->list);
+ kfree(bo_va);
+ return 0;
+}
+
+struct lima_vm *lima_vm_create(struct lima_device *dev)
+{
+ struct lima_vm *vm;
+ void *pd;
+
+ vm = kzalloc(sizeof(*vm), GFP_KERNEL);
+ if (!vm)
+ return NULL;
+
+ vm->dev = dev;
+ vm->va = RB_ROOT_CACHED;
+ kref_init(&vm->refcount);
+
+ vm->pd = lima_bo_create(dev, LIMA_PAGE_SIZE, 0,
+ ttm_bo_type_kernel, NULL, NULL);
+ if (IS_ERR(vm->pd))
+ goto err_out0;
+
+ pd = lima_bo_kmap(vm->pd);
+ if (IS_ERR(pd))
+ goto err_out1;
+
+ if (dev->dlbu_cpu) {
+ int err = lima_vm_map_page_table(
+ vm, &dev->dlbu_dma, LIMA_VA_RESERVE_DLBU,
+ LIMA_VA_RESERVE_DLBU + LIMA_PAGE_SIZE - 1);
+ if (err)
+ goto err_out1;
+ }
+
+ return vm;
+
+err_out1:
+ lima_bo_unref(vm->pd);
+err_out0:
+ kfree(vm);
+ return NULL;
+}
+
+void lima_vm_release(struct kref *kref)
+{
+ struct lima_vm *vm = container_of(kref, struct lima_vm, refcount);
+ struct lima_device *dev = vm->dev;
+ int i;
+
+ if (!RB_EMPTY_ROOT(&vm->va.rb_root)) {
+ dev_err(dev->dev, "still active bo inside vm\n");
+ }
+
+ for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) {
+ if (vm->pt[i])
+ lima_bo_unref(vm->pt[i]);
+ }
+
+ if (vm->pd)
+ lima_bo_unref(vm->pd);
+
+ kfree(vm);
+}
+
+void lima_vm_print(struct lima_vm *vm)
+{
+ int i, j;
+ u32 *pd = lima_bo_kmap(vm->pd);
+
+ /* to avoid the defined by not used warning */
+ (void)&lima_vm_it_iter_next;
+
+ for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) {
+ if (pd[i]) {
+ u32 *pt = lima_bo_kmap(vm->pt[i]);
+
+ printk(KERN_INFO "lima vm pd %03x:%08x\n", i, pd[i]);
+ for (j = 0; j < LIMA_PAGE_ENT_NUM; j++) {
+ if (pt[j])
+ printk(KERN_INFO " pt %03x:%08x\n", j, pt[j]);
+ }
+ }
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h
new file mode 100644
index 000000000000..20506459def0
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_vm.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_VM_H__
+#define __LIMA_VM_H__
+
+#include <linux/rbtree.h>
+#include <linux/kref.h>
+
+#define LIMA_PAGE_SIZE 4096
+#define LIMA_PAGE_MASK (LIMA_PAGE_SIZE - 1)
+#define LIMA_PAGE_ENT_NUM (LIMA_PAGE_SIZE / sizeof(u32))
+
+#define LIMA_VA_RESERVE_START 0xFFF00000
+#define LIMA_VA_RESERVE_DLBU LIMA_VA_RESERVE_START
+#define LIMA_VA_RESERVE_END 0x100000000
+
+struct lima_bo;
+struct lima_device;
+
+struct lima_vm {
+ struct kref refcount;
+
+ /* tree of virtual addresses mapped */
+ struct rb_root_cached va;
+
+ struct lima_device *dev;
+
+ struct lima_bo *pd;
+ struct lima_bo *pt[LIMA_PAGE_ENT_NUM];
+};
+
+int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start);
+int lima_vm_bo_unmap(struct lima_vm *vm, struct lima_bo *bo, u32 start);
+
+int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo);
+int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo);
+
+struct lima_vm *lima_vm_create(struct lima_device *dev);
+void lima_vm_release(struct kref *kref);
+
+static inline struct lima_vm *lima_vm_get(struct lima_vm *vm)
+{
+ kref_get(&vm->refcount);
+ return vm;
+}
+
+static inline void lima_vm_put(struct lima_vm *vm)
+{
+ kref_put(&vm->refcount, lima_vm_release);
+}
+
+void lima_vm_print(struct lima_vm *vm);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,481 @@
From f31bbd84c9aab62a0aee72e540d9d8c9d998a958 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 14 May 2018 22:28:36 +0800
Subject: [PATCH 054/146] drm/lima: add TTM subsystem functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_ttm.c | 409 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_ttm.h | 44 ++++
2 files changed, 453 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_ttm.c
create mode 100644 drivers/gpu/drm/lima/lima_ttm.h
diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c
new file mode 100644
index 000000000000..5325f3f48ae7
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ttm.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/mm.h>
+#include <drm/ttm/ttm_page_alloc.h>
+
+#include "lima_drv.h"
+#include "lima_device.h"
+#include "lima_object.h"
+
+
+static int lima_ttm_mem_global_init(struct drm_global_reference *ref)
+{
+ return ttm_mem_global_init(ref->object);
+}
+
+static void lima_ttm_mem_global_release(struct drm_global_reference *ref)
+{
+ ttm_mem_global_release(ref->object);
+}
+
+static int lima_ttm_global_init(struct lima_device *dev)
+{
+ struct drm_global_reference *global_ref;
+ int err;
+
+ dev->mman.mem_global_referenced = false;
+ global_ref = &dev->mman.mem_global_ref;
+ global_ref->global_type = DRM_GLOBAL_TTM_MEM;
+ global_ref->size = sizeof(struct ttm_mem_global);
+ global_ref->init = &lima_ttm_mem_global_init;
+ global_ref->release = &lima_ttm_mem_global_release;
+
+ err = drm_global_item_ref(global_ref);
+ if (err != 0) {
+ dev_err(dev->dev, "Failed setting up TTM memory accounting "
+ "subsystem.\n");
+ return err;
+ }
+
+ dev->mman.bo_global_ref.mem_glob =
+ dev->mman.mem_global_ref.object;
+ global_ref = &dev->mman.bo_global_ref.ref;
+ global_ref->global_type = DRM_GLOBAL_TTM_BO;
+ global_ref->size = sizeof(struct ttm_bo_global);
+ global_ref->init = &ttm_bo_global_init;
+ global_ref->release = &ttm_bo_global_release;
+ err = drm_global_item_ref(global_ref);
+ if (err != 0) {
+ dev_err(dev->dev, "Failed setting up TTM BO subsystem.\n");
+ drm_global_item_unref(&dev->mman.mem_global_ref);
+ return err;
+ }
+
+ dev->mman.mem_global_referenced = true;
+ return 0;
+}
+
+static void lima_ttm_global_fini(struct lima_device *dev)
+{
+ if (dev->mman.mem_global_referenced) {
+ drm_global_item_unref(&dev->mman.bo_global_ref.ref);
+ drm_global_item_unref(&dev->mman.mem_global_ref);
+ dev->mman.mem_global_referenced = false;
+ }
+}
+
+struct lima_tt_mgr {
+ spinlock_t lock;
+ unsigned long available;
+};
+
+static int lima_ttm_bo_man_init(struct ttm_mem_type_manager *man,
+ unsigned long p_size)
+{
+ struct lima_tt_mgr *mgr;
+
+ mgr = kmalloc(sizeof(*mgr), GFP_KERNEL);
+ if (!mgr)
+ return -ENOMEM;
+
+ spin_lock_init(&mgr->lock);
+ mgr->available = p_size;
+ man->priv = mgr;
+ return 0;
+}
+
+static int lima_ttm_bo_man_takedown(struct ttm_mem_type_manager *man)
+{
+ struct lima_tt_mgr *mgr = man->priv;
+
+ kfree(mgr);
+ man->priv = NULL;
+ return 0;
+}
+
+static int lima_ttm_bo_man_get_node(struct ttm_mem_type_manager *man,
+ struct ttm_buffer_object *bo,
+ const struct ttm_place *place,
+ struct ttm_mem_reg *mem)
+{
+ struct lima_tt_mgr *mgr = man->priv;
+
+ /* don't exceed the mem limit */
+ spin_lock(&mgr->lock);
+ if (mgr->available < mem->num_pages) {
+ spin_unlock(&mgr->lock);
+ return 0;
+ }
+ mgr->available -= mem->num_pages;
+ spin_unlock(&mgr->lock);
+
+ /* just fake a non-null pointer to tell caller success */
+ mem->mm_node = (void *)1;
+ return 0;
+}
+
+static void lima_ttm_bo_man_put_node(struct ttm_mem_type_manager *man,
+ struct ttm_mem_reg *mem)
+{
+ struct lima_tt_mgr *mgr = man->priv;
+
+ spin_lock(&mgr->lock);
+ mgr->available += mem->num_pages;
+ spin_unlock(&mgr->lock);
+
+ mem->mm_node = NULL;
+}
+
+static void lima_ttm_bo_man_debug(struct ttm_mem_type_manager *man,
+ struct drm_printer *printer)
+{
+}
+
+static const struct ttm_mem_type_manager_func lima_bo_manager_func = {
+ .init = lima_ttm_bo_man_init,
+ .takedown = lima_ttm_bo_man_takedown,
+ .get_node = lima_ttm_bo_man_get_node,
+ .put_node = lima_ttm_bo_man_put_node,
+ .debug = lima_ttm_bo_man_debug
+};
+
+static int lima_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+ struct ttm_mem_type_manager *man)
+{
+ struct lima_device *dev = ttm_to_lima_dev(bdev);
+
+ switch (type) {
+ case TTM_PL_SYSTEM:
+ /* System memory */
+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_MASK_CACHING;
+ man->default_caching = TTM_PL_FLAG_CACHED;
+ break;
+ case TTM_PL_TT:
+ man->func = &lima_bo_manager_func;
+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_MASK_CACHING;
+ man->default_caching = TTM_PL_FLAG_CACHED;
+ break;
+ default:
+ dev_err(dev->dev, "Unsupported memory type %u\n",
+ (unsigned int)type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int lima_ttm_backend_bind(struct ttm_tt *ttm,
+ struct ttm_mem_reg *bo_mem)
+{
+ return 0;
+}
+
+static int lima_ttm_backend_unbind(struct ttm_tt *ttm)
+{
+ return 0;
+}
+
+static void lima_ttm_backend_destroy(struct ttm_tt *ttm)
+{
+ struct lima_ttm_tt *tt = (void *)ttm;
+
+ ttm_dma_tt_fini(&tt->ttm);
+ kfree(tt);
+}
+
+static struct ttm_backend_func lima_ttm_backend_func = {
+ .bind = &lima_ttm_backend_bind,
+ .unbind = &lima_ttm_backend_unbind,
+ .destroy = &lima_ttm_backend_destroy,
+};
+
+static struct ttm_tt *lima_ttm_tt_create(struct ttm_buffer_object *bo,
+ uint32_t page_flags)
+{
+ struct lima_ttm_tt *tt;
+
+ tt = kzalloc(sizeof(struct lima_ttm_tt), GFP_KERNEL);
+ if (tt == NULL)
+ return NULL;
+
+ tt->ttm.ttm.func = &lima_ttm_backend_func;
+
+ if (ttm_sg_tt_init(&tt->ttm, bo, page_flags)) {
+ kfree(tt);
+ return NULL;
+ }
+
+ return &tt->ttm.ttm;
+}
+
+static int lima_ttm_tt_populate(struct ttm_tt *ttm,
+ struct ttm_operation_ctx *ctx)
+{
+ struct lima_device *dev = ttm_to_lima_dev(ttm->bdev);
+ struct lima_ttm_tt *tt = (void *)ttm;
+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+ if (slave) {
+ drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
+ tt->ttm.dma_address,
+ ttm->num_pages);
+ ttm->state = tt_unbound;
+ return 0;
+ }
+
+ return ttm_populate_and_map_pages(dev->dev, &tt->ttm, ctx);
+}
+
+static void lima_ttm_tt_unpopulate(struct ttm_tt *ttm)
+{
+ struct lima_device *dev = ttm_to_lima_dev(ttm->bdev);
+ struct lima_ttm_tt *tt = (void *)ttm;
+ bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
+
+ if (slave)
+ return;
+
+ ttm_unmap_and_unpopulate_pages(dev->dev, &tt->ttm);
+}
+
+static int lima_invalidate_caches(struct ttm_bo_device *bdev,
+ uint32_t flags)
+{
+ struct lima_device *dev = ttm_to_lima_dev(bdev);
+
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+ return 0;
+}
+
+static void lima_evict_flags(struct ttm_buffer_object *tbo,
+ struct ttm_placement *placement)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+ struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static int lima_verify_access(struct ttm_buffer_object *tbo,
+ struct file *filp)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+
+ return drm_vma_node_verify_access(&bo->gem.vma_node,
+ filp->private_data);
+}
+
+static int lima_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+ struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
+
+ mem->bus.addr = NULL;
+ mem->bus.offset = 0;
+ mem->bus.size = mem->num_pages << PAGE_SHIFT;
+ mem->bus.base = 0;
+ mem->bus.is_iomem = false;
+
+ if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
+ return -EINVAL;
+
+ switch (mem->mem_type) {
+ case TTM_PL_SYSTEM:
+ case TTM_PL_TT:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void lima_ttm_io_mem_free(struct ttm_bo_device *bdev,
+ struct ttm_mem_reg *mem)
+{
+
+}
+
+static void lima_bo_move_notify(struct ttm_buffer_object *tbo, bool evict,
+ struct ttm_mem_reg *new_mem)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+ struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+ if (evict)
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static void lima_bo_swap_notify(struct ttm_buffer_object *tbo)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+ struct lima_device *dev = to_lima_dev(bo->gem.dev);
+
+ dev_err(dev->dev, "%s not implemented\n", __FUNCTION__);
+}
+
+static struct ttm_bo_driver lima_bo_driver = {
+ .ttm_tt_create = lima_ttm_tt_create,
+ .ttm_tt_populate = lima_ttm_tt_populate,
+ .ttm_tt_unpopulate = lima_ttm_tt_unpopulate,
+ .invalidate_caches = lima_invalidate_caches,
+ .init_mem_type = lima_init_mem_type,
+ .eviction_valuable = ttm_bo_eviction_valuable,
+ .evict_flags = lima_evict_flags,
+ .verify_access = lima_verify_access,
+ .io_mem_reserve = lima_ttm_io_mem_reserve,
+ .io_mem_free = lima_ttm_io_mem_free,
+ .move_notify = lima_bo_move_notify,
+ .swap_notify = lima_bo_swap_notify,
+};
+
+int lima_ttm_init(struct lima_device *dev)
+{
+ int err;
+ bool need_dma32;
+ u64 gtt_size;
+
+ err = lima_ttm_global_init(dev);
+ if (err)
+ return err;
+
+#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
+ need_dma32 = false;
+#else
+ need_dma32 = true;
+#endif
+
+ err = ttm_bo_device_init(&dev->mman.bdev,
+ dev->mman.bo_global_ref.ref.object,
+ &lima_bo_driver,
+ dev->ddev->anon_inode->i_mapping,
+ DRM_FILE_PAGE_OFFSET,
+ need_dma32);
+ if (err) {
+ dev_err(dev->dev, "failed initializing buffer object "
+ "driver(%d).\n", err);
+ goto err_out0;
+ }
+
+ if (lima_max_mem < 0) {
+ struct sysinfo si;
+ si_meminfo(&si);
+ /* TODO: better to have lower 32 mem size */
+ gtt_size = min(((u64)si.totalram * si.mem_unit * 3/4),
+ 0x100000000ULL);
+ }
+ else
+ gtt_size = (u64)lima_max_mem << 20;
+
+ err = ttm_bo_init_mm(&dev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);
+ if (err) {
+ dev_err(dev->dev, "Failed initializing GTT heap.\n");
+ goto err_out1;
+ }
+ return 0;
+
+err_out1:
+ ttm_bo_device_release(&dev->mman.bdev);
+err_out0:
+ lima_ttm_global_fini(dev);
+ return err;
+}
+
+void lima_ttm_fini(struct lima_device *dev)
+{
+ ttm_bo_device_release(&dev->mman.bdev);
+ lima_ttm_global_fini(dev);
+ dev_info(dev->dev, "ttm finalized\n");
+}
diff --git a/drivers/gpu/drm/lima/lima_ttm.h b/drivers/gpu/drm/lima/lima_ttm.h
new file mode 100644
index 000000000000..1d36d06a47a3
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ttm.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_TTM_H__
+#define __LIMA_TTM_H__
+
+#include <drm/ttm/ttm_bo_driver.h>
+
+struct lima_mman {
+ struct ttm_bo_global_ref bo_global_ref;
+ struct drm_global_reference mem_global_ref;
+ struct ttm_bo_device bdev;
+ bool mem_global_referenced;
+};
+
+struct lima_ttm_tt {
+ struct ttm_dma_tt ttm;
+};
+
+struct lima_device;
+struct lima_bo;
+
+int lima_ttm_init(struct lima_device *dev);
+void lima_ttm_fini(struct lima_device *dev);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,235 @@
From bde1f6b4f2fc7c20343e175ea9f1ef18f0aaedfa Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Wed, 16 May 2018 10:31:44 +0800
Subject: [PATCH 055/146] drm/lima: add buffer object functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_object.c | 120 +++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_object.h | 87 +++++++++++++++++++++
2 files changed, 207 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_object.c
create mode 100644 drivers/gpu/drm/lima/lima_object.h
diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c
new file mode 100644
index 000000000000..5a22b235626b
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_object.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <drm/drm_prime.h>
+
+#include "lima_object.h"
+
+static void lima_bo_init_placement(struct lima_bo *bo)
+{
+ struct ttm_placement *placement = &bo->placement;
+ struct ttm_place *place = &bo->place;
+
+ place->fpfn = 0;
+ place->lpfn = 0;
+ place->flags = TTM_PL_FLAG_TT | TTM_PL_FLAG_WC;
+
+ /* pin all bo for now */
+ place->flags |= TTM_PL_FLAG_NO_EVICT;
+
+ placement->num_placement = 1;
+ placement->placement = place;
+
+ placement->num_busy_placement = 1;
+ placement->busy_placement = place;
+}
+
+static void lima_bo_destroy(struct ttm_buffer_object *tbo)
+{
+ struct lima_bo *bo = ttm_to_lima_bo(tbo);
+
+ if (bo->gem.import_attach)
+ drm_prime_gem_destroy(&bo->gem, bo->tbo.sg);
+ drm_gem_object_release(&bo->gem);
+ kfree(bo);
+}
+
+struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size,
+ u32 flags, enum ttm_bo_type type,
+ struct sg_table *sg,
+ struct reservation_object *resv)
+{
+ struct lima_bo *bo;
+ struct ttm_mem_type_manager *man;
+ size_t acc_size;
+ int err;
+
+ size = PAGE_ALIGN(size);
+ man = dev->mman.bdev.man + TTM_PL_TT;
+ if (size >= (man->size << PAGE_SHIFT))
+ return ERR_PTR(-ENOMEM);
+
+ acc_size = ttm_bo_dma_acc_size(&dev->mman.bdev, size,
+ sizeof(struct lima_bo));
+
+ bo = kzalloc(sizeof(*bo), GFP_KERNEL);
+ if (!bo)
+ return ERR_PTR(-ENOMEM);
+
+ drm_gem_private_object_init(dev->ddev, &bo->gem, size);
+
+ INIT_LIST_HEAD(&bo->va);
+
+ bo->tbo.bdev = &dev->mman.bdev;
+
+ lima_bo_init_placement(bo);
+
+ err = ttm_bo_init(&dev->mman.bdev, &bo->tbo, size, type,
+ &bo->placement, 0, type != ttm_bo_type_kernel,
+ acc_size, sg, resv, &lima_bo_destroy);
+ if (err)
+ goto err_out;
+
+ return bo;
+
+err_out:
+ kfree(bo);
+ return ERR_PTR(err);
+}
+
+dma_addr_t *lima_bo_get_pages(struct lima_bo *bo)
+{
+ struct lima_ttm_tt *ttm = (void *)bo->tbo.ttm;
+ return ttm->ttm.dma_address;
+}
+
+void *lima_bo_kmap(struct lima_bo *bo)
+{
+ bool is_iomem;
+ void *ret;
+ int err;
+
+ ret = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+ if (ret)
+ return ret;
+
+ err = ttm_bo_kmap(&bo->tbo, 0, bo->tbo.num_pages, &bo->kmap);
+ if (err)
+ return ERR_PTR(err);
+
+ return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
+}
diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h
new file mode 100644
index 000000000000..2b8b8fcb9063
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_object.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_OBJECT_H__
+#define __LIMA_OBJECT_H__
+
+#include <drm/drm_gem.h>
+#include <drm/ttm/ttm_placement.h>
+#include <drm/ttm/ttm_bo_api.h>
+
+#include "lima_device.h"
+
+struct lima_bo {
+ struct drm_gem_object gem;
+
+ struct ttm_place place;
+ struct ttm_placement placement;
+ struct ttm_buffer_object tbo;
+ struct ttm_bo_kmap_obj kmap;
+
+ struct list_head va;
+};
+
+static inline struct lima_bo *
+to_lima_bo(struct drm_gem_object *obj)
+{
+ return container_of(obj, struct lima_bo, gem);
+}
+
+static inline struct lima_bo *
+ttm_to_lima_bo(struct ttm_buffer_object *tbo)
+{
+ return container_of(tbo, struct lima_bo, tbo);
+}
+
+static inline int lima_bo_reserve(struct lima_bo *bo, bool intr)
+{
+ struct lima_device *dev = ttm_to_lima_dev(bo->tbo.bdev);
+ int r;
+
+ r = ttm_bo_reserve(&bo->tbo, intr, false, NULL);
+ if (unlikely(r != 0)) {
+ if (r != -ERESTARTSYS)
+ dev_err(dev->dev, "%p reserve failed\n", bo);
+ return r;
+ }
+ return 0;
+}
+
+static inline void lima_bo_unreserve(struct lima_bo *bo)
+{
+ ttm_bo_unreserve(&bo->tbo);
+}
+
+struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size,
+ u32 flags, enum ttm_bo_type type,
+ struct sg_table *sg,
+ struct reservation_object *resv);
+
+static inline void lima_bo_unref(struct lima_bo *bo)
+{
+ struct ttm_buffer_object *tbo = &bo->tbo;
+ ttm_bo_unref(&tbo);
+}
+
+dma_addr_t *lima_bo_get_pages(struct lima_bo *bo);
+void *lima_bo_kmap(struct lima_bo *bo);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,530 @@
From fda6ccdbd4930361a5a1dce1d2adf0998f63441e Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Wed, 16 May 2018 10:34:29 +0800
Subject: [PATCH 056/146] drm/lima: add GEM related functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/lima/lima_gem.c | 459 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_gem.h | 41 +++
2 files changed, 500 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_gem.c
create mode 100644 drivers/gpu/drm/lima/lima_gem.h
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
new file mode 100644
index 000000000000..1ad3f38ddfde
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <drm/drmP.h>
+#include <linux/dma-mapping.h>
+#include <linux/pagemap.h>
+#include <linux/sync_file.h>
+
+#include <drm/lima_drm.h>
+
+#include "lima_drv.h"
+#include "lima_gem.h"
+#include "lima_vm.h"
+#include "lima_object.h"
+
+int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
+ u32 size, u32 flags, u32 *handle)
+{
+ int err;
+ struct lima_bo *bo;
+ struct lima_device *ldev = to_lima_dev(dev);
+
+ bo = lima_bo_create(ldev, size, flags, ttm_bo_type_device, NULL, NULL);
+ if (IS_ERR(bo))
+ return PTR_ERR(bo);
+
+ err = drm_gem_handle_create(file, &bo->gem, handle);
+
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_put_unlocked(&bo->gem);
+
+ return err;
+}
+
+void lima_gem_free_object(struct drm_gem_object *obj)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+
+ if (!list_empty(&bo->va))
+ dev_err(obj->dev->dev, "lima gem free bo still has va\n");
+
+ lima_bo_unref(bo);
+}
+
+int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+ int err;
+
+ err = lima_bo_reserve(bo, true);
+ if (err)
+ return err;
+
+ err = lima_vm_bo_add(vm, bo);
+
+ lima_bo_unreserve(bo);
+ return err;
+}
+
+void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *file)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+ struct lima_device *dev = to_lima_dev(obj->dev);
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+
+ LIST_HEAD(list);
+ struct ttm_validate_buffer tv_bo, tv_pd;
+ struct ww_acquire_ctx ticket;
+ int r;
+
+ tv_bo.bo = &bo->tbo;
+ tv_bo.shared = true;
+ list_add(&tv_bo.head, &list);
+
+ tv_pd.bo = &vm->pd->tbo;
+ tv_pd.shared = true;
+ list_add(&tv_pd.head, &list);
+
+ r = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ if (r) {
+ dev_err(dev->dev, "leeking bo va because we "
+ "fail to reserve bo (%d)\n", r);
+ return;
+ }
+
+ lima_vm_bo_del(vm, bo);
+
+ ttm_eu_backoff_reservation(&ticket, &list);
+}
+
+int lima_gem_mmap_offset(struct drm_file *file, u32 handle, u64 *offset)
+{
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+ *offset = drm_vma_node_offset_addr(&bo->tbo.vma_node);
+
+ drm_gem_object_put_unlocked(obj);
+ return 0;
+}
+
+int lima_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct drm_file *file_priv;
+ struct lima_device *dev;
+
+ if (unlikely(vma->vm_pgoff < DRM_FILE_PAGE_OFFSET))
+ return -EINVAL;
+
+ file_priv = filp->private_data;
+ dev = file_priv->minor->dev->dev_private;
+ if (dev == NULL)
+ return -EINVAL;
+
+ return ttm_bo_mmap(filp, vma, &dev->mman.bdev);
+}
+
+int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va)
+{
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+ struct lima_device *dev;
+ int err;
+
+ LIST_HEAD(list);
+ struct ttm_validate_buffer tv_bo, tv_pd;
+ struct ww_acquire_ctx ticket;
+
+ if (!PAGE_ALIGNED(va))
+ return -EINVAL;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+ dev = to_lima_dev(obj->dev);
+
+ /* carefully handle overflow when calculate range */
+ if (va < dev->va_start || dev->va_end - obj->size < va) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ tv_bo.bo = &bo->tbo;
+ tv_bo.shared = true;
+ list_add(&tv_bo.head, &list);
+
+ tv_pd.bo = &vm->pd->tbo;
+ tv_pd.shared = true;
+ list_add(&tv_pd.head, &list);
+
+ err = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ if (err)
+ goto out;
+
+ err = lima_vm_bo_map(vm, bo, va);
+
+ ttm_eu_backoff_reservation(&ticket, &list);
+out:
+ drm_gem_object_put_unlocked(obj);
+ return err;
+}
+
+int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va)
+{
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+ int err;
+
+ LIST_HEAD(list);
+ struct ttm_validate_buffer tv_bo, tv_pd;
+ struct ww_acquire_ctx ticket;
+
+ if (!PAGE_ALIGNED(va))
+ return -EINVAL;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+
+ tv_bo.bo = &bo->tbo;
+ tv_bo.shared = true;
+ list_add(&tv_bo.head, &list);
+
+ tv_pd.bo = &vm->pd->tbo;
+ tv_pd.shared = true;
+ list_add(&tv_pd.head, &list);
+
+ err = ttm_eu_reserve_buffers(&ticket, &list, false, NULL);
+ if (err)
+ goto out;
+
+ err = lima_vm_bo_unmap(vm, bo, va);
+
+ ttm_eu_backoff_reservation(&ticket, &list);
+out:
+ drm_gem_object_put_unlocked(obj);
+ return err;
+}
+
+static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo,
+ bool write, bool explicit)
+{
+ int i, err;
+ struct dma_fence *f;
+ u64 context = task->base.s_fence->finished.context;
+
+ if (!write) {
+ err = reservation_object_reserve_shared(bo->tbo.resv);
+ if (err)
+ return err;
+ }
+
+ /* explicit sync use user passed dep fence */
+ if (explicit)
+ return 0;
+
+ /* implicit sync use bo fence in resv obj */
+ if (write) {
+ struct reservation_object_list *fobj =
+ reservation_object_get_list(bo->tbo.resv);
+
+ if (fobj && fobj->shared_count > 0) {
+ for (i = 0; i < fobj->shared_count; i++) {
+ f = rcu_dereference_protected(
+ fobj->shared[i],
+ reservation_object_held(bo->tbo.resv));
+ if (f->context != context) {
+ err = lima_sched_task_add_dep(task, f);
+ if (err)
+ return err;
+ }
+ }
+ }
+ }
+
+ f = reservation_object_get_excl(bo->tbo.resv);
+ if (f) {
+ err = lima_sched_task_add_dep(task, f);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int lima_gem_add_deps(struct lima_ctx_mgr *mgr, struct lima_submit *submit)
+{
+ int i, err = 0;
+
+ for (i = 0; i < submit->nr_deps; i++) {
+ union drm_lima_gem_submit_dep *dep = submit->deps + i;
+ struct dma_fence *fence;
+
+ if (dep->type == LIMA_SUBMIT_DEP_FENCE) {
+ fence = lima_ctx_get_native_fence(
+ mgr, dep->fence.ctx, dep->fence.pipe,
+ dep->fence.seq);
+ if (IS_ERR(fence)) {
+ err = PTR_ERR(fence);
+ break;
+ }
+ }
+ else if (dep->type == LIMA_SUBMIT_DEP_SYNC_FD) {
+ fence = sync_file_get_fence(dep->sync_fd.fd);
+ if (!fence) {
+ err = -EINVAL;
+ break;
+ }
+ }
+ else {
+ err = -EINVAL;
+ break;
+ }
+
+ if (fence) {
+ err = lima_sched_task_add_dep(submit->task, fence);
+ dma_fence_put(fence);
+ if (err)
+ break;
+ }
+ }
+
+ return err;
+}
+
+static int lima_gem_get_sync_fd(struct dma_fence *fence)
+{
+ struct sync_file *sync_file;
+ int fd;
+
+ fd = get_unused_fd_flags(O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+
+ sync_file = sync_file_create(fence);
+ if (!sync_file) {
+ put_unused_fd(fd);
+ return -ENOMEM;
+ }
+
+ fd_install(fd, sync_file->file);
+ return fd;
+}
+
+int lima_gem_submit(struct drm_file *file, struct lima_submit *submit)
+{
+ int i, err = 0;
+ struct lima_drm_priv *priv = to_lima_drm_priv(file);
+ struct lima_vm *vm = priv->vm;
+
+ INIT_LIST_HEAD(&submit->validated);
+ INIT_LIST_HEAD(&submit->duplicates);
+
+ for (i = 0; i < submit->nr_bos; i++) {
+ struct drm_gem_object *obj;
+ struct drm_lima_gem_submit_bo *bo = submit->bos + i;
+ struct ttm_validate_buffer *vb = submit->vbs + i;
+
+ obj = drm_gem_object_lookup(file, bo->handle);
+ if (!obj) {
+ err = -ENOENT;
+ goto out0;
+ }
+
+ vb->bo = &to_lima_bo(obj)->tbo;
+ vb->shared = !(bo->flags & LIMA_SUBMIT_BO_WRITE);
+ list_add_tail(&vb->head, &submit->validated);
+ }
+
+ submit->vm_pd_vb.bo = &vm->pd->tbo;
+ submit->vm_pd_vb.shared = true;
+ list_add(&submit->vm_pd_vb.head, &submit->validated);
+
+ err = ttm_eu_reserve_buffers(&submit->ticket, &submit->validated,
+ true, &submit->duplicates);
+ if (err)
+ goto out0;
+
+ err = lima_sched_task_init(
+ submit->task, submit->ctx->context + submit->pipe, vm);
+ if (err)
+ goto out1;
+
+ err = lima_gem_add_deps(&priv->ctx_mgr, submit);
+ if (err)
+ goto out2;
+
+ for (i = 0; i < submit->nr_bos; i++) {
+ struct ttm_validate_buffer *vb = submit->vbs + i;
+ struct lima_bo *bo = ttm_to_lima_bo(vb->bo);
+ err = lima_gem_sync_bo(
+ submit->task, bo, !vb->shared,
+ submit->flags & LIMA_SUBMIT_FLAG_EXPLICIT_FENCE);
+ if (err)
+ goto out2;
+ }
+
+ if (submit->flags & LIMA_SUBMIT_FLAG_SYNC_FD_OUT) {
+ int fd = lima_gem_get_sync_fd(
+ &submit->task->base.s_fence->finished);
+ if (fd < 0) {
+ err = fd;
+ goto out2;
+ }
+ submit->sync_fd = fd;
+ }
+
+ submit->fence = lima_sched_context_queue_task(
+ submit->ctx->context + submit->pipe, submit->task,
+ &submit->done);
+
+ ttm_eu_fence_buffer_objects(&submit->ticket, &submit->validated,
+ &submit->task->base.s_fence->finished);
+
+out2:
+ if (err)
+ lima_sched_task_fini(submit->task);
+out1:
+ if (err)
+ ttm_eu_backoff_reservation(&submit->ticket, &submit->validated);
+out0:
+ for (i = 0; i < submit->nr_bos; i++) {
+ struct ttm_validate_buffer *vb = submit->vbs + i;
+ if (!vb->bo)
+ break;
+ drm_gem_object_put_unlocked(&ttm_to_lima_bo(vb->bo)->gem);
+ }
+ return err;
+}
+
+int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns)
+{
+ bool write = op & LIMA_GEM_WAIT_WRITE;
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+ signed long ret;
+ unsigned long timeout;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+
+ timeout = timeout_ns ? lima_timeout_to_jiffies(timeout_ns) : 0;
+
+ ret = lima_bo_reserve(bo, true);
+ if (ret)
+ goto out;
+
+ /* must use long for result check because in 64bit arch int
+ * will overflow if timeout is too large and get <0 result
+ */
+ ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, write, true, timeout);
+ if (ret == 0)
+ ret = timeout ? -ETIMEDOUT : -EBUSY;
+ else if (ret > 0)
+ ret = 0;
+
+ lima_bo_unreserve(bo);
+out:
+ drm_gem_object_put_unlocked(obj);
+ return ret;
+}
diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h
new file mode 100644
index 000000000000..8e3c4110825d
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_GEM_H__
+#define __LIMA_GEM_H__
+
+struct lima_bo;
+struct lima_submit;
+
+struct lima_bo *lima_gem_create_bo(struct drm_device *dev, u32 size, u32 flags);
+int lima_gem_create_handle(struct drm_device *dev, struct drm_file *file,
+ u32 size, u32 flags, u32 *handle);
+void lima_gem_free_object(struct drm_gem_object *obj);
+int lima_gem_object_open(struct drm_gem_object *obj, struct drm_file *file);
+void lima_gem_object_close(struct drm_gem_object *obj, struct drm_file *file);
+int lima_gem_mmap_offset(struct drm_file *file, u32 handle, u64 *offset);
+int lima_gem_mmap(struct file *filp, struct vm_area_struct *vma);
+int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va);
+int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va);
+int lima_gem_submit(struct drm_file *file, struct lima_submit *submit);
+int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,126 @@
From 2a5a3ab8cf45c868fa158fb2766f7a9707d187b0 Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Wed, 16 May 2018 10:38:28 +0800
Subject: [PATCH 057/146] drm/lima: add GEM Prime related functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Erico Nunes <nunes.erico@gmail.com>
---
drivers/gpu/drm/lima/lima_gem_prime.c | 66 +++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_gem_prime.h | 31 +++++++++++++
2 files changed, 97 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.c
create mode 100644 drivers/gpu/drm/lima/lima_gem_prime.h
diff --git a/drivers/gpu/drm/lima/lima_gem_prime.c b/drivers/gpu/drm/lima/lima_gem_prime.c
new file mode 100644
index 000000000000..74da43a4378f
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem_prime.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/dma-buf.h>
+#include <drm/drm_prime.h>
+
+#include "lima_device.h"
+#include "lima_object.h"
+#include "lima_gem_prime.h"
+
+struct drm_gem_object *lima_gem_prime_import_sg_table(
+ struct drm_device *dev, struct dma_buf_attachment *attach,
+ struct sg_table *sgt)
+{
+ struct reservation_object *resv = attach->dmabuf->resv;
+ struct lima_device *ldev = to_lima_dev(dev);
+ struct lima_bo *bo;
+
+ ww_mutex_lock(&resv->lock, NULL);
+
+ bo = lima_bo_create(ldev, attach->dmabuf->size, 0,
+ ttm_bo_type_sg, sgt, resv);
+ if (IS_ERR(bo))
+ goto err_out;
+
+ ww_mutex_unlock(&resv->lock);
+ return &bo->gem;
+
+err_out:
+ ww_mutex_unlock(&resv->lock);
+ return (void *)bo;
+}
+
+struct reservation_object *lima_gem_prime_res_obj(struct drm_gem_object *obj)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+
+ return bo->tbo.resv;
+}
+
+struct sg_table *lima_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+ struct lima_bo *bo = to_lima_bo(obj);
+ int npages = bo->tbo.num_pages;
+
+ return drm_prime_pages_to_sg(bo->tbo.ttm->pages, npages);
+}
diff --git a/drivers/gpu/drm/lima/lima_gem_prime.h b/drivers/gpu/drm/lima/lima_gem_prime.h
new file mode 100644
index 000000000000..023bf5ba2d7b
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_gem_prime.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_GEM_PRIME_H__
+#define __LIMA_GEM_PRIME_H__
+
+struct drm_gem_object *lima_gem_prime_import_sg_table(
+ struct drm_device *dev, struct dma_buf_attachment *attach,
+ struct sg_table *sgt);
+struct sg_table *lima_gem_prime_get_sg_table(struct drm_gem_object *obj);
+struct reservation_object *lima_gem_prime_res_obj(struct drm_gem_object *obj);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,651 @@
From f76c22d3c634633a1d27dce98d042f211f0ac35e Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Wed, 16 May 2018 10:40:58 +0800
Subject: [PATCH 058/146] drm/lima: add GPU schedule using DRM_SCHED
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_sched.c | 497 ++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_sched.h | 126 ++++++++
2 files changed, 623 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_sched.c
create mode 100644 drivers/gpu/drm/lima/lima_sched.h
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
new file mode 100644
index 000000000000..190932955e9b
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -0,0 +1,497 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/kthread.h>
+#include <linux/slab.h>
+
+#include "lima_drv.h"
+#include "lima_sched.h"
+#include "lima_vm.h"
+#include "lima_mmu.h"
+#include "lima_l2_cache.h"
+
+struct lima_fence {
+ struct dma_fence base;
+ struct lima_sched_pipe *pipe;
+};
+
+static struct kmem_cache *lima_fence_slab = NULL;
+
+int lima_sched_slab_init(void)
+{
+ lima_fence_slab = kmem_cache_create(
+ "lima_fence", sizeof(struct lima_fence), 0,
+ SLAB_HWCACHE_ALIGN, NULL);
+ if (!lima_fence_slab)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void lima_sched_slab_fini(void)
+{
+ if (lima_fence_slab)
+ kmem_cache_destroy(lima_fence_slab);
+}
+
+static inline struct lima_fence *to_lima_fence(struct dma_fence *fence)
+{
+ return container_of(fence, struct lima_fence, base);
+}
+
+static const char *lima_fence_get_driver_name(struct dma_fence *fence)
+{
+ return "lima";
+}
+
+static const char *lima_fence_get_timeline_name(struct dma_fence *fence)
+{
+ struct lima_fence *f = to_lima_fence(fence);
+
+ return f->pipe->base.name;
+}
+
+static bool lima_fence_enable_signaling(struct dma_fence *fence)
+{
+ return true;
+}
+
+static void lima_fence_release_rcu(struct rcu_head *rcu)
+{
+ struct dma_fence *f = container_of(rcu, struct dma_fence, rcu);
+ struct lima_fence *fence = to_lima_fence(f);
+
+ kmem_cache_free(lima_fence_slab, fence);
+}
+
+static void lima_fence_release(struct dma_fence *fence)
+{
+ struct lima_fence *f = to_lima_fence(fence);
+
+ call_rcu(&f->base.rcu, lima_fence_release_rcu);
+}
+
+static const struct dma_fence_ops lima_fence_ops = {
+ .get_driver_name = lima_fence_get_driver_name,
+ .get_timeline_name = lima_fence_get_timeline_name,
+ .enable_signaling = lima_fence_enable_signaling,
+ .wait = dma_fence_default_wait,
+ .release = lima_fence_release,
+};
+
+static struct lima_fence *lima_fence_create(struct lima_sched_pipe *pipe)
+{
+ struct lima_fence *fence;
+
+ fence = kmem_cache_zalloc(lima_fence_slab, GFP_KERNEL);
+ if (!fence)
+ return NULL;
+
+ fence->pipe = pipe;
+ dma_fence_init(&fence->base, &lima_fence_ops, &pipe->fence_lock,
+ pipe->fence_context, ++pipe->fence_seqno);
+
+ return fence;
+}
+
+static inline struct lima_sched_task *to_lima_task(struct drm_sched_job *job)
+{
+ return container_of(job, struct lima_sched_task, base);
+}
+
+static inline struct lima_sched_pipe *to_lima_pipe(struct drm_gpu_scheduler *sched)
+{
+ return container_of(sched, struct lima_sched_pipe, base);
+}
+
+int lima_sched_task_init(struct lima_sched_task *task,
+ struct lima_sched_context *context,
+ struct lima_vm *vm)
+{
+ int err;
+
+ err = drm_sched_job_init(&task->base, context->base.sched,
+ &context->base, context);
+ if (err)
+ return err;
+
+ task->vm = lima_vm_get(vm);
+ return 0;
+}
+
+void lima_sched_task_fini(struct lima_sched_task *task)
+{
+ dma_fence_put(&task->base.s_fence->finished);
+ lima_vm_put(task->vm);
+}
+
+int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence)
+{
+ int i, new_dep = 4;
+
+ if (task->dep && task->num_dep == task->max_dep)
+ new_dep = task->max_dep * 2;
+
+ if (task->max_dep < new_dep) {
+ void *dep = krealloc(task->dep, sizeof(*task->dep) * new_dep, GFP_KERNEL);
+ if (!dep)
+ return -ENOMEM;
+ task->max_dep = new_dep;
+ task->dep = dep;
+ }
+
+ dma_fence_get(fence);
+ for (i = 0; i < task->num_dep; i++) {
+ if (task->dep[i]->context == fence->context &&
+ dma_fence_is_later(fence, task->dep[i])) {
+ dma_fence_put(task->dep[i]);
+ task->dep[i] = fence;
+ return 0;
+ }
+ }
+
+ task->dep[task->num_dep++] = fence;
+ return 0;
+}
+
+int lima_sched_context_init(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context,
+ atomic_t *guilty)
+{
+ struct drm_sched_rq *rq = pipe->base.sched_rq + DRM_SCHED_PRIORITY_NORMAL;
+ int err;
+
+ context->fences =
+ kzalloc(sizeof(*context->fences) * lima_sched_max_tasks, GFP_KERNEL);
+ if (!context->fences)
+ return -ENOMEM;
+
+ mutex_init(&context->lock);
+ err = drm_sched_entity_init(&pipe->base, &context->base, rq,
+ lima_sched_max_tasks, guilty);
+ if (err) {
+ kfree(context->fences);
+ context->fences = NULL;
+ return err;
+ }
+
+ return 0;
+}
+
+void lima_sched_context_fini(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context)
+{
+ drm_sched_entity_fini(&pipe->base, &context->base);
+
+ mutex_destroy(&context->lock);
+
+ if (context->fences)
+ kfree(context->fences);
+}
+
+static uint32_t lima_sched_context_add_fence(struct lima_sched_context *context,
+ struct dma_fence *fence,
+ uint32_t *done)
+{
+ uint32_t seq, idx, i;
+ struct dma_fence *other;
+
+ mutex_lock(&context->lock);
+
+ seq = context->sequence;
+ idx = seq & (lima_sched_max_tasks - 1);
+ other = context->fences[idx];
+
+ if (other) {
+ int err = dma_fence_wait(other, false);
+ if (err)
+ DRM_ERROR("Error %d waiting context fence\n", err);
+ }
+
+ context->fences[idx] = dma_fence_get(fence);
+ context->sequence++;
+
+ /* get finished fence offset from seq */
+ for (i = 1; i < lima_sched_max_tasks; i++) {
+ idx = (seq - i) & (lima_sched_max_tasks - 1);
+ if (!context->fences[idx] ||
+ dma_fence_is_signaled(context->fences[idx]))
+ break;
+ }
+
+ mutex_unlock(&context->lock);
+
+ dma_fence_put(other);
+
+ *done = i;
+ return seq;
+}
+
+struct dma_fence *lima_sched_context_get_fence(
+ struct lima_sched_context *context, uint32_t seq)
+{
+ struct dma_fence *fence;
+ int idx;
+ uint32_t max, min;
+
+ mutex_lock(&context->lock);
+
+ max = context->sequence - 1;
+ min = context->sequence - lima_sched_max_tasks;
+
+ /* handle overflow case */
+ if ((min < max && (seq < min || seq > max)) ||
+ (min > max && (seq < min && seq > max))) {
+ fence = NULL;
+ goto out;
+ }
+
+ idx = seq & (lima_sched_max_tasks - 1);
+ fence = dma_fence_get(context->fences[idx]);
+
+out:
+ mutex_unlock(&context->lock);
+
+ return fence;
+}
+
+uint32_t lima_sched_context_queue_task(struct lima_sched_context *context,
+ struct lima_sched_task *task,
+ uint32_t *done)
+{
+ uint32_t seq = lima_sched_context_add_fence(
+ context, &task->base.s_fence->finished, done);
+ drm_sched_entity_push_job(&task->base, &context->base);
+ return seq;
+}
+
+static struct dma_fence *lima_sched_dependency(struct drm_sched_job *job,
+ struct drm_sched_entity *entity)
+{
+ struct lima_sched_task *task = to_lima_task(job);
+ int i;
+
+ for (i = 0; i < task->num_dep; i++) {
+ struct dma_fence *fence = task->dep[i];
+
+ if (!task->dep[i])
+ continue;
+
+ task->dep[i] = NULL;
+
+ if (!dma_fence_is_signaled(fence))
+ return fence;
+
+ dma_fence_put(fence);
+ }
+
+ return NULL;
+}
+
+static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job)
+{
+ struct lima_sched_task *task = to_lima_task(job);
+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
+ struct lima_fence *fence;
+ struct dma_fence *ret;
+ struct lima_vm *vm = NULL, *last_vm = NULL;
+ int i;
+
+ /* after GPU reset */
+ if (job->s_fence->finished.error < 0)
+ return NULL;
+
+ fence = lima_fence_create(pipe);
+ if (!fence)
+ return NULL;
+ task->fence = &fence->base;
+
+ /* for caller usage of the fence, otherwise irq handler
+ * may consume the fence before caller use it */
+ ret = dma_fence_get(task->fence);
+
+ pipe->current_task = task;
+
+ /* this is needed for MMU to work correctly, otherwise GP/PP
+ * will hang or page fault for unknown reason after running for
+ * a while.
+ *
+ * Need to investigate:
+ * 1. is it related to TLB
+ * 2. how much performance will be affected by L2 cache flush
+ * 3. can we reduce the calling of this function because all
+ * GP/PP use the same L2 cache on mali400
+ *
+ * TODO:
+ * 1. move this to task fini to save some wait time?
+ * 2. when GP/PP use different l2 cache, need PP wait GP l2
+ * cache flush?
+ */
+ for (i = 0; i < pipe->num_l2_cache; i++)
+ lima_l2_cache_flush(pipe->l2_cache[i]);
+
+ if (task->vm != pipe->current_vm) {
+ vm = lima_vm_get(task->vm);
+ last_vm = pipe->current_vm;
+ pipe->current_vm = task->vm;
+ }
+
+ if (pipe->bcast_mmu)
+ lima_mmu_switch_vm(pipe->bcast_mmu, vm);
+ else {
+ for (i = 0; i < pipe->num_mmu; i++)
+ lima_mmu_switch_vm(pipe->mmu[i], vm);
+ }
+
+ if (last_vm)
+ lima_vm_put(last_vm);
+
+ pipe->error = false;
+ pipe->task_run(pipe, task);
+
+ return task->fence;
+}
+
+static void lima_sched_handle_error_task(struct lima_sched_pipe *pipe,
+ struct lima_sched_task *task)
+{
+ kthread_park(pipe->base.thread);
+ drm_sched_hw_job_reset(&pipe->base, &task->base);
+
+ pipe->task_error(pipe);
+
+ if (pipe->bcast_mmu)
+ lima_mmu_page_fault_resume(pipe->bcast_mmu);
+ else {
+ int i;
+ for (i = 0; i < pipe->num_mmu; i++)
+ lima_mmu_page_fault_resume(pipe->mmu[i]);
+ }
+
+ if (pipe->current_vm)
+ lima_vm_put(pipe->current_vm);
+
+ pipe->current_vm = NULL;
+ pipe->current_task = NULL;
+
+ drm_sched_job_recovery(&pipe->base);
+ kthread_unpark(pipe->base.thread);
+}
+
+static void lima_sched_timedout_job(struct drm_sched_job *job)
+{
+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
+ struct lima_sched_task *task = to_lima_task(job);
+
+ lima_sched_handle_error_task(pipe, task);
+}
+
+static void lima_sched_free_job(struct drm_sched_job *job)
+{
+ struct lima_sched_task *task = to_lima_task(job);
+ struct lima_sched_pipe *pipe = to_lima_pipe(job->sched);
+ int i;
+
+ dma_fence_put(task->fence);
+
+ for (i = 0; i < task->num_dep; i++) {
+ if (task->dep[i])
+ dma_fence_put(task->dep[i]);
+ }
+
+ if (task->dep)
+ kfree(task->dep);
+
+ lima_vm_put(task->vm);
+ kmem_cache_free(pipe->task_slab, task);
+}
+
+const struct drm_sched_backend_ops lima_sched_ops = {
+ .dependency = lima_sched_dependency,
+ .run_job = lima_sched_run_job,
+ .timedout_job = lima_sched_timedout_job,
+ .free_job = lima_sched_free_job,
+};
+
+static void lima_sched_error_work(struct work_struct *work)
+{
+ struct lima_sched_pipe *pipe =
+ container_of(work, struct lima_sched_pipe, error_work);
+ struct lima_sched_task *task = pipe->current_task;
+
+ lima_sched_handle_error_task(pipe, task);
+}
+
+int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
+{
+ long timeout;
+
+ if (lima_sched_timeout_ms <= 0)
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ else
+ timeout = msecs_to_jiffies(lima_sched_timeout_ms);
+
+ pipe->fence_context = dma_fence_context_alloc(1);
+ spin_lock_init(&pipe->fence_lock);
+
+ INIT_WORK(&pipe->error_work, lima_sched_error_work);
+
+ return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0, timeout, name);
+}
+
+void lima_sched_pipe_fini(struct lima_sched_pipe *pipe)
+{
+ drm_sched_fini(&pipe->base);
+}
+
+unsigned long lima_timeout_to_jiffies(u64 timeout_ns)
+{
+ unsigned long timeout_jiffies;
+ ktime_t timeout;
+
+ /* clamp timeout if it's to large */
+ if (((s64)timeout_ns) < 0)
+ return MAX_SCHEDULE_TIMEOUT;
+
+ timeout = ktime_sub(ns_to_ktime(timeout_ns), ktime_get());
+ if (ktime_to_ns(timeout) < 0)
+ return 0;
+
+ timeout_jiffies = nsecs_to_jiffies(ktime_to_ns(timeout));
+ /* clamp timeout to avoid unsigned-> signed overflow */
+ if (timeout_jiffies > MAX_SCHEDULE_TIMEOUT )
+ return MAX_SCHEDULE_TIMEOUT;
+
+ return timeout_jiffies;
+}
+
+void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe)
+{
+ if (pipe->error)
+ schedule_work(&pipe->error_work);
+ else {
+ struct lima_sched_task *task = pipe->current_task;
+
+ pipe->task_fini(pipe);
+ dma_fence_signal(task->fence);
+ }
+}
diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h
new file mode 100644
index 000000000000..b93b7b4eded4
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_sched.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_SCHED_H__
+#define __LIMA_SCHED_H__
+
+#include <drm/gpu_scheduler.h>
+
+struct lima_vm;
+
+struct lima_sched_task {
+ struct drm_sched_job base;
+
+ struct lima_vm *vm;
+ void *frame;
+
+ struct dma_fence **dep;
+ int num_dep;
+ int max_dep;
+
+ /* pipe fence */
+ struct dma_fence *fence;
+};
+
+struct lima_sched_context {
+ struct drm_sched_entity base;
+ struct mutex lock;
+ struct dma_fence **fences;
+ uint32_t sequence;
+};
+
+#define LIMA_SCHED_PIPE_MAX_MMU 8
+#define LIMA_SCHED_PIPE_MAX_L2_CACHE 2
+#define LIMA_SCHED_PIPE_MAX_PROCESSOR 8
+
+struct lima_ip;
+
+struct lima_sched_pipe {
+ struct drm_gpu_scheduler base;
+
+ u64 fence_context;
+ u32 fence_seqno;
+ spinlock_t fence_lock;
+
+ struct lima_sched_task *current_task;
+ struct lima_vm *current_vm;
+
+ struct lima_ip *mmu[LIMA_SCHED_PIPE_MAX_MMU];
+ int num_mmu;
+
+ struct lima_ip *l2_cache[LIMA_SCHED_PIPE_MAX_L2_CACHE];
+ int num_l2_cache;
+
+ struct lima_ip *processor[LIMA_SCHED_PIPE_MAX_PROCESSOR];
+ int num_processor;
+
+ struct lima_ip *bcast_processor;
+ struct lima_ip *bcast_mmu;
+
+ u32 done;
+ bool error;
+ atomic_t task;
+
+ int frame_size;
+ struct kmem_cache *task_slab;
+
+ int (*task_validate)(struct lima_sched_pipe *pipe, struct lima_sched_task *task);
+ void (*task_run)(struct lima_sched_pipe *pipe, struct lima_sched_task *task);
+ void (*task_fini)(struct lima_sched_pipe *pipe);
+ void (*task_error)(struct lima_sched_pipe *pipe);
+ void (*task_mmu_error)(struct lima_sched_pipe *pipe);
+
+ struct work_struct error_work;
+};
+
+int lima_sched_task_init(struct lima_sched_task *task,
+ struct lima_sched_context *context,
+ struct lima_vm *vm);
+void lima_sched_task_fini(struct lima_sched_task *task);
+int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence);
+
+int lima_sched_context_init(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context,
+ atomic_t *guilty);
+void lima_sched_context_fini(struct lima_sched_pipe *pipe,
+ struct lima_sched_context *context);
+uint32_t lima_sched_context_queue_task(struct lima_sched_context *context,
+ struct lima_sched_task *task,
+ uint32_t *done);
+struct dma_fence *lima_sched_context_get_fence(
+ struct lima_sched_context *context, uint32_t seq);
+
+int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name);
+void lima_sched_pipe_fini(struct lima_sched_pipe *pipe);
+void lima_sched_pipe_task_done(struct lima_sched_pipe *pipe);
+
+static inline void lima_sched_pipe_mmu_error(struct lima_sched_pipe *pipe)
+{
+ pipe->error = true;
+ pipe->task_mmu_error(pipe);
+}
+
+int lima_sched_slab_init(void);
+void lima_sched_slab_fini(void);
+
+unsigned long lima_timeout_to_jiffies(u64 timeout_ns);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,222 @@
From fcfa6c7b5a84fac51109efd86b4edf5085359485 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Wed, 16 May 2018 11:14:41 +0800
Subject: [PATCH 059/146] drm/lima: add context related functions
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_ctx.c | 143 ++++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_ctx.h | 51 ++++++++++++
2 files changed, 194 insertions(+)
create mode 100644 drivers/gpu/drm/lima/lima_ctx.c
create mode 100644 drivers/gpu/drm/lima/lima_ctx.h
diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c
new file mode 100644
index 000000000000..7243861760b4
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ctx.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/slab.h>
+
+#include "lima_device.h"
+#include "lima_ctx.h"
+
+int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id)
+{
+ struct lima_ctx *ctx;
+ int i, err;
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+ ctx->dev = dev;
+ kref_init(&ctx->refcnt);
+
+ for (i = 0; i < lima_pipe_num; i++) {
+ err = lima_sched_context_init(dev->pipe + i, ctx->context + i, &ctx->guilty);
+ if (err)
+ goto err_out0;
+ }
+
+ idr_preload(GFP_KERNEL);
+ spin_lock(&mgr->lock);
+ err = idr_alloc(&mgr->handles, ctx, 1, 0, GFP_ATOMIC);
+ spin_unlock(&mgr->lock);
+ idr_preload_end();
+ if (err < 0)
+ goto err_out0;
+
+ *id = err;
+ return 0;
+
+err_out0:
+ for (i--; i >= 0; i--)
+ lima_sched_context_fini(dev->pipe + i, ctx->context + i);
+ kfree(ctx);
+ return err;
+}
+
+static void lima_ctx_do_release(struct kref *ref)
+{
+ struct lima_ctx *ctx = container_of(ref, struct lima_ctx, refcnt);
+ int i;
+
+ for (i = 0; i < lima_pipe_num; i++)
+ lima_sched_context_fini(ctx->dev->pipe + i, ctx->context + i);
+ kfree(ctx);
+}
+
+int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id)
+{
+ struct lima_ctx *ctx;
+
+ spin_lock(&mgr->lock);
+ ctx = idr_remove(&mgr->handles, id);
+ spin_unlock(&mgr->lock);
+
+ if (ctx) {
+ kref_put(&ctx->refcnt, lima_ctx_do_release);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id)
+{
+ struct lima_ctx *ctx;
+
+ spin_lock(&mgr->lock);
+ ctx = idr_find(&mgr->handles, id);
+ if (ctx)
+ kref_get(&ctx->refcnt);
+ spin_unlock(&mgr->lock);
+ return ctx;
+}
+
+void lima_ctx_put(struct lima_ctx *ctx)
+{
+ kref_put(&ctx->refcnt, lima_ctx_do_release);
+}
+
+void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr)
+{
+ spin_lock_init(&mgr->lock);
+ idr_init(&mgr->handles);
+}
+
+void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr)
+{
+ struct lima_ctx *ctx;
+ struct idr *idp;
+ uint32_t id;
+
+ idp = &mgr->handles;
+
+ idr_for_each_entry(idp, ctx, id) {
+ kref_put(&ctx->refcnt, lima_ctx_do_release);
+ }
+
+ idr_destroy(&mgr->handles);
+}
+
+struct dma_fence *lima_ctx_get_native_fence(struct lima_ctx_mgr *mgr,
+ u32 ctx, u32 pipe, u32 seq)
+{
+ struct lima_ctx *c;
+ struct dma_fence *ret;
+
+ if (pipe >= lima_pipe_num)
+ return ERR_PTR(-EINVAL);
+
+ c = lima_ctx_get(mgr, ctx);
+ if (!c)
+ return ERR_PTR(-ENOENT);
+
+ ret = lima_sched_context_get_fence(c->context + pipe, seq);
+
+ lima_ctx_put(c);
+ return ret;
+}
diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h
new file mode 100644
index 000000000000..591f64532772
--- /dev/null
+++ b/drivers/gpu/drm/lima/lima_ctx.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017-2018 Lima Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef __LIMA_CTX_H__
+#define __LIMA_CTX_H__
+
+#include <linux/idr.h>
+
+#include "lima_device.h"
+
+struct lima_ctx {
+ struct kref refcnt;
+ struct lima_device *dev;
+ struct lima_sched_context context[lima_pipe_num];
+ atomic_t guilty;
+};
+
+struct lima_ctx_mgr {
+ spinlock_t lock;
+ struct idr handles;
+};
+
+int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id);
+int lima_ctx_free(struct lima_ctx_mgr *mgr, u32 id);
+struct lima_ctx *lima_ctx_get(struct lima_ctx_mgr *mgr, u32 id);
+void lima_ctx_put(struct lima_ctx *ctx);
+void lima_ctx_mgr_init(struct lima_ctx_mgr *mgr);
+void lima_ctx_mgr_fini(struct lima_ctx_mgr *mgr);
+
+struct dma_fence *lima_ctx_get_native_fence(struct lima_ctx_mgr *mgr,
+ u32 ctx, u32 pipe, u32 seq);
+
+#endif
--
2.17.1

View file

@ -0,0 +1,83 @@
From f7f324da0402ba4efe3656e68d573fb649fd60f5 Mon Sep 17 00:00:00 2001
From: Lima Project Developers <dri-devel@lists.freedesktop.org>
Date: Wed, 16 May 2018 11:17:06 +0800
Subject: [PATCH 060/146] drm/lima: add makefile and kconfig
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Simon Shields <simon@lineageos.org>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
drivers/gpu/drm/Kconfig | 2 ++
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/lima/Kconfig | 9 +++++++++
drivers/gpu/drm/lima/Makefile | 19 +++++++++++++++++++
4 files changed, 31 insertions(+)
create mode 100644 drivers/gpu/drm/lima/Kconfig
create mode 100644 drivers/gpu/drm/lima/Makefile
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index cb88528e7b10..145c093c3dec 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -315,6 +315,8 @@ source "drivers/gpu/drm/tve200/Kconfig"
source "drivers/gpu/drm/xen/Kconfig"
+source "drivers/gpu/drm/lima/Kconfig"
+
# Keep legacy drivers last
menuconfig DRM_LEGACY
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a6771cef85e2..302b4c8e7cf0 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -107,3 +107,4 @@ obj-$(CONFIG_DRM_TINYDRM) += tinydrm/
obj-$(CONFIG_DRM_PL111) += pl111/
obj-$(CONFIG_DRM_TVE200) += tve200/
obj-$(CONFIG_DRM_XEN) += xen/
+obj-$(CONFIG_DRM_LIMA) += lima/
diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig
new file mode 100644
index 000000000000..4ce9ac2e8204
--- /dev/null
+++ b/drivers/gpu/drm/lima/Kconfig
@@ -0,0 +1,9 @@
+
+config DRM_LIMA
+ tristate "LIMA (DRM support for ARM Mali 400/450 GPU)"
+ depends on DRM
+ depends on ARCH_SUNXI || ARCH_ROCKCHIP || ARCH_EXYNOS || ARCH_MESON
+ select DRM_SCHED
+ select DRM_TTM
+ help
+ DRM driver for ARM Mali 400/450 GPUs.
diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile
new file mode 100644
index 000000000000..0a1d6605f164
--- /dev/null
+++ b/drivers/gpu/drm/lima/Makefile
@@ -0,0 +1,19 @@
+lima-y := \
+ lima_drv.o \
+ lima_device.o \
+ lima_pmu.o \
+ lima_l2_cache.o \
+ lima_mmu.o \
+ lima_gp.o \
+ lima_pp.o \
+ lima_gem.o \
+ lima_vm.o \
+ lima_sched.o \
+ lima_ctx.o \
+ lima_gem_prime.o \
+ lima_dlbu.o \
+ lima_bcast.o \
+ lima_ttm.o \
+ lima_object.o
+
+obj-$(CONFIG_DRM_LIMA) += lima.o
--
2.17.1

View file

@ -0,0 +1,306 @@
From 7e7c821aec6eb45f26b40f3ec2f3d8408ec58300 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 21 May 2018 18:47:02 +0800
Subject: [PATCH 062/146] drm/lima: lima_reg.h use BIT()
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_regs.h | 238 +++++++++++++++----------------
1 file changed, 119 insertions(+), 119 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h
index 0d8dced21633..91ae9d6c197b 100644
--- a/drivers/gpu/drm/lima/lima_regs.h
+++ b/drivers/gpu/drm/lima/lima_regs.h
@@ -9,9 +9,9 @@
/* PMU regs */
#define LIMA_PMU_POWER_UP 0x00
#define LIMA_PMU_POWER_DOWN 0x04
-#define LIMA_PMU_POWER_GP0_MASK (1 << 0)
-#define LIMA_PMU_POWER_L2_MASK (1 << 1)
-#define LIMA_PMU_POWER_PP_MASK(i) (1 << (2 + i))
+#define LIMA_PMU_POWER_GP0_MASK BIT(0)
+#define LIMA_PMU_POWER_L2_MASK BIT(1)
+#define LIMA_PMU_POWER_PP_MASK(i) BIT(2 + i)
/*
* On Mali450 each block automatically starts up its corresponding L2
@@ -26,25 +26,25 @@
#define LIMA_PMU_INT_MASK 0x0C
#define LIMA_PMU_INT_RAWSTAT 0x10
#define LIMA_PMU_INT_CLEAR 0x18
-#define LIMA_PMU_INT_CMD_MASK (1 << 0)
+#define LIMA_PMU_INT_CMD_MASK BIT(0)
#define LIMA_PMU_SW_DELAY 0x1C
/* L2 cache regs */
-#define LIMA_L2_CACHE_SIZE 0x0004
-#define LIMA_L2_CACHE_STATUS 0x0008
-#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY (1 << 0)
-#define LIMA_L2_CACHE_STATUS_DATA_BUSY (1 << 1)
-#define LIMA_L2_CACHE_COMMAND 0x0010
-#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL (1 << 0)
-#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014
-#define LIMA_L2_CACHE_MAX_READS 0x0018
-#define LIMA_L2_CACHE_ENABLE 0x001C
-#define LIMA_L2_CACHE_ENABLE_ACCESS (1 << 0)
-#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE (1 << 1)
-#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020
-#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024
-#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028
-#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C
+#define LIMA_L2_CACHE_SIZE 0x0004
+#define LIMA_L2_CACHE_STATUS 0x0008
+#define LIMA_L2_CACHE_STATUS_COMMAND_BUSY BIT(0)
+#define LIMA_L2_CACHE_STATUS_DATA_BUSY BIT(1)
+#define LIMA_L2_CACHE_COMMAND 0x0010
+#define LIMA_L2_CACHE_COMMAND_CLEAR_ALL BIT(0)
+#define LIMA_L2_CACHE_CLEAR_PAGE 0x0014
+#define LIMA_L2_CACHE_MAX_READS 0x0018
+#define LIMA_L2_CACHE_ENABLE 0x001C
+#define LIMA_L2_CACHE_ENABLE_ACCESS BIT(0)
+#define LIMA_L2_CACHE_ENABLE_READ_ALLOCATE BIT(1)
+#define LIMA_L2_CACHE_PERFCNT_SRC0 0x0020
+#define LIMA_L2_CACHE_PERFCNT_VAL0 0x0024
+#define LIMA_L2_CACHE_PERFCNT_SRC1 0x0028
+#define LIMA_L2_CACHE_ERFCNT_VAL1 0x002C
/* GP regs */
#define LIMA_GP_VSCL_START_ADDR 0x00
@@ -54,36 +54,36 @@
#define LIMA_GP_PLBU_ALLOC_START_ADDR 0x10
#define LIMA_GP_PLBU_ALLOC_END_ADDR 0x14
#define LIMA_GP_CMD 0x20
-#define LIMA_GP_CMD_START_VS (1 << 0)
-#define LIMA_GP_CMD_START_PLBU (1 << 1)
-#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC (1 << 4)
-#define LIMA_GP_CMD_RESET (1 << 5)
-#define LIMA_GP_CMD_FORCE_HANG (1 << 6)
-#define LIMA_GP_CMD_STOP_BUS (1 << 9)
-#define LIMA_GP_CMD_SOFT_RESET (1 << 10)
+#define LIMA_GP_CMD_START_VS BIT(0)
+#define LIMA_GP_CMD_START_PLBU BIT(1)
+#define LIMA_GP_CMD_UPDATE_PLBU_ALLOC BIT(4)
+#define LIMA_GP_CMD_RESET BIT(5)
+#define LIMA_GP_CMD_FORCE_HANG BIT(6)
+#define LIMA_GP_CMD_STOP_BUS BIT(9)
+#define LIMA_GP_CMD_SOFT_RESET BIT(10)
#define LIMA_GP_INT_RAWSTAT 0x24
#define LIMA_GP_INT_CLEAR 0x28
#define LIMA_GP_INT_MASK 0x2C
#define LIMA_GP_INT_STAT 0x30
-#define LIMA_GP_IRQ_VS_END_CMD_LST (1 << 0)
-#define LIMA_GP_IRQ_PLBU_END_CMD_LST (1 << 1)
-#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM (1 << 2)
-#define LIMA_GP_IRQ_VS_SEM_IRQ (1 << 3)
-#define LIMA_GP_IRQ_PLBU_SEM_IRQ (1 << 4)
-#define LIMA_GP_IRQ_HANG (1 << 5)
-#define LIMA_GP_IRQ_FORCE_HANG (1 << 6)
-#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT (1 << 7)
-#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT (1 << 8)
-#define LIMA_GP_IRQ_WRITE_BOUND_ERR (1 << 9)
-#define LIMA_GP_IRQ_SYNC_ERROR (1 << 10)
-#define LIMA_GP_IRQ_AXI_BUS_ERROR (1 << 11)
-#define LIMA_GP_IRQ_AXI_BUS_STOPPED (1 << 12)
-#define LIMA_GP_IRQ_VS_INVALID_CMD (1 << 13)
-#define LIMA_GP_IRQ_PLB_INVALID_CMD (1 << 14)
-#define LIMA_GP_IRQ_RESET_COMPLETED (1 << 19)
-#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW (1 << 20)
-#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW (1 << 21)
-#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22)
+#define LIMA_GP_IRQ_VS_END_CMD_LST BIT(0)
+#define LIMA_GP_IRQ_PLBU_END_CMD_LST BIT(1)
+#define LIMA_GP_IRQ_PLBU_OUT_OF_MEM BIT(2)
+#define LIMA_GP_IRQ_VS_SEM_IRQ BIT(3)
+#define LIMA_GP_IRQ_PLBU_SEM_IRQ BIT(4)
+#define LIMA_GP_IRQ_HANG BIT(5)
+#define LIMA_GP_IRQ_FORCE_HANG BIT(6)
+#define LIMA_GP_IRQ_PERF_CNT_0_LIMIT BIT(7)
+#define LIMA_GP_IRQ_PERF_CNT_1_LIMIT BIT(8)
+#define LIMA_GP_IRQ_WRITE_BOUND_ERR BIT(9)
+#define LIMA_GP_IRQ_SYNC_ERROR BIT(10)
+#define LIMA_GP_IRQ_AXI_BUS_ERROR BIT(11)
+#define LIMA_GP_IRQ_AXI_BUS_STOPPED BIT(12)
+#define LIMA_GP_IRQ_VS_INVALID_CMD BIT(13)
+#define LIMA_GP_IRQ_PLB_INVALID_CMD BIT(14)
+#define LIMA_GP_IRQ_RESET_COMPLETED BIT(19)
+#define LIMA_GP_IRQ_SEMAPHORE_UNDERFLOW BIT(20)
+#define LIMA_GP_IRQ_SEMAPHORE_OVERFLOW BIT(21)
+#define LIMA_GP_IRQ_PTR_ARRAY_OUT_OF_BOUNDS BIT(22)
#define LIMA_GP_WRITE_BOUND_LOW 0x34
#define LIMA_GP_PERF_CNT_0_ENABLE 0x3C
#define LIMA_GP_PERF_CNT_1_ENABLE 0x40
@@ -93,11 +93,11 @@
#define LIMA_GP_PERF_CNT_1_VALUE 0x50
#define LIMA_GP_PERF_CNT_0_LIMIT 0x54
#define LIMA_GP_STATUS 0x68
-#define LIMA_GP_STATUS_VS_ACTIVE (1 << 1)
-#define LIMA_GP_STATUS_BUS_STOPPED (1 << 2)
-#define LIMA_GP_STATUS_PLBU_ACTIVE (1 << 3)
-#define LIMA_GP_STATUS_BUS_ERROR (1 << 6)
-#define LIMA_GP_STATUS_WRITE_BOUND_ERR (1 << 8)
+#define LIMA_GP_STATUS_VS_ACTIVE BIT(1)
+#define LIMA_GP_STATUS_BUS_STOPPED BIT(2)
+#define LIMA_GP_STATUS_PLBU_ACTIVE BIT(3)
+#define LIMA_GP_STATUS_BUS_ERROR BIT(6)
+#define LIMA_GP_STATUS_WRITE_BOUND_ERR BIT(8)
#define LIMA_GP_VERSION 0x6C
#define LIMA_GP_VSCL_START_ADDR_READ 0x80
#define LIMA_GP_PLBCL_START_ADDR_READ 0x84
@@ -156,42 +156,42 @@
#define LIMA_PP_VERSION 0x1000
#define LIMA_PP_CURRENT_REND_LIST_ADDR 0x1004
-#define LIMA_PP_STATUS 0x1008
-#define LIMA_PP_STATUS_RENDERING_ACTIVE (1 << 0)
-#define LIMA_PP_STATUS_BUS_STOPPED (1 << 4)
-#define LIMA_PP_CTRL 0x100c
-#define LIMA_PP_CTRL_STOP_BUS (1 << 0)
-#define LIMA_PP_CTRL_FLUSH_CACHES (1 << 3)
-#define LIMA_PP_CTRL_FORCE_RESET (1 << 5)
-#define LIMA_PP_CTRL_START_RENDERING (1 << 6)
-#define LIMA_PP_CTRL_SOFT_RESET (1 << 7)
-#define LIMA_PP_INT_RAWSTAT 0x1020
-#define LIMA_PP_INT_CLEAR 0x1024
-#define LIMA_PP_INT_MASK 0x1028
-#define LIMA_PP_INT_STATUS 0x102c
-#define LIMA_PP_IRQ_END_OF_FRAME (1 << 0)
-#define LIMA_PP_IRQ_END_OF_TILE (1 << 1)
-#define LIMA_PP_IRQ_HANG (1 << 2)
-#define LIMA_PP_IRQ_FORCE_HANG (1 << 3)
-#define LIMA_PP_IRQ_BUS_ERROR (1 << 4)
-#define LIMA_PP_IRQ_BUS_STOP (1 << 5)
-#define LIMA_PP_IRQ_CNT_0_LIMIT (1 << 6)
-#define LIMA_PP_IRQ_CNT_1_LIMIT (1 << 7)
-#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR (1 << 8)
-#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND (1 << 9)
-#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW (1 << 10)
-#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW (1 << 11)
-#define LIMA_PP_IRQ_RESET_COMPLETED (1 << 12)
-#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044
-#define LIMA_PP_BUS_ERROR_STATUS 0x1050
-#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080
-#define LIMA_PP_PERF_CNT_0_SRC 0x1084
-#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088
-#define LIMA_PP_PERF_CNT_0_VALUE 0x108c
-#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0
-#define LIMA_PP_PERF_CNT_1_SRC 0x10a4
-#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8
-#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac
+#define LIMA_PP_STATUS 0x1008
+#define LIMA_PP_STATUS_RENDERING_ACTIVE BIT(0)
+#define LIMA_PP_STATUS_BUS_STOPPED BIT(4)
+#define LIMA_PP_CTRL 0x100c
+#define LIMA_PP_CTRL_STOP_BUS BIT(0)
+#define LIMA_PP_CTRL_FLUSH_CACHES BIT(3)
+#define LIMA_PP_CTRL_FORCE_RESET BIT(5)
+#define LIMA_PP_CTRL_START_RENDERING BIT(6)
+#define LIMA_PP_CTRL_SOFT_RESET BIT(7)
+#define LIMA_PP_INT_RAWSTAT 0x1020
+#define LIMA_PP_INT_CLEAR 0x1024
+#define LIMA_PP_INT_MASK 0x1028
+#define LIMA_PP_INT_STATUS 0x102c
+#define LIMA_PP_IRQ_END_OF_FRAME BIT(0)
+#define LIMA_PP_IRQ_END_OF_TILE BIT(1)
+#define LIMA_PP_IRQ_HANG BIT(2)
+#define LIMA_PP_IRQ_FORCE_HANG BIT(3)
+#define LIMA_PP_IRQ_BUS_ERROR BIT(4)
+#define LIMA_PP_IRQ_BUS_STOP BIT(5)
+#define LIMA_PP_IRQ_CNT_0_LIMIT BIT(6)
+#define LIMA_PP_IRQ_CNT_1_LIMIT BIT(7)
+#define LIMA_PP_IRQ_WRITE_BOUNDARY_ERROR BIT(8)
+#define LIMA_PP_IRQ_INVALID_PLIST_COMMAND BIT(9)
+#define LIMA_PP_IRQ_CALL_STACK_UNDERFLOW BIT(10)
+#define LIMA_PP_IRQ_CALL_STACK_OVERFLOW BIT(11)
+#define LIMA_PP_IRQ_RESET_COMPLETED BIT(12)
+#define LIMA_PP_WRITE_BOUNDARY_LOW 0x1044
+#define LIMA_PP_BUS_ERROR_STATUS 0x1050
+#define LIMA_PP_PERF_CNT_0_ENABLE 0x1080
+#define LIMA_PP_PERF_CNT_0_SRC 0x1084
+#define LIMA_PP_PERF_CNT_0_LIMIT 0x1088
+#define LIMA_PP_PERF_CNT_0_VALUE 0x108c
+#define LIMA_PP_PERF_CNT_1_ENABLE 0x10a0
+#define LIMA_PP_PERF_CNT_1_SRC 0x10a4
+#define LIMA_PP_PERF_CNT_1_LIMIT 0x10a8
+#define LIMA_PP_PERF_CNT_1_VALUE 0x10ac
#define LIMA_PP_PERFMON_CONTR 0x10b0
#define LIMA_PP_PERFMON_BASE 0x10b4
@@ -226,41 +226,41 @@
LIMA_PP_IRQ_MASK_ERROR)
/* MMU regs */
-#define LIMA_MMU_DTE_ADDR 0x0000
-#define LIMA_MMU_STATUS 0x0004
-#define LIMA_MMU_STATUS_PAGING_ENABLED (1 << 0)
-#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE (1 << 1)
-#define LIMA_MMU_STATUS_STALL_ACTIVE (1 << 2)
-#define LIMA_MMU_STATUS_IDLE (1 << 3)
-#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY (1 << 4)
-#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE (1 << 5)
+#define LIMA_MMU_DTE_ADDR 0x0000
+#define LIMA_MMU_STATUS 0x0004
+#define LIMA_MMU_STATUS_PAGING_ENABLED BIT(0)
+#define LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE BIT(1)
+#define LIMA_MMU_STATUS_STALL_ACTIVE BIT(2)
+#define LIMA_MMU_STATUS_IDLE BIT(3)
+#define LIMA_MMU_STATUS_REPLAY_BUFFER_EMPTY BIT(4)
+#define LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE BIT(5)
#define LIMA_MMU_STATUS_BUS_ID(x) ((x >> 6) & 0x1F)
-#define LIMA_MMU_COMMAND 0x0008
-#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00
-#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01
-#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02
-#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03
-#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04
-#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05
-#define LIMA_MMU_COMMAND_HARD_RESET 0x06
-#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C
-#define LIMA_MMU_ZAP_ONE_LINE 0x0010
-#define LIMA_MMU_INT_RAWSTAT 0x0014
-#define LIMA_MMU_INT_CLEAR 0x0018
-#define LIMA_MMU_INT_MASK 0x001C
-#define LIMA_MMU_INT_PAGE_FAULT 0x01
-#define LIMA_MMU_INT_READ_BUS_ERROR 0x02
-#define LIMA_MMU_INT_STATUS 0x0020
+#define LIMA_MMU_COMMAND 0x0008
+#define LIMA_MMU_COMMAND_ENABLE_PAGING 0x00
+#define LIMA_MMU_COMMAND_DISABLE_PAGING 0x01
+#define LIMA_MMU_COMMAND_ENABLE_STALL 0x02
+#define LIMA_MMU_COMMAND_DISABLE_STALL 0x03
+#define LIMA_MMU_COMMAND_ZAP_CACHE 0x04
+#define LIMA_MMU_COMMAND_PAGE_FAULT_DONE 0x05
+#define LIMA_MMU_COMMAND_HARD_RESET 0x06
+#define LIMA_MMU_PAGE_FAULT_ADDR 0x000C
+#define LIMA_MMU_ZAP_ONE_LINE 0x0010
+#define LIMA_MMU_INT_RAWSTAT 0x0014
+#define LIMA_MMU_INT_CLEAR 0x0018
+#define LIMA_MMU_INT_MASK 0x001C
+#define LIMA_MMU_INT_PAGE_FAULT BIT(0)
+#define LIMA_MMU_INT_READ_BUS_ERROR BIT(1)
+#define LIMA_MMU_INT_STATUS 0x0020
-#define LIMA_VM_FLAG_PRESENT (1 << 0)
-#define LIMA_VM_FLAG_READ_PERMISSION (1 << 1)
-#define LIMA_VM_FLAG_WRITE_PERMISSION (1 << 2)
-#define LIMA_VM_FLAG_OVERRIDE_CACHE (1 << 3)
-#define LIMA_VM_FLAG_WRITE_CACHEABLE (1 << 4)
-#define LIMA_VM_FLAG_WRITE_ALLOCATE (1 << 5)
-#define LIMA_VM_FLAG_WRITE_BUFFERABLE (1 << 6)
-#define LIMA_VM_FLAG_READ_CACHEABLE (1 << 7)
-#define LIMA_VM_FLAG_READ_ALLOCATE (1 << 8)
+#define LIMA_VM_FLAG_PRESENT BIT(0)
+#define LIMA_VM_FLAG_READ_PERMISSION BIT(1)
+#define LIMA_VM_FLAG_WRITE_PERMISSION BIT(2)
+#define LIMA_VM_FLAG_OVERRIDE_CACHE BIT(3)
+#define LIMA_VM_FLAG_WRITE_CACHEABLE BIT(4)
+#define LIMA_VM_FLAG_WRITE_ALLOCATE BIT(5)
+#define LIMA_VM_FLAG_WRITE_BUFFERABLE BIT(6)
+#define LIMA_VM_FLAG_READ_CACHEABLE BIT(7)
+#define LIMA_VM_FLAG_READ_ALLOCATE BIT(8)
#define LIMA_VM_FLAG_MASK 0x1FF
#define LIMA_VM_FLAGS_CACHE ( \
--
2.17.1

View file

@ -0,0 +1,30 @@
From 9d7b31732a23ae2f07df1276b7d94cff59d7f0f6 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Thu, 24 May 2018 08:36:21 +0800
Subject: [PATCH 063/146] drm/lima: add IRQF_SHARED for GP irq
On some platform all IRQs of GPU share the same line.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_gp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c
index 280a40d857f4..10d7ee16a1d5 100644
--- a/drivers/gpu/drm/lima/lima_gp.c
+++ b/drivers/gpu/drm/lima/lima_gp.c
@@ -224,8 +224,8 @@ int lima_gp_init(struct lima_ip *ip)
if (err)
return err;
- err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler, 0,
- lima_ip_name(ip), ip);
+ err = devm_request_irq(dev->dev, ip->irq, lima_gp_irq_handler,
+ IRQF_SHARED, lima_ip_name(ip), ip);
if (err) {
dev_err(dev->dev, "gp %s fail to request irq\n",
lima_ip_name(ip));
--
2.17.1

View file

@ -0,0 +1,30 @@
From 6d3f37068bbfac21355642148a182c125eb28d19 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Thu, 24 May 2018 14:22:03 +0800
Subject: [PATCH 064/146] drm/lima: Kconfig only depend on ARM or ARM64
The depend list gets longer and longer. When adding
ARCH_ZYNQMP I decide to just depend on ARM or ARM64
as this GPU can be seen on many ARM SoCs.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig
index 7256625aee04..870f66f407b8 100644
--- a/drivers/gpu/drm/lima/Kconfig
+++ b/drivers/gpu/drm/lima/Kconfig
@@ -4,7 +4,7 @@
config DRM_LIMA
tristate "LIMA (DRM support for ARM Mali 400/450 GPU)"
depends on DRM
- depends on ARCH_SUNXI || ARCH_ROCKCHIP || ARCH_EXYNOS || ARCH_MESON
+ depends on ARM || ARM64 || COMPILE_TEST
select DRM_SCHED
select DRM_TTM
help
--
2.17.1

View file

@ -0,0 +1,31 @@
From 27a1223c73a19b993d0b0a45d0908fc0d76fae0d Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Thu, 24 May 2018 14:33:36 +0800
Subject: [PATCH 065/146] drm/lima: add comments for lima_reg.h
This file is based on official ARM Mali Utgard GPU
kernel driver.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_regs.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h
index 91ae9d6c197b..d8c762c17e52 100644
--- a/drivers/gpu/drm/lima/lima_regs.h
+++ b/drivers/gpu/drm/lima/lima_regs.h
@@ -6,6 +6,10 @@
#ifndef __LIMA_REGS_H__
#define __LIMA_REGS_H__
+/* This file's register definition is collected from the
+ * official ARM Mali Utgard GPU kernel driver source code
+ */
+
/* PMU regs */
#define LIMA_PMU_POWER_UP 0x00
#define LIMA_PMU_POWER_DOWN 0x04
--
2.17.1

View file

@ -0,0 +1,114 @@
From 4402e0d7858450f531f38aa7766233b4b8c8e1bb Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 28 May 2018 17:36:59 +0800
Subject: [PATCH 066/146] drm/lima: wait bo fence before bo close
We can't bring preclose back, so use this
method for user application termination.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_drv.c | 9 +--------
drivers/gpu/drm/lima/lima_sched.c | 2 +-
drivers/gpu/drm/lima/lima_vm.c | 32 +++++++++++++++++++++++++++++++
3 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index 7f2e47da6801..d3ab9f7abb93 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -270,17 +270,11 @@ static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file)
return err;
}
-static void lima_drm_driver_preclose(struct drm_device *dev, struct drm_file *file)
-{
- struct lima_drm_priv *priv = file->driver_priv;
-
- lima_ctx_mgr_fini(&priv->ctx_mgr);
-}
-
static void lima_drm_driver_postclose(struct drm_device *dev, struct drm_file *file)
{
struct lima_drm_priv *priv = file->driver_priv;
+ lima_ctx_mgr_fini(&priv->ctx_mgr);
lima_vm_put(priv->vm);
kfree(priv);
}
@@ -310,7 +304,6 @@ static const struct file_operations lima_drm_driver_fops = {
static struct drm_driver lima_drm_driver = {
.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_PRIME,
.open = lima_drm_driver_open,
- .preclose = lima_drm_driver_preclose,
.postclose = lima_drm_driver_postclose,
.ioctls = lima_drm_driver_ioctls,
.num_ioctls = ARRAY_SIZE(lima_drm_driver_ioctls),
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index 3b5ea2e4674d..89e758718d62 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -112,7 +112,7 @@ int lima_sched_task_init(struct lima_sched_task *task,
int err;
err = drm_sched_job_init(&task->base, context->base.sched,
- &context->base, context);
+ &context->base, vm);
if (err)
return err;
diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
index 11eb3c278df2..19a683c2921b 100644
--- a/drivers/gpu/drm/lima/lima_vm.c
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -195,15 +195,47 @@ int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo)
return 0;
}
+/* wait only fence of resv from task using vm */
+static int lima_vm_wait_resv(struct lima_vm *vm,
+ struct reservation_object *resv)
+{
+ unsigned nr_fences;
+ struct dma_fence **fences;
+ int i;
+ long err;
+
+ err = reservation_object_get_fences_rcu(resv, NULL, &nr_fences, &fences);
+ if (err || !nr_fences)
+ return err;
+
+ for (i = 0; i < nr_fences; i++) {
+ struct drm_sched_fence *sf = to_drm_sched_fence(fences[i]);
+ if (sf && sf->owner == vm)
+ err |= dma_fence_wait(fences[i], false);
+ dma_fence_put(fences[i]);
+ }
+
+ kfree(fences);
+ return err;
+}
+
int lima_vm_bo_del(struct lima_vm *vm, struct lima_bo *bo)
{
struct lima_bo_va *bo_va;
struct lima_bo_va_mapping *mapping, *tmp;
+ int err;
bo_va = lima_vm_bo_find(vm, bo);
if (--bo_va->ref_count > 0)
return 0;
+ /* wait bo idle before unmap it from vm in case user
+ * space application is terminated when bo is busy.
+ */
+ err = lima_vm_wait_resv(vm, bo->tbo.resv);
+ if (err)
+ dev_err(vm->dev->dev, "bo del fail to wait (%d)\n", err);
+
list_for_each_entry_safe(mapping, tmp, &bo_va->mapping, list) {
lima_vm_unmap(vm, mapping);
}
--
2.17.1

View file

@ -0,0 +1,125 @@
From 5c2d27d3a2b35475ea707b14a41e5c557c9ebad2 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 28 May 2018 18:55:39 +0800
Subject: [PATCH 067/146] drm/lima: refine lima_gem_sync_bo
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_gem.c | 58 +++++++++++++++++--------------
drivers/gpu/drm/lima/lima_sched.c | 5 ++-
2 files changed, 36 insertions(+), 27 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index d9c15acb7cf8..3bdff19eb2f9 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -217,9 +217,7 @@ int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va)
static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo,
bool write, bool explicit)
{
- int i, err;
- struct dma_fence *f;
- u64 context = task->base.s_fence->finished.context;
+ int err = 0;
if (!write) {
err = reservation_object_reserve_shared(bo->tbo.resv);
@@ -233,31 +231,38 @@ static int lima_gem_sync_bo(struct lima_sched_task *task, struct lima_bo *bo,
/* implicit sync use bo fence in resv obj */
if (write) {
- struct reservation_object_list *fobj =
- reservation_object_get_list(bo->tbo.resv);
-
- if (fobj && fobj->shared_count > 0) {
- for (i = 0; i < fobj->shared_count; i++) {
- f = rcu_dereference_protected(
- fobj->shared[i],
- reservation_object_held(bo->tbo.resv));
- if (f->context != context) {
- err = lima_sched_task_add_dep(task, f);
- if (err)
- return err;
- }
- }
- }
- }
+ unsigned nr_fences;
+ struct dma_fence **fences;
+ int i;
- f = reservation_object_get_excl(bo->tbo.resv);
- if (f) {
- err = lima_sched_task_add_dep(task, f);
- if (err)
+ err = reservation_object_get_fences_rcu(
+ bo->tbo.resv, NULL, &nr_fences, &fences);
+ if (err || !nr_fences)
return err;
+
+ for (i = 0; i < nr_fences; i++) {
+ err = lima_sched_task_add_dep(task, fences[i]);
+ if (err)
+ break;
+ }
+
+ /* for error case free remaining fences */
+ for ( ; i < nr_fences; i++)
+ dma_fence_put(fences[i]);
+
+ kfree(fences);
+ }
+ else {
+ struct dma_fence *fence;
+ fence = reservation_object_get_excl_rcu(bo->tbo.resv);
+ if (fence) {
+ err = lima_sched_task_add_dep(task, fence);
+ if (err)
+ dma_fence_put(fence);
+ }
}
- return 0;
+ return err;
}
static int lima_gem_add_deps(struct lima_ctx_mgr *mgr, struct lima_submit *submit)
@@ -291,9 +296,10 @@ static int lima_gem_add_deps(struct lima_ctx_mgr *mgr, struct lima_submit *submi
if (fence) {
err = lima_sched_task_add_dep(submit->task, fence);
- dma_fence_put(fence);
- if (err)
+ if (err) {
+ dma_fence_put(fence);
break;
+ }
}
}
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index 89e758718d62..91ec00811071 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -130,6 +130,10 @@ int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fenc
{
int i, new_dep = 4;
+ /* same context's fence is definitly earlier then this task */
+ if (fence->context == task->base.s_fence->finished.context)
+ return 0;
+
if (task->dep && task->num_dep == task->max_dep)
new_dep = task->max_dep * 2;
@@ -141,7 +145,6 @@ int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fenc
task->dep = dep;
}
- dma_fence_get(fence);
for (i = 0; i < task->num_dep; i++) {
if (task->dep[i]->context == fence->context &&
dma_fence_is_later(fence, task->dep[i])) {
--
2.17.1

View file

@ -0,0 +1,25 @@
From 2d89860b45cc744356186504b9880c361c158476 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Mon, 28 May 2018 19:01:48 +0800
Subject: [PATCH 068/146] drm/lima: vm will be freed when lima_sched_free_job
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_sched.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index 91ec00811071..20ed966578a3 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -123,7 +123,6 @@ int lima_sched_task_init(struct lima_sched_task *task,
void lima_sched_task_fini(struct lima_sched_task *task)
{
dma_fence_put(&task->base.s_fence->finished);
- lima_vm_put(task->vm);
}
int lima_sched_task_add_dep(struct lima_sched_task *task, struct dma_fence *fence)
--
2.17.1

View file

@ -0,0 +1,189 @@
From 063d7ebf17304fe8a7b85ecb4662f20c4839b6af Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Wed, 30 May 2018 19:18:03 +0800
Subject: [PATCH 069/146] drm/lima: vm alloc buffer with multi page table
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_vm.c | 95 ++++++++++++++++++++++------------
drivers/gpu/drm/lima/lima_vm.h | 6 ++-
2 files changed, 66 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
index 19a683c2921b..ab7438685234 100644
--- a/drivers/gpu/drm/lima/lima_vm.c
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -28,8 +28,18 @@ struct lima_bo_va {
struct lima_vm *vm;
};
-#define LIMA_PDE(va) (va >> 22)
-#define LIMA_PTE(va) ((va & 0x3FFFFF) >> 12)
+#define LIMA_VM_PD_SHIFT 22
+#define LIMA_VM_PT_SHIFT 12
+#define LIMA_VM_PB_SHIFT (LIMA_VM_PD_SHIFT + LIMA_VM_NUM_PT_PER_BT_SHIFT)
+#define LIMA_VM_BT_SHIFT LIMA_VM_PT_SHIFT
+
+#define LIMA_VM_PT_MASK ((1 << LIMA_VM_PD_SHIFT) - 1)
+#define LIMA_VM_BT_MASK ((1 << LIMA_VM_PB_SHIFT) - 1)
+
+#define LIMA_PDE(va) (va >> LIMA_VM_PD_SHIFT)
+#define LIMA_PTE(va) ((va & LIMA_VM_PT_MASK) >> LIMA_VM_PT_SHIFT)
+#define LIMA_PBE(va) (va >> LIMA_VM_PB_SHIFT)
+#define LIMA_BTE(va) ((va & LIMA_VM_BT_MASK) >> LIMA_VM_BT_SHIFT)
#define START(node) ((node)->start)
#define LAST(node) ((node)->last)
@@ -45,12 +55,12 @@ static void lima_vm_unmap_page_table(struct lima_vm *vm, u32 start, u32 end)
u32 addr;
for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) {
- u32 pde = LIMA_PDE(addr);
- u32 pte = LIMA_PTE(addr);
- u32 *pt;
+ u32 pbe = LIMA_PBE(addr);
+ u32 bte = LIMA_BTE(addr);
+ u32 *bt;
- pt = lima_bo_kmap(vm->pt[pde]);
- pt[pte] = 0;
+ bt = lima_bo_kmap(vm->bts[pbe]);
+ bt[bte] = 0;
}
}
@@ -61,32 +71,43 @@ static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma,
int err, i = 0;
for (addr = start; addr <= end; addr += LIMA_PAGE_SIZE) {
- u32 pde = LIMA_PDE(addr);
- u32 pte = LIMA_PTE(addr);
- u32 *pd, *pt;
+ u32 pbe = LIMA_PBE(addr);
+ u32 bte = LIMA_BTE(addr);
+ u32 *bt;
- if (vm->pt[pde])
- pt = lima_bo_kmap(vm->pt[pde]);
+ if (vm->bts[pbe])
+ bt = lima_bo_kmap(vm->bts[pbe]);
else {
- vm->pt[pde] = lima_bo_create(
- vm->dev, LIMA_PAGE_SIZE, 0, ttm_bo_type_kernel,
+ struct lima_bo *bt_bo;
+ dma_addr_t *pts;
+ u32 *pd;
+ int j;
+
+ bt_bo = lima_bo_create(
+ vm->dev, LIMA_PAGE_SIZE << LIMA_VM_NUM_PT_PER_BT_SHIFT,
+ 0, ttm_bo_type_kernel,
NULL, vm->pd->tbo.resv);
- if (IS_ERR(vm->pt[pde])) {
- err = PTR_ERR(vm->pt[pde]);
+ if (IS_ERR(bt_bo)) {
+ err = PTR_ERR(bt_bo);
goto err_out;
}
- pt = lima_bo_kmap(vm->pt[pde]);
- if (IS_ERR(pt)) {
- err = PTR_ERR(pt);
+ bt = lima_bo_kmap(bt_bo);
+ if (IS_ERR(bt)) {
+ lima_bo_unref(bt_bo);
+ err = PTR_ERR(bt);
goto err_out;
}
+ vm->bts[pbe] = bt_bo;
pd = lima_bo_kmap(vm->pd);
- pd[pde] = *lima_bo_get_pages(vm->pt[pde]) | LIMA_VM_FLAG_PRESENT;
+ pd += pbe << LIMA_VM_NUM_PT_PER_BT_SHIFT;
+ pts = lima_bo_get_pages(bt_bo);
+ for (j = 0; j < LIMA_VM_NUM_PT_PER_BT; j++)
+ *pd++ = *pts++ | LIMA_VM_FLAG_PRESENT;
}
- pt[pte] = dma[i++] | LIMA_VM_FLAGS_CACHE;
+ bt[bte] = dma[i++] | LIMA_VM_FLAGS_CACHE;
}
return 0;
@@ -293,9 +314,9 @@ void lima_vm_release(struct kref *kref)
dev_err(dev->dev, "still active bo inside vm\n");
}
- for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) {
- if (vm->pt[i])
- lima_bo_unref(vm->pt[i]);
+ for (i = 0; i < LIMA_VM_NUM_BT; i++) {
+ if (vm->bts[i])
+ lima_bo_unref(vm->bts[i]);
}
if (vm->pd)
@@ -306,20 +327,26 @@ void lima_vm_release(struct kref *kref)
void lima_vm_print(struct lima_vm *vm)
{
- int i, j;
- u32 *pd = lima_bo_kmap(vm->pd);
+ int i, j, k;
+ u32 *pd, *pt;
/* to avoid the defined by not used warning */
(void)&lima_vm_it_iter_next;
- for (i = 0; i < LIMA_PAGE_ENT_NUM; i++) {
- if (pd[i]) {
- u32 *pt = lima_bo_kmap(vm->pt[i]);
-
- printk(KERN_INFO "lima vm pd %03x:%08x\n", i, pd[i]);
- for (j = 0; j < LIMA_PAGE_ENT_NUM; j++) {
- if (pt[j])
- printk(KERN_INFO " pt %03x:%08x\n", j, pt[j]);
+ pd = lima_bo_kmap(vm->pd);
+ for (i = 0; i < LIMA_VM_NUM_BT; i++) {
+ if (!vm->bts[i])
+ continue;
+
+ pt = lima_bo_kmap(vm->bts[i]);
+ for (j = 0; j < LIMA_VM_NUM_PT_PER_BT; j++) {
+ int idx = (i << LIMA_VM_NUM_PT_PER_BT_SHIFT) + j;
+ printk(KERN_INFO "lima vm pd %03x:%08x\n", idx, pd[idx]);
+
+ for (k = 0; k < LIMA_PAGE_ENT_NUM; k++) {
+ u32 pte = *pt++;
+ if (pte)
+ printk(KERN_INFO " pt %03x:%08x\n", k, pte);
}
}
}
diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h
index c891a1ee95df..598708ac0d31 100644
--- a/drivers/gpu/drm/lima/lima_vm.h
+++ b/drivers/gpu/drm/lima/lima_vm.h
@@ -12,6 +12,10 @@
#define LIMA_PAGE_MASK (LIMA_PAGE_SIZE - 1)
#define LIMA_PAGE_ENT_NUM (LIMA_PAGE_SIZE / sizeof(u32))
+#define LIMA_VM_NUM_PT_PER_BT_SHIFT 3
+#define LIMA_VM_NUM_PT_PER_BT (1 << LIMA_VM_NUM_PT_PER_BT_SHIFT)
+#define LIMA_VM_NUM_BT (LIMA_PAGE_ENT_NUM >> LIMA_VM_NUM_PT_PER_BT_SHIFT)
+
#define LIMA_VA_RESERVE_START 0xFFF00000
#define LIMA_VA_RESERVE_DLBU LIMA_VA_RESERVE_START
#define LIMA_VA_RESERVE_END 0x100000000
@@ -28,7 +32,7 @@ struct lima_vm {
struct lima_device *dev;
struct lima_bo *pd;
- struct lima_bo *pt[LIMA_PAGE_ENT_NUM];
+ struct lima_bo *bts[LIMA_VM_NUM_BT];
};
int lima_vm_bo_map(struct lima_vm *vm, struct lima_bo *bo, u32 start);
--
2.17.1

View file

@ -0,0 +1,35 @@
From 3930833ef2781427cccc0860a86525498d646f72 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Thu, 31 May 2018 16:19:07 +0800
Subject: [PATCH 070/146] drm/lima: clear vm page table when alloc
ttm_bo_type_kernel will not be cleared when alloc.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_vm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
index ab7438685234..514115df4e4c 100644
--- a/drivers/gpu/drm/lima/lima_vm.c
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -98,6 +98,7 @@ static int lima_vm_map_page_table(struct lima_vm *vm, dma_addr_t *dma,
err = PTR_ERR(bt);
goto err_out;
}
+ memset(bt, 0, LIMA_PAGE_SIZE << LIMA_VM_NUM_PT_PER_BT_SHIFT);
vm->bts[pbe] = bt_bo;
pd = lima_bo_kmap(vm->pd);
@@ -286,6 +287,7 @@ struct lima_vm *lima_vm_create(struct lima_device *dev)
pd = lima_bo_kmap(vm->pd);
if (IS_ERR(pd))
goto err_out1;
+ memset(pd, 0, LIMA_PAGE_SIZE);
if (dev->dlbu_cpu) {
int err = lima_vm_map_page_table(
--
2.17.1

View file

@ -0,0 +1,514 @@
From d1267be906c38af372a6b1ebe5145158667e6768 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Thu, 31 May 2018 22:37:45 +0800
Subject: [PATCH 071/146] drm/lima: update SPDX header to match kernel rules
See
https://www.kernel.org/doc/html/latest/process/license-rules.html
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/Kconfig | 2 +-
drivers/gpu/drm/lima/Makefile | 2 +-
drivers/gpu/drm/lima/lima_bcast.c | 5 ++---
drivers/gpu/drm/lima/lima_bcast.h | 5 ++---
drivers/gpu/drm/lima/lima_ctx.c | 5 ++---
drivers/gpu/drm/lima/lima_ctx.h | 5 ++---
drivers/gpu/drm/lima/lima_device.c | 5 ++---
drivers/gpu/drm/lima/lima_device.h | 5 ++---
drivers/gpu/drm/lima/lima_dlbu.c | 5 ++---
drivers/gpu/drm/lima/lima_dlbu.h | 5 ++---
drivers/gpu/drm/lima/lima_drv.c | 5 ++---
drivers/gpu/drm/lima/lima_drv.h | 5 ++---
drivers/gpu/drm/lima/lima_gem.c | 5 ++---
drivers/gpu/drm/lima/lima_gem.h | 5 ++---
drivers/gpu/drm/lima/lima_gem_prime.c | 5 ++---
drivers/gpu/drm/lima/lima_gem_prime.h | 5 ++---
drivers/gpu/drm/lima/lima_gp.c | 5 ++---
drivers/gpu/drm/lima/lima_gp.h | 5 ++---
drivers/gpu/drm/lima/lima_l2_cache.c | 5 ++---
drivers/gpu/drm/lima/lima_l2_cache.h | 5 ++---
drivers/gpu/drm/lima/lima_mmu.c | 5 ++---
drivers/gpu/drm/lima/lima_mmu.h | 5 ++---
drivers/gpu/drm/lima/lima_object.c | 5 ++---
drivers/gpu/drm/lima/lima_object.h | 5 ++---
drivers/gpu/drm/lima/lima_pmu.c | 5 ++---
drivers/gpu/drm/lima/lima_pmu.h | 5 ++---
drivers/gpu/drm/lima/lima_pp.c | 5 ++---
drivers/gpu/drm/lima/lima_pp.h | 5 ++---
drivers/gpu/drm/lima/lima_regs.h | 2 +-
drivers/gpu/drm/lima/lima_sched.c | 5 ++---
drivers/gpu/drm/lima/lima_sched.h | 5 ++---
drivers/gpu/drm/lima/lima_ttm.c | 5 ++---
drivers/gpu/drm/lima/lima_ttm.h | 5 ++---
drivers/gpu/drm/lima/lima_vm.c | 5 ++---
drivers/gpu/drm/lima/lima_vm.h | 5 ++---
include/uapi/drm/lima_drm.h | 5 ++---
36 files changed, 69 insertions(+), 102 deletions(-)
diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig
index 870f66f407b8..bb75bcb97ccb 100644
--- a/drivers/gpu/drm/lima/Kconfig
+++ b/drivers/gpu/drm/lima/Kconfig
@@ -1,5 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0 OR MIT
# Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
-# SPDX-License-Identifier: MIT
config DRM_LIMA
tristate "LIMA (DRM support for ARM Mali 400/450 GPU)"
diff --git a/drivers/gpu/drm/lima/Makefile b/drivers/gpu/drm/lima/Makefile
index 848310557e42..8bb97410d961 100644
--- a/drivers/gpu/drm/lima/Makefile
+++ b/drivers/gpu/drm/lima/Makefile
@@ -1,5 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0 OR MIT
# Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
-# SPDX-License-Identifier: MIT
lima-y := \
lima_drv.o \
diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c
index 0786336d3c77..6c2004dce648 100644
--- a/drivers/gpu/drm/lima/lima_bcast.c
+++ b/drivers/gpu/drm/lima/lima_bcast.c
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/io.h>
#include <linux/device.h>
diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h
index f1ba32852742..fb8e1f318c5c 100644
--- a/drivers/gpu/drm/lima/lima_bcast.h
+++ b/drivers/gpu/drm/lima/lima_bcast.h
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_BCAST_H__
#define __LIMA_BCAST_H__
diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c
index 3c8f0aba0169..3f8a944d9266 100644
--- a/drivers/gpu/drm/lima/lima_ctx.c
+++ b/drivers/gpu/drm/lima/lima_ctx.c
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/slab.h>
diff --git a/drivers/gpu/drm/lima/lima_ctx.h b/drivers/gpu/drm/lima/lima_ctx.h
index f3bee2e1893a..80e55e16619f 100644
--- a/drivers/gpu/drm/lima/lima_ctx.h
+++ b/drivers/gpu/drm/lima/lima_ctx.h
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_CTX_H__
#define __LIMA_CTX_H__
diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c
index 8611ed466a29..c85196af8830 100644
--- a/drivers/gpu/drm/lima/lima_device.c
+++ b/drivers/gpu/drm/lima/lima_device.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
diff --git a/drivers/gpu/drm/lima/lima_device.h b/drivers/gpu/drm/lima/lima_device.h
index 29501f8361d9..d355a2c5c40b 100644
--- a/drivers/gpu/drm/lima/lima_device.h
+++ b/drivers/gpu/drm/lima/lima_device.h
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_DEVICE_H__
#define __LIMA_DEVICE_H__
diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c
index 0b612149accb..444a74348d5e 100644
--- a/drivers/gpu/drm/lima/lima_dlbu.c
+++ b/drivers/gpu/drm/lima/lima_dlbu.c
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/io.h>
#include <linux/device.h>
diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h
index bc441dccb1ba..6d85403fa410 100644
--- a/drivers/gpu/drm/lima/lima_dlbu.h
+++ b/drivers/gpu/drm/lima/lima_dlbu.h
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_DLBU_H__
#define __LIMA_DLBU_H__
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index d3ab9f7abb93..e7004e4e1853 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/module.h>
#include <linux/of_platform.h>
diff --git a/drivers/gpu/drm/lima/lima_drv.h b/drivers/gpu/drm/lima/lima_drv.h
index d7dba79950d6..455bf44ae25e 100644
--- a/drivers/gpu/drm/lima/lima_drv.h
+++ b/drivers/gpu/drm/lima/lima_drv.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_DRV_H__
#define __LIMA_DRV_H__
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 3bdff19eb2f9..ee903ce17494 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <drm/drmP.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h
index 35098b692b2e..03daad9a85af 100644
--- a/drivers/gpu/drm/lima/lima_gem.h
+++ b/drivers/gpu/drm/lima/lima_gem.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_GEM_H__
#define __LIMA_GEM_H__
diff --git a/drivers/gpu/drm/lima/lima_gem_prime.c b/drivers/gpu/drm/lima/lima_gem_prime.c
index 9a401a6a039b..0e0350ca7f87 100644
--- a/drivers/gpu/drm/lima/lima_gem_prime.c
+++ b/drivers/gpu/drm/lima/lima_gem_prime.c
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/dma-buf.h>
#include <drm/drm_prime.h>
diff --git a/drivers/gpu/drm/lima/lima_gem_prime.h b/drivers/gpu/drm/lima/lima_gem_prime.h
index 407482f1a7c0..6dea7dd65b1a 100644
--- a/drivers/gpu/drm/lima/lima_gem_prime.h
+++ b/drivers/gpu/drm/lima/lima_gem_prime.h
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_GEM_PRIME_H__
#define __LIMA_GEM_PRIME_H__
diff --git a/drivers/gpu/drm/lima/lima_gp.c b/drivers/gpu/drm/lima/lima_gp.c
index 10d7ee16a1d5..706652cb1741 100644
--- a/drivers/gpu/drm/lima/lima_gp.c
+++ b/drivers/gpu/drm/lima/lima_gp.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/interrupt.h>
#include <linux/io.h>
diff --git a/drivers/gpu/drm/lima/lima_gp.h b/drivers/gpu/drm/lima/lima_gp.h
index 45e654737767..55bc48ec7603 100644
--- a/drivers/gpu/drm/lima/lima_gp.h
+++ b/drivers/gpu/drm/lima/lima_gp.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_GP_H__
#define __LIMA_GP_H__
diff --git a/drivers/gpu/drm/lima/lima_l2_cache.c b/drivers/gpu/drm/lima/lima_l2_cache.c
index 25313ab5fe92..e7cdec720e5d 100644
--- a/drivers/gpu/drm/lima/lima_l2_cache.c
+++ b/drivers/gpu/drm/lima/lima_l2_cache.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/io.h>
#include <linux/device.h>
diff --git a/drivers/gpu/drm/lima/lima_l2_cache.h b/drivers/gpu/drm/lima/lima_l2_cache.h
index 6ecc07e33430..2ff91eafefbe 100644
--- a/drivers/gpu/drm/lima/lima_l2_cache.h
+++ b/drivers/gpu/drm/lima/lima_l2_cache.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_L2_CACHE_H__
#define __LIMA_L2_CACHE_H__
diff --git a/drivers/gpu/drm/lima/lima_mmu.c b/drivers/gpu/drm/lima/lima_mmu.c
index 7de3935b5cc6..234fb90a4285 100644
--- a/drivers/gpu/drm/lima/lima_mmu.c
+++ b/drivers/gpu/drm/lima/lima_mmu.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/interrupt.h>
#include <linux/io.h>
diff --git a/drivers/gpu/drm/lima/lima_mmu.h b/drivers/gpu/drm/lima/lima_mmu.h
index ac32f620e3d9..ca173b60fc73 100644
--- a/drivers/gpu/drm/lima/lima_mmu.h
+++ b/drivers/gpu/drm/lima/lima_mmu.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_MMU_H__
#define __LIMA_MMU_H__
diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c
index 6ca17ef2e701..c44e1f81abf8 100644
--- a/drivers/gpu/drm/lima/lima_object.c
+++ b/drivers/gpu/drm/lima/lima_object.c
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#include <drm/drm_prime.h>
diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h
index ae67de9d2565..7286514c0f07 100644
--- a/drivers/gpu/drm/lima/lima_object.h
+++ b/drivers/gpu/drm/lima/lima_object.h
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_OBJECT_H__
#define __LIMA_OBJECT_H__
diff --git a/drivers/gpu/drm/lima/lima_pmu.c b/drivers/gpu/drm/lima/lima_pmu.c
index f4548c90b6b7..e852077c1e52 100644
--- a/drivers/gpu/drm/lima/lima_pmu.c
+++ b/drivers/gpu/drm/lima/lima_pmu.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/of.h>
#include <linux/io.h>
diff --git a/drivers/gpu/drm/lima/lima_pmu.h b/drivers/gpu/drm/lima/lima_pmu.h
index b807e9f42928..1cf94a35bdf9 100644
--- a/drivers/gpu/drm/lima/lima_pmu.h
+++ b/drivers/gpu/drm/lima/lima_pmu.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_PMU_H__
#define __LIMA_PMU_H__
diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
index 8db3d134e244..29e3ddfb394b 100644
--- a/drivers/gpu/drm/lima/lima_pp.c
+++ b/drivers/gpu/drm/lima/lima_pp.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/interrupt.h>
#include <linux/io.h>
diff --git a/drivers/gpu/drm/lima/lima_pp.h b/drivers/gpu/drm/lima/lima_pp.h
index b928f9516d30..f83f8cb4d30a 100644
--- a/drivers/gpu/drm/lima/lima_pp.h
+++ b/drivers/gpu/drm/lima/lima_pp.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_PP_H__
#define __LIMA_PP_H__
diff --git a/drivers/gpu/drm/lima/lima_regs.h b/drivers/gpu/drm/lima/lima_regs.h
index d8c762c17e52..d5ade8fc8901 100644
--- a/drivers/gpu/drm/lima/lima_regs.h
+++ b/drivers/gpu/drm/lima/lima_regs.h
@@ -1,6 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright 2010-2017 ARM Limited. All rights reserved.
* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: GPL-2.0
*/
#ifndef __LIMA_REGS_H__
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index 20ed966578a3..e725e793a668 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/kthread.h>
#include <linux/slab.h>
diff --git a/drivers/gpu/drm/lima/lima_sched.h b/drivers/gpu/drm/lima/lima_sched.h
index 581b8601fe81..e1393767128f 100644
--- a/drivers/gpu/drm/lima/lima_sched.h
+++ b/drivers/gpu/drm/lima/lima_sched.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_SCHED_H__
#define __LIMA_SCHED_H__
diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c
index 4be441b02f6c..a79ff0e86929 100644
--- a/drivers/gpu/drm/lima/lima_ttm.c
+++ b/drivers/gpu/drm/lima/lima_ttm.c
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/mm.h>
#include <drm/ttm/ttm_page_alloc.h>
diff --git a/drivers/gpu/drm/lima/lima_ttm.h b/drivers/gpu/drm/lima/lima_ttm.h
index 42af0b136ffb..df3c06aa92a9 100644
--- a/drivers/gpu/drm/lima/lima_ttm.h
+++ b/drivers/gpu/drm/lima/lima_ttm.h
@@ -1,6 +1,5 @@
-/* Copyright 2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_TTM_H__
#define __LIMA_TTM_H__
diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c
index 514115df4e4c..a264f3ae83fe 100644
--- a/drivers/gpu/drm/lima/lima_vm.c
+++ b/drivers/gpu/drm/lima/lima_vm.c
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#include <linux/slab.h>
#include <linux/dma-mapping.h>
diff --git a/drivers/gpu/drm/lima/lima_vm.h b/drivers/gpu/drm/lima/lima_vm.h
index 598708ac0d31..f615f8dfe71d 100644
--- a/drivers/gpu/drm/lima/lima_vm.h
+++ b/drivers/gpu/drm/lima/lima_vm.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_VM_H__
#define __LIMA_VM_H__
diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h
index a489bba517c7..e453bc4f0de4 100644
--- a/include/uapi/drm/lima_drm.h
+++ b/include/uapi/drm/lima_drm.h
@@ -1,6 +1,5 @@
-/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com>
- * SPDX-License-Identifier: MIT
- */
+/* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */
+/* Copyright 2017-2018 Qiang Yu <yuq825@gmail.com> */
#ifndef __LIMA_DRM_H__
#define __LIMA_DRM_H__
--
2.17.1

View file

@ -0,0 +1,33 @@
From c578aadd5ccfe5c64f628ef3aa8c7ff88600e421 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Tue, 19 Jun 2018 13:51:17 +0800
Subject: [PATCH 072/146] drm/fourcc: add ARM tiled format modifier
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
include/uapi/drm/drm_fourcc.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 721ab7e54d96..097d9faca608 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -581,6 +581,15 @@ extern "C" {
*/
#define AFBC_FORMAT_MOD_SC (1ULL << 9)
+/*
+ * ARM tiled format
+ *
+ * This is used by ARM Mali Utgard/Midgard GPU. It divides buffer into
+ * 16x16 pixel blocks. Blocks are stored linearly in order, but pixels
+ * in the block are reordered.
+ */
+#define DRM_FORMAT_MOD_ARM_TILED fourcc_mod_code(ARM, 1)
+
#if defined(__cplusplus)
}
#endif
--
2.17.1

View file

@ -0,0 +1,172 @@
From e0cc638d05b59eb60cd268106d883e1913c62de5 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Tue, 19 Jun 2018 22:22:09 +0800
Subject: [PATCH 073/146] drm/lima: add DRM_LIMA_GEM_MOD ioctl
Used to share buffer format across processes.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_drv.c | 13 ++++++++++++
drivers/gpu/drm/lima/lima_gem.c | 32 ++++++++++++++++++++++++++++++
drivers/gpu/drm/lima/lima_gem.h | 2 ++
drivers/gpu/drm/lima/lima_object.c | 2 ++
drivers/gpu/drm/lima/lima_object.h | 2 ++
include/uapi/drm/lima_drm.h | 11 ++++++++++
6 files changed, 62 insertions(+)
diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c
index e7004e4e1853..536d0d442970 100644
--- a/drivers/gpu/drm/lima/lima_drv.c
+++ b/drivers/gpu/drm/lima/lima_drv.c
@@ -243,6 +243,18 @@ static int lima_ioctl_ctx(struct drm_device *dev, void *data, struct drm_file *f
return -EINVAL;
}
+static int lima_ioctl_gem_mod(struct drm_device *dev, void *data, struct drm_file *file)
+{
+ struct drm_lima_gem_mod *args = data;
+
+ if (args->op == LIMA_GEM_MOD_OP_GET)
+ return lima_gem_get_modifier(file, args->handle, &args->modifier);
+ else if (args->op == LIMA_GEM_MOD_OP_SET)
+ return lima_gem_set_modifier(file, args->handle, args->modifier);
+
+ return -EINVAL;
+}
+
static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file)
{
int err;
@@ -287,6 +299,7 @@ static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = {
DRM_IOCTL_DEF_DRV(LIMA_WAIT_FENCE, lima_ioctl_wait_fence, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(LIMA_GEM_WAIT, lima_ioctl_gem_wait, DRM_AUTH|DRM_RENDER_ALLOW),
DRM_IOCTL_DEF_DRV(LIMA_CTX, lima_ioctl_ctx, DRM_AUTH|DRM_RENDER_ALLOW),
+ DRM_IOCTL_DEF_DRV(LIMA_GEM_MOD, lima_ioctl_gem_mod, DRM_AUTH|DRM_RENDER_ALLOW),
};
static const struct file_operations lima_drm_driver_fops = {
diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index ee903ce17494..02bf76113a66 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -444,3 +444,35 @@ int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns)
drm_gem_object_put_unlocked(obj);
return ret;
}
+
+int lima_gem_get_modifier(struct drm_file *file, u32 handle, u64 *modifier)
+{
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+ *modifier = bo->modifier;
+
+ drm_gem_object_put_unlocked(obj);
+ return 0;
+}
+
+int lima_gem_set_modifier(struct drm_file *file, u32 handle, u64 modifier)
+{
+ struct drm_gem_object *obj;
+ struct lima_bo *bo;
+
+ obj = drm_gem_object_lookup(file, handle);
+ if (!obj)
+ return -ENOENT;
+
+ bo = to_lima_bo(obj);
+ bo->modifier = modifier;
+
+ drm_gem_object_put_unlocked(obj);
+ return 0;
+}
diff --git a/drivers/gpu/drm/lima/lima_gem.h b/drivers/gpu/drm/lima/lima_gem.h
index 03daad9a85af..da6968fab6bb 100644
--- a/drivers/gpu/drm/lima/lima_gem.h
+++ b/drivers/gpu/drm/lima/lima_gem.h
@@ -19,5 +19,7 @@ int lima_gem_va_map(struct drm_file *file, u32 handle, u32 flags, u32 va);
int lima_gem_va_unmap(struct drm_file *file, u32 handle, u32 va);
int lima_gem_submit(struct drm_file *file, struct lima_submit *submit);
int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, u64 timeout_ns);
+int lima_gem_get_modifier(struct drm_file *file, u32 handle, u64 *modifier);
+int lima_gem_set_modifier(struct drm_file *file, u32 handle, u64 modifier);
#endif
diff --git a/drivers/gpu/drm/lima/lima_object.c b/drivers/gpu/drm/lima/lima_object.c
index c44e1f81abf8..34d9b4dc2df6 100644
--- a/drivers/gpu/drm/lima/lima_object.c
+++ b/drivers/gpu/drm/lima/lima_object.c
@@ -2,6 +2,7 @@
/* Copyright 2018 Qiang Yu <yuq825@gmail.com> */
#include <drm/drm_prime.h>
+#include <drm/drm_fourcc.h>
#include "lima_object.h"
@@ -70,6 +71,7 @@ struct lima_bo *lima_bo_create(struct lima_device *dev, u64 size,
if (err)
goto err_out;
+ bo->modifier = DRM_FORMAT_MOD_INVALID;
return bo;
err_out:
diff --git a/drivers/gpu/drm/lima/lima_object.h b/drivers/gpu/drm/lima/lima_object.h
index 7286514c0f07..f854a25637f2 100644
--- a/drivers/gpu/drm/lima/lima_object.h
+++ b/drivers/gpu/drm/lima/lima_object.h
@@ -19,6 +19,8 @@ struct lima_bo {
struct ttm_bo_kmap_obj kmap;
struct list_head va;
+
+ u64 modifier;
};
static inline struct lima_bo *
diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h
index e453bc4f0de4..77cb39af1a45 100644
--- a/include/uapi/drm/lima_drm.h
+++ b/include/uapi/drm/lima_drm.h
@@ -152,6 +152,15 @@ struct drm_lima_ctx {
__u32 id; /* in/out */
};
+#define LIMA_GEM_MOD_OP_GET 0
+#define LIMA_GEM_MOD_OP_SET 1
+
+struct drm_lima_gem_mod {
+ __u32 handle; /* in */
+ __u32 op; /* in */
+ __u64 modifier; /* in/out */
+};
+
#define DRM_LIMA_INFO 0x00
#define DRM_LIMA_GEM_CREATE 0x01
#define DRM_LIMA_GEM_INFO 0x02
@@ -160,6 +169,7 @@ struct drm_lima_ctx {
#define DRM_LIMA_WAIT_FENCE 0x05
#define DRM_LIMA_GEM_WAIT 0x06
#define DRM_LIMA_CTX 0x07
+#define DRM_LIMA_GEM_MOD 0x08
#define DRM_IOCTL_LIMA_INFO DRM_IOR(DRM_COMMAND_BASE + DRM_LIMA_INFO, struct drm_lima_info)
#define DRM_IOCTL_LIMA_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_CREATE, struct drm_lima_gem_create)
@@ -169,6 +179,7 @@ struct drm_lima_ctx {
#define DRM_IOCTL_LIMA_WAIT_FENCE DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_WAIT_FENCE, struct drm_lima_wait_fence)
#define DRM_IOCTL_LIMA_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + DRM_LIMA_GEM_WAIT, struct drm_lima_gem_wait)
#define DRM_IOCTL_LIMA_CTX DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_CTX, struct drm_lima_ctx)
+#define DRM_IOCTL_LIMA_GEM_MOD DRM_IOWR(DRM_COMMAND_BASE + DRM_LIMA_GEM_MOD, struct drm_lima_gem_mod)
#if defined(__cplusplus)
}
--
2.17.1

View file

@ -0,0 +1,58 @@
From 9c4d2eb582078788a3f115fef91824d9213e237d Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Tue, 24 Jul 2018 10:17:55 -0700
Subject: [PATCH 074/146] a64: ccu: enable LDOs for pll-mipi and add min/max
rate for it
---
drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 2 ++
drivers/clk/sunxi-ng/ccu_nkm.c | 5 +++++
drivers/clk/sunxi-ng/ccu_nkm.h | 3 +++
3 files changed, 10 insertions(+)
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
index 1fe3c3fbc9bc..7c645f2c017a 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
@@ -163,6 +163,8 @@ static struct ccu_nkm pll_mipi_clk = {
.n = _SUNXI_CCU_MULT(8, 4),
.k = _SUNXI_CCU_MULT_MIN(4, 2, 2),
.m = _SUNXI_CCU_DIV(0, 4),
+ .min_rate = 300000000,
+ .max_rate = 1400000000,
.common = {
.reg = 0x040,
.hw.init = CLK_HW_INIT("pll-mipi", "pll-video0",
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c
index 841840e35e61..01e6df4c1232 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.c
+++ b/drivers/clk/sunxi-ng/ccu_nkm.c
@@ -122,6 +122,11 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
_nkm.min_m = 1;
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
+ if (rate < nkm->min_rate)
+ rate = nkm->min_rate;
+ if (nkm->max_rate && (rate > nkm->max_rate))
+ rate = nkm->max_rate;
+
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= nkm->fixed_post_div;
diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h
index cc6efb70a102..6e01836ef122 100644
--- a/drivers/clk/sunxi-ng/ccu_nkm.h
+++ b/drivers/clk/sunxi-ng/ccu_nkm.h
@@ -36,6 +36,9 @@ struct ccu_nkm {
unsigned int fixed_post_div;
+ unsigned int min_rate;
+ unsigned int max_rate;
+
struct ccu_common common;
};
--
2.17.1

View file

@ -0,0 +1,25 @@
From 1d3ae34846fcee5e4d4ec54476c85992d03d204e Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Mon, 10 Sep 2018 16:09:30 -0700
Subject: [PATCH 075/146] sopine: baseboard: enable HS200 for eMMC
Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
index dc728b3b5556..abad307b414a 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
@@ -119,6 +119,7 @@
bus-width = <8>;
non-removable;
cap-mmc-hw-reset;
+ mmc-hs200-1_8v;
status = "okay";
};
--
2.17.1

View file

@ -0,0 +1,63 @@
From fa09957c702e5aa41c09ca452bd7220c1e8a6985 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Sun, 15 Jul 2018 11:24:41 +0800
Subject: [PATCH 076/146] drm/lima: remove depend on ARM arch
Mali GPU is used on x86-64 arch too:
https://en.wikipedia.org/wiki/Rockchip#Tablet_processors_with_integrated_modem
Always use need_dma32 as it won't cause any trouble
on 32bit arch.
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/Kconfig | 1 -
drivers/gpu/drm/lima/lima_ttm.c | 9 +--------
2 files changed, 1 insertion(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/lima/Kconfig b/drivers/gpu/drm/lima/Kconfig
index bb75bcb97ccb..89d63cca8a75 100644
--- a/drivers/gpu/drm/lima/Kconfig
+++ b/drivers/gpu/drm/lima/Kconfig
@@ -4,7 +4,6 @@
config DRM_LIMA
tristate "LIMA (DRM support for ARM Mali 400/450 GPU)"
depends on DRM
- depends on ARM || ARM64 || COMPILE_TEST
select DRM_SCHED
select DRM_TTM
help
diff --git a/drivers/gpu/drm/lima/lima_ttm.c b/drivers/gpu/drm/lima/lima_ttm.c
index a79ff0e86929..af46dd1edf43 100644
--- a/drivers/gpu/drm/lima/lima_ttm.c
+++ b/drivers/gpu/drm/lima/lima_ttm.c
@@ -333,25 +333,18 @@ static struct ttm_bo_driver lima_bo_driver = {
int lima_ttm_init(struct lima_device *dev)
{
int err;
- bool need_dma32;
u64 gtt_size;
err = lima_ttm_global_init(dev);
if (err)
return err;
-#if defined(CONFIG_ARM) && !defined(CONFIG_ARM_LPAE)
- need_dma32 = false;
-#else
- need_dma32 = true;
-#endif
-
err = ttm_bo_device_init(&dev->mman.bdev,
dev->mman.bo_global_ref.ref.object,
&lima_bo_driver,
dev->ddev->anon_inode->i_mapping,
DRM_FILE_PAGE_OFFSET,
- need_dma32);
+ true);
if (err) {
dev_err(dev->dev, "failed initializing buffer object "
"driver(%d).\n", err);
--
2.17.1

View file

@ -0,0 +1,27 @@
From 3785d95f0a1735e427c3ddf6c5f49545ff7559e9 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Sun, 15 Jul 2018 12:26:26 +0800
Subject: [PATCH 077/146] drm/lima: port to 4.18 kernel
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_sched.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_sched.c b/drivers/gpu/drm/lima/lima_sched.c
index e725e793a668..1e715e58d33b 100644
--- a/drivers/gpu/drm/lima/lima_sched.c
+++ b/drivers/gpu/drm/lima/lima_sched.c
@@ -169,8 +169,7 @@ int lima_sched_context_init(struct lima_sched_pipe *pipe,
return -ENOMEM;
mutex_init(&context->lock);
- err = drm_sched_entity_init(&pipe->base, &context->base, rq,
- lima_sched_max_tasks, guilty);
+ err = drm_sched_entity_init(&pipe->base, &context->base, rq, guilty);
if (err) {
kfree(context->fences);
context->fences = NULL;
--
2.17.1

View file

@ -0,0 +1,309 @@
From ed6a8088a598439e2cd5d1ab86389b658f19e465 Mon Sep 17 00:00:00 2001
From: Qiang Yu <yuq825@gmail.com>
Date: Wed, 15 Aug 2018 11:17:09 +0800
Subject: [PATCH 078/146] drm/lima: user can choose not to use dlbu on mali450
Signed-off-by: Qiang Yu <yuq825@gmail.com>
---
drivers/gpu/drm/lima/lima_bcast.c | 24 +++++-----
drivers/gpu/drm/lima/lima_bcast.h | 3 +-
drivers/gpu/drm/lima/lima_device.c | 5 --
drivers/gpu/drm/lima/lima_dlbu.c | 4 +-
drivers/gpu/drm/lima/lima_dlbu.h | 2 +-
drivers/gpu/drm/lima/lima_pp.c | 75 ++++++++++++++++++------------
include/uapi/drm/lima_drm.h | 9 +++-
7 files changed, 67 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/drm/lima/lima_bcast.c b/drivers/gpu/drm/lima/lima_bcast.c
index 6c2004dce648..63754f6465ea 100644
--- a/drivers/gpu/drm/lima/lima_bcast.c
+++ b/drivers/gpu/drm/lima/lima_bcast.c
@@ -11,31 +11,31 @@
#define bcast_write(reg, data) writel(data, ip->iomem + LIMA_BCAST_##reg)
#define bcast_read(reg) readl(ip->iomem + LIMA_BCAST_##reg)
-void lima_bcast_enable(struct lima_device *dev)
+void lima_bcast_enable(struct lima_device *dev, int num_pp)
{
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
struct lima_ip *ip = dev->ip + lima_ip_bcast;
- int i, mask = 0;
+ int i, mask = bcast_read(BROADCAST_MASK) & 0xffff0000;
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < num_pp; i++) {
struct lima_ip *pp = pipe->processor[i];
mask |= 1 << (pp->id - lima_ip_pp0);
}
- bcast_write(BROADCAST_MASK, (mask << 16) | mask);
- bcast_write(INTERRUPT_MASK, mask);
+ bcast_write(BROADCAST_MASK, mask);
}
-void lima_bcast_disable(struct lima_device *dev)
+int lima_bcast_init(struct lima_ip *ip)
{
- struct lima_ip *ip = dev->ip + lima_ip_bcast;
+ int i, mask = 0;
- bcast_write(BROADCAST_MASK, 0);
- bcast_write(INTERRUPT_MASK, 0);
-}
+ for (i = lima_ip_pp0; i <= lima_ip_pp7; i++) {
+ if (ip->dev->ip[i].present)
+ mask |= 1 << (i - lima_ip_pp0);
+ }
-int lima_bcast_init(struct lima_ip *ip)
-{
+ bcast_write(BROADCAST_MASK, mask << 16);
+ bcast_write(INTERRUPT_MASK, mask);
return 0;
}
diff --git a/drivers/gpu/drm/lima/lima_bcast.h b/drivers/gpu/drm/lima/lima_bcast.h
index fb8e1f318c5c..345e3e809860 100644
--- a/drivers/gpu/drm/lima/lima_bcast.h
+++ b/drivers/gpu/drm/lima/lima_bcast.h
@@ -9,7 +9,6 @@ struct lima_ip;
int lima_bcast_init(struct lima_ip *ip);
void lima_bcast_fini(struct lima_ip *ip);
-void lima_bcast_enable(struct lima_device *dev);
-void lima_bcast_disable(struct lima_device *dev);
+void lima_bcast_enable(struct lima_device *dev, int num_pp);
#endif
diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c
index c85196af8830..b88c84d796fc 100644
--- a/drivers/gpu/drm/lima/lima_device.c
+++ b/drivers/gpu/drm/lima/lima_device.c
@@ -338,11 +338,6 @@ int lima_device_init(struct lima_device *ldev)
if (err)
goto err_out6;
- if (ldev->id == lima_gpu_mali450) {
- lima_dlbu_enable(ldev);
- lima_bcast_enable(ldev);
- }
-
return 0;
err_out6:
diff --git a/drivers/gpu/drm/lima/lima_dlbu.c b/drivers/gpu/drm/lima/lima_dlbu.c
index 444a74348d5e..6697d4ddd887 100644
--- a/drivers/gpu/drm/lima/lima_dlbu.c
+++ b/drivers/gpu/drm/lima/lima_dlbu.c
@@ -12,13 +12,13 @@
#define dlbu_write(reg, data) writel(data, ip->iomem + LIMA_DLBU_##reg)
#define dlbu_read(reg) readl(ip->iomem + LIMA_DLBU_##reg)
-void lima_dlbu_enable(struct lima_device *dev)
+void lima_dlbu_enable(struct lima_device *dev, int num_pp)
{
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
struct lima_ip *ip = dev->ip + lima_ip_dlbu;
int i, mask = 0;
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < num_pp; i++) {
struct lima_ip *pp = pipe->processor[i];
mask |= 1 << (pp->id - lima_ip_pp0);
}
diff --git a/drivers/gpu/drm/lima/lima_dlbu.h b/drivers/gpu/drm/lima/lima_dlbu.h
index 6d85403fa410..60cba387cf30 100644
--- a/drivers/gpu/drm/lima/lima_dlbu.h
+++ b/drivers/gpu/drm/lima/lima_dlbu.h
@@ -7,7 +7,7 @@
struct lima_ip;
struct lima_device;
-void lima_dlbu_enable(struct lima_device *dev);
+void lima_dlbu_enable(struct lima_device *dev, int num_pp);
void lima_dlbu_disable(struct lima_device *dev);
void lima_dlbu_set_reg(struct lima_ip *ip, u32 *reg);
diff --git a/drivers/gpu/drm/lima/lima_pp.c b/drivers/gpu/drm/lima/lima_pp.c
index 29e3ddfb394b..3355895ceeba 100644
--- a/drivers/gpu/drm/lima/lima_pp.c
+++ b/drivers/gpu/drm/lima/lima_pp.c
@@ -64,8 +64,9 @@ static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data)
struct lima_ip *pp_bcast = data;
struct lima_device *dev = pp_bcast->dev;
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
+ struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame;
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < frame->num_pp; i++) {
struct lima_ip *ip = pipe->processor[i];
u32 status, state;
@@ -135,7 +136,9 @@ static int lima_pp_soft_reset_async_wait(struct lima_ip *ip)
if (ip->id == lima_ip_pp_bcast) {
struct lima_device *dev = ip->dev;
struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
- for (i = 0; i < pipe->num_processor; i++)
+ struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame;
+
+ for (i = 0; i < frame->num_pp; i++)
err |= lima_pp_soft_reset_async_wait_one(pipe->processor[i]);
}
else
@@ -145,24 +148,17 @@ static int lima_pp_soft_reset_async_wait(struct lima_ip *ip)
return err;
}
-static void lima_pp_start_task(struct lima_ip *ip, u32 *frame, u32 *wb,
- bool skip_stack_addr)
+static void lima_pp_write_frame(struct lima_ip *ip, u32 *frame, u32 *wb)
{
int i, j, n = 0;
- for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++) {
- if (skip_stack_addr && i * 4 == LIMA_PP_STACK)
- continue;
-
+ for (i = 0; i < LIMA_PP_FRAME_REG_NUM; i++)
writel(frame[i], ip->iomem + LIMA_PP_FRAME + i * 4);
- }
for (i = 0; i < 3; i++) {
for (j = 0; j < LIMA_PP_WB_REG_NUM; j++)
writel(wb[n++], ip->iomem + LIMA_PP_WB(i) + j * 4);
}
-
- pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
}
static int lima_pp_hard_reset(struct lima_ip *ip)
@@ -271,13 +267,20 @@ void lima_pp_bcast_fini(struct lima_ip *ip)
static int lima_pp_task_validate(struct lima_sched_pipe *pipe,
struct lima_sched_task *task)
{
- if (!pipe->bcast_processor) {
- struct drm_lima_m400_pp_frame *f = task->frame;
+ u32 num_pp;
- if (f->num_pp > pipe->num_processor)
- return -EINVAL;
+ if (pipe->bcast_processor) {
+ struct drm_lima_m450_pp_frame *f = task->frame;
+ num_pp = f->num_pp;
+ }
+ else {
+ struct drm_lima_m400_pp_frame *f = task->frame;
+ num_pp = f->num_pp;
}
+ if (num_pp == 0 || num_pp > pipe->num_processor)
+ return -EINVAL;
+
return 0;
}
@@ -287,23 +290,36 @@ static void lima_pp_task_run(struct lima_sched_pipe *pipe,
if (pipe->bcast_processor) {
struct drm_lima_m450_pp_frame *frame = task->frame;
struct lima_device *dev = pipe->bcast_processor->dev;
+ struct lima_ip *ip = pipe->bcast_processor;
int i;
pipe->done = 0;
- atomic_set(&pipe->task, pipe->num_processor);
+ atomic_set(&pipe->task, frame->num_pp);
- frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU;
- lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs);
+ if (frame->use_dlbu) {
+ lima_dlbu_enable(dev, frame->num_pp);
- lima_pp_soft_reset_async_wait(pipe->bcast_processor);
+ frame->frame[LIMA_PP_FRAME >> 2] = LIMA_VA_RESERVE_DLBU;
+ lima_dlbu_set_reg(dev->ip + lima_ip_dlbu, frame->dlbu_regs);
+ }
+ else
+ lima_dlbu_disable(dev);
+
+ lima_bcast_enable(dev, frame->num_pp);
+
+ lima_pp_soft_reset_async_wait(ip);
+
+ lima_pp_write_frame(ip, frame->frame, frame->wb);
- for (i = 0; i < pipe->num_processor; i++) {
+ for (i = 0; i < frame->num_pp; i++) {
struct lima_ip *ip = pipe->processor[i];
+
pp_write(STACK, frame->fragment_stack_address[i]);
+ if (!frame->use_dlbu)
+ pp_write(FRAME, frame->plbu_array_address[i]);
}
- lima_pp_start_task(pipe->bcast_processor, frame->frame,
- frame->wb, true);
+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
}
else {
struct drm_lima_m400_pp_frame *frame = task->frame;
@@ -312,15 +328,18 @@ static void lima_pp_task_run(struct lima_sched_pipe *pipe,
atomic_set(&pipe->task, frame->num_pp);
for (i = 0; i < frame->num_pp; i++) {
+ struct lima_ip *ip = pipe->processor[i];
+
frame->frame[LIMA_PP_FRAME >> 2] =
frame->plbu_array_address[i];
frame->frame[LIMA_PP_STACK >> 2] =
frame->fragment_stack_address[i];
- lima_pp_soft_reset_async_wait(pipe->processor[i]);
+ lima_pp_soft_reset_async_wait(ip);
+
+ lima_pp_write_frame(ip, frame->frame, frame->wb);
- lima_pp_start_task(pipe->processor[i], frame->frame,
- frame->wb, false);
+ pp_write(CTRL, LIMA_PP_CTRL_START_RENDERING);
}
}
}
@@ -340,14 +359,8 @@ static void lima_pp_task_error(struct lima_sched_pipe *pipe)
{
int i;
- if (pipe->bcast_processor)
- lima_bcast_disable(pipe->bcast_processor->dev);
-
for (i = 0; i < pipe->num_processor; i++)
lima_pp_hard_reset(pipe->processor[i]);
-
- if (pipe->bcast_processor)
- lima_bcast_enable(pipe->bcast_processor->dev);
}
static void lima_pp_task_mmu_error(struct lima_sched_pipe *pipe)
diff --git a/include/uapi/drm/lima_drm.h b/include/uapi/drm/lima_drm.h
index 77cb39af1a45..0c17bf693184 100644
--- a/include/uapi/drm/lima_drm.h
+++ b/include/uapi/drm/lima_drm.h
@@ -91,9 +91,14 @@ struct drm_lima_m400_pp_frame {
struct drm_lima_m450_pp_frame {
__u32 frame[LIMA_PP_FRAME_REG_NUM];
- __u32 _pad;
+ __u32 num_pp;
__u32 wb[3 * LIMA_PP_WB_REG_NUM];
- __u32 dlbu_regs[4];
+ __u32 use_dlbu;
+ __u32 _pad;
+ union {
+ __u32 plbu_array_address[8];
+ __u32 dlbu_regs[4];
+ };
__u32 fragment_stack_address[8];
};
--
2.17.1

View file

@ -0,0 +1,58 @@
From 87c27a1c822a43d8f6d7bc2bb889be2d3d80a100 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Sun, 3 Sep 2017 11:32:34 +0200
Subject: [PATCH 079/146] drm: bridge: Add audio workaround for dw_hdmi v1.32a
Allwinner SoCs with dw hdmi v1.32a seems to have an issue with manual
setting CTS value. BSP driver sets it to auto mode and that works
here too.
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 30 +++++++++++++++--------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 5971976284bf..4b08840749bd 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -424,16 +424,26 @@ static struct i2c_adapter *dw_hdmi_i2c_adapter(struct dw_hdmi *hdmi)
static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
unsigned int n)
{
- /* Must be set/cleared first */
- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
-
- /* nshift factor = 0 */
- hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
-
- hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
- HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
- hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
- hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
+ /*
+ * Manual CTS setting doesn't work correctly on Allwinner SoCs with
+ * dw hdmi v1.32a.
+ */
+ if (hdmi->version != 0x132a) {
+ /* Must be set/cleared first */
+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
+
+ /* nshift factor = 0 */
+ hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
+
+ hdmi_writeb(hdmi,
+ ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
+ HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
+ hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
+ hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
+ } else {
+ /* set automatic CTS calculation */
+ hdmi_writeb(hdmi, 0x00, HDMI_AUD_CTS3);
+ }
hdmi_writeb(hdmi, (n >> 16) & 0x0f, HDMI_AUD_N3);
hdmi_writeb(hdmi, (n >> 8) & 0xff, HDMI_AUD_N2);
--
2.17.1

View file

@ -0,0 +1,26 @@
From 02d04263581ac956a4822b02ee7ccd15aa5600af Mon Sep 17 00:00:00 2001
From: Vasily Khoruzhick <anarsoul@gmail.com>
Date: Mon, 10 Sep 2018 20:32:51 -0700
Subject: [PATCH 080/146] rtl8723bs: disable error message about failure to
alloc recvbuf
---
drivers/staging/rtl8723bs/hal/sdio_ops.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c
index d6b93e1f78d8..ecc4d1db9bbe 100644
--- a/drivers/staging/rtl8723bs/hal/sdio_ops.c
+++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c
@@ -947,7 +947,7 @@ static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size)
recv_priv = &adapter->recvpriv;
recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue);
if (!recvbuf) {
- DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
+ //DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
return NULL;
}
--
2.17.1

View file

@ -0,0 +1,178 @@
From 40fc81b67d761368566053d7498c03088adedc10 Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Thu, 10 May 2018 21:27:50 -0500
Subject: [PATCH 081/146] arm64: arch_timer: Workaround for Allwinner A64 timer
instability
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Allwinner A64 SoC is known [1] to have an unstable architectural
timer, which manifests itself most obviously in the time jumping forward
a multiple of 95 years [2][3]. This coincides with 2^56 cycles at a
timer frequency of 24 MHz, implying that the time went slightly backward
(and this was interpreted by the kernel as it jumping forward and
wrapping around past the epoch).
Further investigation revealed instability in the low bits of CNTVCT at
the point a high bit rolls over. This leads to power-of-two cycle
forward and backward jumps. (Testing shows that forward jumps are about
twice as likely as backward jumps.)
Without trapping reads to CNTVCT, a userspace program is able to read it
in a loop faster than it changes. A test program running on all 4 CPU
cores that reported jumps larger than 100 ms was run for 13.6 hours and
reported the following:
Count | Event
-------+---------------------------
9940 | jumped backward 699ms
268 | jumped backward 1398ms
1 | jumped backward 2097ms
16020 | jumped forward 175ms
6443 | jumped forward 699ms
2976 | jumped forward 1398ms
9 | jumped forward 356516ms
9 | jumped forward 357215ms
4 | jumped forward 714430ms
1 | jumped forward 3578440ms
This works out to a jump larger than 100 ms about every 5.5 seconds on
each CPU core.
The largest jump (almost an hour!) was the following sequence of reads:
0x0000007fffffffff → 0x00000093feffffff → 0x0000008000000000
Note that the middle bits don't necessarily all read as all zeroes or
all ones during the anomalous behavior; however the low 11 bits checked
by the function in this patch have never been observed with any other
value.
Also note that smaller jumps are much more common, with the smallest
backward jumps of 2048 cycles observed over 400 times per second on each
core. (Of course, this is partially due to lower bits rolling over more
frequently.) Any one of these could have caused the 95 year time skip.
Similar anomalies were observed while reading CNTPCT (after patching the
kernel to allow reads from userspace). However, the jumps are much less
frequent, and only small jumps were observed. The same program as before
(except now reading CNTPCT) observed after 72 hours:
Count | Event
-------+---------------------------
17 | jumped backward 699ms
52 | jumped forward 175ms
2831 | jumped forward 699ms
5 | jumped forward 1398ms
Acked-by: Maxime Ripard <maxime.ripard@bootlin.com>
Tested-by: Andre Przywara <andre.przywara@arm.com>
========================================================================
Because the CPU can read the CNTPCT/CNTVCT registers faster than they
change, performing two reads of the register and comparing the high bits
(like other workarounds) is not a workable solution. And because the
timer can jump both forward and backward, no pair of reads can
distinguish a good value from a bad one. The only way to guarantee a
good value from consecutive reads would be to read _three_ times, and
take the middle value iff the three values are 1) individually unique
and 2) increasing. This takes at minimum 3 cycles (125 ns), or more if
an anomaly is detected.
However, since there is a distinct pattern to the bad values, we can
optimize the common case (2046/2048 of the time) to a single read by
simply ignoring values that match the pattern. This still takes no more
than 3 cycles in the worst case, and requires much less code.
[1]: https://github.com/armbian/build/commit/a08cd6fe7ae9
[2]: https://forum.armbian.com/topic/3458-a64-datetime-clock-issue/
[3]: https://irclog.whitequark.org/linux-sunxi/2018-01-26
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
drivers/clocksource/Kconfig | 11 ++++++++
drivers/clocksource/arm_arch_timer.c | 39 ++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index a11f4ba98b05..bb7fa4175954 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -364,6 +364,17 @@ config ARM64_ERRATUM_858921
The workaround will be dynamically enabled when an affected
core is detected.
+config SUN50I_A64_UNSTABLE_TIMER
+ bool "Workaround for Allwinner A64 timer instability"
+ default y
+ depends on ARM_ARCH_TIMER && ARM64 && ARCH_SUNXI
+ select ARM_ARCH_TIMER_OOL_WORKAROUND
+ help
+ This option enables a workaround for instability in the timer on
+ the Allwinner A64 SoC. The workaround will only be active if the
+ allwinner,sun50i-a64-unstable-timer property is found in the
+ timer node.
+
config ARM_GLOBAL_TIMER
bool "Support for the ARM global timer" if COMPILE_TEST
select TIMER_OF if OF
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
index d8c7f5750cdb..e10456525dda 100644
--- a/drivers/clocksource/arm_arch_timer.c
+++ b/drivers/clocksource/arm_arch_timer.c
@@ -319,6 +319,36 @@ static u64 notrace arm64_858921_read_cntvct_el0(void)
}
#endif
+#ifdef CONFIG_SUN50I_A64_UNSTABLE_TIMER
+/*
+ * The low bits of each register can transiently read as all ones or all zeroes
+ * when bit 11 or greater rolls over. Since the value can jump both backward
+ * (7ff -> 000 -> 800) and forward (7ff -> fff -> 800), it is simplest to just
+ * ignore register values with all ones or zeros in the low bits.
+ */
+static u64 notrace sun50i_a64_read_cntpct_el0(void)
+{
+ u64 val;
+
+ do {
+ val = read_sysreg(cntpct_el0);
+ } while (((val + 1) & GENMASK(10, 0)) <= 1);
+
+ return val;
+}
+
+static u64 notrace sun50i_a64_read_cntvct_el0(void)
+{
+ u64 val;
+
+ do {
+ val = read_sysreg(cntvct_el0);
+ } while (((val + 1) & GENMASK(10, 0)) <= 1);
+
+ return val;
+}
+#endif
+
#ifdef CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND
DEFINE_PER_CPU(const struct arch_timer_erratum_workaround *, timer_unstable_counter_workaround);
EXPORT_SYMBOL_GPL(timer_unstable_counter_workaround);
@@ -408,6 +438,15 @@ static const struct arch_timer_erratum_workaround ool_workarounds[] = {
.read_cntvct_el0 = arm64_858921_read_cntvct_el0,
},
#endif
+#ifdef CONFIG_SUN50I_A64_UNSTABLE_TIMER
+ {
+ .match_type = ate_match_dt,
+ .id = "allwinner,sun50i-a64-unstable-timer",
+ .desc = "Allwinner A64 timer instability",
+ .read_cntpct_el0 = sun50i_a64_read_cntpct_el0,
+ .read_cntvct_el0 = sun50i_a64_read_cntvct_el0,
+ },
+#endif
};
typedef bool (*ate_match_fn_t)(const struct arch_timer_erratum_workaround *,
--
2.17.1

View file

@ -0,0 +1,30 @@
From a740ecc40aa9df18fbfb12925c1b7600c043a3cd Mon Sep 17 00:00:00 2001
From: Samuel Holland <samuel@sholland.org>
Date: Thu, 10 May 2018 21:27:51 -0500
Subject: [PATCH 082/146] arm64: dts: allwinner: a64: Enable A64 timer
workaround
As instability in the architectural timer has been observed on multiple
devices using this SoC, inluding the Pine64 and the Orange Pi Win,
enable the workaround in the SoC's device tree.
Signed-off-by: Samuel Holland <samuel@sholland.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index 62b880f68d6a..73f7e69755f8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -281,6 +281,7 @@
timer {
compatible = "arm,armv8-timer";
+ allwinner,sun50i-a64-unstable-timer;
interrupts = <GIC_PPI 13
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
<GIC_PPI 14
--
2.17.1

View file

@ -1,3 +1,20 @@
From a977683c5364eb855601b152e20bd7b45f157874 Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Thu, 9 Aug 2018 18:52:13 +0200
Subject: [PATCH 083/146] clk: sunxi-ng: Add maximum rate constraint to NM PLLs
On some NM PLLs, frequency can be set above PLL working range.
Add a constraint for maximum supported rate. This way, drivers can
specify which is maximum allowed rate for PLL.
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
drivers/clk/sunxi-ng/ccu_nm.c | 7 +++++++
drivers/clk/sunxi-ng/ccu_nm.h | 30 ++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c diff --git a/drivers/clk/sunxi-ng/ccu_nm.c b/drivers/clk/sunxi-ng/ccu_nm.c
index 4e2073307f34..6fe3c14f7b2d 100644 index 4e2073307f34..6fe3c14f7b2d 100644
--- a/drivers/clk/sunxi-ng/ccu_nm.c --- a/drivers/clk/sunxi-ng/ccu_nm.c
@ -64,3 +81,6 @@ index 1d8b459c50b7..de232f2199a6 100644
#define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \ #define SUNXI_CCU_NM_WITH_GATE_LOCK(_struct, _name, _parent, _reg, \
_nshift, _nwidth, \ _nshift, _nwidth, \
_mshift, _mwidth, \ _mshift, _mwidth, \
--
2.17.1

View file

@ -1,3 +1,27 @@
From 461aa98f7ee6d5347625728949d51122ee92999b Mon Sep 17 00:00:00 2001
From: Jernej Skrabec <jernej.skrabec@siol.net>
Date: Thu, 9 Aug 2018 18:52:14 +0200
Subject: [PATCH 084/146] clk: sunxi-ng: h3/h5: Add max. rate constraint to
pll-video
As it turns out, pll-video can be set to higher rate that it is really
supported by HW.
For example, one monitor requested 185.58 MHz pixel clock. Clock
framework calculated that minimum rate error would be when pll-video
is set to 2040 MHz. This is clearly out of specs.
Both H3 and H5 user manuals specify 600 MHz as maximum supported rate.
However, BSP clock drivers allow up to 912 MHz and 1008 MHz
respectively. Here 912 MHz is chosen because user manuals were already
proven wrong once for lower limits.
Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c b/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
index 77ed0b0ba681..eb5c608428fa 100644 index 77ed0b0ba681..eb5c608428fa 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c --- a/drivers/clk/sunxi-ng/ccu-sun8i-h3.c
@ -34,3 +58,6 @@ index 77ed0b0ba681..eb5c608428fa 100644
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve", static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
"osc24M", 0x0018, "osc24M", 0x0018,
--
2.17.1

Some files were not shown because too many files have changed in this diff Show more