mirror of
				https://github.com/Ysurac/openmptcprouter.git
				synced 2025-03-09 15:40:20 +00:00 
			
		
		
		
	Fix RPI5 support
This commit is contained in:
		
							parent
							
								
									57beb2ec60
								
							
						
					
					
						commit
						3743692973
					
				
					 1017 changed files with 232368 additions and 4124 deletions
				
			
		
							
								
								
									
										208
									
								
								6.1/package/firmware/linux-firmware/broadcom.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										208
									
								
								6.1/package/firmware/linux-firmware/broadcom.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,208 @@
 | 
			
		|||
Package/brcmfmac-firmware-4339-sdio = $(call Package/firmware-default,Broadcom 4339 FullMAC SDIO firmware)
 | 
			
		||||
define Package/brcmfmac-firmware-4339-sdio/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/cypress
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/cypress/cyfmac4339-sdio.bin \
 | 
			
		||||
		$(1)/lib/firmware/cypress/
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		../cypress/cyfmac4339-sdio.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac4339-sdio.bin
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-firmware-4339-sdio))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-firmware-43602a1-pcie = $(call Package/firmware-default,Broadcom 43602a1 FullMAC PCIe firmware)
 | 
			
		||||
define Package/brcmfmac-firmware-43602a1-pcie/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43602-pcie.ap.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43602-pcie.bin
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-firmware-43602a1-pcie))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-firmware-4366b1-pcie = $(call Package/firmware-default,Broadcom 4366b1 FullMAC PCIe firmware)
 | 
			
		||||
define Package/brcmfmac-firmware-4366b1-pcie/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac4366b-pcie.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-firmware-4366b1-pcie))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-firmware-4366c0-pcie = $(call Package/firmware-default,Broadcom 4366c0 FullMAC PCIe firmware)
 | 
			
		||||
define Package/brcmfmac-firmware-4366c0-pcie/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac4366c-pcie.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-firmware-4366c0-pcie))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-firmware-4329-sdio = $(call Package/firmware-default,Broadcom BCM4329 FullMac SDIO firmware)
 | 
			
		||||
define Package/brcmfmac-firmware-4329-sdio/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac4329-sdio.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac4329-sdio.bin
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-firmware-4329-sdio))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-nvram-43430-sdio = $(call Package/firmware-default,Broadcom BCM43430 SDIO NVRAM)
 | 
			
		||||
define Package/brcmfmac-nvram-43430-sdio/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.sinovoip,bpi-m2-plus.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.sinovoip,bpi-m2-zero.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.sinovoip,bpi-m2-ultra.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.sinovoip,bpi-m3.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.friendlyarm,nanopi-r1.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.starfive,visionfive-v1.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.beagle,beaglev-starlight-jh7100-a1.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.AP6212.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.beagle,beaglev-starlight-jh7100-r0.txt
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43430-sdio.Hampoo-D2D3_Vi8A1.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43430-sdio.MUR1DX.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43430-sdio.raspberrypi,3-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.raspberrypi,3-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,model-zero-w.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43430-sdio.raspberrypi,3-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,model-zero-2-w.txt
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-nvram-43430-sdio))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-firmware-43430a0-sdio = $(call Package/firmware-default,Broadcom BCM43430a0 FullMac SDIO firmware)
 | 
			
		||||
define Package/brcmfmac-firmware-43430a0-sdio/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43430a0-sdio.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43430a0-sdio.bin
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-firmware-43430a0-sdio))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-nvram-43455-sdio = $(call Package/firmware-default,Broadcom BCM43455 SDIO NVRAM)
 | 
			
		||||
define Package/brcmfmac-nvram-43455-sdio/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43455-sdio.acepc-t8.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,3-model-a-plus.txt
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43455-sdio.raspberrypi,4-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.raspberrypi,4-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,4-compute-module.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.raspberrypi,4-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.Raspberry\ Pi\ Foundation-Raspberry\ Pi\ 4\ Model\ B.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.raspberrypi,4-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberry,5-model-b.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.raspberrypi,4-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.Raspberry\ Pi\ Foundation-Raspberry\ Pi\ 5\ Model\ B.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.raspberrypi,4-model-b.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.Raspberry\ Pi\ Foundation-Raspberry\ Pi\ Compute\ Module\ 4.txt
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43455-sdio.MINIX-NEO\ Z83-4.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43455-sdio.AW-CM256SM.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.AW-CM256SM.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.beagle,am5729-beagleboneai.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.AW-CM256SM.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.pine64,pinebook-pro.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.AW-CM256SM.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.pine64,pinephone-pro.txt
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac43455-sdio.AW-CM256SM.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac43455-sdio.pine64,quartz64-b.txt
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-nvram-43455-sdio))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-nvram-4356-sdio = $(call Package/firmware-default,Broadcom BCM4356 SDIO NVRAM)
 | 
			
		||||
define Package/brcmfmac-nvram-4356-sdio/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac4356-sdio.AP6356S.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(LN) \
 | 
			
		||||
		brcmfmac4356-sdio.AP6356S.txt \
 | 
			
		||||
		$(1)/lib/firmware/brcm/brcmfmac4356-sdio.friendlyarm,nanopc-t4.txt
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-nvram-4356-sdio))
 | 
			
		||||
 | 
			
		||||
Package/brcmfmac-firmware-usb = $(call Package/firmware-default,Broadcom BCM43xx fullmac USB firmware)
 | 
			
		||||
define Package/brcmfmac-firmware-usb/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43236b.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/brcm/brcmfmac43143.bin \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmfmac-firmware-usb))
 | 
			
		||||
 | 
			
		||||
Package/brcmsmac-firmware = $(call Package/firmware-default,Broadcom BCM43xx softmac PCIe firmware)
 | 
			
		||||
define Package/brcmsmac-firmware/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/brcm
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx-0.fw \
 | 
			
		||||
		$(PKG_BUILD_DIR)/$(PKG_LINUX_FIRMWARE_SUBDIR)/brcm/bcm43xx_hdr-0.fw \
 | 
			
		||||
		$(1)/lib/firmware/brcm/
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,brcmsmac-firmware))
 | 
			
		||||
 | 
			
		||||
Package/bnx2-firmware = $(call Package/firmware-default,Broadcom BCM5706/5708/5709/5716 firmware)
 | 
			
		||||
define Package/bnx2-firmware/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/bnx2
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/bnx2/* \
 | 
			
		||||
		$(1)/lib/firmware/bnx2/
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,bnx2-firmware))
 | 
			
		||||
 | 
			
		||||
Package/bnx2x-firmware = $(call Package/firmware-default,=QLogic 5771x/578xx firmware)
 | 
			
		||||
define Package/bnx2x-firmware/install
 | 
			
		||||
	$(INSTALL_DIR) $(1)/lib/firmware/bnx2x
 | 
			
		||||
	$(INSTALL_DATA) \
 | 
			
		||||
		$(PKG_BUILD_DIR)/bnx2x/* \
 | 
			
		||||
		$(1)/lib/firmware/bnx2x/
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call BuildPackage,bnx2x-firmware))
 | 
			
		||||
							
								
								
									
										185
									
								
								6.1/package/kernel/bcm27xx-gpu-fw/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								6.1/package/kernel/bcm27xx-gpu-fw/Makefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,185 @@
 | 
			
		|||
include $(TOPDIR)/rules.mk
 | 
			
		||||
include $(INCLUDE_DIR)/kernel.mk
 | 
			
		||||
 | 
			
		||||
PKG_NAME:=bcm27xx-gpu-fw
 | 
			
		||||
PKG_VERSION:=2023-10-19
 | 
			
		||||
PKG_RELEASE:=ce3a0b4197eaf311ba0734efdb9f5bdedefe5e27
 | 
			
		||||
 | 
			
		||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)/rpi-firmware-$(PKG_RELEASE)
 | 
			
		||||
 | 
			
		||||
PKG_FLAGS:=nonshared
 | 
			
		||||
 | 
			
		||||
include $(INCLUDE_DIR)/package.mk
 | 
			
		||||
 | 
			
		||||
RPI_FIRMWARE_URL:=@GITHUB/raspberrypi/firmware/$(PKG_RELEASE)/boot/
 | 
			
		||||
RPI_FIRMWARE_FILE:=rpi-firmware-$(PKG_RELEASE)
 | 
			
		||||
 | 
			
		||||
define Download/LICENCE_broadcom
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-LICENCE.broadcom
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=LICENCE.broadcom
 | 
			
		||||
  HASH:=c7283ff51f863d93a275c66e3b4cb08021a5dd4d8c1e7acc47d872fbe52d3d6b
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,LICENCE_broadcom))
 | 
			
		||||
 | 
			
		||||
define Download/bootcode_bin
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-bootcode.bin
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=bootcode.bin
 | 
			
		||||
  HASH:=af603ebd97e7b692c30195563f7b25656eb05d57838cf1a715ebb470d1614ce4
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,bootcode_bin))
 | 
			
		||||
 | 
			
		||||
define Download/fixup_dat
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-fixup.dat
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=fixup.dat
 | 
			
		||||
  HASH:=c28ea955e672e374016dca61d63afa026490f0473a98115908586ab48e324aeb
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,fixup_dat))
 | 
			
		||||
 | 
			
		||||
define Download/fixup_cd_dat
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-fixup_cd.dat
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=fixup_cd.dat
 | 
			
		||||
  HASH:=3cf1aef5f596ca106203ed5dac9ad45e85929ec55ce44c813588645e174442ec
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,fixup_cd_dat))
 | 
			
		||||
 | 
			
		||||
define Download/fixup_x_dat
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-fixup_x.dat
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=fixup_x.dat
 | 
			
		||||
  HASH:=56525c8feabde1ab86f36bb09bc55171659b2993f94132cf81ffc4293d62269d
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,fixup_x_dat))
 | 
			
		||||
 | 
			
		||||
define Download/fixup4_dat
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-fixup4.dat
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=fixup4.dat
 | 
			
		||||
  HASH:=615f8595801bf52373039f73ad5ad9513f83400d355eb1b2c075c7ae907e927c
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,fixup4_dat))
 | 
			
		||||
 | 
			
		||||
define Download/fixup4cd_dat
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-fixup4cd.dat
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=fixup4cd.dat
 | 
			
		||||
  HASH:=3cf1aef5f596ca106203ed5dac9ad45e85929ec55ce44c813588645e174442ec
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,fixup4cd_dat))
 | 
			
		||||
 | 
			
		||||
define Download/fixup4x_dat
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-fixup4x.dat
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=fixup4x.dat
 | 
			
		||||
  HASH:=6d27a4b8ecb78cef9e1f03751b4aaec5ce8749d36988f381145a8a41dbf164ae
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,fixup4x_dat))
 | 
			
		||||
 | 
			
		||||
define Download/start_elf
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-start.elf
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=start.elf
 | 
			
		||||
  HASH:=e8348e88522e7a1d0e2b0944ab66d7d8f4f30da98f326e2b3c123522e45f71b2
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,start_elf))
 | 
			
		||||
 | 
			
		||||
define Download/start_cd_elf
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-start_cd.elf
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=start_cd.elf
 | 
			
		||||
  HASH:=c9b4de3f12bec7808868b898c49f656b5378ddc315f12ccab83d6519bad51680
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,start_cd_elf))
 | 
			
		||||
 | 
			
		||||
define Download/start_x_elf
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-start_x.elf
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=start_x.elf
 | 
			
		||||
  HASH:=0b5c06c109984361eeed0ab14d146f686d8aa8da2025689b887e9cb098636db9
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,start_x_elf))
 | 
			
		||||
 | 
			
		||||
define Download/start4_elf
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-start4.elf
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=start4.elf
 | 
			
		||||
  HASH:=fedc4ecd72c9d21018e210240dcd2e41a8bb5f936fb5674c3351f2a447a22203
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,start4_elf))
 | 
			
		||||
 | 
			
		||||
define Download/start4cd_elf
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-start4cd.elf
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=start4cd.elf
 | 
			
		||||
  HASH:=ea22282a77666801378137a651e7e0b17cc186f63cdbdc8b9bb98749cd12b256
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,start4cd_elf))
 | 
			
		||||
 | 
			
		||||
define Download/start4x_elf
 | 
			
		||||
  FILE:=$(RPI_FIRMWARE_FILE)-start4x.elf
 | 
			
		||||
  URL:=$(RPI_FIRMWARE_URL)
 | 
			
		||||
  URL_FILE:=start4x.elf
 | 
			
		||||
  HASH:=c509e73a9cba7af3223dea885f58294bd04845e822aa3d6278500fa4dcdb112f
 | 
			
		||||
endef
 | 
			
		||||
$(eval $(call Download,start4x_elf))
 | 
			
		||||
 | 
			
		||||
define Package/bcm27xx-gpu-fw
 | 
			
		||||
  SECTION:=boot
 | 
			
		||||
  CATEGORY:=Boot Loaders
 | 
			
		||||
  DEPENDS:=@TARGET_bcm27xx
 | 
			
		||||
  TITLE:=bcm27xx-gpu-fw
 | 
			
		||||
  DEFAULT:=y if TARGET_bcm27xx
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/bcm27xx-gpu-fw/description
 | 
			
		||||
 GPU and kernel boot firmware for bcm27xx.
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Prepare
 | 
			
		||||
	rm -rf $(PKG_BUILD_DIR)
 | 
			
		||||
	mkdir -p $(PKG_BUILD_DIR)
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-LICENCE.broadcom $(PKG_BUILD_DIR)/LICENCE.broadcom
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-bootcode.bin $(PKG_BUILD_DIR)/bootcode.bin
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup.dat $(PKG_BUILD_DIR)/fixup.dat
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup_cd.dat $(PKG_BUILD_DIR)/fixup_cd.dat
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup_x.dat $(PKG_BUILD_DIR)/fixup_x.dat
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup4.dat $(PKG_BUILD_DIR)/fixup4.dat
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup4cd.dat $(PKG_BUILD_DIR)/fixup4cd.dat
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-fixup4x.dat $(PKG_BUILD_DIR)/fixup4x.dat
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start.elf $(PKG_BUILD_DIR)/start.elf
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start_cd.elf $(PKG_BUILD_DIR)/start_cd.elf
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start_x.elf $(PKG_BUILD_DIR)/start_x.elf
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start4.elf $(PKG_BUILD_DIR)/start4.elf
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start4cd.elf $(PKG_BUILD_DIR)/start4cd.elf
 | 
			
		||||
	$(CP) $(DL_DIR)/$(RPI_FIRMWARE_FILE)-start4x.elf $(PKG_BUILD_DIR)/start4x.elf
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/Compile
 | 
			
		||||
	true
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Package/bcm27xx-gpu-fw/install
 | 
			
		||||
	true
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
define Build/InstallDev
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/bootcode.bin $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/LICENCE.broadcom $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/start.elf $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/start_cd.elf $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/start_x.elf $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/start4.elf $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/start4cd.elf $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/start4x.elf $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/fixup.dat $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/fixup_cd.dat $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/fixup_x.dat $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/fixup4.dat $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/fixup4cd.dat $(KERNEL_BUILD_DIR)
 | 
			
		||||
	$(CP) $(PKG_BUILD_DIR)/fixup4x.dat $(KERNEL_BUILD_DIR)
 | 
			
		||||
endef
 | 
			
		||||
 | 
			
		||||
$(eval $(call BuildPackage,bcm27xx-gpu-fw))
 | 
			
		||||
| 
						 | 
				
			
			@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 | 
			
		|||
ARCH:=arm
 | 
			
		||||
BOARD:=bcm27xx
 | 
			
		||||
BOARDNAME:=Broadcom BCM27xx
 | 
			
		||||
FEATURES:=audio boot-part display ext4 fpu gpio rootfs-part rtc squashfs usb usbgadget
 | 
			
		||||
FEATURES:=audio boot-part display ext4 fpu gpio rootfs-part rtc squashfs usb usbgadget pci pcie
 | 
			
		||||
SUBTARGETS:=bcm2708 bcm2709 bcm2710 bcm2711 bcm2712
 | 
			
		||||
 | 
			
		||||
KERNEL_PATCHVER:=6.1
 | 
			
		||||
| 
						 | 
				
			
			@ -24,9 +24,9 @@ DEFAULT_PACKAGES := $(filter-out urngd,$(DEFAULT_PACKAGES))
 | 
			
		|||
DEFAULT_PACKAGES += \
 | 
			
		||||
	bcm27xx-gpu-fw \
 | 
			
		||||
	kmod-usb-hid \
 | 
			
		||||
	kmod-sound-core kmod-sound-arm-bcm2835 \
 | 
			
		||||
	kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 \
 | 
			
		||||
	partx-utils mkf2fs e2fsprogs
 | 
			
		||||
#	kmod-sound-core kmod-sound-arm-bcm2835 \
 | 
			
		||||
 | 
			
		||||
KERNELNAME:=Image dtbs
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										35
									
								
								6.1/target/linux/bcm27xx/base-files/etc/board.d/02_network
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								6.1/target/linux/bcm27xx/base-files/etc/board.d/02_network
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,35 @@
 | 
			
		|||
# Copyright (C) 2014-2016 OpenWrt.org
 | 
			
		||||
# Copyright (C) 2017 LEDE project
 | 
			
		||||
 | 
			
		||||
. /lib/functions/uci-defaults.sh
 | 
			
		||||
. /lib/functions.sh
 | 
			
		||||
. /lib/functions/system.sh
 | 
			
		||||
 | 
			
		||||
board_config_update
 | 
			
		||||
 | 
			
		||||
board=$(board_name)
 | 
			
		||||
 | 
			
		||||
case "$board" in
 | 
			
		||||
raspberrypi,2-model-b |\
 | 
			
		||||
raspberrypi,2-model-b-rev2 |\
 | 
			
		||||
raspberrypi,3-model-b |\
 | 
			
		||||
raspberrypi,3-model-b-plus |\
 | 
			
		||||
raspberrypi,400 |\
 | 
			
		||||
raspberrypi,4-compute-module |\
 | 
			
		||||
raspberrypi,4-model-b |\
 | 
			
		||||
raspberrypi,5-model-b |\
 | 
			
		||||
raspberrypi,model-b |\
 | 
			
		||||
raspberrypi,model-b-plus |\
 | 
			
		||||
raspberrypi,model-b-rev2)
 | 
			
		||||
	ucidef_set_interface_lan "eth0"
 | 
			
		||||
	;;
 | 
			
		||||
 | 
			
		||||
raspberrypi,model-zero-2 |\
 | 
			
		||||
raspberrypi,model-zero-w)
 | 
			
		||||
	ucidef_set_interface_lan "wlan0"
 | 
			
		||||
	;;
 | 
			
		||||
esac
 | 
			
		||||
 | 
			
		||||
board_config_flush
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
							
								
								
									
										44
									
								
								6.1/target/linux/bcm27xx/base-files/etc/diag.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								6.1/target/linux/bcm27xx/base-files/etc/diag.sh
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,44 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
# Copyright (C) 2015-2016 OpenWrt.org
 | 
			
		||||
# Copyright (C) 2017 LEDE project
 | 
			
		||||
 | 
			
		||||
. /lib/functions.sh
 | 
			
		||||
. /lib/functions/leds.sh
 | 
			
		||||
 | 
			
		||||
set_state() {
 | 
			
		||||
	case "$(board_name)" in
 | 
			
		||||
	raspberrypi,2-model-b |\
 | 
			
		||||
	raspberrypi,2-model-b-rev2 |\
 | 
			
		||||
	raspberrypi,3-model-b |\
 | 
			
		||||
	raspberrypi,3-model-b-plus |\
 | 
			
		||||
	raspberrypi,400 |\
 | 
			
		||||
	raspberrypi,4-compute-module |\
 | 
			
		||||
	raspberrypi,4-model-b |\
 | 
			
		||||
	raspberrypi,5-model-b |\
 | 
			
		||||
	raspberrypi,model-b-plus)
 | 
			
		||||
		status_led="led1"
 | 
			
		||||
		;;
 | 
			
		||||
	raspberrypi,3-compute-module |\
 | 
			
		||||
	raspberrypi,model-b |\
 | 
			
		||||
	raspberrypi,model-zero |\
 | 
			
		||||
	raspberrypi,model-zero-2 |\
 | 
			
		||||
	raspberrypi,model-zero-w)
 | 
			
		||||
		status_led="led0"
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
 | 
			
		||||
	case "$1" in
 | 
			
		||||
	preinit)
 | 
			
		||||
		status_led_blink_preinit
 | 
			
		||||
		;;
 | 
			
		||||
	failsafe)
 | 
			
		||||
		status_led_blink_failsafe
 | 
			
		||||
		;;
 | 
			
		||||
	preinit_regular)
 | 
			
		||||
		status_led_blink_preinit_regular
 | 
			
		||||
		;;
 | 
			
		||||
	done)
 | 
			
		||||
		status_led_on
 | 
			
		||||
		;;
 | 
			
		||||
	esac
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ CONFIG_APERTURE_HELPERS=y
 | 
			
		|||
CONFIG_ARCH_BCM=y
 | 
			
		||||
CONFIG_ARCH_BCM2835=y
 | 
			
		||||
CONFIG_ARCH_BINFMT_ELF_EXTRA_PHDRS=y
 | 
			
		||||
CONFIG_ARCH_BRCMSTB=y
 | 
			
		||||
CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE=y
 | 
			
		||||
CONFIG_ARCH_DMA_ADDR_T_64BIT=y
 | 
			
		||||
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 | 
			
		||||
| 
						 | 
				
			
			@ -47,28 +48,45 @@ CONFIG_ARM_AMBA=y
 | 
			
		|||
CONFIG_ARM_ARCH_TIMER=y
 | 
			
		||||
CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
 | 
			
		||||
CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND=y
 | 
			
		||||
CONFIG_ARM_BRCMSTB_AVS_CPUFREQ=y
 | 
			
		||||
CONFIG_ARM_GIC=y
 | 
			
		||||
CONFIG_ARM_GIC_V2M=y
 | 
			
		||||
CONFIG_ARM_GIC_V3=y
 | 
			
		||||
CONFIG_ARM_GIC_V3_ITS=y
 | 
			
		||||
CONFIG_ARM_GIC_V3_ITS_PCI=y
 | 
			
		||||
# CONFIG_ARM_MHU_V2 is not set
 | 
			
		||||
# CONFIG_ARM_PL172_MPMC is not set
 | 
			
		||||
CONFIG_ARM_PSCI_FW=y
 | 
			
		||||
CONFIG_ARM_RASPBERRYPI_CPUFREQ=y
 | 
			
		||||
# CONFIG_ARM_SMMU is not set
 | 
			
		||||
# CONFIG_ARM_SMMU_V3 is not set
 | 
			
		||||
CONFIG_ARM_TIMER_SP804=y
 | 
			
		||||
CONFIG_ASSOCIATIVE_ARRAY=y
 | 
			
		||||
CONFIG_AUDIT_ARCH_COMPAT_GENERIC=y
 | 
			
		||||
CONFIG_BCM2708_VCMEM=y
 | 
			
		||||
CONFIG_BCM2711_THERMAL=y
 | 
			
		||||
CONFIG_BCM2835_DEVGPIOMEM=y
 | 
			
		||||
CONFIG_BCM2712_IOMMU=y
 | 
			
		||||
CONFIG_BCM2712_MIP=y
 | 
			
		||||
CONFIG_BCM2835_MBOX=y
 | 
			
		||||
CONFIG_BCM2835_POWER=y
 | 
			
		||||
# CONFIG_BCM2835_SMI is not set
 | 
			
		||||
# CONFIG_BCM2835_THERMAL is not set
 | 
			
		||||
CONFIG_BCM2835_SMI=y
 | 
			
		||||
CONFIG_BCM2835_SMI_DEV=m
 | 
			
		||||
CONFIG_BCM2835_THERMAL=y
 | 
			
		||||
CONFIG_BCM2835_VCHIQ=y
 | 
			
		||||
# CONFIG_BCM2835_VCHIQ_MMAL is not set
 | 
			
		||||
CONFIG_BCM2835_WDT=y
 | 
			
		||||
CONFIG_BCM7038_L1_IRQ=y
 | 
			
		||||
CONFIG_BCM7120_L2_IRQ=y
 | 
			
		||||
CONFIG_BCM7XXX_PHY=y
 | 
			
		||||
CONFIG_BCMA=y
 | 
			
		||||
CONFIG_BCMA_BLOCKIO=y
 | 
			
		||||
# CONFIG_BCMA_DEBUG is not set
 | 
			
		||||
# CONFIG_BCMA_DRIVER_GMAC_CMN is not set
 | 
			
		||||
CONFIG_BCMA_DRIVER_PCI=y
 | 
			
		||||
CONFIG_BCMA_FALLBACK_SPROM=y
 | 
			
		||||
CONFIG_BCMA_HOST_PCI=y
 | 
			
		||||
CONFIG_BCMA_HOST_PCI_POSSIBLE=y
 | 
			
		||||
# CONFIG_BCMA_HOST_SOC is not set
 | 
			
		||||
CONFIG_BCMGENET=y
 | 
			
		||||
CONFIG_BCM_NET_PHYLIB=y
 | 
			
		||||
CONFIG_BCM_VCIO=y
 | 
			
		||||
| 
						 | 
				
			
			@ -76,14 +94,20 @@ CONFIG_BCM_VCIO=y
 | 
			
		|||
CONFIG_BCM_VIDEOCORE=y
 | 
			
		||||
# CONFIG_BLK_DEV_INITRD is not set
 | 
			
		||||
CONFIG_BLK_DEV_LOOP=y
 | 
			
		||||
CONFIG_BLK_DEV_NVME=y
 | 
			
		||||
CONFIG_BLK_DEV_RAM=y
 | 
			
		||||
CONFIG_BLK_DEV_RAM_COUNT=16
 | 
			
		||||
CONFIG_BLK_DEV_RAM_SIZE=4096
 | 
			
		||||
CONFIG_BLK_DEV_SD=y
 | 
			
		||||
CONFIG_BLK_MQ_PCI=y
 | 
			
		||||
CONFIG_BLK_PM=y
 | 
			
		||||
CONFIG_BRCMSTB_DPFE=y
 | 
			
		||||
CONFIG_BRCMSTB_L2_IRQ=y
 | 
			
		||||
CONFIG_BRCMSTB_MEMC=y
 | 
			
		||||
CONFIG_BRCMSTB_PM=y
 | 
			
		||||
# CONFIG_BRCMSTB_THERMAL is not set
 | 
			
		||||
CONFIG_BRCM_CHAR_DRIVERS=y
 | 
			
		||||
CONFIG_BRCM_USB_PINMAP=y
 | 
			
		||||
CONFIG_BROADCOM_PHY=y
 | 
			
		||||
CONFIG_CAVIUM_ERRATUM_22375=y
 | 
			
		||||
CONFIG_CAVIUM_ERRATUM_23154=y
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +133,8 @@ CONFIG_CMA_SIZE_SEL_MBYTES=y
 | 
			
		|||
# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
 | 
			
		||||
# CONFIG_CMA_SYSFS is not set
 | 
			
		||||
CONFIG_COMMON_CLK=y
 | 
			
		||||
CONFIG_COMMON_CLK_RP1=y
 | 
			
		||||
# CONFIG_COMMON_CLK_RP1_SDIO is not set
 | 
			
		||||
CONFIG_COMMON_CLK_XGENE=y
 | 
			
		||||
CONFIG_COMPACT_UNEVICTABLE_DEFAULT=1
 | 
			
		||||
# CONFIG_COMPAT_32BIT_TIME is not set
 | 
			
		||||
| 
						 | 
				
			
			@ -140,6 +166,9 @@ CONFIG_CPU_RMAP=y
 | 
			
		|||
CONFIG_CRC16=y
 | 
			
		||||
CONFIG_CRYPTO_AES_ARM64=y
 | 
			
		||||
CONFIG_CRYPTO_AES_ARM64_BS=y
 | 
			
		||||
CONFIG_CRYPTO_AES_ARM64_CE=y
 | 
			
		||||
CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
 | 
			
		||||
CONFIG_CRYPTO_AES_ARM64_CE_CCM=y
 | 
			
		||||
CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y
 | 
			
		||||
CONFIG_CRYPTO_CBC=y
 | 
			
		||||
CONFIG_CRYPTO_CRC32=y
 | 
			
		||||
| 
						 | 
				
			
			@ -150,23 +179,32 @@ CONFIG_CRYPTO_DRBG=y
 | 
			
		|||
CONFIG_CRYPTO_DRBG_HMAC=y
 | 
			
		||||
CONFIG_CRYPTO_DRBG_MENU=y
 | 
			
		||||
CONFIG_CRYPTO_ECB=y
 | 
			
		||||
CONFIG_CRYPTO_GHASH_ARM64_CE=y
 | 
			
		||||
CONFIG_CRYPTO_HMAC=y
 | 
			
		||||
CONFIG_CRYPTO_JITTERENTROPY=y
 | 
			
		||||
CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
 | 
			
		||||
CONFIG_CRYPTO_LIB_SHA1=y
 | 
			
		||||
CONFIG_CRYPTO_LIB_SHA256=y
 | 
			
		||||
CONFIG_CRYPTO_LIB_UTILS=y
 | 
			
		||||
# CONFIG_CRYPTO_POLYVAL_ARM64_CE is not set
 | 
			
		||||
CONFIG_CRYPTO_RNG=y
 | 
			
		||||
CONFIG_CRYPTO_RNG2=y
 | 
			
		||||
CONFIG_CRYPTO_RNG_DEFAULT=y
 | 
			
		||||
CONFIG_CRYPTO_SEQIV=y
 | 
			
		||||
CONFIG_CRYPTO_SHA1=y
 | 
			
		||||
CONFIG_CRYPTO_SHA1_ARM64_CE=y
 | 
			
		||||
CONFIG_CRYPTO_SHA256=y
 | 
			
		||||
CONFIG_CRYPTO_SHA256_ARM64=y
 | 
			
		||||
CONFIG_CRYPTO_SHA2_ARM64_CE=y
 | 
			
		||||
CONFIG_CRYPTO_SHA3=y
 | 
			
		||||
CONFIG_CRYPTO_SHA3_ARM64=y
 | 
			
		||||
CONFIG_CRYPTO_SHA512=y
 | 
			
		||||
CONFIG_CRYPTO_SHA512_ARM64=y
 | 
			
		||||
# CONFIG_CRYPTO_SM4_ARM64_CE_BLK is not set
 | 
			
		||||
# CONFIG_CRYPTO_SM4_ARM64_NEON_BLK is not set
 | 
			
		||||
CONFIG_CRYPTO_SHA512_ARM64_CE=y
 | 
			
		||||
CONFIG_CRYPTO_SM3=y
 | 
			
		||||
CONFIG_CRYPTO_SM3_ARM64_CE=y
 | 
			
		||||
CONFIG_CRYPTO_SM4=y
 | 
			
		||||
CONFIG_CRYPTO_SM4_ARM64_CE=y
 | 
			
		||||
CONFIG_CRYPTO_SM4_ARM64_CE_BLK=y
 | 
			
		||||
CONFIG_CRYPTO_XTS=y
 | 
			
		||||
CONFIG_DCACHE_WORD_ACCESS=y
 | 
			
		||||
CONFIG_DEBUG_BUGVERBOSE=y
 | 
			
		||||
| 
						 | 
				
			
			@ -182,6 +220,7 @@ CONFIG_DMA_CMA=y
 | 
			
		|||
CONFIG_DMA_DIRECT_REMAP=y
 | 
			
		||||
CONFIG_DMA_ENGINE=y
 | 
			
		||||
CONFIG_DMA_OF=y
 | 
			
		||||
CONFIG_DMA_OPS=y
 | 
			
		||||
CONFIG_DMA_SHARED_BUFFER=y
 | 
			
		||||
CONFIG_DMA_VIRTUAL_CHANNELS=y
 | 
			
		||||
CONFIG_DNOTIFY=y
 | 
			
		||||
| 
						 | 
				
			
			@ -239,6 +278,7 @@ CONFIG_GENERIC_IDLE_POLL_SETUP=y
 | 
			
		|||
CONFIG_GENERIC_IOREMAP=y
 | 
			
		||||
CONFIG_GENERIC_IRQ_CHIP=y
 | 
			
		||||
CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
 | 
			
		||||
CONFIG_GENERIC_IRQ_INJECTION=y
 | 
			
		||||
CONFIG_GENERIC_IRQ_MIGRATION=y
 | 
			
		||||
CONFIG_GENERIC_IRQ_SHOW=y
 | 
			
		||||
CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
 | 
			
		||||
| 
						 | 
				
			
			@ -255,32 +295,58 @@ CONFIG_GENERIC_SMP_IDLE_THREAD=y
 | 
			
		|||
CONFIG_GENERIC_STRNCPY_FROM_USER=y
 | 
			
		||||
CONFIG_GENERIC_STRNLEN_USER=y
 | 
			
		||||
CONFIG_GENERIC_TIME_VSYSCALL=y
 | 
			
		||||
CONFIG_GLOB=y
 | 
			
		||||
CONFIG_GPIOLIB_IRQCHIP=y
 | 
			
		||||
CONFIG_GPIO_BCM_VIRT=y
 | 
			
		||||
CONFIG_GPIO_BRCMSTB=y
 | 
			
		||||
CONFIG_GPIO_CDEV=y
 | 
			
		||||
# CONFIG_GPIO_FSM is not set
 | 
			
		||||
CONFIG_GPIO_GENERIC=y
 | 
			
		||||
CONFIG_GPIO_RASPBERRYPI_EXP=y
 | 
			
		||||
CONFIG_HARDIRQS_SW_RESEND=y
 | 
			
		||||
CONFIG_HAS_DMA=y
 | 
			
		||||
CONFIG_HAS_IOMEM=y
 | 
			
		||||
CONFIG_HAS_IOPORT_MAP=y
 | 
			
		||||
CONFIG_HOTPLUG_CPU=y
 | 
			
		||||
CONFIG_HOTPLUG_PCI=y
 | 
			
		||||
# CONFIG_HOTPLUG_PCI_CPCI is not set
 | 
			
		||||
# CONFIG_HOTPLUG_PCI_PCIE is not set
 | 
			
		||||
CONFIG_HOTPLUG_PCI_SHPC=y
 | 
			
		||||
CONFIG_HWMON=y
 | 
			
		||||
CONFIG_HW_CONSOLE=y
 | 
			
		||||
CONFIG_HW_RANDOM=y
 | 
			
		||||
CONFIG_HW_RANDOM_IPROC_RNG200=y
 | 
			
		||||
CONFIG_I2C=y
 | 
			
		||||
CONFIG_I2C_ALGOBIT=y
 | 
			
		||||
# CONFIG_I2C_BCM2708 is not set
 | 
			
		||||
CONFIG_I2C_BCM2835=y
 | 
			
		||||
CONFIG_I2C_BOARDINFO=y
 | 
			
		||||
CONFIG_I2C_BRCMSTB=y
 | 
			
		||||
CONFIG_I2C_DESIGNWARE_CORE=y
 | 
			
		||||
CONFIG_I2C_DESIGNWARE_PLATFORM=y
 | 
			
		||||
CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000
 | 
			
		||||
CONFIG_INPUT=y
 | 
			
		||||
CONFIG_INPUT_MOUSEDEV=y
 | 
			
		||||
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 | 
			
		||||
CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 | 
			
		||||
CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 | 
			
		||||
CONFIG_INPUT_RASPBERRYPI_BUTTON=y
 | 
			
		||||
CONFIG_IOMMU_API=y
 | 
			
		||||
# CONFIG_IOMMU_DEBUGFS is not set
 | 
			
		||||
# CONFIG_IOMMU_DEFAULT_DMA_LAZY is not set
 | 
			
		||||
CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
 | 
			
		||||
# CONFIG_IOMMU_DEFAULT_PASSTHROUGH is not set
 | 
			
		||||
CONFIG_IOMMU_DMA=y
 | 
			
		||||
CONFIG_IOMMU_IOVA=y
 | 
			
		||||
# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set
 | 
			
		||||
# CONFIG_IOMMU_IO_PGTABLE_DART is not set
 | 
			
		||||
# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set
 | 
			
		||||
CONFIG_IOMMU_SUPPORT=y
 | 
			
		||||
CONFIG_IRQCHIP=y
 | 
			
		||||
CONFIG_IRQ_DOMAIN=y
 | 
			
		||||
CONFIG_IRQ_DOMAIN_HIERARCHY=y
 | 
			
		||||
CONFIG_IRQ_FORCED_THREADING=y
 | 
			
		||||
CONFIG_IRQ_MSI_IOMMU=y
 | 
			
		||||
CONFIG_IRQ_WORK=y
 | 
			
		||||
CONFIG_JBD2=y
 | 
			
		||||
CONFIG_KEYS=y
 | 
			
		||||
| 
						 | 
				
			
			@ -295,6 +361,9 @@ CONFIG_LOGO=y
 | 
			
		|||
CONFIG_LOGO_LINUX_CLUT224=y
 | 
			
		||||
# CONFIG_LOGO_LINUX_MONO is not set
 | 
			
		||||
# CONFIG_LOGO_LINUX_VGA16 is not set
 | 
			
		||||
CONFIG_MACB=y
 | 
			
		||||
CONFIG_MACB_PCI=y
 | 
			
		||||
CONFIG_MACB_USE_HWSTAMP=y
 | 
			
		||||
CONFIG_MAC_PARTITION=y
 | 
			
		||||
CONFIG_MAGIC_SYSRQ=y
 | 
			
		||||
CONFIG_MAILBOX=y
 | 
			
		||||
| 
						 | 
				
			
			@ -304,11 +373,14 @@ CONFIG_MDIO_BUS=y
 | 
			
		|||
CONFIG_MDIO_DEVICE=y
 | 
			
		||||
CONFIG_MDIO_DEVRES=y
 | 
			
		||||
CONFIG_MEMFD_CREATE=y
 | 
			
		||||
CONFIG_MEMORY=y
 | 
			
		||||
CONFIG_MEMORY_ISOLATION=y
 | 
			
		||||
CONFIG_MFD_CORE=y
 | 
			
		||||
# CONFIG_MFD_RASPBERRYPI_POE_HAT is not set
 | 
			
		||||
CONFIG_MFD_RP1=y
 | 
			
		||||
# CONFIG_MFD_RPISENSE_CORE is not set
 | 
			
		||||
CONFIG_MFD_RASPBERRYPI_POE_HAT=y
 | 
			
		||||
CONFIG_MFD_SYSCON=y
 | 
			
		||||
CONFIG_MICROCHIP_PHY=y
 | 
			
		||||
CONFIG_MIGRATION=y
 | 
			
		||||
CONFIG_MMC=y
 | 
			
		||||
# CONFIG_MMC_BCM2835 is not set
 | 
			
		||||
| 
						 | 
				
			
			@ -318,13 +390,15 @@ CONFIG_MMC_BCM2835_PIO_DMA_BARRIER=2
 | 
			
		|||
CONFIG_MMC_BCM2835_SDHOST=y
 | 
			
		||||
CONFIG_MMC_BLOCK=y
 | 
			
		||||
CONFIG_MMC_BLOCK_MINORS=32
 | 
			
		||||
CONFIG_MMC_CQHCI=y
 | 
			
		||||
CONFIG_MMC_SDHCI=y
 | 
			
		||||
CONFIG_MMC_SDHCI_BRCMSTB=y
 | 
			
		||||
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
 | 
			
		||||
CONFIG_MMC_SDHCI_IPROC=y
 | 
			
		||||
CONFIG_MMC_SDHCI_OF_DWCMSHC=y
 | 
			
		||||
# CONFIG_MMC_SDHCI_PCI is not set
 | 
			
		||||
CONFIG_MMC_SDHCI_PLTFM=y
 | 
			
		||||
CONFIG_MODULES_USE_ELF_RELA=y
 | 
			
		||||
# CONFIG_MTD is not set
 | 
			
		||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
 | 
			
		||||
CONFIG_NEED_DMA_MAP_STATE=y
 | 
			
		||||
CONFIG_NEED_SG_DMA_LENGTH=y
 | 
			
		||||
| 
						 | 
				
			
			@ -339,6 +413,9 @@ CONFIG_NO_HZ_COMMON=y
 | 
			
		|||
CONFIG_NO_HZ_IDLE=y
 | 
			
		||||
CONFIG_NR_CPUS=4
 | 
			
		||||
CONFIG_NVMEM=y
 | 
			
		||||
CONFIG_NVME_CORE=y
 | 
			
		||||
# CONFIG_NVME_HWMON is not set
 | 
			
		||||
# CONFIG_NVME_MULTIPATH is not set
 | 
			
		||||
CONFIG_OF=y
 | 
			
		||||
CONFIG_OF_ADDRESS=y
 | 
			
		||||
CONFIG_OF_CONFIGFS=y
 | 
			
		||||
| 
						 | 
				
			
			@ -346,6 +423,7 @@ CONFIG_OF_DYNAMIC=y
 | 
			
		|||
CONFIG_OF_EARLY_FLATTREE=y
 | 
			
		||||
CONFIG_OF_FLATTREE=y
 | 
			
		||||
CONFIG_OF_GPIO=y
 | 
			
		||||
CONFIG_OF_IOMMU=y
 | 
			
		||||
CONFIG_OF_IRQ=y
 | 
			
		||||
CONFIG_OF_KOBJ=y
 | 
			
		||||
CONFIG_OF_MDIO=y
 | 
			
		||||
| 
						 | 
				
			
			@ -358,18 +436,38 @@ CONFIG_PAGE_SIZE_LESS_THAN_64KB=y
 | 
			
		|||
CONFIG_PARTITION_PERCPU=y
 | 
			
		||||
CONFIG_PCI=y
 | 
			
		||||
CONFIG_PCIEAER=y
 | 
			
		||||
CONFIG_PCIEAER_INJECT=y
 | 
			
		||||
CONFIG_PCIEASPM=y
 | 
			
		||||
# CONFIG_PCIEASPM_DEFAULT is not set
 | 
			
		||||
# CONFIG_PCIEASPM_PERFORMANCE is not set
 | 
			
		||||
# CONFIG_PCIEASPM_POWERSAVE is not set
 | 
			
		||||
CONFIG_PCIEASPM_POWER_SUPERSAVE=y
 | 
			
		||||
CONFIG_PCIEPORTBUS=y
 | 
			
		||||
CONFIG_PCIE_BRCMSTB=y
 | 
			
		||||
CONFIG_PCIE_DW=y
 | 
			
		||||
CONFIG_PCIE_DW_HOST=y
 | 
			
		||||
CONFIG_PCIE_DW_PLAT=y
 | 
			
		||||
CONFIG_PCIE_DW_PLAT_HOST=y
 | 
			
		||||
CONFIG_PCIE_MICROCHIP_HOST=y
 | 
			
		||||
CONFIG_PCIE_PME=y
 | 
			
		||||
CONFIG_PCI_DOMAINS=y
 | 
			
		||||
CONFIG_PCI_DOMAINS_GENERIC=y
 | 
			
		||||
CONFIG_PCI_ECAM=y
 | 
			
		||||
CONFIG_PCI_HOST_COMMON=y
 | 
			
		||||
CONFIG_PCI_HOST_GENERIC=y
 | 
			
		||||
CONFIG_PCI_MSI=y
 | 
			
		||||
CONFIG_PCI_MSI_IRQ_DOMAIN=y
 | 
			
		||||
CONFIG_PCI_STUB=y
 | 
			
		||||
CONFIG_PGTABLE_LEVELS=3
 | 
			
		||||
CONFIG_PHYLIB=y
 | 
			
		||||
CONFIG_PHYLINK=y
 | 
			
		||||
CONFIG_PHYS_ADDR_T_64BIT=y
 | 
			
		||||
# CONFIG_PHY_BRCM_SATA is not set
 | 
			
		||||
CONFIG_PHY_BRCM_USB=y
 | 
			
		||||
CONFIG_PINCTRL=y
 | 
			
		||||
CONFIG_PINCTRL_BCM2712=y
 | 
			
		||||
CONFIG_PINCTRL_BCM2835=y
 | 
			
		||||
CONFIG_PINCTRL_RP1=y
 | 
			
		||||
CONFIG_PM=y
 | 
			
		||||
CONFIG_PM_CLK=y
 | 
			
		||||
CONFIG_PM_GENERIC_DOMAINS=y
 | 
			
		||||
| 
						 | 
				
			
			@ -378,7 +476,6 @@ CONFIG_PM_GENERIC_DOMAINS_SLEEP=y
 | 
			
		|||
CONFIG_PM_OPP=y
 | 
			
		||||
CONFIG_PM_SLEEP=y
 | 
			
		||||
CONFIG_PM_SLEEP_SMP=y
 | 
			
		||||
# CONFIG_PM_USERSPACE_AUTOSLEEP is not set
 | 
			
		||||
CONFIG_POSIX_CPU_TIMERS_TASK_WORK=y
 | 
			
		||||
CONFIG_POWER_RESET=y
 | 
			
		||||
CONFIG_POWER_SUPPLY=y
 | 
			
		||||
| 
						 | 
				
			
			@ -389,12 +486,15 @@ CONFIG_PTP_1588_CLOCK=y
 | 
			
		|||
CONFIG_PTP_1588_CLOCK_OPTIONAL=y
 | 
			
		||||
CONFIG_PWM=y
 | 
			
		||||
CONFIG_PWM_BCM2835=y
 | 
			
		||||
CONFIG_PWM_BRCMSTB=y
 | 
			
		||||
CONFIG_PWM_RP1=y
 | 
			
		||||
CONFIG_PWM_SYSFS=y
 | 
			
		||||
CONFIG_QUEUED_RWLOCKS=y
 | 
			
		||||
CONFIG_QUEUED_SPINLOCKS=y
 | 
			
		||||
CONFIG_RANDSTRUCT_NONE=y
 | 
			
		||||
CONFIG_RAS=y
 | 
			
		||||
CONFIG_RASPBERRYPI_FIRMWARE=y
 | 
			
		||||
CONFIG_RASPBERRYPI_GPIOMEM=y
 | 
			
		||||
CONFIG_RASPBERRYPI_POWER=y
 | 
			
		||||
CONFIG_RATIONAL=y
 | 
			
		||||
# CONFIG_RAVE_SP_CORE is not set
 | 
			
		||||
| 
						 | 
				
			
			@ -403,6 +503,8 @@ CONFIG_REGMAP_MMIO=y
 | 
			
		|||
CONFIG_REGULATOR=y
 | 
			
		||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
 | 
			
		||||
CONFIG_REGULATOR_GPIO=y
 | 
			
		||||
CONFIG_RESET_BRCMSTB=y
 | 
			
		||||
CONFIG_RESET_BRCMSTB_RESCAL=y
 | 
			
		||||
CONFIG_RESET_CONTROLLER=y
 | 
			
		||||
CONFIG_RESET_RASPBERRYPI=y
 | 
			
		||||
CONFIG_RESET_SIMPLE=y
 | 
			
		||||
| 
						 | 
				
			
			@ -411,12 +513,19 @@ CONFIG_RODATA_FULL_DEFAULT_ENABLED=y
 | 
			
		|||
# CONFIG_RPIVID_MEM is not set
 | 
			
		||||
# CONFIG_RPI_POE_POWER is not set
 | 
			
		||||
CONFIG_RPS=y
 | 
			
		||||
CONFIG_RTC_CLASS=y
 | 
			
		||||
CONFIG_RTC_DRV_BRCMSTB=y
 | 
			
		||||
CONFIG_RTC_DRV_RPI=y
 | 
			
		||||
CONFIG_RTC_I2C_AND_SPI=y
 | 
			
		||||
CONFIG_RWSEM_SPIN_ON_OWNER=y
 | 
			
		||||
CONFIG_SCSI=y
 | 
			
		||||
CONFIG_SCSI_COMMON=y
 | 
			
		||||
# CONFIG_SCSI_LOWLEVEL is not set
 | 
			
		||||
# CONFIG_SCSI_PROC_FS is not set
 | 
			
		||||
CONFIG_SENSORS_RASPBERRYPI_HWMON=y
 | 
			
		||||
CONFIG_SENSORS_RP1_ADC=y
 | 
			
		||||
CONFIG_SERIAL_8250_BCM2835AUX=y
 | 
			
		||||
CONFIG_SERIAL_8250_BCM7271=y
 | 
			
		||||
# CONFIG_SERIAL_8250_DMA is not set
 | 
			
		||||
CONFIG_SERIAL_8250_EXTENDED=y
 | 
			
		||||
CONFIG_SERIAL_8250_FSL=y
 | 
			
		||||
| 
						 | 
				
			
			@ -431,7 +540,10 @@ CONFIG_SERIAL_MCTRL_GPIO=y
 | 
			
		|||
CONFIG_SERIAL_OF_PLATFORM=y
 | 
			
		||||
CONFIG_SG_POOL=y
 | 
			
		||||
CONFIG_SMP=y
 | 
			
		||||
CONFIG_SMSC_PHY=y
 | 
			
		||||
CONFIG_SOCK_RX_QUEUE_MAPPING=y
 | 
			
		||||
CONFIG_SOC_BRCMSTB=y
 | 
			
		||||
CONFIG_SOC_BUS=y
 | 
			
		||||
CONFIG_SOFTIRQ_ON_OWN_STACK=y
 | 
			
		||||
CONFIG_SPARSEMEM=y
 | 
			
		||||
CONFIG_SPARSEMEM_EXTREME=y
 | 
			
		||||
| 
						 | 
				
			
			@ -460,14 +572,17 @@ CONFIG_TMPFS_POSIX_ACL=y
 | 
			
		|||
CONFIG_TRACE_IRQFLAGS_NMI_SUPPORT=y
 | 
			
		||||
CONFIG_TREE_RCU=y
 | 
			
		||||
CONFIG_TREE_SRCU=y
 | 
			
		||||
# CONFIG_UACCE is not set
 | 
			
		||||
# CONFIG_UCLAMP_TASK is not set
 | 
			
		||||
CONFIG_UEVENT_HELPER_PATH=""
 | 
			
		||||
CONFIG_UNMAP_KERNEL_AT_EL0=y
 | 
			
		||||
CONFIG_USB=y
 | 
			
		||||
CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 | 
			
		||||
# CONFIG_USB_BRCMSTB is not set
 | 
			
		||||
CONFIG_USB_COMMON=y
 | 
			
		||||
CONFIG_USB_DWCOTG=y
 | 
			
		||||
CONFIG_USB_GADGET=y
 | 
			
		||||
# CONFIG_USB_HCD_BCMA is not set
 | 
			
		||||
CONFIG_USB_PCI=y
 | 
			
		||||
CONFIG_USB_PHY=y
 | 
			
		||||
CONFIG_USB_STORAGE=y
 | 
			
		||||
| 
						 | 
				
			
			@ -488,19 +603,5 @@ CONFIG_XPS=y
 | 
			
		|||
CONFIG_XZ_DEC_ARM=y
 | 
			
		||||
CONFIG_XZ_DEC_BCJ=y
 | 
			
		||||
CONFIG_ZONE_DMA32=y
 | 
			
		||||
CONFIG_INPUT_RASPBERRYPI_BUTTON=y
 | 
			
		||||
CONFIG_RASPBERRYPI_GPIOMEM=y
 | 
			
		||||
CONFIG_PINCTRL_RP1=y
 | 
			
		||||
CONFIG_MFD_RP1=y
 | 
			
		||||
CONFIG_DRM_RP1_DSI=m
 | 
			
		||||
CONFIG_DRM_RP1_DPI=m
 | 
			
		||||
CONFIG_DRM_RP1_VEC=m
 | 
			
		||||
CONFIG_COMMON_CLK_RP1=y
 | 
			
		||||
CONFIG_COMMON_CLK_RP1_SDIO=y
 | 
			
		||||
CONFIG_PWM_RP1=y
 | 
			
		||||
CONFIG_SENSORS_RP1_ADC=m
 | 
			
		||||
CONFIG_BCM2712_MIP=y
 | 
			
		||||
CONFIG_RESET_BRCMSTB=y
 | 
			
		||||
CONFIG_PHY_BRCM_USB=y
 | 
			
		||||
CONFIG_PINCTRL_BCM2712=y
 | 
			
		||||
CONFIG_GPIO_BRCMSTB=y
 | 
			
		||||
# CONFIG_SND_BCM2835_SOC_I2S is not set
 | 
			
		||||
# CONFIG_SND_BCM2835 is not set
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -193,12 +193,9 @@ define Device/rpi-5
 | 
			
		|||
	cypress-firmware-43455-sdio \
 | 
			
		||||
	brcmfmac-nvram-43455-sdio \
 | 
			
		||||
	kmod-brcmfmac wpad-basic-mbedtls \
 | 
			
		||||
	kmod-usb-net-lan78xx \
 | 
			
		||||
	kmod-r8169
 | 
			
		||||
#  IMAGE/sysupgrade.img.gz := boot-common | boot-2712 | sdcard-img | gzip | append-metadata
 | 
			
		||||
#  IMAGE/factory.img.gz := boot-common | boot-2712 | sdcard-img | gzip
 | 
			
		||||
  IMAGE/sysupgrade.img.gz := boot-common | sdcard-img | gzip | append-metadata
 | 
			
		||||
  IMAGE/factory.img.gz := boot-common | sdcard-img | gzip
 | 
			
		||||
	kmod-usb-dwc3 kmod-hwmon-pwfan kmod-usb3
 | 
			
		||||
  IMAGE/sysupgrade.img.gz := boot-common | boot-2712 | sdcard-img | gzip | append-metadata
 | 
			
		||||
  IMAGE/factory.img.gz := boot-common | boot-2712 | sdcard-img | gzip
 | 
			
		||||
endef
 | 
			
		||||
ifeq ($(SUBTARGET),bcm2712)
 | 
			
		||||
  TARGET_DEVICES += rpi-5
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,69 @@
 | 
			
		|||
From 2b0d70ec4fba339947992252c949c8cbd9be04af Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
Date: Tue, 10 Oct 2023 14:49:50 +0100
 | 
			
		||||
Subject: [PATCH] Revert "Revert "xhci: add quirk for host controllers that
 | 
			
		||||
 don't update endpoint DCS""
 | 
			
		||||
 | 
			
		||||
This reverts commit 96a0b80eb1b02e1330d525d4c866ccdfa8c67434.
 | 
			
		||||
---
 | 
			
		||||
 drivers/usb/host/xhci-pci.c  |  4 +++-
 | 
			
		||||
 drivers/usb/host/xhci-ring.c | 25 ++++++++++++++++++++++++-
 | 
			
		||||
 2 files changed, 27 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/usb/host/xhci-pci.c
 | 
			
		||||
+++ b/drivers/usb/host/xhci-pci.c
 | 
			
		||||
@@ -293,8 +293,10 @@ static void xhci_pci_quirks(struct devic
 | 
			
		||||
 			pdev->device == 0x3432)
 | 
			
		||||
 		xhci->quirks |= XHCI_BROKEN_STREAMS;
 | 
			
		||||
 
 | 
			
		||||
-	if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483)
 | 
			
		||||
+	if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) {
 | 
			
		||||
 		xhci->quirks |= XHCI_LPM_SUPPORT;
 | 
			
		||||
+		xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
 | 
			
		||||
 		pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) {
 | 
			
		||||
--- a/drivers/usb/host/xhci-ring.c
 | 
			
		||||
+++ b/drivers/usb/host/xhci-ring.c
 | 
			
		||||
@@ -592,8 +592,11 @@ static int xhci_move_dequeue_past_td(str
 | 
			
		||||
 	struct xhci_ring *ep_ring;
 | 
			
		||||
 	struct xhci_command *cmd;
 | 
			
		||||
 	struct xhci_segment *new_seg;
 | 
			
		||||
+	struct xhci_segment *halted_seg = NULL;
 | 
			
		||||
 	union xhci_trb *new_deq;
 | 
			
		||||
 	int new_cycle;
 | 
			
		||||
+	union xhci_trb *halted_trb;
 | 
			
		||||
+	int index = 0;
 | 
			
		||||
 	dma_addr_t addr;
 | 
			
		||||
 	u64 hw_dequeue;
 | 
			
		||||
 	bool cycle_found = false;
 | 
			
		||||
@@ -631,7 +634,27 @@ static int xhci_move_dequeue_past_td(str
 | 
			
		||||
 	hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id);
 | 
			
		||||
 	new_seg = ep_ring->deq_seg;
 | 
			
		||||
 	new_deq = ep_ring->dequeue;
 | 
			
		||||
-	new_cycle = hw_dequeue & 0x1;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Quirk: xHC write-back of the DCS field in the hardware dequeue
 | 
			
		||||
+	 * pointer is wrong - use the cycle state of the TRB pointed to by
 | 
			
		||||
+	 * the dequeue pointer.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (xhci->quirks & XHCI_EP_CTX_BROKEN_DCS &&
 | 
			
		||||
+	    !(ep->ep_state & EP_HAS_STREAMS))
 | 
			
		||||
+		halted_seg = trb_in_td(xhci, td->start_seg,
 | 
			
		||||
+				       td->first_trb, td->last_trb,
 | 
			
		||||
+				       hw_dequeue & ~0xf, false);
 | 
			
		||||
+	if (halted_seg) {
 | 
			
		||||
+		index = ((dma_addr_t)(hw_dequeue & ~0xf) - halted_seg->dma) /
 | 
			
		||||
+			 sizeof(*halted_trb);
 | 
			
		||||
+		halted_trb = &halted_seg->trbs[index];
 | 
			
		||||
+		new_cycle = halted_trb->generic.field[3] & 0x1;
 | 
			
		||||
+		xhci_dbg(xhci, "Endpoint DCS = %d TRB index = %d cycle = %d\n",
 | 
			
		||||
+			 (u8)(hw_dequeue & 0x1), index, new_cycle);
 | 
			
		||||
+	} else {
 | 
			
		||||
+		new_cycle = hw_dequeue & 0x1;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * We want to find the pointer, segment and cycle state of the new trb
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
From d290d16da3157fe9fa6fddff6153fd533109a3f3 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Joerg Quinten <aBUGSworstnightmare@gmail.com>
 | 
			
		||||
Date: Fri, 18 Jun 2021 13:02:29 +0200
 | 
			
		||||
Subject: [PATCH] Support RPi DPI interface in mode6 for 18-bit color
 | 
			
		||||
 | 
			
		||||
A matching media bus format was added and an overlay for using it,
 | 
			
		||||
both with FB and VC4 was added as well.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Joerg Quinten <aBUGSworstnightmare@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dpi.c | 6 ++++++
 | 
			
		||||
 1 file changed, 6 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
 | 
			
		||||
@@ -170,10 +170,16 @@ static void vc4_dpi_encoder_enable(struc
 | 
			
		||||
 				dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR,
 | 
			
		||||
 						       DPI_ORDER);
 | 
			
		||||
 				break;
 | 
			
		||||
+			case MEDIA_BUS_FMT_BGR666_1X24_CPADHI:
 | 
			
		||||
+				dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER);
 | 
			
		||||
+				fallthrough;
 | 
			
		||||
 			case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
 | 
			
		||||
 				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_2,
 | 
			
		||||
 						       DPI_FORMAT);
 | 
			
		||||
 				break;
 | 
			
		||||
+			case MEDIA_BUS_FMT_BGR666_1X18:
 | 
			
		||||
+				dpi_c |= VC4_SET_FIELD(DPI_ORDER_BGR, DPI_ORDER);
 | 
			
		||||
+				fallthrough;
 | 
			
		||||
 			case MEDIA_BUS_FMT_RGB666_1X18:
 | 
			
		||||
 				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1,
 | 
			
		||||
 						       DPI_FORMAT);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
From 378c0fb11b0a3b2fd873728379fc276f20564770 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Tue, 19 May 2020 16:20:30 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4: Add FKMS as an acceptable node for dma ranges.
 | 
			
		||||
 | 
			
		||||
Under FKMS, the firmware (via FKMS) also requires the VideoCore cache
 | 
			
		||||
aliases for image planes, as defined by the dma-ranges under /soc.
 | 
			
		||||
 | 
			
		||||
Add rpi-firmware-kms to the list of acceptable nodes to look for
 | 
			
		||||
to copy dma config from.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_drv.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_drv.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
 | 
			
		||||
@@ -276,6 +276,7 @@ static void vc4_component_unbind_all(voi
 | 
			
		||||
 static const struct of_device_id vc4_dma_range_matches[] = {
 | 
			
		||||
 	{ .compatible = "brcm,bcm2711-hvs" },
 | 
			
		||||
 	{ .compatible = "brcm,bcm2835-hvs" },
 | 
			
		||||
+	{ .compatible = "raspberrypi,rpi-firmware-kms" },
 | 
			
		||||
 	{ .compatible = "brcm,bcm2835-v3d" },
 | 
			
		||||
 	{ .compatible = "brcm,cygnus-v3d" },
 | 
			
		||||
 	{ .compatible = "brcm,vc4-v3d" },
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From fdea56559f905b8397630fedd72833ee80e8503f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 26 Oct 2020 12:38:27 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Add the 2711 HVS as a suitable DMA node
 | 
			
		||||
 | 
			
		||||
With vc4-drv node not being under /soc on Pi4, we need to
 | 
			
		||||
adopt the correct DMA parameters from a suitable sub-component.
 | 
			
		||||
Add "brcm,bcm2711-hvs" to that list of components.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_drv.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_drv.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
 | 
			
		||||
@@ -276,6 +276,7 @@ static void vc4_component_unbind_all(voi
 | 
			
		||||
 static const struct of_device_id vc4_dma_range_matches[] = {
 | 
			
		||||
 	{ .compatible = "brcm,bcm2711-hvs" },
 | 
			
		||||
 	{ .compatible = "brcm,bcm2835-hvs" },
 | 
			
		||||
+	{ .compatible = "brcm,bcm2711-hvs" },
 | 
			
		||||
 	{ .compatible = "raspberrypi,rpi-firmware-kms" },
 | 
			
		||||
 	{ .compatible = "brcm,bcm2835-v3d" },
 | 
			
		||||
 	{ .compatible = "brcm,cygnus-v3d" },
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
From 5ed2ba8530cfb805fa494f4c8a8577e3239e9198 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 12 Feb 2021 17:31:37 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Change the default DPI format to being 18bpp, not
 | 
			
		||||
 24.
 | 
			
		||||
 | 
			
		||||
DPI hasn't really been used up until now, so the default has
 | 
			
		||||
been meaningless.
 | 
			
		||||
In theory we should be able to pass the desired format for the
 | 
			
		||||
adjacent bridge chip through, but framework seems to be missing
 | 
			
		||||
for that.
 | 
			
		||||
 | 
			
		||||
As the main device to use DPI is the VGA666 or Adafruit Kippah,
 | 
			
		||||
both of which use RGB666, change the default to being RGB666 instead
 | 
			
		||||
of RGB888.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dpi.c | 4 ++--
 | 
			
		||||
 1 file changed, 2 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
 | 
			
		||||
@@ -150,8 +150,8 @@ static void vc4_dpi_encoder_enable(struc
 | 
			
		||||
 	}
 | 
			
		||||
 	drm_connector_list_iter_end(&conn_iter);
 | 
			
		||||
 
 | 
			
		||||
-	/* Default to 24bit if no connector or format found. */
 | 
			
		||||
-	dpi_c |= VC4_SET_FIELD(DPI_FORMAT_24BIT_888_RGB, DPI_FORMAT);
 | 
			
		||||
+	/* Default to 18bit if no connector or format found. */
 | 
			
		||||
+	dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, DPI_FORMAT);
 | 
			
		||||
 
 | 
			
		||||
 	if (connector) {
 | 
			
		||||
 		if (connector->display_info.num_bus_formats) {
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From 72b0f65ba954201286e99cf89583cbb0cfa2ecc6 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Thu, 7 Jan 2021 16:30:55 +0000
 | 
			
		||||
Subject: [PATCH] drm/atomic: Don't fixup modes that haven't been reset
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/drm_atomic_helper.c | 5 +++++
 | 
			
		||||
 1 file changed, 5 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/drm_atomic_helper.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_atomic_helper.c
 | 
			
		||||
@@ -443,6 +443,11 @@ mode_fixup(struct drm_atomic_state *stat
 | 
			
		||||
 		new_crtc_state =
 | 
			
		||||
 			drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);
 | 
			
		||||
 
 | 
			
		||||
+		if (!new_crtc_state->mode_changed &&
 | 
			
		||||
+		    !new_crtc_state->connectors_changed) {
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
 		/*
 | 
			
		||||
 		 * Each encoder has at most one connector (since we always steal
 | 
			
		||||
 		 * it away), so we won't call ->mode_fixup twice.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
From 30a8ce6736c11903c205b667d61e059b1510913f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
Date: Thu, 15 Jul 2021 01:07:30 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Fix timings for VEC modes
 | 
			
		||||
 | 
			
		||||
This commit fixes vertical timings of the VEC (composite output) modes
 | 
			
		||||
to accurately represent the 525-line ("NTSC") and 625-line ("PAL") ITU-R
 | 
			
		||||
standards.
 | 
			
		||||
 | 
			
		||||
Previous timings were actually defined as 502 and 601 lines, resulting
 | 
			
		||||
in non-standard 62.69 Hz and 52 Hz signals being generated,
 | 
			
		||||
respectively.
 | 
			
		||||
 | 
			
		||||
Changes to vc4_crtc.c have also been made, to make the PixelValve
 | 
			
		||||
vertical timings accurately correspond to the DRM modeline in interlaced
 | 
			
		||||
modes. The resulting VERTA/VERTB register values have been verified
 | 
			
		||||
against the reference values set by the Raspberry Pi firmware.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_crtc.c | 70 +++++++++++++++++++++-------------
 | 
			
		||||
 1 file changed, 43 insertions(+), 27 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
@@ -326,8 +326,14 @@ static void vc4_crtc_config_pv(struct dr
 | 
			
		||||
 	bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
 | 
			
		||||
 		       vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
 | 
			
		||||
 	bool is_dsi1 = vc4_encoder->type == VC4_ENCODER_TYPE_DSI1;
 | 
			
		||||
+	bool is_vec = vc4_encoder->type == VC4_ENCODER_TYPE_VEC;
 | 
			
		||||
 	u32 format = is_dsi1 ? PV_CONTROL_FORMAT_DSIV_24 : PV_CONTROL_FORMAT_24;
 | 
			
		||||
 	u8 ppc = pv_data->pixels_per_clock;
 | 
			
		||||
+
 | 
			
		||||
+	u16 vert_bp = mode->crtc_vtotal - mode->crtc_vsync_end;
 | 
			
		||||
+	u16 vert_sync = mode->crtc_vsync_end - mode->crtc_vsync_start;
 | 
			
		||||
+	u16 vert_fp = mode->crtc_vsync_start - mode->crtc_vdisplay;
 | 
			
		||||
+
 | 
			
		||||
 	bool debug_dump_regs = false;
 | 
			
		||||
 	int idx;
 | 
			
		||||
 
 | 
			
		||||
@@ -355,49 +361,59 @@ static void vc4_crtc_config_pv(struct dr
 | 
			
		||||
 		   VC4_SET_FIELD(mode->hdisplay * pixel_rep / ppc,
 | 
			
		||||
 				 PV_HORZB_HACTIVE));
 | 
			
		||||
 
 | 
			
		||||
-	CRTC_WRITE(PV_VERTA,
 | 
			
		||||
-		   VC4_SET_FIELD(mode->crtc_vtotal - mode->crtc_vsync_end +
 | 
			
		||||
-				 interlace,
 | 
			
		||||
-				 PV_VERTA_VBP) |
 | 
			
		||||
-		   VC4_SET_FIELD(mode->crtc_vsync_end - mode->crtc_vsync_start,
 | 
			
		||||
-				 PV_VERTA_VSYNC));
 | 
			
		||||
-	CRTC_WRITE(PV_VERTB,
 | 
			
		||||
-		   VC4_SET_FIELD(mode->crtc_vsync_start - mode->crtc_vdisplay,
 | 
			
		||||
-				 PV_VERTB_VFP) |
 | 
			
		||||
-		   VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
 | 
			
		||||
-
 | 
			
		||||
 	if (interlace) {
 | 
			
		||||
+		bool odd_field_first = false;
 | 
			
		||||
+		u32 field_delay = mode->htotal * pixel_rep / (2 * ppc);
 | 
			
		||||
+		u16 vert_bp_even = vert_bp;
 | 
			
		||||
+		u16 vert_fp_even = vert_fp;
 | 
			
		||||
+
 | 
			
		||||
+		if (is_vec) {
 | 
			
		||||
+			/* VEC (composite output) */
 | 
			
		||||
+			++field_delay;
 | 
			
		||||
+			if (mode->htotal == 858) {
 | 
			
		||||
+				/* 525-line mode (NTSC or PAL-M) */
 | 
			
		||||
+				odd_field_first = true;
 | 
			
		||||
+			}
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		if (odd_field_first)
 | 
			
		||||
+			++vert_fp_even;
 | 
			
		||||
+		else
 | 
			
		||||
+			++vert_bp;
 | 
			
		||||
+
 | 
			
		||||
 		CRTC_WRITE(PV_VERTA_EVEN,
 | 
			
		||||
-			   VC4_SET_FIELD(mode->crtc_vtotal -
 | 
			
		||||
-					 mode->crtc_vsync_end,
 | 
			
		||||
-					 PV_VERTA_VBP) |
 | 
			
		||||
-			   VC4_SET_FIELD(mode->crtc_vsync_end -
 | 
			
		||||
-					 mode->crtc_vsync_start,
 | 
			
		||||
-					 PV_VERTA_VSYNC));
 | 
			
		||||
+			   VC4_SET_FIELD(vert_bp_even, PV_VERTA_VBP) |
 | 
			
		||||
+			   VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC));
 | 
			
		||||
 		CRTC_WRITE(PV_VERTB_EVEN,
 | 
			
		||||
-			   VC4_SET_FIELD(mode->crtc_vsync_start -
 | 
			
		||||
-					 mode->crtc_vdisplay,
 | 
			
		||||
-					 PV_VERTB_VFP) |
 | 
			
		||||
+			   VC4_SET_FIELD(vert_fp_even, PV_VERTB_VFP) |
 | 
			
		||||
 			   VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
 | 
			
		||||
 
 | 
			
		||||
-		/* We set up first field even mode for HDMI.  VEC's
 | 
			
		||||
-		 * NTSC mode would want first field odd instead, once
 | 
			
		||||
-		 * we support it (to do so, set ODD_FIRST and put the
 | 
			
		||||
-		 * delay in VSYNCD_EVEN instead).
 | 
			
		||||
+		/* We set up first field even mode for HDMI and VEC's PAL.
 | 
			
		||||
+		 * For NTSC, we need first field odd.
 | 
			
		||||
 		 */
 | 
			
		||||
 		CRTC_WRITE(PV_V_CONTROL,
 | 
			
		||||
 			   PV_VCONTROL_CONTINUOUS |
 | 
			
		||||
 			   (is_dsi ? PV_VCONTROL_DSI : 0) |
 | 
			
		||||
 			   PV_VCONTROL_INTERLACE |
 | 
			
		||||
-			   VC4_SET_FIELD(mode->htotal * pixel_rep / (2 * ppc),
 | 
			
		||||
-					 PV_VCONTROL_ODD_DELAY));
 | 
			
		||||
-		CRTC_WRITE(PV_VSYNCD_EVEN, 0);
 | 
			
		||||
+			   (odd_field_first
 | 
			
		||||
+				   ? PV_VCONTROL_ODD_FIRST
 | 
			
		||||
+				   : VC4_SET_FIELD(field_delay,
 | 
			
		||||
+						   PV_VCONTROL_ODD_DELAY)));
 | 
			
		||||
+		CRTC_WRITE(PV_VSYNCD_EVEN,
 | 
			
		||||
+			   (odd_field_first ? field_delay : 0));
 | 
			
		||||
 	} else {
 | 
			
		||||
 		CRTC_WRITE(PV_V_CONTROL,
 | 
			
		||||
 			   PV_VCONTROL_CONTINUOUS |
 | 
			
		||||
 			   (is_dsi ? PV_VCONTROL_DSI : 0));
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	CRTC_WRITE(PV_VERTA,
 | 
			
		||||
+		   VC4_SET_FIELD(vert_bp, PV_VERTA_VBP) |
 | 
			
		||||
+		   VC4_SET_FIELD(vert_sync, PV_VERTA_VSYNC));
 | 
			
		||||
+	CRTC_WRITE(PV_VERTB,
 | 
			
		||||
+		   VC4_SET_FIELD(vert_fp, PV_VERTB_VFP) |
 | 
			
		||||
+		   VC4_SET_FIELD(mode->crtc_vdisplay, PV_VERTB_VACTIVE));
 | 
			
		||||
+
 | 
			
		||||
 	if (is_dsi)
 | 
			
		||||
 		CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,77 @@
 | 
			
		|||
From b42ffab72e99a43ca50c1cbbd981d8e60e5973a7 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
Date: Thu, 15 Jul 2021 01:07:53 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Fix definition of PAL-M mode
 | 
			
		||||
 | 
			
		||||
PAL-M is a Brazilian analog TV standard that uses a PAL-style chroma
 | 
			
		||||
subcarrier at 3.575611[888111] MHz on top of 525-line (480i60) timings.
 | 
			
		||||
This commit makes the driver actually use the proper VEC preset for this
 | 
			
		||||
mode instead of just changing PAL subcarrier frequency.
 | 
			
		||||
 | 
			
		||||
DRM mode constant names have also been changed, as they no longer
 | 
			
		||||
correspond to the "NTSC" or "PAL" terms.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_vec.c | 18 +++++++++---------
 | 
			
		||||
 1 file changed, 9 insertions(+), 9 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
@@ -69,6 +69,7 @@
 | 
			
		||||
 #define VEC_CONFIG0_STD_MASK		GENMASK(1, 0)
 | 
			
		||||
 #define VEC_CONFIG0_NTSC_STD		0
 | 
			
		||||
 #define VEC_CONFIG0_PAL_BDGHI_STD	1
 | 
			
		||||
+#define VEC_CONFIG0_PAL_M_STD		2
 | 
			
		||||
 #define VEC_CONFIG0_PAL_N_STD		3
 | 
			
		||||
 
 | 
			
		||||
 #define VEC_SCHPH			0x108
 | 
			
		||||
@@ -224,14 +225,14 @@ static const struct debugfs_reg32 vec_re
 | 
			
		||||
 	VC4_REG32(VEC_DAC_MISC),
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
-static const struct drm_display_mode ntsc_mode = {
 | 
			
		||||
+static const struct drm_display_mode drm_mode_480i = {
 | 
			
		||||
 	DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
 		 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
 | 
			
		||||
 		 480, 480 + 7, 480 + 7 + 6, 525, 0,
 | 
			
		||||
 		 DRM_MODE_FLAG_INTERLACE)
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
-static const struct drm_display_mode pal_mode = {
 | 
			
		||||
+static const struct drm_display_mode drm_mode_576i = {
 | 
			
		||||
 	DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
 		 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
 | 
			
		||||
 		 576, 576 + 4, 576 + 4 + 6, 625, 0,
 | 
			
		||||
@@ -240,25 +241,24 @@ static const struct drm_display_mode pal
 | 
			
		||||
 
 | 
			
		||||
 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
 | 
			
		||||
 	[VC4_VEC_TV_MODE_NTSC] = {
 | 
			
		||||
-		.mode = &ntsc_mode,
 | 
			
		||||
+		.mode = &drm_mode_480i,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_NTSC_J] = {
 | 
			
		||||
-		.mode = &ntsc_mode,
 | 
			
		||||
+		.mode = &drm_mode_480i,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_NTSC_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL] = {
 | 
			
		||||
-		.mode = &pal_mode,
 | 
			
		||||
+		.mode = &drm_mode_576i,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL_M] = {
 | 
			
		||||
-		.mode = &pal_mode,
 | 
			
		||||
-		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
 | 
			
		||||
-		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
 | 
			
		||||
-		.custom_freq = 0x223b61d1,
 | 
			
		||||
+		.mode = &drm_mode_480i,
 | 
			
		||||
+		.config0 = VEC_CONFIG0_PAL_M_STD,
 | 
			
		||||
+		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,148 @@
 | 
			
		|||
From 80848aa95fcdffe65cb430b362e3be1910c2a6c6 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
Date: Thu, 15 Jul 2021 01:07:58 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Add support for more analog TV standards
 | 
			
		||||
 | 
			
		||||
Add support for the following composite output modes (all of them are
 | 
			
		||||
somewhat more obscure than the previously defined ones):
 | 
			
		||||
 | 
			
		||||
- NTSC_443 - NTSC-style signal with the chroma subcarrier shifted to
 | 
			
		||||
  4.43361875 MHz (the PAL subcarrier frequency). Never used for
 | 
			
		||||
  broadcasting, but sometimes used as a hack to play NTSC content in PAL
 | 
			
		||||
  regions (e.g. on VCRs).
 | 
			
		||||
- PAL_N - PAL with alternative chroma subcarrier frequency,
 | 
			
		||||
  3.58205625 MHz. Used as a broadcast standard in Argentina, Paraguay
 | 
			
		||||
  and Uruguay to fit 576i50 with colour in 6 MHz channel raster.
 | 
			
		||||
- PAL60 - 480i60 signal with PAL-style color at normal European PAL
 | 
			
		||||
  frequency. Another non-standard, non-broadcast mode, used in similar
 | 
			
		||||
  contexts as NTSC_443. Some displays support one but not the other.
 | 
			
		||||
- SECAM - French frequency-modulated analog color standard; also have
 | 
			
		||||
  been broadcast in Eastern Europe and various parts of Africa and Asia.
 | 
			
		||||
  Uses the same 576i50 timings as PAL.
 | 
			
		||||
 | 
			
		||||
Also added some comments explaining color subcarrier frequency
 | 
			
		||||
registers.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_vec.c | 63 +++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 63 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
@@ -46,6 +46,7 @@
 | 
			
		||||
 #define VEC_CONFIG0_YDEL(x)		((x) << 26)
 | 
			
		||||
 #define VEC_CONFIG0_CDEL_MASK		GENMASK(25, 24)
 | 
			
		||||
 #define VEC_CONFIG0_CDEL(x)		((x) << 24)
 | 
			
		||||
+#define VEC_CONFIG0_SECAM_STD		BIT(21)
 | 
			
		||||
 #define VEC_CONFIG0_PBPR_FIL		BIT(18)
 | 
			
		||||
 #define VEC_CONFIG0_CHROMA_GAIN_MASK	GENMASK(17, 16)
 | 
			
		||||
 #define VEC_CONFIG0_CHROMA_GAIN_UNITY	(0 << 16)
 | 
			
		||||
@@ -76,6 +77,27 @@
 | 
			
		||||
 #define VEC_SOFT_RESET			0x10c
 | 
			
		||||
 #define VEC_CLMP0_START			0x144
 | 
			
		||||
 #define VEC_CLMP0_END			0x148
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * These set the color subcarrier frequency
 | 
			
		||||
+ * if VEC_CONFIG1_CUSTOM_FREQ is enabled.
 | 
			
		||||
+ *
 | 
			
		||||
+ * VEC_FREQ1_0 contains the most significant 16-bit half-word,
 | 
			
		||||
+ * VEC_FREQ3_2 contains the least significant 16-bit half-word.
 | 
			
		||||
+ * 0x80000000 seems to be equivalent to the pixel clock
 | 
			
		||||
+ * (which itself is the VEC clock divided by 8).
 | 
			
		||||
+ *
 | 
			
		||||
+ * Reference values (with the default pixel clock of 13.5 MHz):
 | 
			
		||||
+ *
 | 
			
		||||
+ * NTSC  (3579545.[45] Hz)     - 0x21F07C1F
 | 
			
		||||
+ * PAL   (4433618.75 Hz)       - 0x2A098ACB
 | 
			
		||||
+ * PAL-M (3575611.[888111] Hz) - 0x21E6EFE3
 | 
			
		||||
+ * PAL-N (3582056.25 Hz)       - 0x21F69446
 | 
			
		||||
+ *
 | 
			
		||||
+ * NOTE: For SECAM, it is used as the Dr center frequency,
 | 
			
		||||
+ * regardless of whether VEC_CONFIG1_CUSTOM_FREQ is enabled or not;
 | 
			
		||||
+ * that is specified as 4406250 Hz, which corresponds to 0x29C71C72.
 | 
			
		||||
+ */
 | 
			
		||||
 #define VEC_FREQ3_2			0x180
 | 
			
		||||
 #define VEC_FREQ1_0			0x184
 | 
			
		||||
 
 | 
			
		||||
@@ -118,6 +140,14 @@
 | 
			
		||||
 
 | 
			
		||||
 #define VEC_INTERRUPT_CONTROL		0x190
 | 
			
		||||
 #define VEC_INTERRUPT_STATUS		0x194
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * Db center frequency for SECAM; the clock for this is the same as for
 | 
			
		||||
+ * VEC_FREQ3_2/VEC_FREQ1_0, which is used for Dr center frequency.
 | 
			
		||||
+ *
 | 
			
		||||
+ * This is specified as 4250000 Hz, which corresponds to 0x284BDA13.
 | 
			
		||||
+ * That is also the default value, so no need to set it explicitly.
 | 
			
		||||
+ */
 | 
			
		||||
 #define VEC_FCW_SECAM_B			0x198
 | 
			
		||||
 #define VEC_SECAM_GAIN_VAL		0x19c
 | 
			
		||||
 
 | 
			
		||||
@@ -187,8 +217,12 @@ encoder_to_vc4_vec(struct drm_encoder *e
 | 
			
		||||
 enum vc4_vec_tv_mode_id {
 | 
			
		||||
 	VC4_VEC_TV_MODE_NTSC,
 | 
			
		||||
 	VC4_VEC_TV_MODE_NTSC_J,
 | 
			
		||||
+	VC4_VEC_TV_MODE_NTSC_443,
 | 
			
		||||
 	VC4_VEC_TV_MODE_PAL,
 | 
			
		||||
 	VC4_VEC_TV_MODE_PAL_M,
 | 
			
		||||
+	VC4_VEC_TV_MODE_PAL_N,
 | 
			
		||||
+	VC4_VEC_TV_MODE_PAL60,
 | 
			
		||||
+	VC4_VEC_TV_MODE_SECAM,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 struct vc4_vec_tv_mode {
 | 
			
		||||
@@ -250,6 +284,13 @@ static const struct vc4_vec_tv_mode vc4_
 | 
			
		||||
 		.config0 = VEC_CONFIG0_NTSC_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
+	[VC4_VEC_TV_MODE_NTSC_443] = {
 | 
			
		||||
+		/* NTSC with PAL chroma frequency */
 | 
			
		||||
+		.mode = &drm_mode_480i,
 | 
			
		||||
+		.config0 = VEC_CONFIG0_NTSC_STD,
 | 
			
		||||
+		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
 | 
			
		||||
+		.custom_freq = 0x2a098acb,
 | 
			
		||||
+	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL] = {
 | 
			
		||||
 		.mode = &drm_mode_576i,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
 | 
			
		||||
@@ -260,6 +301,24 @@ static const struct vc4_vec_tv_mode vc4_
 | 
			
		||||
 		.config0 = VEC_CONFIG0_PAL_M_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL_N] = {
 | 
			
		||||
+		.mode = &drm_mode_576i,
 | 
			
		||||
+		.config0 = VEC_CONFIG0_PAL_N_STD,
 | 
			
		||||
+		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
+	},
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL60] = {
 | 
			
		||||
+		/* PAL-M with chroma frequency of regular PAL */
 | 
			
		||||
+		.mode = &drm_mode_480i,
 | 
			
		||||
+		.config0 = VEC_CONFIG0_PAL_M_STD,
 | 
			
		||||
+		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
 | 
			
		||||
+		.custom_freq = 0x2a098acb,
 | 
			
		||||
+	},
 | 
			
		||||
+	[VC4_VEC_TV_MODE_SECAM] = {
 | 
			
		||||
+		.mode = &drm_mode_576i,
 | 
			
		||||
+		.config0 = VEC_CONFIG0_SECAM_STD,
 | 
			
		||||
+		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
+		.custom_freq = 0x29c71c72,
 | 
			
		||||
+	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static enum drm_connector_status
 | 
			
		||||
@@ -503,8 +562,12 @@ static const struct of_device_id vc4_vec
 | 
			
		||||
 static const char * const tv_mode_names[] = {
 | 
			
		||||
 	[VC4_VEC_TV_MODE_NTSC] = "NTSC",
 | 
			
		||||
 	[VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_NTSC_443] = "NTSC-443",
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL] = "PAL",
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL_N] = "PAL-N",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL60] = "PAL60",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_SECAM] = "SECAM",
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,142 @@
 | 
			
		|||
From 29dc851079145c632f1d1b0edcefa107bd98e982 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
Date: Thu, 15 Jul 2021 01:08:01 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Allow setting the TV norm via module parameter
 | 
			
		||||
 | 
			
		||||
Similar to the ch7006 and nouveau drivers, introduce a "tv_mode" module
 | 
			
		||||
parameter that allow setting the TV norm by specifying vc4.tv_norm= on
 | 
			
		||||
the kernel command line.
 | 
			
		||||
 | 
			
		||||
If that is not specified, try inferring one of the most popular norms
 | 
			
		||||
(PAL or NTSC) from the video mode specified on the command line. On
 | 
			
		||||
Raspberry Pis, this causes the most common cases of the sdtv_mode
 | 
			
		||||
setting in config.txt to be respected.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_vec.c | 72 ++++++++++++++++++++++++++++-------
 | 
			
		||||
 1 file changed, 58 insertions(+), 14 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
@@ -67,7 +67,7 @@
 | 
			
		||||
 #define VEC_CONFIG0_YCDELAY		BIT(4)
 | 
			
		||||
 #define VEC_CONFIG0_RAMPEN		BIT(2)
 | 
			
		||||
 #define VEC_CONFIG0_YCDIS		BIT(2)
 | 
			
		||||
-#define VEC_CONFIG0_STD_MASK		GENMASK(1, 0)
 | 
			
		||||
+#define VEC_CONFIG0_STD_MASK		(VEC_CONFIG0_SECAM_STD | GENMASK(1, 0))
 | 
			
		||||
 #define VEC_CONFIG0_NTSC_STD		0
 | 
			
		||||
 #define VEC_CONFIG0_PAL_BDGHI_STD	1
 | 
			
		||||
 #define VEC_CONFIG0_PAL_M_STD		2
 | 
			
		||||
@@ -186,6 +186,8 @@
 | 
			
		||||
 #define VEC_DAC_MISC_DAC_RST_N		BIT(0)
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
+static char *vc4_vec_tv_norm;
 | 
			
		||||
+
 | 
			
		||||
 struct vc4_vec_variant {
 | 
			
		||||
 	u32 dac_config;
 | 
			
		||||
 };
 | 
			
		||||
@@ -321,6 +323,44 @@ static const struct vc4_vec_tv_mode vc4_
 | 
			
		||||
 	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static const char * const tv_mode_names[] = {
 | 
			
		||||
+	[VC4_VEC_TV_MODE_NTSC] = "NTSC",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_NTSC_443] = "NTSC-443",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL] = "PAL",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL_N] = "PAL-N",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_PAL60] = "PAL60",
 | 
			
		||||
+	[VC4_VEC_TV_MODE_SECAM] = "SECAM",
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+enum vc4_vec_tv_mode_id
 | 
			
		||||
+vc4_vec_get_default_mode(struct drm_connector *connector)
 | 
			
		||||
+{
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	if (vc4_vec_tv_norm) {
 | 
			
		||||
+		for (i = 0; i < ARRAY_SIZE(tv_mode_names); i++)
 | 
			
		||||
+			if (strcmp(vc4_vec_tv_norm, tv_mode_names[i]) == 0)
 | 
			
		||||
+				return (enum vc4_vec_tv_mode_id) i;
 | 
			
		||||
+	} else if (connector->cmdline_mode.specified &&
 | 
			
		||||
+		   ((connector->cmdline_mode.refresh_specified &&
 | 
			
		||||
+		     (connector->cmdline_mode.refresh == 25 ||
 | 
			
		||||
+		      connector->cmdline_mode.refresh == 50)) ||
 | 
			
		||||
+		    (!connector->cmdline_mode.refresh_specified &&
 | 
			
		||||
+		     (connector->cmdline_mode.yres == 288 ||
 | 
			
		||||
+		      connector->cmdline_mode.yres == 576)))) {
 | 
			
		||||
+		/*
 | 
			
		||||
+		 * no explicitly specified TV norm; use PAL if a mode that
 | 
			
		||||
+		 * looks like PAL has been specified on the command line
 | 
			
		||||
+		 */
 | 
			
		||||
+		return VC4_VEC_TV_MODE_PAL;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* in all other cases, default to NTSC */
 | 
			
		||||
+	return VC4_VEC_TV_MODE_NTSC;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static enum drm_connector_status
 | 
			
		||||
 vc4_vec_connector_detect(struct drm_connector *connector, bool force)
 | 
			
		||||
 {
 | 
			
		||||
@@ -344,10 +384,18 @@ static int vc4_vec_connector_get_modes(s
 | 
			
		||||
 	return 1;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void vc4_vec_connector_reset(struct drm_connector *connector)
 | 
			
		||||
+{
 | 
			
		||||
+	drm_atomic_helper_connector_reset(connector);
 | 
			
		||||
+	/* preserve TV standard */
 | 
			
		||||
+	if (connector->state)
 | 
			
		||||
+		connector->state->tv.mode = vc4_vec_get_default_mode(connector);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static const struct drm_connector_funcs vc4_vec_connector_funcs = {
 | 
			
		||||
 	.detect = vc4_vec_connector_detect,
 | 
			
		||||
 	.fill_modes = drm_helper_probe_single_connector_modes,
 | 
			
		||||
-	.reset = drm_atomic_helper_connector_reset,
 | 
			
		||||
+	.reset = vc4_vec_connector_reset,
 | 
			
		||||
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 | 
			
		||||
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 | 
			
		||||
 };
 | 
			
		||||
@@ -372,7 +420,7 @@ static int vc4_vec_connector_init(struct
 | 
			
		||||
 
 | 
			
		||||
 	drm_object_attach_property(&connector->base,
 | 
			
		||||
 				   dev->mode_config.tv_mode_property,
 | 
			
		||||
-				   VC4_VEC_TV_MODE_NTSC);
 | 
			
		||||
+				   vc4_vec_get_default_mode(connector));
 | 
			
		||||
 
 | 
			
		||||
 	drm_connector_attach_encoder(connector, &vec->encoder.base);
 | 
			
		||||
 
 | 
			
		||||
@@ -559,17 +607,6 @@ static const struct of_device_id vc4_vec
 | 
			
		||||
 	{ /* sentinel */ },
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
-static const char * const tv_mode_names[] = {
 | 
			
		||||
-	[VC4_VEC_TV_MODE_NTSC] = "NTSC",
 | 
			
		||||
-	[VC4_VEC_TV_MODE_NTSC_J] = "NTSC-J",
 | 
			
		||||
-	[VC4_VEC_TV_MODE_NTSC_443] = "NTSC-443",
 | 
			
		||||
-	[VC4_VEC_TV_MODE_PAL] = "PAL",
 | 
			
		||||
-	[VC4_VEC_TV_MODE_PAL_M] = "PAL-M",
 | 
			
		||||
-	[VC4_VEC_TV_MODE_PAL_N] = "PAL-N",
 | 
			
		||||
-	[VC4_VEC_TV_MODE_PAL60] = "PAL60",
 | 
			
		||||
-	[VC4_VEC_TV_MODE_SECAM] = "SECAM",
 | 
			
		||||
-};
 | 
			
		||||
-
 | 
			
		||||
 static int vc4_vec_bind(struct device *dev, struct device *master, void *data)
 | 
			
		||||
 {
 | 
			
		||||
 	struct platform_device *pdev = to_platform_device(dev);
 | 
			
		||||
@@ -650,3 +687,10 @@ struct platform_driver vc4_vec_driver =
 | 
			
		||||
 		.of_match_table = vc4_vec_dt_match,
 | 
			
		||||
 	},
 | 
			
		||||
 };
 | 
			
		||||
+
 | 
			
		||||
+module_param_named(tv_norm, vc4_vec_tv_norm, charp, 0600);
 | 
			
		||||
+MODULE_PARM_DESC(tv_norm, "Default TV norm.\n"
 | 
			
		||||
+		 "\t\tSupported: NTSC, NTSC-J, NTSC-443, PAL, PAL-M, PAL-N,\n"
 | 
			
		||||
+		 "\t\t\tPAL60, SECAM.\n"
 | 
			
		||||
+		 "\t\tDefault: PAL if a 50 Hz mode has been set via video=,\n"
 | 
			
		||||
+		 "\t\t\tNTSC otherwise");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
From 51db525c675adb41eeae0d23a8e13cbc7ce76284 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
Date: Thu, 15 Jul 2021 01:08:05 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Refactor mode checking logic
 | 
			
		||||
 | 
			
		||||
Replace drm_encoder_helper_funcs::atomic_check with
 | 
			
		||||
drm_connector_helper_funcs::atomic_check - the former is not called
 | 
			
		||||
during drm_mode_obj_set_property_ioctl(). Set crtc_state->mode_changed
 | 
			
		||||
if TV norm changes even without explicit mode change. This makes things
 | 
			
		||||
like "xrandr --output Composite-1 --set mode PAL-M" work properly.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_vec.c | 42 ++++++++++++++++++++++-------------
 | 
			
		||||
 1 file changed, 26 insertions(+), 16 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
@@ -392,6 +392,31 @@ static void vc4_vec_connector_reset(stru
 | 
			
		||||
 		connector->state->tv.mode = vc4_vec_get_default_mode(connector);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int vc4_vec_connector_atomic_check(struct drm_connector *conn,
 | 
			
		||||
+					  struct drm_atomic_state *state)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_connector_state *old_state =
 | 
			
		||||
+		drm_atomic_get_old_connector_state(state, conn);
 | 
			
		||||
+	struct drm_connector_state *new_state =
 | 
			
		||||
+		drm_atomic_get_new_connector_state(state, conn);
 | 
			
		||||
+
 | 
			
		||||
+	const struct vc4_vec_tv_mode *vec_mode =
 | 
			
		||||
+		&vc4_vec_tv_modes[new_state->tv.mode];
 | 
			
		||||
+
 | 
			
		||||
+	if (new_state->crtc) {
 | 
			
		||||
+		struct drm_crtc_state *crtc_state =
 | 
			
		||||
+			drm_atomic_get_new_crtc_state(state, new_state->crtc);
 | 
			
		||||
+
 | 
			
		||||
+		if (!drm_mode_equal(vec_mode->mode, &crtc_state->mode))
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		if (old_state->tv.mode != new_state->tv.mode)
 | 
			
		||||
+			crtc_state->mode_changed = true;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static const struct drm_connector_funcs vc4_vec_connector_funcs = {
 | 
			
		||||
 	.detect = vc4_vec_connector_detect,
 | 
			
		||||
 	.fill_modes = drm_helper_probe_single_connector_modes,
 | 
			
		||||
@@ -402,6 +427,7 @@ static const struct drm_connector_funcs
 | 
			
		||||
 
 | 
			
		||||
 static const struct drm_connector_helper_funcs vc4_vec_connector_helper_funcs = {
 | 
			
		||||
 	.get_modes = vc4_vec_connector_get_modes,
 | 
			
		||||
+	.atomic_check = vc4_vec_connector_atomic_check,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int vc4_vec_connector_init(struct drm_device *dev, struct vc4_vec *vec)
 | 
			
		||||
@@ -550,23 +576,7 @@ err_dev_exit:
 | 
			
		||||
 	drm_dev_exit(idx);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
 | 
			
		||||
-					struct drm_crtc_state *crtc_state,
 | 
			
		||||
-					struct drm_connector_state *conn_state)
 | 
			
		||||
-{
 | 
			
		||||
-	const struct vc4_vec_tv_mode *vec_mode;
 | 
			
		||||
-
 | 
			
		||||
-	vec_mode = &vc4_vec_tv_modes[conn_state->tv.mode];
 | 
			
		||||
-
 | 
			
		||||
-	if (conn_state->crtc &&
 | 
			
		||||
-	    !drm_mode_equal(vec_mode->mode, &crtc_state->adjusted_mode))
 | 
			
		||||
-		return -EINVAL;
 | 
			
		||||
-
 | 
			
		||||
-	return 0;
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
 | 
			
		||||
-	.atomic_check = vc4_vec_encoder_atomic_check,
 | 
			
		||||
 	.atomic_disable = vc4_vec_encoder_disable,
 | 
			
		||||
 	.atomic_enable = vc4_vec_encoder_enable,
 | 
			
		||||
 };
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,276 @@
 | 
			
		|||
From ef1315fc9e665d4ca9c8743ac43c7849dcd07605 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Tue, 27 Apr 2021 14:24:21 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Add support for gamma on BCM2711
 | 
			
		||||
 | 
			
		||||
BCM2711 changes from a 256 entry lookup table to a 16 point
 | 
			
		||||
piecewise linear function as the pipeline bitdepth has increased
 | 
			
		||||
to make a LUT unwieldy.
 | 
			
		||||
 | 
			
		||||
Implement a simple conversion from a 256 entry LUT that userspace
 | 
			
		||||
is likely to expect to 16 evenly spread points in the PWL. This
 | 
			
		||||
could be improved with curve fitting at a later date.
 | 
			
		||||
 | 
			
		||||
Co-developed-by: Juerg Haefliger <juergh@canonical.com>
 | 
			
		||||
Signed-off-by: Juerg Haefliger <juergh@canonical.com>
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_crtc.c | 35 ++++++++++---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_drv.h  | 28 +++++++++--
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c  | 89 ++++++++++++++++++++++++++++++++--
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_regs.h | 22 +++++++++
 | 
			
		||||
 4 files changed, 162 insertions(+), 12 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
@@ -1326,19 +1326,42 @@ int vc4_crtc_init(struct drm_device *drm
 | 
			
		||||
 
 | 
			
		||||
 	if (!vc4->is_vc5) {
 | 
			
		||||
 		drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
 | 
			
		||||
+	} else {
 | 
			
		||||
+		/* This is a lie for hvs5 which uses a 16 point PWL, but it
 | 
			
		||||
+		 * allows for something smarter than just 16 linearly spaced
 | 
			
		||||
+		 * segments. Conversion is done in vc5_hvs_update_gamma_lut.
 | 
			
		||||
+		 */
 | 
			
		||||
+		drm_mode_crtc_set_gamma_size(crtc, 256);
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
-		drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
 | 
			
		||||
+	drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
 | 
			
		||||
 
 | 
			
		||||
+	if (!vc4->is_vc5) {
 | 
			
		||||
 		/* We support CTM, but only for one CRTC at a time. It's therefore
 | 
			
		||||
 		 * implemented as private driver state in vc4_kms, not here.
 | 
			
		||||
 		 */
 | 
			
		||||
 		drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
 | 
			
		||||
-	}
 | 
			
		||||
 
 | 
			
		||||
-	for (i = 0; i < crtc->gamma_size; i++) {
 | 
			
		||||
-		vc4_crtc->lut_r[i] = i;
 | 
			
		||||
-		vc4_crtc->lut_g[i] = i;
 | 
			
		||||
-		vc4_crtc->lut_b[i] = i;
 | 
			
		||||
+		/* Initialize the VC4 gamma LUTs */
 | 
			
		||||
+		for (i = 0; i < crtc->gamma_size; i++) {
 | 
			
		||||
+			vc4_crtc->lut_r[i] = i;
 | 
			
		||||
+			vc4_crtc->lut_g[i] = i;
 | 
			
		||||
+			vc4_crtc->lut_b[i] = i;
 | 
			
		||||
+		}
 | 
			
		||||
+	} else {
 | 
			
		||||
+		/* Initialize the VC5 gamma PWL entries. Assume 12-bit pipeline,
 | 
			
		||||
+		 * evenly spread over full range.
 | 
			
		||||
+		 */
 | 
			
		||||
+		for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++) {
 | 
			
		||||
+			vc4_crtc->pwl_r[i] =
 | 
			
		||||
+				VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
 | 
			
		||||
+			vc4_crtc->pwl_g[i] =
 | 
			
		||||
+				VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
 | 
			
		||||
+			vc4_crtc->pwl_b[i] =
 | 
			
		||||
+				VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
 | 
			
		||||
+			vc4_crtc->pwl_a[i] =
 | 
			
		||||
+				VC5_HVS_SET_GAMMA_ENTRY(i << 8, i << 12, 1 << 8);
 | 
			
		||||
+		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
 #include <drm/drm_modeset_lock.h>
 | 
			
		||||
 
 | 
			
		||||
 #include "uapi/drm/vc4_drm.h"
 | 
			
		||||
+#include "vc4_regs.h"
 | 
			
		||||
 
 | 
			
		||||
 struct drm_device;
 | 
			
		||||
 struct drm_gem_object;
 | 
			
		||||
@@ -481,6 +482,17 @@ struct vc4_pv_data {
 | 
			
		||||
 	enum vc4_encoder_type encoder_types[4];
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+struct vc5_gamma_entry {
 | 
			
		||||
+	u32 x_c_terms;
 | 
			
		||||
+	u32 grad_term;
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+#define VC5_HVS_SET_GAMMA_ENTRY(x, c, g) (struct vc5_gamma_entry){	\
 | 
			
		||||
+	.x_c_terms = VC4_SET_FIELD((x), SCALER5_DSPGAMMA_OFF_X) | 	\
 | 
			
		||||
+		     VC4_SET_FIELD((c), SCALER5_DSPGAMMA_OFF_C),	\
 | 
			
		||||
+	.grad_term = (g)						\
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 struct vc4_crtc {
 | 
			
		||||
 	struct drm_crtc base;
 | 
			
		||||
 	struct platform_device *pdev;
 | 
			
		||||
@@ -490,9 +502,19 @@ struct vc4_crtc {
 | 
			
		||||
 	/* Timestamp at start of vblank irq - unaffected by lock delays. */
 | 
			
		||||
 	ktime_t t_vblank;
 | 
			
		||||
 
 | 
			
		||||
-	u8 lut_r[256];
 | 
			
		||||
-	u8 lut_g[256];
 | 
			
		||||
-	u8 lut_b[256];
 | 
			
		||||
+	union {
 | 
			
		||||
+		struct {  /* VC4 gamma LUT */
 | 
			
		||||
+			u8 lut_r[256];
 | 
			
		||||
+			u8 lut_g[256];
 | 
			
		||||
+			u8 lut_b[256];
 | 
			
		||||
+		};
 | 
			
		||||
+		struct {  /* VC5 gamma PWL entries */
 | 
			
		||||
+			struct vc5_gamma_entry pwl_r[SCALER5_DSPGAMMA_NUM_POINTS];
 | 
			
		||||
+			struct vc5_gamma_entry pwl_g[SCALER5_DSPGAMMA_NUM_POINTS];
 | 
			
		||||
+			struct vc5_gamma_entry pwl_b[SCALER5_DSPGAMMA_NUM_POINTS];
 | 
			
		||||
+			struct vc5_gamma_entry pwl_a[SCALER5_DSPGAMMA_NUM_POINTS];
 | 
			
		||||
+		};
 | 
			
		||||
+	};
 | 
			
		||||
 
 | 
			
		||||
 	struct drm_pending_vblank_event *event;
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -241,7 +241,8 @@ static void vc4_hvs_lut_load(struct vc4_
 | 
			
		||||
 static void vc4_hvs_update_gamma_lut(struct vc4_hvs *hvs,
 | 
			
		||||
 				     struct vc4_crtc *vc4_crtc)
 | 
			
		||||
 {
 | 
			
		||||
-	struct drm_crtc_state *crtc_state = vc4_crtc->base.state;
 | 
			
		||||
+	struct drm_crtc *crtc = &vc4_crtc->base;
 | 
			
		||||
+	struct drm_crtc_state *crtc_state = crtc->state;
 | 
			
		||||
 	struct drm_color_lut *lut = crtc_state->gamma_lut->data;
 | 
			
		||||
 	u32 length = drm_color_lut_size(crtc_state->gamma_lut);
 | 
			
		||||
 	u32 i;
 | 
			
		||||
@@ -255,6 +256,81 @@ static void vc4_hvs_update_gamma_lut(str
 | 
			
		||||
 	vc4_hvs_lut_load(hvs, vc4_crtc);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void vc5_hvs_write_gamma_entry(struct vc4_hvs *hvs,
 | 
			
		||||
+				      u32 offset,
 | 
			
		||||
+				      struct vc5_gamma_entry *gamma)
 | 
			
		||||
+{
 | 
			
		||||
+	HVS_WRITE(offset, gamma->x_c_terms);
 | 
			
		||||
+	HVS_WRITE(offset + 4, gamma->grad_term);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void vc5_hvs_lut_load(struct vc4_hvs *hvs,
 | 
			
		||||
+			     struct vc4_crtc *vc4_crtc)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_crtc *crtc = &vc4_crtc->base;
 | 
			
		||||
+	struct drm_crtc_state *crtc_state = crtc->state;
 | 
			
		||||
+	struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state);
 | 
			
		||||
+	u32 i;
 | 
			
		||||
+	u32 offset = SCALER5_DSPGAMMA_START +
 | 
			
		||||
+		vc4_state->assigned_channel * SCALER5_DSPGAMMA_CHAN_OFFSET;
 | 
			
		||||
+
 | 
			
		||||
+	for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
 | 
			
		||||
+		vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_r[i]);
 | 
			
		||||
+	for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
 | 
			
		||||
+		vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_g[i]);
 | 
			
		||||
+	for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
 | 
			
		||||
+		vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_b[i]);
 | 
			
		||||
+
 | 
			
		||||
+	if (vc4_state->assigned_channel == 2) {
 | 
			
		||||
+		/* Alpha only valid on channel 2 */
 | 
			
		||||
+		for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8)
 | 
			
		||||
+			vc5_hvs_write_gamma_entry(hvs, offset, &vc4_crtc->pwl_a[i]);
 | 
			
		||||
+	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void vc5_hvs_update_gamma_lut(struct vc4_hvs *hvs,
 | 
			
		||||
+				     struct vc4_crtc *vc4_crtc)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_crtc *crtc = &vc4_crtc->base;
 | 
			
		||||
+	struct drm_color_lut *lut = crtc->state->gamma_lut->data;
 | 
			
		||||
+	unsigned int step, i;
 | 
			
		||||
+	u32 start, end;
 | 
			
		||||
+
 | 
			
		||||
+#define VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl, chan)			\
 | 
			
		||||
+	start = drm_color_lut_extract(lut[i * step].chan, 12);		\
 | 
			
		||||
+	end = drm_color_lut_extract(lut[(i + 1) * step - 1].chan, 12);	\
 | 
			
		||||
+									\
 | 
			
		||||
+	/* Negative gradients not permitted by the hardware, so		\
 | 
			
		||||
+	 * flatten such points out.					\
 | 
			
		||||
+	 */								\
 | 
			
		||||
+	if (end < start)						\
 | 
			
		||||
+		end = start;						\
 | 
			
		||||
+									\
 | 
			
		||||
+	/* Assume 12bit pipeline.					\
 | 
			
		||||
+	 * X evenly spread over full range (12 bit).			\
 | 
			
		||||
+	 * C as U12.4 format.						\
 | 
			
		||||
+	 * Gradient as U4.8 format.					\
 | 
			
		||||
+	*/								\
 | 
			
		||||
+	vc4_crtc->pwl[i] =						\
 | 
			
		||||
+		VC5_HVS_SET_GAMMA_ENTRY(i << 8, start << 4,		\
 | 
			
		||||
+				((end - start) << 4) / (step - 1))
 | 
			
		||||
+
 | 
			
		||||
+	/* HVS5 has a 16 point piecewise linear function for each colour
 | 
			
		||||
+	 * channel (including alpha on channel 2) on each display channel.
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * Currently take a crude subsample of the gamma LUT, but this could
 | 
			
		||||
+	 * be improved to implement curve fitting.
 | 
			
		||||
+	 */
 | 
			
		||||
+	step = crtc->gamma_size / SCALER5_DSPGAMMA_NUM_POINTS;
 | 
			
		||||
+	for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++) {
 | 
			
		||||
+		VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl_r, red);
 | 
			
		||||
+		VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl_g, green);
 | 
			
		||||
+		VC5_HVS_UPDATE_GAMMA_ENTRY_FROM_LUT(pwl_b, blue);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	vc5_hvs_lut_load(hvs, vc4_crtc);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 u8 vc4_hvs_get_fifo_frame_count(struct vc4_hvs *hvs, unsigned int fifo)
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_device *drm = &hvs->vc4->base;
 | 
			
		||||
@@ -398,7 +474,10 @@ static int vc4_hvs_init_channel(struct v
 | 
			
		||||
 	/* Reload the LUT, since the SRAMs would have been disabled if
 | 
			
		||||
 	 * all CRTCs had SCALER_DISPBKGND_GAMMA unset at once.
 | 
			
		||||
 	 */
 | 
			
		||||
-	vc4_hvs_lut_load(hvs, vc4_crtc);
 | 
			
		||||
+	if (!vc4->is_vc5)
 | 
			
		||||
+		vc4_hvs_lut_load(hvs, vc4_crtc);
 | 
			
		||||
+	else
 | 
			
		||||
+		vc5_hvs_lut_load(hvs, vc4_crtc);
 | 
			
		||||
 
 | 
			
		||||
 	drm_dev_exit(idx);
 | 
			
		||||
 
 | 
			
		||||
@@ -628,7 +707,11 @@ void vc4_hvs_atomic_flush(struct drm_crt
 | 
			
		||||
 		u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel));
 | 
			
		||||
 
 | 
			
		||||
 		if (crtc->state->gamma_lut) {
 | 
			
		||||
-			vc4_hvs_update_gamma_lut(hvs, vc4_crtc);
 | 
			
		||||
+			if (!vc4->is_vc5)
 | 
			
		||||
+				vc4_hvs_update_gamma_lut(hvs, vc4_crtc);
 | 
			
		||||
+			else
 | 
			
		||||
+				vc5_hvs_update_gamma_lut(hvs, vc4_crtc);
 | 
			
		||||
+
 | 
			
		||||
 			dispbkgndx |= SCALER_DISPBKGND_GAMMA;
 | 
			
		||||
 		} else {
 | 
			
		||||
 			/* Unsetting DISPBKGND_GAMMA skips the gamma lut step
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_regs.h
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
 | 
			
		||||
@@ -512,6 +512,28 @@
 | 
			
		||||
 #define SCALER_DLIST_START                      0x00002000
 | 
			
		||||
 #define SCALER_DLIST_SIZE                       0x00004000
 | 
			
		||||
 
 | 
			
		||||
+/* Gamma PWL for each channel. 16 points for each of 4 colour channels (alpha
 | 
			
		||||
+ * only on channel 2). 8 bytes per entry, offsets first, then gradient:
 | 
			
		||||
+ *   Y = GRAD * X + C
 | 
			
		||||
+ *
 | 
			
		||||
+ * Values for X and C are left justified, and vary depending on the width of
 | 
			
		||||
+ * the HVS channel:
 | 
			
		||||
+ *    8-bit pipeline: X uses [31:24], C is U8.8 format, and GRAD is U4.8.
 | 
			
		||||
+ *   12-bit pipeline: X uses [31:20], C is U12.4 format, and GRAD is U4.8.
 | 
			
		||||
+ *
 | 
			
		||||
+ * The 3 HVS channels start at 0x400 offsets (ie chan 1 starts at 0x2400, and
 | 
			
		||||
+ * chan 2 at 0x2800).
 | 
			
		||||
+ */
 | 
			
		||||
+#define SCALER5_DSPGAMMA_NUM_POINTS		16
 | 
			
		||||
+#define SCALER5_DSPGAMMA_START			0x00002000
 | 
			
		||||
+#define SCALER5_DSPGAMMA_CHAN_OFFSET		0x400
 | 
			
		||||
+# define SCALER5_DSPGAMMA_OFF_X_MASK		VC4_MASK(31, 20)
 | 
			
		||||
+# define SCALER5_DSPGAMMA_OFF_X_SHIFT		20
 | 
			
		||||
+# define SCALER5_DSPGAMMA_OFF_C_MASK		VC4_MASK(15, 0)
 | 
			
		||||
+# define SCALER5_DSPGAMMA_OFF_C_SHIFT		0
 | 
			
		||||
+# define SCALER5_DSPGAMMA_GRAD_MASK		VC4_MASK(11, 0)
 | 
			
		||||
+# define SCALER5_DSPGAMMA_GRAD_SHIFT		0
 | 
			
		||||
+
 | 
			
		||||
 #define SCALER5_DLIST_START			0x00004000
 | 
			
		||||
 
 | 
			
		||||
 # define VC4_HDMI_SW_RESET_FORMAT_DETECT	BIT(1)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,122 @@
 | 
			
		|||
From 1c28783729a1b8f68d26950874a92538beafa04f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Wed, 28 Apr 2021 12:32:10 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Add debugfs node that dumps the vc5 gamma PWL
 | 
			
		||||
 entries
 | 
			
		||||
 | 
			
		||||
This helps with debugging the conversion from a 256 point gamma LUT to
 | 
			
		||||
16 point PWL entries as used by the BCM2711.
 | 
			
		||||
 | 
			
		||||
Co-developed-by: Juerg Haefliger <juergh@canonical.com>
 | 
			
		||||
Signed-off-by: Juerg Haefliger <juergh@canonical.com>
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c | 85 ++++++++++++++++++++++++++++++++++-
 | 
			
		||||
 1 file changed, 84 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -141,6 +141,85 @@ static int vc4_hvs_debugfs_dlist(struct
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int vc5_hvs_debugfs_gamma(struct seq_file *m, void *data)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_info_node *node = m->private;
 | 
			
		||||
+	struct drm_device *dev = node->minor->dev;
 | 
			
		||||
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
 | 
			
		||||
+	struct vc4_hvs *hvs = vc4->hvs;
 | 
			
		||||
+	struct drm_printer p = drm_seq_file_printer(m);
 | 
			
		||||
+	unsigned int i, chan;
 | 
			
		||||
+	u32 dispstat, dispbkgndx;
 | 
			
		||||
+
 | 
			
		||||
+	for (chan = 0; chan < SCALER_CHANNELS_COUNT; chan++) {
 | 
			
		||||
+		u32 x_c, grad;
 | 
			
		||||
+		u32 offset = SCALER5_DSPGAMMA_START +
 | 
			
		||||
+			chan * SCALER5_DSPGAMMA_CHAN_OFFSET;
 | 
			
		||||
+
 | 
			
		||||
+		dispstat = VC4_GET_FIELD(HVS_READ(SCALER_DISPSTATX(chan)),
 | 
			
		||||
+					 SCALER_DISPSTATX_MODE);
 | 
			
		||||
+		if (dispstat == SCALER_DISPSTATX_MODE_DISABLED ||
 | 
			
		||||
+		    dispstat == SCALER_DISPSTATX_MODE_EOF) {
 | 
			
		||||
+			drm_printf(&p, "HVS channel %u: Channel disabled\n", chan);
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(chan));
 | 
			
		||||
+		if (!(dispbkgndx & SCALER_DISPBKGND_GAMMA)) {
 | 
			
		||||
+			drm_printf(&p, "HVS channel %u: Gamma disabled\n", chan);
 | 
			
		||||
+			continue;
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		drm_printf(&p, "HVS channel %u:\n", chan);
 | 
			
		||||
+		drm_printf(&p, "  red:\n");
 | 
			
		||||
+		for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
 | 
			
		||||
+			x_c = HVS_READ(offset);
 | 
			
		||||
+			grad = HVS_READ(offset + 4);
 | 
			
		||||
+			drm_printf(&p, "  %08x %08x - x %u, c %u, grad %u\n",
 | 
			
		||||
+				   x_c, grad,
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
 | 
			
		||||
+				   grad);
 | 
			
		||||
+		}
 | 
			
		||||
+		drm_printf(&p, "  green:\n");
 | 
			
		||||
+		for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
 | 
			
		||||
+			x_c = HVS_READ(offset);
 | 
			
		||||
+			grad = HVS_READ(offset + 4);
 | 
			
		||||
+			drm_printf(&p, "  %08x %08x - x %u, c %u, grad %u\n",
 | 
			
		||||
+				   x_c, grad,
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
 | 
			
		||||
+				   grad);
 | 
			
		||||
+		}
 | 
			
		||||
+		drm_printf(&p, "  blue:\n");
 | 
			
		||||
+		for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
 | 
			
		||||
+			x_c = HVS_READ(offset);
 | 
			
		||||
+			grad = HVS_READ(offset + 4);
 | 
			
		||||
+			drm_printf(&p, "  %08x %08x - x %u, c %u, grad %u\n",
 | 
			
		||||
+				   x_c, grad,
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
 | 
			
		||||
+				   grad);
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
+		/* Alpha only valid on channel 2 */
 | 
			
		||||
+		if (chan != 2)
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		drm_printf(&p, "  alpha:\n");
 | 
			
		||||
+		for (i = 0; i < SCALER5_DSPGAMMA_NUM_POINTS; i++, offset += 8) {
 | 
			
		||||
+			x_c = HVS_READ(offset);
 | 
			
		||||
+			grad = HVS_READ(offset + 4);
 | 
			
		||||
+			drm_printf(&p, "  %08x %08x - x %u, c %u, grad %u\n",
 | 
			
		||||
+				   x_c, grad,
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_X),
 | 
			
		||||
+				   VC4_GET_FIELD(x_c, SCALER5_DSPGAMMA_OFF_C),
 | 
			
		||||
+				   grad);
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /* The filter kernel is composed of dwords each containing 3 9-bit
 | 
			
		||||
  * signed integers packed next to each other.
 | 
			
		||||
  */
 | 
			
		||||
@@ -833,11 +912,15 @@ int vc4_hvs_debugfs_init(struct drm_mino
 | 
			
		||||
 	if (!vc4->hvs)
 | 
			
		||||
 		return -ENODEV;
 | 
			
		||||
 
 | 
			
		||||
-	if (!vc4->is_vc5)
 | 
			
		||||
+	if (!vc4->is_vc5) {
 | 
			
		||||
 		debugfs_create_bool("hvs_load_tracker", S_IRUGO | S_IWUSR,
 | 
			
		||||
 				    minor->debugfs_root,
 | 
			
		||||
 				    &vc4->load_tracker_enabled);
 | 
			
		||||
 
 | 
			
		||||
+		vc4_debugfs_add_file(minor, "hvs_gamma", vc5_hvs_debugfs_gamma,
 | 
			
		||||
+				     NULL);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	ret = vc4_debugfs_add_file(minor, "hvs_dlists",
 | 
			
		||||
 				   vc4_hvs_debugfs_dlist, NULL);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,105 @@
 | 
			
		|||
From 3d1acc837abb35e453ca1fe88222dad8e8307f76 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
Date: Mon, 14 Jun 2021 15:28:30 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: hvs: Force modeset on gamma lut change
 | 
			
		||||
 | 
			
		||||
The HVS Gamma block can only be updated when idle, so we need to disable
 | 
			
		||||
the HVS channel when the gamma property is set in an atomic commit.
 | 
			
		||||
 | 
			
		||||
Since the pixelvalve cannot have its assigned channel halted without
 | 
			
		||||
stalling unless it's disabled as well, in our case that means forcing a
 | 
			
		||||
full disable / enable cycle on the pipeline.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_crtc.c | 17 +++++++++++++++++
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_drv.h  |  3 +++
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c  | 32 +++++++++++++++++++++++++++++++-
 | 
			
		||||
 3 files changed, 51 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
@@ -293,6 +293,23 @@ struct drm_encoder *vc4_get_crtc_encoder
 | 
			
		||||
 	return NULL;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+#define drm_for_each_connector_mask(connector, dev, connector_mask) \
 | 
			
		||||
+	list_for_each_entry((connector), &(dev)->mode_config.connector_list, head) \
 | 
			
		||||
+		for_each_if ((connector_mask) & drm_connector_mask(connector))
 | 
			
		||||
+
 | 
			
		||||
+struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
 | 
			
		||||
+					     struct drm_crtc_state *state)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_connector *connector;
 | 
			
		||||
+
 | 
			
		||||
+	WARN_ON(hweight32(state->connector_mask) > 1);
 | 
			
		||||
+
 | 
			
		||||
+	drm_for_each_connector_mask(connector, crtc->dev, state->connector_mask)
 | 
			
		||||
+		return connector;
 | 
			
		||||
+
 | 
			
		||||
+	return NULL;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void vc4_crtc_pixelvalve_reset(struct drm_crtc *crtc)
 | 
			
		||||
 {
 | 
			
		||||
 	struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
@@ -568,6 +568,9 @@ vc4_crtc_to_vc4_pv_data(const struct vc4
 | 
			
		||||
 	return container_of(data, struct vc4_pv_data, base);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+struct drm_connector *vc4_get_crtc_connector(struct drm_crtc *crtc,
 | 
			
		||||
+					     struct drm_crtc_state *state);
 | 
			
		||||
+
 | 
			
		||||
 struct drm_encoder *vc4_get_crtc_encoder(struct drm_crtc *crtc,
 | 
			
		||||
 					 struct drm_crtc_state *state);
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -594,6 +594,36 @@ out:
 | 
			
		||||
 	drm_dev_exit(idx);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int vc4_hvs_gamma_check(struct drm_crtc *crtc,
 | 
			
		||||
+			       struct drm_atomic_state *state)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 | 
			
		||||
+	struct drm_connector_state *conn_state;
 | 
			
		||||
+	struct drm_connector *connector;
 | 
			
		||||
+	struct drm_device *dev = crtc->dev;
 | 
			
		||||
+	struct vc4_dev *vc4 = to_vc4_dev(dev);
 | 
			
		||||
+
 | 
			
		||||
+	if (!vc4->is_vc5)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	if (!crtc_state->color_mgmt_changed)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	connector = vc4_get_crtc_connector(crtc, crtc_state);
 | 
			
		||||
+	if (!connector)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	if (!(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
+	conn_state = drm_atomic_get_connector_state(state, connector);
 | 
			
		||||
+	if (!conn_state)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	crtc_state->mode_changed = true;
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state)
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 | 
			
		||||
@@ -624,7 +654,7 @@ int vc4_hvs_atomic_check(struct drm_crtc
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	return 0;
 | 
			
		||||
+	return vc4_hvs_gamma_check(crtc, state);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void vc4_hvs_install_dlist(struct drm_crtc *crtc)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,149 @@
 | 
			
		|||
From 7232a4e31a7a38b4376596b386777d030923c9bb Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
Date: Thu, 15 Jul 2021 01:08:08 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Relax VEC modeline requirements and add progressive
 | 
			
		||||
 mode support
 | 
			
		||||
 | 
			
		||||
Make vc4_vec_encoder_atomic_check() accept arbitrary modelines, as long
 | 
			
		||||
as they result in somewhat sane output from the VEC. The bounds have
 | 
			
		||||
been determined empirically. Additionally, add support for the
 | 
			
		||||
progressive 262-line and 312-line modes.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_crtc.c |  1 +
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_vec.c  | 94 ++++++++++++++++++++++++++++++----
 | 
			
		||||
 2 files changed, 85 insertions(+), 10 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
@@ -422,6 +422,7 @@ static void vc4_crtc_config_pv(struct dr
 | 
			
		||||
 		CRTC_WRITE(PV_V_CONTROL,
 | 
			
		||||
 			   PV_VCONTROL_CONTINUOUS |
 | 
			
		||||
 			   (is_dsi ? PV_VCONTROL_DSI : 0));
 | 
			
		||||
+		CRTC_WRITE(PV_VSYNCD_EVEN, 0);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	CRTC_WRITE(PV_VERTA,
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
@@ -400,18 +400,11 @@ static int vc4_vec_connector_atomic_chec
 | 
			
		||||
 	struct drm_connector_state *new_state =
 | 
			
		||||
 		drm_atomic_get_new_connector_state(state, conn);
 | 
			
		||||
 
 | 
			
		||||
-	const struct vc4_vec_tv_mode *vec_mode =
 | 
			
		||||
-		&vc4_vec_tv_modes[new_state->tv.mode];
 | 
			
		||||
-
 | 
			
		||||
-	if (new_state->crtc) {
 | 
			
		||||
+	if (new_state->crtc && old_state->tv.mode != new_state->tv.mode) {
 | 
			
		||||
 		struct drm_crtc_state *crtc_state =
 | 
			
		||||
 			drm_atomic_get_new_crtc_state(state, new_state->crtc);
 | 
			
		||||
 
 | 
			
		||||
-		if (!drm_mode_equal(vec_mode->mode, &crtc_state->mode))
 | 
			
		||||
-			return -EINVAL;
 | 
			
		||||
-
 | 
			
		||||
-		if (old_state->tv.mode != new_state->tv.mode)
 | 
			
		||||
-			crtc_state->mode_changed = true;
 | 
			
		||||
+		crtc_state->mode_changed = true;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
@@ -546,7 +539,10 @@ static void vc4_vec_encoder_enable(struc
 | 
			
		||||
 	VEC_WRITE(VEC_CLMP0_START, 0xac);
 | 
			
		||||
 	VEC_WRITE(VEC_CLMP0_END, 0xec);
 | 
			
		||||
 	VEC_WRITE(VEC_CONFIG2,
 | 
			
		||||
-		  VEC_CONFIG2_UV_DIG_DIS | VEC_CONFIG2_RGB_DIG_DIS);
 | 
			
		||||
+		  VEC_CONFIG2_UV_DIG_DIS |
 | 
			
		||||
+		  VEC_CONFIG2_RGB_DIG_DIS |
 | 
			
		||||
+		  ((encoder->crtc->state->adjusted_mode.flags &
 | 
			
		||||
+		    DRM_MODE_FLAG_INTERLACE) ? 0 : VEC_CONFIG2_PROG_SCAN));
 | 
			
		||||
 	VEC_WRITE(VEC_CONFIG3, VEC_CONFIG3_HORIZ_LEN_STD);
 | 
			
		||||
 	VEC_WRITE(VEC_DAC_CONFIG, vec->variant->dac_config);
 | 
			
		||||
 
 | 
			
		||||
@@ -575,8 +571,86 @@ err_put_runtime_pm:
 | 
			
		||||
 err_dev_exit:
 | 
			
		||||
 	drm_dev_exit(idx);
 | 
			
		||||
 }
 | 
			
		||||
+static int vc4_vec_encoder_atomic_check(struct drm_encoder *encoder,
 | 
			
		||||
+					struct drm_crtc_state *crtc_state,
 | 
			
		||||
+					struct drm_connector_state *conn_state)
 | 
			
		||||
+{
 | 
			
		||||
+	const struct drm_display_mode *reference_mode =
 | 
			
		||||
+		vc4_vec_tv_modes[conn_state->tv.mode].mode;
 | 
			
		||||
+
 | 
			
		||||
+	if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
 | 
			
		||||
+	    crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||
 | 
			
		||||
+	    crtc_state->adjusted_mode.crtc_hdisplay % 4 != 0 ||
 | 
			
		||||
+	    crtc_state->adjusted_mode.crtc_hsync_end -
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_hsync_start < 1)
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	switch (reference_mode->vtotal) {
 | 
			
		||||
+	case 525:
 | 
			
		||||
+		if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vdisplay > 253 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vsync_start -
 | 
			
		||||
+			    crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vsync_end -
 | 
			
		||||
+			    crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vtotal -
 | 
			
		||||
+			    crtc_state->adjusted_mode.crtc_vsync_end < 4 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vtotal > 262)
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		if ((crtc_state->adjusted_mode.flags &
 | 
			
		||||
+		     DRM_MODE_FLAG_INTERLACE) &&
 | 
			
		||||
+		    (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
 | 
			
		||||
+		     crtc_state->adjusted_mode.vsync_start % 2 != 1 ||
 | 
			
		||||
+		     crtc_state->adjusted_mode.vsync_end % 2 != 1 ||
 | 
			
		||||
+		     crtc_state->adjusted_mode.vtotal % 2 != 1))
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		/* progressive mode is hard-wired to 262 total lines */
 | 
			
		||||
+		if (!(crtc_state->adjusted_mode.flags &
 | 
			
		||||
+		      DRM_MODE_FLAG_INTERLACE) &&
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vtotal != 262)
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		break;
 | 
			
		||||
+
 | 
			
		||||
+	case 625:
 | 
			
		||||
+		if (crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vdisplay > 305 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vsync_start -
 | 
			
		||||
+			    crtc_state->adjusted_mode.crtc_vdisplay < 1 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vsync_end -
 | 
			
		||||
+			    crtc_state->adjusted_mode.crtc_vsync_start != 3 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vtotal -
 | 
			
		||||
+			    crtc_state->adjusted_mode.crtc_vsync_end < 2 ||
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vtotal > 312)
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		if ((crtc_state->adjusted_mode.flags &
 | 
			
		||||
+		     DRM_MODE_FLAG_INTERLACE) &&
 | 
			
		||||
+		    (crtc_state->adjusted_mode.vdisplay % 2 != 0 ||
 | 
			
		||||
+		     crtc_state->adjusted_mode.vsync_start % 2 != 0 ||
 | 
			
		||||
+		     crtc_state->adjusted_mode.vsync_end % 2 != 0 ||
 | 
			
		||||
+		     crtc_state->adjusted_mode.vtotal % 2 != 1))
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		/* progressive mode is hard-wired to 312 total lines */
 | 
			
		||||
+		if (!(crtc_state->adjusted_mode.flags &
 | 
			
		||||
+		      DRM_MODE_FLAG_INTERLACE) &&
 | 
			
		||||
+		    crtc_state->adjusted_mode.crtc_vtotal != 312)
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+		break;
 | 
			
		||||
+
 | 
			
		||||
+	default:
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
 
 | 
			
		||||
 static const struct drm_encoder_helper_funcs vc4_vec_encoder_helper_funcs = {
 | 
			
		||||
+	.atomic_check = vc4_vec_encoder_atomic_check,
 | 
			
		||||
 	.atomic_disable = vc4_vec_encoder_disable,
 | 
			
		||||
 	.atomic_enable = vc4_vec_encoder_enable,
 | 
			
		||||
 };
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,164 @@
 | 
			
		|||
From acef474b7826abe16fb140da1f3ee03cdc9928b8 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
Date: Thu, 15 Jul 2021 01:08:11 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: Make VEC progressive modes readily accessible
 | 
			
		||||
 | 
			
		||||
Add predefined modelines for the 240p (NTSC) and 288p (PAL) progressive
 | 
			
		||||
modes, and report them through vc4_vec_connector_get_modes().
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Mateusz Kwiatkowski <kfyatek+publicgit@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_vec.c | 73 ++++++++++++++++++++++++++---------
 | 
			
		||||
 1 file changed, 55 insertions(+), 18 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_vec.c
 | 
			
		||||
@@ -228,7 +228,8 @@ enum vc4_vec_tv_mode_id {
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 struct vc4_vec_tv_mode {
 | 
			
		||||
-	const struct drm_display_mode *mode;
 | 
			
		||||
+	const struct drm_display_mode *interlaced_mode;
 | 
			
		||||
+	const struct drm_display_mode *progressive_mode;
 | 
			
		||||
 	u32 config0;
 | 
			
		||||
 	u32 config1;
 | 
			
		||||
 	u32 custom_freq;
 | 
			
		||||
@@ -262,61 +263,81 @@ static const struct debugfs_reg32 vec_re
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct drm_display_mode drm_mode_480i = {
 | 
			
		||||
-	DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
+	DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
 		 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
 | 
			
		||||
 		 480, 480 + 7, 480 + 7 + 6, 525, 0,
 | 
			
		||||
 		 DRM_MODE_FLAG_INTERLACE)
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static const struct drm_display_mode drm_mode_240p = {
 | 
			
		||||
+	DRM_MODE("720x240", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
+		 720, 720 + 14, 720 + 14 + 64, 720 + 14 + 64 + 60, 0,
 | 
			
		||||
+		 240, 240 + 3, 240 + 3 + 3, 262, 0, 0)
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 static const struct drm_display_mode drm_mode_576i = {
 | 
			
		||||
-	DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
+	DRM_MODE("720x576i", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
 		 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
 | 
			
		||||
 		 576, 576 + 4, 576 + 4 + 6, 625, 0,
 | 
			
		||||
 		 DRM_MODE_FLAG_INTERLACE)
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static const struct drm_display_mode drm_mode_288p = {
 | 
			
		||||
+	DRM_MODE("720x288", DRM_MODE_TYPE_DRIVER, 13500,
 | 
			
		||||
+		 720, 720 + 20, 720 + 20 + 64, 720 + 20 + 64 + 60, 0,
 | 
			
		||||
+		 288, 288 + 2, 288 + 2 + 3, 312, 0, 0)
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
 static const struct vc4_vec_tv_mode vc4_vec_tv_modes[] = {
 | 
			
		||||
 	[VC4_VEC_TV_MODE_NTSC] = {
 | 
			
		||||
-		.mode = &drm_mode_480i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_480i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_240p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_NTSC_STD | VEC_CONFIG0_PDEN,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_NTSC_J] = {
 | 
			
		||||
-		.mode = &drm_mode_480i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_480i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_240p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_NTSC_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_NTSC_443] = {
 | 
			
		||||
 		/* NTSC with PAL chroma frequency */
 | 
			
		||||
-		.mode = &drm_mode_480i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_480i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_240p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_NTSC_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
 | 
			
		||||
 		.custom_freq = 0x2a098acb,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL] = {
 | 
			
		||||
-		.mode = &drm_mode_576i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_576i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_288p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_PAL_BDGHI_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL_M] = {
 | 
			
		||||
-		.mode = &drm_mode_480i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_480i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_240p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_PAL_M_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL_N] = {
 | 
			
		||||
-		.mode = &drm_mode_576i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_576i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_288p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_PAL_N_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_PAL60] = {
 | 
			
		||||
 		/* PAL-M with chroma frequency of regular PAL */
 | 
			
		||||
-		.mode = &drm_mode_480i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_480i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_240p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_PAL_M_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS | VEC_CONFIG1_CUSTOM_FREQ,
 | 
			
		||||
 		.custom_freq = 0x2a098acb,
 | 
			
		||||
 	},
 | 
			
		||||
 	[VC4_VEC_TV_MODE_SECAM] = {
 | 
			
		||||
-		.mode = &drm_mode_576i,
 | 
			
		||||
+		.interlaced_mode = &drm_mode_576i,
 | 
			
		||||
+		.progressive_mode = &drm_mode_288p,
 | 
			
		||||
 		.config0 = VEC_CONFIG0_SECAM_STD,
 | 
			
		||||
 		.config1 = VEC_CONFIG1_C_CVBS_CVBS,
 | 
			
		||||
 		.custom_freq = 0x29c71c72,
 | 
			
		||||
@@ -370,16 +391,32 @@ vc4_vec_connector_detect(struct drm_conn
 | 
			
		||||
 static int vc4_vec_connector_get_modes(struct drm_connector *connector)
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_connector_state *state = connector->state;
 | 
			
		||||
-	struct drm_display_mode *mode;
 | 
			
		||||
+	struct drm_display_mode *interlaced_mode, *progressive_mode;
 | 
			
		||||
 
 | 
			
		||||
-	mode = drm_mode_duplicate(connector->dev,
 | 
			
		||||
-				  vc4_vec_tv_modes[state->tv.mode].mode);
 | 
			
		||||
-	if (!mode) {
 | 
			
		||||
+	interlaced_mode =
 | 
			
		||||
+		drm_mode_duplicate(connector->dev,
 | 
			
		||||
+				   vc4_vec_tv_modes[state->tv.mode].interlaced_mode);
 | 
			
		||||
+	progressive_mode =
 | 
			
		||||
+		drm_mode_duplicate(connector->dev,
 | 
			
		||||
+				   vc4_vec_tv_modes[state->tv.mode].progressive_mode);
 | 
			
		||||
+	if (!interlaced_mode || !progressive_mode) {
 | 
			
		||||
 		DRM_ERROR("Failed to create a new display mode\n");
 | 
			
		||||
+		drm_mode_destroy(connector->dev, interlaced_mode);
 | 
			
		||||
+		drm_mode_destroy(connector->dev, progressive_mode);
 | 
			
		||||
 		return -ENOMEM;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	drm_mode_probed_add(connector, mode);
 | 
			
		||||
+	if (connector->cmdline_mode.specified &&
 | 
			
		||||
+	    connector->cmdline_mode.refresh_specified &&
 | 
			
		||||
+	    !connector->cmdline_mode.interlace)
 | 
			
		||||
+		/* progressive mode set at boot, let's make it preferred */
 | 
			
		||||
+		progressive_mode->type |= DRM_MODE_TYPE_PREFERRED;
 | 
			
		||||
+	else
 | 
			
		||||
+		/* otherwise, interlaced mode is preferred */
 | 
			
		||||
+		interlaced_mode->type |= DRM_MODE_TYPE_PREFERRED;
 | 
			
		||||
+
 | 
			
		||||
+	drm_mode_probed_add(connector, interlaced_mode);
 | 
			
		||||
+	drm_mode_probed_add(connector, progressive_mode);
 | 
			
		||||
 
 | 
			
		||||
 	return 1;
 | 
			
		||||
 }
 | 
			
		||||
@@ -576,7 +613,7 @@ static int vc4_vec_encoder_atomic_check(
 | 
			
		||||
 					struct drm_connector_state *conn_state)
 | 
			
		||||
 {
 | 
			
		||||
 	const struct drm_display_mode *reference_mode =
 | 
			
		||||
-		vc4_vec_tv_modes[conn_state->tv.mode].mode;
 | 
			
		||||
+		vc4_vec_tv_modes[conn_state->tv.mode].interlaced_mode;
 | 
			
		||||
 
 | 
			
		||||
 	if (crtc_state->adjusted_mode.crtc_clock != reference_mode->clock ||
 | 
			
		||||
 	    crtc_state->adjusted_mode.crtc_htotal != reference_mode->htotal ||
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
From 61cdd8f4f24116cf877a3b865fb3c01b74d018f4 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Tue, 2 Nov 2021 16:01:36 +0000
 | 
			
		||||
Subject: [PATCH] drm: Check whether the gamma lut has changed before updating
 | 
			
		||||
 | 
			
		||||
drm_crtc_legacy_gamma_set updates the gamma_lut blob unconditionally,
 | 
			
		||||
which leads to unnecessary reprogramming of hardware.
 | 
			
		||||
 | 
			
		||||
Check whether the blob contents has actually changed before
 | 
			
		||||
signalling that it has been updated.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/drm_color_mgmt.c | 4 +++-
 | 
			
		||||
 1 file changed, 3 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/drm_color_mgmt.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_color_mgmt.c
 | 
			
		||||
@@ -330,7 +330,9 @@ static int drm_crtc_legacy_gamma_set(str
 | 
			
		||||
 	replaced = drm_property_replace_blob(&crtc_state->degamma_lut,
 | 
			
		||||
 					     use_gamma_lut ? NULL : blob);
 | 
			
		||||
 	replaced |= drm_property_replace_blob(&crtc_state->ctm, NULL);
 | 
			
		||||
-	replaced |= drm_property_replace_blob(&crtc_state->gamma_lut,
 | 
			
		||||
+	if (!crtc_state->gamma_lut || !crtc_state->gamma_lut->data ||
 | 
			
		||||
+	    memcmp(crtc_state->gamma_lut->data, blob_data, blob->length))
 | 
			
		||||
+		replaced |= drm_property_replace_blob(&crtc_state->gamma_lut,
 | 
			
		||||
 					      use_gamma_lut ? blob : NULL);
 | 
			
		||||
 	crtc_state->color_mgmt_changed |= replaced;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
From 8757ab629ec26bd78885c66ea24a65df2b48bd55 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 8 Nov 2021 17:32:45 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Enable gamma block only when required.
 | 
			
		||||
 | 
			
		||||
With HVS5 the gamma block is now only reprogrammed with
 | 
			
		||||
a disable/enable. Loading the table from vc4_hvs_init_channel
 | 
			
		||||
(called from vc4_hvs_atomic_enable) appears to be at an
 | 
			
		||||
invalid point in time and so isn't applied.
 | 
			
		||||
 | 
			
		||||
Switch to enabling and disabling the gamma table instead. This
 | 
			
		||||
isn't safe if the pipeline is running, but it isn't now.
 | 
			
		||||
For HVS4 it is safe to enable and disable dynamically, so
 | 
			
		||||
adopt that approach there too.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c | 22 ++++++++++++++++------
 | 
			
		||||
 1 file changed, 16 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -546,8 +546,11 @@ static int vc4_hvs_init_channel(struct v
 | 
			
		||||
 	dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
 | 
			
		||||
 	dispbkgndx &= ~SCALER_DISPBKGND_INTERLACE;
 | 
			
		||||
 
 | 
			
		||||
+	if (crtc->state->gamma_lut)
 | 
			
		||||
+		/* Enable gamma on if required */
 | 
			
		||||
+		dispbkgndx |= SCALER_DISPBKGND_GAMMA;
 | 
			
		||||
+
 | 
			
		||||
 	HVS_WRITE(SCALER_DISPBKGNDX(chan), dispbkgndx |
 | 
			
		||||
-		  ((!vc4->is_vc5) ? SCALER_DISPBKGND_GAMMA : 0) |
 | 
			
		||||
 		  (interlace ? SCALER_DISPBKGND_INTERLACE : 0));
 | 
			
		||||
 
 | 
			
		||||
 	/* Reload the LUT, since the SRAMs would have been disabled if
 | 
			
		||||
@@ -816,18 +819,25 @@ void vc4_hvs_atomic_flush(struct drm_crt
 | 
			
		||||
 		u32 dispbkgndx = HVS_READ(SCALER_DISPBKGNDX(channel));
 | 
			
		||||
 
 | 
			
		||||
 		if (crtc->state->gamma_lut) {
 | 
			
		||||
-			if (!vc4->is_vc5)
 | 
			
		||||
+			if (!vc4->is_vc5) {
 | 
			
		||||
 				vc4_hvs_update_gamma_lut(hvs, vc4_crtc);
 | 
			
		||||
-			else
 | 
			
		||||
+				dispbkgndx |= SCALER_DISPBKGND_GAMMA;
 | 
			
		||||
+			} else {
 | 
			
		||||
 				vc5_hvs_update_gamma_lut(hvs, vc4_crtc);
 | 
			
		||||
-
 | 
			
		||||
-			dispbkgndx |= SCALER_DISPBKGND_GAMMA;
 | 
			
		||||
+			}
 | 
			
		||||
 		} else {
 | 
			
		||||
 			/* Unsetting DISPBKGND_GAMMA skips the gamma lut step
 | 
			
		||||
 			 * in hardware, which is the same as a linear lut that
 | 
			
		||||
 			 * DRM expects us to use in absence of a user lut.
 | 
			
		||||
+			 *
 | 
			
		||||
+			 * Do NOT change state dynamically for hvs5 as it
 | 
			
		||||
+			 * inserts a delay in the pipeline that will cause
 | 
			
		||||
+			 * stalls if enabled/disabled whilst running. The other
 | 
			
		||||
+			 * should already be disabling/enabling the pipeline
 | 
			
		||||
+			 * when gamma changes.
 | 
			
		||||
 			 */
 | 
			
		||||
-			dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
 | 
			
		||||
+			if (!vc4->is_vc5)
 | 
			
		||||
+				dispbkgndx &= ~SCALER_DISPBKGND_GAMMA;
 | 
			
		||||
 		}
 | 
			
		||||
 		HVS_WRITE(SCALER_DISPBKGNDX(channel), dispbkgndx);
 | 
			
		||||
 	}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,26 @@
 | 
			
		|||
From 0f75707bf8c04af5a931b8e991c26aeef4ba881e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 8 Nov 2021 18:25:49 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Only add gamma properties once.
 | 
			
		||||
 | 
			
		||||
Two calls were made to drm_crtc_enable_color_mgmt to add gamma
 | 
			
		||||
and CTM, however they were both set to add the gamma properties,
 | 
			
		||||
so they ended up added twice.
 | 
			
		||||
 | 
			
		||||
Fixes: 766cc6b1f7fc "drm/vc4: Add CTM support"
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_crtc.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
@@ -1358,7 +1358,7 @@ int vc4_crtc_init(struct drm_device *drm
 | 
			
		||||
 		/* We support CTM, but only for one CRTC at a time. It's therefore
 | 
			
		||||
 		 * implemented as private driver state in vc4_kms, not here.
 | 
			
		||||
 		 */
 | 
			
		||||
-		drm_crtc_enable_color_mgmt(crtc, 0, true, crtc->gamma_size);
 | 
			
		||||
+		drm_crtc_enable_color_mgmt(crtc, 0, true, 0);
 | 
			
		||||
 
 | 
			
		||||
 		/* Initialize the VC4 gamma LUTs */
 | 
			
		||||
 		for (i = 0; i < crtc->gamma_size; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
From a3133296825850c7f7328b91eb25dbeec65628e4 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Wed, 10 Nov 2021 16:36:12 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Validate the size of the gamma_lut
 | 
			
		||||
 | 
			
		||||
Add a check to vc4_hvs_gamma_check to ensure a new non-empty
 | 
			
		||||
gamma LUT is of the correct length before accepting it.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c | 10 ++++++++++
 | 
			
		||||
 1 file changed, 10 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -612,6 +612,16 @@ static int vc4_hvs_gamma_check(struct dr
 | 
			
		||||
 	if (!crtc_state->color_mgmt_changed)
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
+	if (crtc_state->gamma_lut) {
 | 
			
		||||
+		unsigned int len = drm_color_lut_size(crtc_state->gamma_lut);
 | 
			
		||||
+
 | 
			
		||||
+		if (len != crtc->gamma_size) {
 | 
			
		||||
+			DRM_DEBUG_KMS("Invalid LUT size; got %u, expected %u\n",
 | 
			
		||||
+				      len, crtc->gamma_size);
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	connector = vc4_get_crtc_connector(crtc, crtc_state);
 | 
			
		||||
 	if (!connector)
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
From 8f2abdff33e32469f735aa68197969306d847727 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Thu, 13 Jan 2022 11:30:42 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Disable Gamma control on HVS5 due to issues writing
 | 
			
		||||
 the table
 | 
			
		||||
 | 
			
		||||
Still under investigation, but the conditions under which the HVS
 | 
			
		||||
will accept values written to the gamma PWL are not straightforward.
 | 
			
		||||
 | 
			
		||||
Disable gamma on HVS5 again until it can be resolved to avoid
 | 
			
		||||
gamma being enabled with an incorrect table.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_crtc.c | 8 +-------
 | 
			
		||||
 1 file changed, 1 insertion(+), 7 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
@@ -1344,15 +1344,9 @@ int vc4_crtc_init(struct drm_device *drm
 | 
			
		||||
 
 | 
			
		||||
 	if (!vc4->is_vc5) {
 | 
			
		||||
 		drm_mode_crtc_set_gamma_size(crtc, ARRAY_SIZE(vc4_crtc->lut_r));
 | 
			
		||||
-	} else {
 | 
			
		||||
-		/* This is a lie for hvs5 which uses a 16 point PWL, but it
 | 
			
		||||
-		 * allows for something smarter than just 16 linearly spaced
 | 
			
		||||
-		 * segments. Conversion is done in vc5_hvs_update_gamma_lut.
 | 
			
		||||
-		 */
 | 
			
		||||
-		drm_mode_crtc_set_gamma_size(crtc, 256);
 | 
			
		||||
+		drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	drm_crtc_enable_color_mgmt(crtc, 0, false, crtc->gamma_size);
 | 
			
		||||
 
 | 
			
		||||
 	if (!vc4->is_vc5) {
 | 
			
		||||
 		/* We support CTM, but only for one CRTC at a time. It's therefore
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,223 @@
 | 
			
		|||
From 06389a94233146be1104c6e90f0d5d99360d67ff Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Wed, 8 Apr 2020 16:12:02 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4_hdmi: Add Broadcast RGB property to allow override of
 | 
			
		||||
 RGB range
 | 
			
		||||
 | 
			
		||||
Copy Intel's "Broadcast RGB" property semantics to add manual override
 | 
			
		||||
of the HDMI pixel range for monitors that don't abide by the content
 | 
			
		||||
of the AVI Infoframe.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hdmi.c | 104 +++++++++++++++++++++++++++++++++
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hdmi.h |  15 +++++
 | 
			
		||||
 2 files changed, 119 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
 | 
			
		||||
@@ -57,6 +57,14 @@
 | 
			
		||||
 #include "vc4_hdmi_regs.h"
 | 
			
		||||
 #include "vc4_regs.h"
 | 
			
		||||
 
 | 
			
		||||
+/*
 | 
			
		||||
+ * "Broadcast RGB" property.
 | 
			
		||||
+ * Allows overriding of HDMI full or limited range RGB
 | 
			
		||||
+ */
 | 
			
		||||
+#define VC4_BROADCAST_RGB_AUTO 0
 | 
			
		||||
+#define VC4_BROADCAST_RGB_FULL 1
 | 
			
		||||
+#define VC4_BROADCAST_RGB_LIMITED 2
 | 
			
		||||
+
 | 
			
		||||
 #define VC5_HDMI_HORZA_HFP_SHIFT		16
 | 
			
		||||
 #define VC5_HDMI_HORZA_HFP_MASK			VC4_MASK(28, 16)
 | 
			
		||||
 #define VC5_HDMI_HORZA_VPOS			BIT(15)
 | 
			
		||||
@@ -155,6 +163,11 @@ static bool vc4_hdmi_is_full_range_rgb(s
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
 | 
			
		||||
 
 | 
			
		||||
+	if (vc4_hdmi->broadcast_rgb == VC4_BROADCAST_RGB_LIMITED)
 | 
			
		||||
+		return false;
 | 
			
		||||
+	else if (vc4_hdmi->broadcast_rgb == VC4_BROADCAST_RGB_FULL)
 | 
			
		||||
+		return true;
 | 
			
		||||
+
 | 
			
		||||
 	return !display->is_hdmi ||
 | 
			
		||||
 		drm_default_rgb_quant_range(mode) == HDMI_QUANTIZATION_RANGE_FULL;
 | 
			
		||||
 }
 | 
			
		||||
@@ -544,6 +557,65 @@ static int vc4_hdmi_connector_atomic_che
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+/**
 | 
			
		||||
+ * vc4_hdmi_connector_atomic_get_property - hook for
 | 
			
		||||
+ *						connector->atomic_get_property.
 | 
			
		||||
+ * @connector: Connector to get the property for.
 | 
			
		||||
+ * @state: Connector state to retrieve the property from.
 | 
			
		||||
+ * @property: Property to retrieve.
 | 
			
		||||
+ * @val: Return value for the property.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Returns the atomic property value for a digital connector.
 | 
			
		||||
+ */
 | 
			
		||||
+int vc4_hdmi_connector_get_property(struct drm_connector *connector,
 | 
			
		||||
+				    const struct drm_connector_state *state,
 | 
			
		||||
+				    struct drm_property *property,
 | 
			
		||||
+				    uint64_t *val)
 | 
			
		||||
+{
 | 
			
		||||
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 | 
			
		||||
+	const struct vc4_hdmi_connector_state *vc4_conn_state =
 | 
			
		||||
+				const_conn_state_to_vc4_hdmi_conn_state(state);
 | 
			
		||||
+
 | 
			
		||||
+	if (property == vc4_hdmi->broadcast_rgb_property) {
 | 
			
		||||
+		*val = vc4_conn_state->broadcast_rgb;
 | 
			
		||||
+	} else {
 | 
			
		||||
+		DRM_DEBUG_ATOMIC("Unknown property [PROP:%d:%s]\n",
 | 
			
		||||
+				 property->base.id, property->name);
 | 
			
		||||
+		return -EINVAL;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
+ * vc4_hdmi_connector_atomic_set_property - hook for
 | 
			
		||||
+ *						connector->atomic_set_property.
 | 
			
		||||
+ * @connector: Connector to set the property for.
 | 
			
		||||
+ * @state: Connector state to set the property on.
 | 
			
		||||
+ * @property: Property to set.
 | 
			
		||||
+ * @val: New value for the property.
 | 
			
		||||
+ *
 | 
			
		||||
+ * Sets the atomic property value for a digital connector.
 | 
			
		||||
+ */
 | 
			
		||||
+int vc4_hdmi_connector_set_property(struct drm_connector *connector,
 | 
			
		||||
+				    struct drm_connector_state *state,
 | 
			
		||||
+				    struct drm_property *property,
 | 
			
		||||
+				    uint64_t val)
 | 
			
		||||
+{
 | 
			
		||||
+	struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
 | 
			
		||||
+	struct vc4_hdmi_connector_state *vc4_conn_state =
 | 
			
		||||
+				conn_state_to_vc4_hdmi_conn_state(state);
 | 
			
		||||
+
 | 
			
		||||
+	if (property == vc4_hdmi->broadcast_rgb_property) {
 | 
			
		||||
+		vc4_conn_state->broadcast_rgb = val;
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	DRM_DEBUG_ATOMIC("Unknown property [PROP:%d:%s]\n",
 | 
			
		||||
+			 property->base.id, property->name);
 | 
			
		||||
+	return -EINVAL;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void vc4_hdmi_connector_reset(struct drm_connector *connector)
 | 
			
		||||
 {
 | 
			
		||||
 	struct vc4_hdmi_connector_state *old_state =
 | 
			
		||||
@@ -580,6 +652,7 @@ vc4_hdmi_connector_duplicate_state(struc
 | 
			
		||||
 	new_state->tmds_char_rate = vc4_state->tmds_char_rate;
 | 
			
		||||
 	new_state->output_bpc = vc4_state->output_bpc;
 | 
			
		||||
 	new_state->output_format = vc4_state->output_format;
 | 
			
		||||
+	new_state->broadcast_rgb = vc4_state->broadcast_rgb;
 | 
			
		||||
 	__drm_atomic_helper_connector_duplicate_state(connector, &new_state->base);
 | 
			
		||||
 
 | 
			
		||||
 	return &new_state->base;
 | 
			
		||||
@@ -590,6 +663,8 @@ static const struct drm_connector_funcs
 | 
			
		||||
 	.reset = vc4_hdmi_connector_reset,
 | 
			
		||||
 	.atomic_duplicate_state = vc4_hdmi_connector_duplicate_state,
 | 
			
		||||
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 | 
			
		||||
+	.atomic_get_property = vc4_hdmi_connector_get_property,
 | 
			
		||||
+	.atomic_set_property = vc4_hdmi_connector_set_property,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
 | 
			
		||||
@@ -598,6 +673,32 @@ static const struct drm_connector_helper
 | 
			
		||||
 	.atomic_check = vc4_hdmi_connector_atomic_check,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static const struct drm_prop_enum_list broadcast_rgb_names[] = {
 | 
			
		||||
+	{ VC4_BROADCAST_RGB_AUTO, "Automatic" },
 | 
			
		||||
+	{ VC4_BROADCAST_RGB_FULL, "Full" },
 | 
			
		||||
+	{ VC4_BROADCAST_RGB_LIMITED, "Limited 16:235" },
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+static void
 | 
			
		||||
+vc4_hdmi_attach_broadcast_rgb_property(struct drm_device *dev,
 | 
			
		||||
+				       struct vc4_hdmi *vc4_hdmi)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_property *prop = vc4_hdmi->broadcast_rgb_property;
 | 
			
		||||
+
 | 
			
		||||
+	if (!prop) {
 | 
			
		||||
+		prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM,
 | 
			
		||||
+						"Broadcast RGB",
 | 
			
		||||
+						broadcast_rgb_names,
 | 
			
		||||
+						ARRAY_SIZE(broadcast_rgb_names));
 | 
			
		||||
+		if (!prop)
 | 
			
		||||
+			return;
 | 
			
		||||
+
 | 
			
		||||
+		vc4_hdmi->broadcast_rgb_property = prop;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	drm_object_attach_property(&vc4_hdmi->connector.base, prop, 0);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int vc4_hdmi_connector_init(struct drm_device *dev,
 | 
			
		||||
 				   struct vc4_hdmi *vc4_hdmi)
 | 
			
		||||
 {
 | 
			
		||||
@@ -644,6 +745,8 @@ static int vc4_hdmi_connector_init(struc
 | 
			
		||||
 	if (vc4_hdmi->variant->supports_hdr)
 | 
			
		||||
 		drm_connector_attach_hdr_output_metadata_property(connector);
 | 
			
		||||
 
 | 
			
		||||
+	vc4_hdmi_attach_broadcast_rgb_property(dev, vc4_hdmi);
 | 
			
		||||
+
 | 
			
		||||
 	drm_connector_attach_encoder(connector, encoder);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
@@ -1683,6 +1786,7 @@ static void vc4_hdmi_encoder_atomic_mode
 | 
			
		||||
 	mutex_lock(&vc4_hdmi->mutex);
 | 
			
		||||
 	drm_mode_copy(&vc4_hdmi->saved_adjusted_mode,
 | 
			
		||||
 		      &crtc_state->adjusted_mode);
 | 
			
		||||
+	vc4_hdmi->broadcast_rgb = vc4_state->broadcast_rgb;
 | 
			
		||||
 	vc4_hdmi->output_bpc = vc4_state->output_bpc;
 | 
			
		||||
 	vc4_hdmi->output_format = vc4_state->output_format;
 | 
			
		||||
 	mutex_unlock(&vc4_hdmi->mutex);
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
 | 
			
		||||
@@ -129,6 +129,8 @@ struct vc4_hdmi {
 | 
			
		||||
 
 | 
			
		||||
 	struct delayed_work scrambling_work;
 | 
			
		||||
 
 | 
			
		||||
+	struct drm_property *broadcast_rgb_property;
 | 
			
		||||
+
 | 
			
		||||
 	struct i2c_adapter *ddc;
 | 
			
		||||
 	void __iomem *hdmicore_regs;
 | 
			
		||||
 	void __iomem *hd_regs;
 | 
			
		||||
@@ -229,6 +231,12 @@ struct vc4_hdmi {
 | 
			
		||||
 	 * for use outside of KMS hooks. Protected by @mutex.
 | 
			
		||||
 	 */
 | 
			
		||||
 	enum vc4_hdmi_output_format output_format;
 | 
			
		||||
+
 | 
			
		||||
+	/**
 | 
			
		||||
+	 * @broadcast_rgb: Copy of @vc4_connector_state.broadcast_rgb
 | 
			
		||||
+	 * for use outside of KMS hooks. Protected by @mutex.
 | 
			
		||||
+	 */
 | 
			
		||||
+	int broadcast_rgb;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static inline struct vc4_hdmi *
 | 
			
		||||
@@ -249,6 +257,7 @@ struct vc4_hdmi_connector_state {
 | 
			
		||||
 	unsigned long long		tmds_char_rate;
 | 
			
		||||
 	unsigned int 			output_bpc;
 | 
			
		||||
 	enum vc4_hdmi_output_format	output_format;
 | 
			
		||||
+	int				broadcast_rgb;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static inline struct vc4_hdmi_connector_state *
 | 
			
		||||
@@ -256,6 +265,12 @@ conn_state_to_vc4_hdmi_conn_state(struct
 | 
			
		||||
 {
 | 
			
		||||
 	return container_of(conn_state, struct vc4_hdmi_connector_state, base);
 | 
			
		||||
 }
 | 
			
		||||
+
 | 
			
		||||
+static inline const struct vc4_hdmi_connector_state *
 | 
			
		||||
+const_conn_state_to_vc4_hdmi_conn_state(const struct drm_connector_state *conn_state)
 | 
			
		||||
+{
 | 
			
		||||
+	return container_of(conn_state, struct vc4_hdmi_connector_state, base);
 | 
			
		||||
+}
 | 
			
		||||
 
 | 
			
		||||
 void vc4_hdmi_phy_init(struct vc4_hdmi *vc4_hdmi,
 | 
			
		||||
 		       struct vc4_hdmi_connector_state *vc4_conn_state);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,51 @@
 | 
			
		|||
From c898725a27960d08d3aa31a4b23e3ba8840388cd Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 31 Jan 2022 16:28:43 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Add DRM 210101010 RGB formats for hvs5.
 | 
			
		||||
 | 
			
		||||
HVS5 supports the 210101010 RGB[A|X] formats, but they were
 | 
			
		||||
missing from the DRM to HVS mapping list, so weren't available.
 | 
			
		||||
Add them in.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 28 ++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 28 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -139,6 +139,34 @@ static const struct hvs_format {
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_XRGB2101010,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+		.hvs5_only = true,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_ARGB2101010,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+		.hvs5_only = true,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_ABGR2101010,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+		.hvs5_only = true,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_XBGR2101010,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+		.hvs5_only = true,
 | 
			
		||||
+	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,30 @@
 | 
			
		|||
From 0fefc9f03f94ba67d97736c884d995b98547d2f0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Chris Morgan <macromorgan@hotmail.com>
 | 
			
		||||
Date: Fri, 28 Jan 2022 17:39:54 -0600
 | 
			
		||||
Subject: [PATCH] drm/vc4: dpi: Support DPI interface in mode3 for RGB565
 | 
			
		||||
 | 
			
		||||
Add support for the VC4 DPI driver to utilize DPI mode 3. This is
 | 
			
		||||
defined here as xxxRRRRRxxGGGGGGxxxBBBBB:
 | 
			
		||||
https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#parallel-display-interface-dpi
 | 
			
		||||
 | 
			
		||||
This mode is required to use the Geekworm MZP280 DPI display.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
 | 
			
		||||
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dpi.c | 4 ++++
 | 
			
		||||
 1 file changed, 4 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dpi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dpi.c
 | 
			
		||||
@@ -188,6 +188,10 @@ static void vc4_dpi_encoder_enable(struc
 | 
			
		||||
 				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_1,
 | 
			
		||||
 						       DPI_FORMAT);
 | 
			
		||||
 				break;
 | 
			
		||||
+			case MEDIA_BUS_FMT_RGB565_1X24_CPADHI:
 | 
			
		||||
+				dpi_c |= VC4_SET_FIELD(DPI_FORMAT_16BIT_565_RGB_2,
 | 
			
		||||
+						       DPI_FORMAT);
 | 
			
		||||
+				break;
 | 
			
		||||
 			default:
 | 
			
		||||
 				DRM_ERROR("Unknown media bus format %d\n",
 | 
			
		||||
 					  bus_format);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,89 @@
 | 
			
		|||
From 311cdb11c4efd3c5c4a64c1f6569794728a4d45f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Tue, 1 Feb 2022 12:20:20 +0000
 | 
			
		||||
Subject: [PATCH] drm/panel: Add and initialise an orientation field to
 | 
			
		||||
 drm_panel
 | 
			
		||||
 | 
			
		||||
Current usage of drm_connector_set_panel_orientation is from a panel's
 | 
			
		||||
get_modes call. However if the panel orientation property doesn't
 | 
			
		||||
exist on the connector at this point, then drm_mode_object triggers
 | 
			
		||||
WARNs as the connector is already registered.
 | 
			
		||||
 | 
			
		||||
Add an orientation variable to struct drm_panel and initialise it from
 | 
			
		||||
drm_panel_init.
 | 
			
		||||
panel_bridge_attach can then create the property before the connector
 | 
			
		||||
is registered.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/bridge/panel.c |  4 ++++
 | 
			
		||||
 drivers/gpu/drm/drm_panel.c    | 15 ++++++++++-----
 | 
			
		||||
 include/drm/drm_panel.h        |  8 ++++++++
 | 
			
		||||
 3 files changed, 22 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/bridge/panel.c
 | 
			
		||||
+++ b/drivers/gpu/drm/bridge/panel.c
 | 
			
		||||
@@ -81,6 +81,10 @@ static int panel_bridge_attach(struct dr
 | 
			
		||||
 		return ret;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* set up connector's "panel orientation" property */
 | 
			
		||||
+	drm_connector_set_panel_orientation(&panel_bridge->connector,
 | 
			
		||||
+					    panel_bridge->panel->orientation);
 | 
			
		||||
+
 | 
			
		||||
 	drm_connector_attach_encoder(&panel_bridge->connector,
 | 
			
		||||
 					  bridge->encoder);
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/gpu/drm/drm_panel.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_panel.c
 | 
			
		||||
@@ -61,6 +61,9 @@ void drm_panel_init(struct drm_panel *pa
 | 
			
		||||
 	panel->dev = dev;
 | 
			
		||||
 	panel->funcs = funcs;
 | 
			
		||||
 	panel->connector_type = connector_type;
 | 
			
		||||
+
 | 
			
		||||
+	panel->orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
 | 
			
		||||
+	of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
 | 
			
		||||
 }
 | 
			
		||||
 EXPORT_SYMBOL(drm_panel_init);
 | 
			
		||||
 
 | 
			
		||||
@@ -289,16 +292,18 @@ int of_drm_get_panel_orientation(const s
 | 
			
		||||
 	if (ret < 0)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	if (rotation == 0)
 | 
			
		||||
+	if (rotation == 0) {
 | 
			
		||||
 		*orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
 | 
			
		||||
-	else if (rotation == 90)
 | 
			
		||||
+	} else if (rotation == 90) {
 | 
			
		||||
 		*orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
 | 
			
		||||
-	else if (rotation == 180)
 | 
			
		||||
+	} else if (rotation == 180) {
 | 
			
		||||
 		*orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
 | 
			
		||||
-	else if (rotation == 270)
 | 
			
		||||
+	} else if (rotation == 270) {
 | 
			
		||||
 		*orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
 | 
			
		||||
-	else
 | 
			
		||||
+	} else {
 | 
			
		||||
+		DRM_ERROR("%pOF: invalid orientation %d\n", np, ret);
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
+	}
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
--- a/include/drm/drm_panel.h
 | 
			
		||||
+++ b/include/drm/drm_panel.h
 | 
			
		||||
@@ -183,6 +183,14 @@ struct drm_panel {
 | 
			
		||||
 	int connector_type;
 | 
			
		||||
 
 | 
			
		||||
 	/**
 | 
			
		||||
+	 * @orientation:
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * Panel orientation at initialisation. This is used to initialise the
 | 
			
		||||
+	 * drm_connector property for panel orientation.
 | 
			
		||||
+	 */
 | 
			
		||||
+	enum drm_panel_orientation orientation;
 | 
			
		||||
+
 | 
			
		||||
+	/**
 | 
			
		||||
 	 * @list:
 | 
			
		||||
 	 *
 | 
			
		||||
 	 * Panel entry in registry.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,76 @@
 | 
			
		|||
From b41713786d56c559cfd093b313145cf34cb624d1 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 17 Dec 2021 13:36:52 +0000
 | 
			
		||||
Subject: [PATCH] drm/dsi: Document the meaning and spec references for
 | 
			
		||||
 MIPI_DSI_MODE_*
 | 
			
		||||
 | 
			
		||||
The MIPI_DSI_MODE_* flags have fairly terse descriptions and no reference
 | 
			
		||||
to the DSI specification as to their exact meaning. Usage has therefore
 | 
			
		||||
been rather fluid.
 | 
			
		||||
 | 
			
		||||
Extend the descriptions and provide references to the part of the
 | 
			
		||||
MIPI DSI specification regarding what they mean.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 include/drm/drm_mipi_dsi.h | 38 ++++++++++++++++++++++++++------------
 | 
			
		||||
 1 file changed, 26 insertions(+), 12 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/include/drm/drm_mipi_dsi.h
 | 
			
		||||
+++ b/include/drm/drm_mipi_dsi.h
 | 
			
		||||
@@ -113,29 +113,43 @@ struct mipi_dsi_host *of_find_mipi_dsi_h
 | 
			
		||||
 
 | 
			
		||||
 /* DSI mode flags */
 | 
			
		||||
 
 | 
			
		||||
-/* video mode */
 | 
			
		||||
+/* Video mode display.
 | 
			
		||||
+ * Not set denotes a command mode display.
 | 
			
		||||
+ */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO		BIT(0)
 | 
			
		||||
-/* video burst mode */
 | 
			
		||||
+/* Video burst mode.
 | 
			
		||||
+ * Link frequency to be configured via platform configuration.
 | 
			
		||||
+ * This should always be set in conjunction with MIPI_DSI_MODE_VIDEO.
 | 
			
		||||
+ * (DSI spec V1.1 8.11.4)
 | 
			
		||||
+ */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO_BURST	BIT(1)
 | 
			
		||||
-/* video pulse mode */
 | 
			
		||||
+/* Video pulse mode.
 | 
			
		||||
+ * Not set denotes sync event mode. (DSI spec V1.1 8.11.2)
 | 
			
		||||
+ */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO_SYNC_PULSE	BIT(2)
 | 
			
		||||
-/* enable auto vertical count mode */
 | 
			
		||||
+/* Enable auto vertical count mode */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO_AUTO_VERT	BIT(3)
 | 
			
		||||
-/* enable hsync-end packets in vsync-pulse and v-porch area */
 | 
			
		||||
+/* Enable hsync-end packets in vsync-pulse and v-porch area */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO_HSE		BIT(4)
 | 
			
		||||
-/* disable hfront-porch area */
 | 
			
		||||
+/* Transmit NULL packets or LP mode during hfront-porch area.
 | 
			
		||||
+ * Not set denotes sending a blanking packet instead. (DSI spec V1.1 8.11.1)
 | 
			
		||||
+ */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO_NO_HFP	BIT(5)
 | 
			
		||||
-/* disable hback-porch area */
 | 
			
		||||
+/* Transmit NULL packets or LP mode during hback-porch area.
 | 
			
		||||
+ * Not set denotes sending a blanking packet instead. (DSI spec V1.1 8.11.1)
 | 
			
		||||
+ */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO_NO_HBP	BIT(6)
 | 
			
		||||
-/* disable hsync-active area */
 | 
			
		||||
+/* Transmit NULL packets or LP mode during hsync-active area.
 | 
			
		||||
+ * Not set denotes sending a blanking packet instead. (DSI spec V1.1 8.11.1)
 | 
			
		||||
+ */
 | 
			
		||||
 #define MIPI_DSI_MODE_VIDEO_NO_HSA	BIT(7)
 | 
			
		||||
-/* flush display FIFO on vsync pulse */
 | 
			
		||||
+/* Flush display FIFO on vsync pulse */
 | 
			
		||||
 #define MIPI_DSI_MODE_VSYNC_FLUSH	BIT(8)
 | 
			
		||||
-/* disable EoT packets in HS mode */
 | 
			
		||||
+/* Disable EoT packets in HS mode. (DSI spec V1.1 8.1)  */
 | 
			
		||||
 #define MIPI_DSI_MODE_NO_EOT_PACKET	BIT(9)
 | 
			
		||||
-/* device supports non-continuous clock behavior (DSI spec 5.6.1) */
 | 
			
		||||
+/* Device supports non-continuous clock behavior (DSI spec V1.1 5.6.1) */
 | 
			
		||||
 #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
 | 
			
		||||
-/* transmit data in low power */
 | 
			
		||||
+/* Transmit data in low power */
 | 
			
		||||
 #define MIPI_DSI_MODE_LPM		BIT(11)
 | 
			
		||||
 /* transmit data ending at the same time for all lanes within one hsync */
 | 
			
		||||
 #define MIPI_DSI_HS_PKT_END_ALIGNED	BIT(12)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From 6638f69e510fe49de651d7ab0e2012e58fc2e6ca Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Thu, 20 Jan 2022 17:29:36 +0000
 | 
			
		||||
Subject: [PATCH] drm/bridge: tc358762: Ignore EPROBE_DEFER when logging errors
 | 
			
		||||
 | 
			
		||||
mipi_dsi_attach can fail due to resources not being available
 | 
			
		||||
yet, therefore do not log error messages should they occur.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/bridge/tc358762.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/bridge/tc358762.c
 | 
			
		||||
+++ b/drivers/gpu/drm/bridge/tc358762.c
 | 
			
		||||
@@ -235,7 +235,7 @@ static int tc358762_probe(struct mipi_ds
 | 
			
		||||
 	ret = mipi_dsi_attach(dsi);
 | 
			
		||||
 	if (ret < 0) {
 | 
			
		||||
 		drm_bridge_remove(&ctx->bridge);
 | 
			
		||||
-		dev_err(dev, "failed to attach dsi\n");
 | 
			
		||||
+		dev_err_probe(dev, ret, "failed to attach dsi\n");
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return ret;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
From 150b1bb8b1406807b94103e6beca1e023377e3a6 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Thu, 30 Sep 2021 17:51:16 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4: Rename bridge to out_bridge
 | 
			
		||||
 | 
			
		||||
In preparation for converting the encoder to being a bridge,
 | 
			
		||||
rename the variable holding the next bridge in the chain to
 | 
			
		||||
out_bridge, so that our bridge can be called bridge.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dsi.c | 12 ++++++------
 | 
			
		||||
 1 file changed, 6 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
@@ -556,7 +556,7 @@ struct vc4_dsi {
 | 
			
		||||
 
 | 
			
		||||
 	struct platform_device *pdev;
 | 
			
		||||
 
 | 
			
		||||
-	struct drm_bridge *bridge;
 | 
			
		||||
+	struct drm_bridge *out_bridge;
 | 
			
		||||
 	struct list_head bridge_chain;
 | 
			
		||||
 
 | 
			
		||||
 	void __iomem *regs;
 | 
			
		||||
@@ -800,7 +800,7 @@ static void vc4_dsi_encoder_disable(stru
 | 
			
		||||
 		if (iter->funcs->disable)
 | 
			
		||||
 			iter->funcs->disable(iter);
 | 
			
		||||
 
 | 
			
		||||
-		if (iter == dsi->bridge)
 | 
			
		||||
+		if (iter == dsi->out_bridge)
 | 
			
		||||
 			break;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1723,9 +1723,9 @@ static int vc4_dsi_bind(struct device *d
 | 
			
		||||
 		return ret;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	dsi->bridge = drmm_of_get_bridge(drm, dev->of_node, 0, 0);
 | 
			
		||||
-	if (IS_ERR(dsi->bridge))
 | 
			
		||||
-		return PTR_ERR(dsi->bridge);
 | 
			
		||||
+	dsi->out_bridge = drmm_of_get_bridge(drm, dev->of_node, 0, 0);
 | 
			
		||||
+	if (IS_ERR(dsi->out_bridge))
 | 
			
		||||
+		return PTR_ERR(dsi->out_bridge);
 | 
			
		||||
 
 | 
			
		||||
 	/* The esc clock rate is supposed to always be 100Mhz. */
 | 
			
		||||
 	ret = clk_set_rate(dsi->escape_clock, 100 * 1000000);
 | 
			
		||||
@@ -1751,7 +1751,7 @@ static int vc4_dsi_bind(struct device *d
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	ret = drm_bridge_attach(encoder, dsi->bridge, NULL, 0);
 | 
			
		||||
+	ret = drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 	/* Disable the atomic helper calls into the bridge.  We
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
From ccd746cc3efa45ce3a657bbe3729133ef8d20495 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 7 Feb 2022 17:14:51 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Move DSI initialisation to encoder_mode_set.
 | 
			
		||||
 | 
			
		||||
Breaking the bridge chain does not work for atomic bridges/panels
 | 
			
		||||
and generally causes issues.
 | 
			
		||||
We need to initialise the DSI host before the bridge pre_enables
 | 
			
		||||
are called, so move that to encoder_mode_set in the same way that
 | 
			
		||||
dw-mipi-dsi does.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dsi.c | 17 +++++++++++++----
 | 
			
		||||
 1 file changed, 13 insertions(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
@@ -867,18 +867,18 @@ static bool vc4_dsi_encoder_mode_fixup(s
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
 | 
			
		||||
+static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
 | 
			
		||||
+				     struct drm_display_mode *mode,
 | 
			
		||||
+				     struct drm_display_mode *adjusted_mode)
 | 
			
		||||
 {
 | 
			
		||||
-	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
 | 
			
		||||
 	struct vc4_dsi *dsi = to_vc4_dsi(encoder);
 | 
			
		||||
 	struct device *dev = &dsi->pdev->dev;
 | 
			
		||||
 	bool debug_dump_regs = false;
 | 
			
		||||
-	struct drm_bridge *iter;
 | 
			
		||||
 	unsigned long hs_clock;
 | 
			
		||||
 	u32 ui_ns;
 | 
			
		||||
 	/* Minimum LP state duration in escape clock cycles. */
 | 
			
		||||
 	u32 lpx = dsi_esc_timing(60);
 | 
			
		||||
-	unsigned long pixel_clock_hz = mode->clock * 1000;
 | 
			
		||||
+	unsigned long pixel_clock_hz = adjusted_mode->clock * 1000;
 | 
			
		||||
 	unsigned long dsip_clock;
 | 
			
		||||
 	unsigned long phy_clock;
 | 
			
		||||
 	int ret;
 | 
			
		||||
@@ -1105,6 +1105,14 @@ static void vc4_dsi_encoder_enable(struc
 | 
			
		||||
 		       ~DSI_PORT_BIT(PHY_AFEC0_RESET));
 | 
			
		||||
 
 | 
			
		||||
 	vc4_dsi_ulps(dsi, false);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
 | 
			
		||||
+{
 | 
			
		||||
+	struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
 | 
			
		||||
+	struct vc4_dsi *dsi = vc4_encoder->dsi;
 | 
			
		||||
+	bool debug_dump_regs = false;
 | 
			
		||||
+	struct drm_bridge *iter;
 | 
			
		||||
 
 | 
			
		||||
 	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
 | 
			
		||||
 		if (iter->funcs->pre_enable)
 | 
			
		||||
@@ -1370,6 +1378,7 @@ static const struct drm_encoder_helper_f
 | 
			
		||||
 	.disable = vc4_dsi_encoder_disable,
 | 
			
		||||
 	.enable = vc4_dsi_encoder_enable,
 | 
			
		||||
 	.mode_fixup = vc4_dsi_encoder_mode_fixup,
 | 
			
		||||
+	.mode_set = vc4_dsi_encoder_mode_set,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int vc4_dsi_late_register(struct drm_encoder *encoder)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,117 @@
 | 
			
		|||
From 5dc162306c4e5ff17493db7eaeccaaa60734ff8f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Wed, 15 Dec 2021 17:44:49 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Remove splitting the bridge chain from the driver.
 | 
			
		||||
 | 
			
		||||
Splitting the bridge chain fails for atomic bridges as the
 | 
			
		||||
framework can't add the relevant state in
 | 
			
		||||
drm_atomic_add_encoder_bridges.
 | 
			
		||||
The chain was split because we needed to power up before
 | 
			
		||||
calling pre_enable, but that is now done in mode_set, and will
 | 
			
		||||
move into the framework.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dsi.c | 47 -----------------------------------
 | 
			
		||||
 1 file changed, 47 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
@@ -557,7 +557,6 @@ struct vc4_dsi {
 | 
			
		||||
 	struct platform_device *pdev;
 | 
			
		||||
 
 | 
			
		||||
 	struct drm_bridge *out_bridge;
 | 
			
		||||
-	struct list_head bridge_chain;
 | 
			
		||||
 
 | 
			
		||||
 	void __iomem *regs;
 | 
			
		||||
 
 | 
			
		||||
@@ -794,23 +793,9 @@ static void vc4_dsi_encoder_disable(stru
 | 
			
		||||
 {
 | 
			
		||||
 	struct vc4_dsi *dsi = to_vc4_dsi(encoder);
 | 
			
		||||
 	struct device *dev = &dsi->pdev->dev;
 | 
			
		||||
-	struct drm_bridge *iter;
 | 
			
		||||
-
 | 
			
		||||
-	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
 | 
			
		||||
-		if (iter->funcs->disable)
 | 
			
		||||
-			iter->funcs->disable(iter);
 | 
			
		||||
-
 | 
			
		||||
-		if (iter == dsi->out_bridge)
 | 
			
		||||
-			break;
 | 
			
		||||
-	}
 | 
			
		||||
 
 | 
			
		||||
 	vc4_dsi_ulps(dsi, true);
 | 
			
		||||
 
 | 
			
		||||
-	list_for_each_entry_from(iter, &dsi->bridge_chain, chain_node) {
 | 
			
		||||
-		if (iter->funcs->post_disable)
 | 
			
		||||
-			iter->funcs->post_disable(iter);
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
 	clk_disable_unprepare(dsi->pll_phy_clock);
 | 
			
		||||
 	clk_disable_unprepare(dsi->escape_clock);
 | 
			
		||||
 	clk_disable_unprepare(dsi->pixel_clock);
 | 
			
		||||
@@ -1112,12 +1097,6 @@ static void vc4_dsi_encoder_enable(struc
 | 
			
		||||
 	struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
 | 
			
		||||
 	struct vc4_dsi *dsi = vc4_encoder->dsi;
 | 
			
		||||
 	bool debug_dump_regs = false;
 | 
			
		||||
-	struct drm_bridge *iter;
 | 
			
		||||
-
 | 
			
		||||
-	list_for_each_entry_reverse(iter, &dsi->bridge_chain, chain_node) {
 | 
			
		||||
-		if (iter->funcs->pre_enable)
 | 
			
		||||
-			iter->funcs->pre_enable(iter);
 | 
			
		||||
-	}
 | 
			
		||||
 
 | 
			
		||||
 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
 | 
			
		||||
 		DSI_PORT_WRITE(DISP0_CTRL,
 | 
			
		||||
@@ -1134,11 +1113,6 @@ static void vc4_dsi_encoder_enable(struc
 | 
			
		||||
 			       DSI_DISP0_ENABLE);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	list_for_each_entry(iter, &dsi->bridge_chain, chain_node) {
 | 
			
		||||
-		if (iter->funcs->enable)
 | 
			
		||||
-			iter->funcs->enable(iter);
 | 
			
		||||
-	}
 | 
			
		||||
-
 | 
			
		||||
 	if (debug_dump_regs) {
 | 
			
		||||
 		struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
 | 
			
		||||
 		dev_info(&dsi->pdev->dev, "DSI regs after:\n");
 | 
			
		||||
@@ -1626,7 +1600,6 @@ static int vc4_dsi_bind(struct device *d
 | 
			
		||||
 
 | 
			
		||||
 	dsi->variant = of_device_get_match_data(dev);
 | 
			
		||||
 
 | 
			
		||||
-	INIT_LIST_HEAD(&dsi->bridge_chain);
 | 
			
		||||
 	dsi->encoder.type = dsi->variant->port ?
 | 
			
		||||
 		VC4_ENCODER_TYPE_DSI1 : VC4_ENCODER_TYPE_DSI0;
 | 
			
		||||
 
 | 
			
		||||
@@ -1763,32 +1736,12 @@ static int vc4_dsi_bind(struct device *d
 | 
			
		||||
 	ret = drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
-	/* Disable the atomic helper calls into the bridge.  We
 | 
			
		||||
-	 * manually call the bridge pre_enable / enable / etc. calls
 | 
			
		||||
-	 * from our driver, since we need to sequence them within the
 | 
			
		||||
-	 * encoder's enable/disable paths.
 | 
			
		||||
-	 */
 | 
			
		||||
-	list_splice_init(&encoder->bridge_chain, &dsi->bridge_chain);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_dsi_unbind(struct device *dev, struct device *master,
 | 
			
		||||
-			   void *data)
 | 
			
		||||
-{
 | 
			
		||||
-	struct vc4_dsi *dsi = dev_get_drvdata(dev);
 | 
			
		||||
-	struct drm_encoder *encoder = &dsi->encoder.base;
 | 
			
		||||
-
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * Restore the bridge_chain so the bridge detach procedure can happen
 | 
			
		||||
-	 * normally.
 | 
			
		||||
-	 */
 | 
			
		||||
-	list_splice_init(&dsi->bridge_chain, &encoder->bridge_chain);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
 static const struct component_ops vc4_dsi_ops = {
 | 
			
		||||
 	.bind   = vc4_dsi_bind,
 | 
			
		||||
-	.unbind = vc4_dsi_unbind,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int vc4_dsi_dev_probe(struct platform_device *pdev)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
From fbb674cc8153a69d8224e8c5bb15ebbd1440fdc2 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Wed, 15 Dec 2021 17:47:14 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Convert vc4_dsi to use atomic
 | 
			
		||||
 enable/disable/mode_set.
 | 
			
		||||
 | 
			
		||||
The atomic calls are preferred as the non-atomic ones
 | 
			
		||||
are deprecated. In preparation for conversion to a bridge,
 | 
			
		||||
switch to the atomic calls.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dsi.c | 23 +++++++++++++++--------
 | 
			
		||||
 1 file changed, 15 insertions(+), 8 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
@@ -789,7 +789,8 @@ dsi_esc_timing(u32 ns)
 | 
			
		||||
 	return DIV_ROUND_UP(ns, ESC_TIME_NS);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_dsi_encoder_disable(struct drm_encoder *encoder)
 | 
			
		||||
+static void vc4_dsi_encoder_disable(struct drm_encoder *encoder,
 | 
			
		||||
+				    struct drm_atomic_state *state)
 | 
			
		||||
 {
 | 
			
		||||
 	struct vc4_dsi *dsi = to_vc4_dsi(encoder);
 | 
			
		||||
 	struct device *dev = &dsi->pdev->dev;
 | 
			
		||||
@@ -853,17 +854,18 @@ static bool vc4_dsi_encoder_mode_fixup(s
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
 | 
			
		||||
-				     struct drm_display_mode *mode,
 | 
			
		||||
-				     struct drm_display_mode *adjusted_mode)
 | 
			
		||||
+				     struct drm_crtc_state *crtc_state,
 | 
			
		||||
+				     struct drm_connector_state *conn_state)
 | 
			
		||||
 {
 | 
			
		||||
 	struct vc4_dsi *dsi = to_vc4_dsi(encoder);
 | 
			
		||||
 	struct device *dev = &dsi->pdev->dev;
 | 
			
		||||
+	const struct drm_display_mode *mode;
 | 
			
		||||
 	bool debug_dump_regs = false;
 | 
			
		||||
 	unsigned long hs_clock;
 | 
			
		||||
 	u32 ui_ns;
 | 
			
		||||
 	/* Minimum LP state duration in escape clock cycles. */
 | 
			
		||||
 	u32 lpx = dsi_esc_timing(60);
 | 
			
		||||
-	unsigned long pixel_clock_hz = adjusted_mode->clock * 1000;
 | 
			
		||||
+	unsigned long pixel_clock_hz;
 | 
			
		||||
 	unsigned long dsip_clock;
 | 
			
		||||
 	unsigned long phy_clock;
 | 
			
		||||
 	int ret;
 | 
			
		||||
@@ -880,6 +882,10 @@ static void vc4_dsi_encoder_mode_set(str
 | 
			
		||||
 		drm_print_regset32(&p, &dsi->regset);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	mode = &crtc_state->adjusted_mode;
 | 
			
		||||
+
 | 
			
		||||
+	pixel_clock_hz = mode->clock * 1000;
 | 
			
		||||
+
 | 
			
		||||
 	/* Round up the clk_set_rate() request slightly, since
 | 
			
		||||
 	 * PLLD_DSI1 is an integer divider and its rate selection will
 | 
			
		||||
 	 * never round up.
 | 
			
		||||
@@ -1092,7 +1098,8 @@ static void vc4_dsi_encoder_mode_set(str
 | 
			
		||||
 	vc4_dsi_ulps(dsi, false);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_dsi_encoder_enable(struct drm_encoder *encoder)
 | 
			
		||||
+static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
 | 
			
		||||
+				   struct drm_atomic_state *state)
 | 
			
		||||
 {
 | 
			
		||||
 	struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
 | 
			
		||||
 	struct vc4_dsi *dsi = vc4_encoder->dsi;
 | 
			
		||||
@@ -1349,10 +1356,10 @@ static const struct mipi_dsi_host_ops vc
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = {
 | 
			
		||||
-	.disable = vc4_dsi_encoder_disable,
 | 
			
		||||
-	.enable = vc4_dsi_encoder_enable,
 | 
			
		||||
+	.atomic_disable = vc4_dsi_encoder_disable,
 | 
			
		||||
+	.atomic_enable = vc4_dsi_encoder_enable,
 | 
			
		||||
 	.mode_fixup = vc4_dsi_encoder_mode_fixup,
 | 
			
		||||
-	.mode_set = vc4_dsi_encoder_mode_set,
 | 
			
		||||
+	.atomic_mode_set = vc4_dsi_encoder_mode_set,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int vc4_dsi_late_register(struct drm_encoder *encoder)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,266 @@
 | 
			
		|||
From e80165b59d158eb60ac5ade9553127497c4631d9 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Wed, 15 Dec 2021 17:57:45 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Convert vc4_dsi to using a bridge instead of
 | 
			
		||||
 encoder.
 | 
			
		||||
 | 
			
		||||
Remove the encoder functions, and create a bridge attached to
 | 
			
		||||
this dumb encoder which implements the same functionality.
 | 
			
		||||
 | 
			
		||||
As a bridge has state which an encoder doesn't, we need to
 | 
			
		||||
add the state management functions as well.
 | 
			
		||||
 | 
			
		||||
As there is no bridge atomic_mode_set, move the initialisation
 | 
			
		||||
code that was in mode_set into _pre_enable.
 | 
			
		||||
The code to actually enable and disable sending video are split
 | 
			
		||||
from the general control into _enable and _disable.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dsi.c | 122 +++++++++++++++++++++++++---------
 | 
			
		||||
 1 file changed, 90 insertions(+), 32 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
@@ -557,6 +557,7 @@ struct vc4_dsi {
 | 
			
		||||
 	struct platform_device *pdev;
 | 
			
		||||
 
 | 
			
		||||
 	struct drm_bridge *out_bridge;
 | 
			
		||||
+	struct drm_bridge bridge;
 | 
			
		||||
 
 | 
			
		||||
 	void __iomem *regs;
 | 
			
		||||
 
 | 
			
		||||
@@ -608,6 +609,12 @@ to_vc4_dsi(struct drm_encoder *encoder)
 | 
			
		||||
 	return container_of(encoder, struct vc4_dsi, encoder.base);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static inline struct vc4_dsi *
 | 
			
		||||
+bridge_to_vc4_dsi(struct drm_bridge *bridge)
 | 
			
		||||
+{
 | 
			
		||||
+	return container_of(bridge, struct vc4_dsi, bridge);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static inline void
 | 
			
		||||
 dsi_dma_workaround_write(struct vc4_dsi *dsi, u32 offset, u32 val)
 | 
			
		||||
 {
 | 
			
		||||
@@ -789,10 +796,21 @@ dsi_esc_timing(u32 ns)
 | 
			
		||||
 	return DIV_ROUND_UP(ns, ESC_TIME_NS);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_dsi_encoder_disable(struct drm_encoder *encoder,
 | 
			
		||||
-				    struct drm_atomic_state *state)
 | 
			
		||||
+static void vc4_dsi_bridge_disable(struct drm_bridge *bridge,
 | 
			
		||||
+				   struct drm_bridge_state *state)
 | 
			
		||||
 {
 | 
			
		||||
-	struct vc4_dsi *dsi = to_vc4_dsi(encoder);
 | 
			
		||||
+	struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
 | 
			
		||||
+	u32 disp0_ctrl;
 | 
			
		||||
+
 | 
			
		||||
+	disp0_ctrl = DSI_PORT_READ(DISP0_CTRL);
 | 
			
		||||
+	disp0_ctrl &= ~DSI_DISP0_ENABLE;
 | 
			
		||||
+	DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void vc4_dsi_bridge_post_disable(struct drm_bridge *bridge,
 | 
			
		||||
+					struct drm_bridge_state *state)
 | 
			
		||||
+{
 | 
			
		||||
+	struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
 | 
			
		||||
 	struct device *dev = &dsi->pdev->dev;
 | 
			
		||||
 
 | 
			
		||||
 	vc4_dsi_ulps(dsi, true);
 | 
			
		||||
@@ -817,11 +835,11 @@ static void vc4_dsi_encoder_disable(stru
 | 
			
		||||
  * higher-than-expected clock rate to the panel, but that's what the
 | 
			
		||||
  * firmware does too.
 | 
			
		||||
  */
 | 
			
		||||
-static bool vc4_dsi_encoder_mode_fixup(struct drm_encoder *encoder,
 | 
			
		||||
-				       const struct drm_display_mode *mode,
 | 
			
		||||
-				       struct drm_display_mode *adjusted_mode)
 | 
			
		||||
+static bool vc4_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
 | 
			
		||||
+				      const struct drm_display_mode *mode,
 | 
			
		||||
+				      struct drm_display_mode *adjusted_mode)
 | 
			
		||||
 {
 | 
			
		||||
-	struct vc4_dsi *dsi = to_vc4_dsi(encoder);
 | 
			
		||||
+	struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
 | 
			
		||||
 	struct clk *phy_parent = clk_get_parent(dsi->pll_phy_clock);
 | 
			
		||||
 	unsigned long parent_rate = clk_get_rate(phy_parent);
 | 
			
		||||
 	unsigned long pixel_clock_hz = mode->clock * 1000;
 | 
			
		||||
@@ -853,15 +871,18 @@ static bool vc4_dsi_encoder_mode_fixup(s
 | 
			
		||||
 	return true;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_dsi_encoder_mode_set(struct drm_encoder *encoder,
 | 
			
		||||
-				     struct drm_crtc_state *crtc_state,
 | 
			
		||||
-				     struct drm_connector_state *conn_state)
 | 
			
		||||
+static void vc4_dsi_bridge_pre_enable(struct drm_bridge *bridge,
 | 
			
		||||
+				      struct drm_bridge_state *old_state)
 | 
			
		||||
 {
 | 
			
		||||
-	struct vc4_dsi *dsi = to_vc4_dsi(encoder);
 | 
			
		||||
+	struct drm_atomic_state *state = old_state->base.state;
 | 
			
		||||
+	struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
 | 
			
		||||
+	const struct drm_crtc_state *crtc_state;
 | 
			
		||||
 	struct device *dev = &dsi->pdev->dev;
 | 
			
		||||
 	const struct drm_display_mode *mode;
 | 
			
		||||
+	struct drm_connector *connector;
 | 
			
		||||
 	bool debug_dump_regs = false;
 | 
			
		||||
 	unsigned long hs_clock;
 | 
			
		||||
+	struct drm_crtc *crtc;
 | 
			
		||||
 	u32 ui_ns;
 | 
			
		||||
 	/* Minimum LP state duration in escape clock cycles. */
 | 
			
		||||
 	u32 lpx = dsi_esc_timing(60);
 | 
			
		||||
@@ -882,6 +903,14 @@ static void vc4_dsi_encoder_mode_set(str
 | 
			
		||||
 		drm_print_regset32(&p, &dsi->regset);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Retrieve the CRTC adjusted mode. This requires a little dance to go
 | 
			
		||||
+	 * from the bridge to the encoder, to the connector and to the CRTC.
 | 
			
		||||
+	 */
 | 
			
		||||
+	connector = drm_atomic_get_new_connector_for_encoder(state,
 | 
			
		||||
+							     bridge->encoder);
 | 
			
		||||
+	crtc = drm_atomic_get_new_connector_state(state, connector)->crtc;
 | 
			
		||||
+	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
 | 
			
		||||
 	mode = &crtc_state->adjusted_mode;
 | 
			
		||||
 
 | 
			
		||||
 	pixel_clock_hz = mode->clock * 1000;
 | 
			
		||||
@@ -1096,14 +1125,6 @@ static void vc4_dsi_encoder_mode_set(str
 | 
			
		||||
 		       ~DSI_PORT_BIT(PHY_AFEC0_RESET));
 | 
			
		||||
 
 | 
			
		||||
 	vc4_dsi_ulps(dsi, false);
 | 
			
		||||
-}
 | 
			
		||||
-
 | 
			
		||||
-static void vc4_dsi_encoder_enable(struct drm_encoder *encoder,
 | 
			
		||||
-				   struct drm_atomic_state *state)
 | 
			
		||||
-{
 | 
			
		||||
-	struct vc4_dsi_encoder *vc4_encoder = to_vc4_dsi_encoder(encoder);
 | 
			
		||||
-	struct vc4_dsi *dsi = vc4_encoder->dsi;
 | 
			
		||||
-	bool debug_dump_regs = false;
 | 
			
		||||
 
 | 
			
		||||
 	if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
 | 
			
		||||
 		DSI_PORT_WRITE(DISP0_CTRL,
 | 
			
		||||
@@ -1112,13 +1133,23 @@ static void vc4_dsi_encoder_enable(struc
 | 
			
		||||
 			       VC4_SET_FIELD(dsi->format, DSI_DISP0_PFORMAT) |
 | 
			
		||||
 			       VC4_SET_FIELD(DSI_DISP0_LP_STOP_PERFRAME,
 | 
			
		||||
 					     DSI_DISP0_LP_STOP_CTRL) |
 | 
			
		||||
-			       DSI_DISP0_ST_END |
 | 
			
		||||
-			       DSI_DISP0_ENABLE);
 | 
			
		||||
+			       DSI_DISP0_ST_END);
 | 
			
		||||
 	} else {
 | 
			
		||||
 		DSI_PORT_WRITE(DISP0_CTRL,
 | 
			
		||||
-			       DSI_DISP0_COMMAND_MODE |
 | 
			
		||||
-			       DSI_DISP0_ENABLE);
 | 
			
		||||
+			       DSI_DISP0_COMMAND_MODE);
 | 
			
		||||
 	}
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void vc4_dsi_bridge_enable(struct drm_bridge *bridge,
 | 
			
		||||
+				  struct drm_bridge_state *old_state)
 | 
			
		||||
+{
 | 
			
		||||
+	struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
 | 
			
		||||
+	bool debug_dump_regs = false;
 | 
			
		||||
+	u32 disp0_ctrl;
 | 
			
		||||
+
 | 
			
		||||
+	disp0_ctrl = DSI_PORT_READ(DISP0_CTRL);
 | 
			
		||||
+	disp0_ctrl |= DSI_DISP0_ENABLE;
 | 
			
		||||
+	DSI_PORT_WRITE(DISP0_CTRL, disp0_ctrl);
 | 
			
		||||
 
 | 
			
		||||
 	if (debug_dump_regs) {
 | 
			
		||||
 		struct drm_printer p = drm_info_printer(&dsi->pdev->dev);
 | 
			
		||||
@@ -1127,6 +1158,16 @@ static void vc4_dsi_encoder_enable(struc
 | 
			
		||||
 	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int vc4_dsi_bridge_attach(struct drm_bridge *bridge,
 | 
			
		||||
+				 enum drm_bridge_attach_flags flags)
 | 
			
		||||
+{
 | 
			
		||||
+	struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
 | 
			
		||||
+
 | 
			
		||||
+	/* Attach the panel or bridge to the dsi bridge */
 | 
			
		||||
+	return drm_bridge_attach(bridge->encoder, dsi->out_bridge,
 | 
			
		||||
+				 &dsi->bridge, flags);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static ssize_t vc4_dsi_host_transfer(struct mipi_dsi_host *host,
 | 
			
		||||
 				     const struct mipi_dsi_msg *msg)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1303,6 +1344,7 @@ static int vc4_dsi_host_attach(struct mi
 | 
			
		||||
 			       struct mipi_dsi_device *device)
 | 
			
		||||
 {
 | 
			
		||||
 	struct vc4_dsi *dsi = host_to_dsi(host);
 | 
			
		||||
+	int ret;
 | 
			
		||||
 
 | 
			
		||||
 	dsi->lanes = device->lanes;
 | 
			
		||||
 	dsi->channel = device->channel;
 | 
			
		||||
@@ -1337,7 +1379,15 @@ static int vc4_dsi_host_attach(struct mi
 | 
			
		||||
 		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	return component_add(&dsi->pdev->dev, &vc4_dsi_ops);
 | 
			
		||||
+	drm_bridge_add(&dsi->bridge);
 | 
			
		||||
+
 | 
			
		||||
+	ret = component_add(&dsi->pdev->dev, &vc4_dsi_ops);
 | 
			
		||||
+	if (ret) {
 | 
			
		||||
+		drm_bridge_remove(&dsi->bridge);
 | 
			
		||||
+		return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int vc4_dsi_host_detach(struct mipi_dsi_host *host,
 | 
			
		||||
@@ -1346,6 +1396,7 @@ static int vc4_dsi_host_detach(struct mi
 | 
			
		||||
 	struct vc4_dsi *dsi = host_to_dsi(host);
 | 
			
		||||
 
 | 
			
		||||
 	component_del(&dsi->pdev->dev, &vc4_dsi_ops);
 | 
			
		||||
+	drm_bridge_remove(&dsi->bridge);
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
@@ -1355,11 +1406,16 @@ static const struct mipi_dsi_host_ops vc
 | 
			
		||||
 	.transfer = vc4_dsi_host_transfer,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
-static const struct drm_encoder_helper_funcs vc4_dsi_encoder_helper_funcs = {
 | 
			
		||||
-	.atomic_disable = vc4_dsi_encoder_disable,
 | 
			
		||||
-	.atomic_enable = vc4_dsi_encoder_enable,
 | 
			
		||||
-	.mode_fixup = vc4_dsi_encoder_mode_fixup,
 | 
			
		||||
-	.atomic_mode_set = vc4_dsi_encoder_mode_set,
 | 
			
		||||
+static const struct drm_bridge_funcs vc4_dsi_bridge_funcs = {
 | 
			
		||||
+	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
 | 
			
		||||
+	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
 | 
			
		||||
+	.atomic_reset = drm_atomic_helper_bridge_reset,
 | 
			
		||||
+	.atomic_pre_enable = vc4_dsi_bridge_pre_enable,
 | 
			
		||||
+	.atomic_enable = vc4_dsi_bridge_enable,
 | 
			
		||||
+	.atomic_disable = vc4_dsi_bridge_disable,
 | 
			
		||||
+	.atomic_post_disable = vc4_dsi_bridge_post_disable,
 | 
			
		||||
+	.attach = vc4_dsi_bridge_attach,
 | 
			
		||||
+	.mode_fixup = vc4_dsi_bridge_mode_fixup,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static int vc4_dsi_late_register(struct drm_encoder *encoder)
 | 
			
		||||
@@ -1734,13 +1790,11 @@ static int vc4_dsi_bind(struct device *d
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	drm_encoder_helper_add(encoder, &vc4_dsi_encoder_helper_funcs);
 | 
			
		||||
-
 | 
			
		||||
 	ret = devm_pm_runtime_enable(dev);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	ret = drm_bridge_attach(encoder, dsi->out_bridge, NULL, 0);
 | 
			
		||||
+	ret = drm_bridge_attach(encoder, &dsi->bridge, NULL, 0);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -1762,7 +1816,11 @@ static int vc4_dsi_dev_probe(struct plat
 | 
			
		||||
 	dev_set_drvdata(dev, dsi);
 | 
			
		||||
 
 | 
			
		||||
 	kref_init(&dsi->kref);
 | 
			
		||||
+
 | 
			
		||||
 	dsi->pdev = pdev;
 | 
			
		||||
+	dsi->bridge.funcs = &vc4_dsi_bridge_funcs;
 | 
			
		||||
+	dsi->bridge.of_node = dev->of_node;
 | 
			
		||||
+	dsi->bridge.type = DRM_MODE_CONNECTOR_DSI;
 | 
			
		||||
 	dsi->dsi_host.ops = &vc4_dsi_host_ops;
 | 
			
		||||
 	dsi->dsi_host.dev = dev;
 | 
			
		||||
 	mipi_dsi_host_register(&dsi->dsi_host);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
From 8e57d84f06b6847efff162a69223200fe6553319 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 11 Feb 2022 14:15:26 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Remove entry to ULPS from vc4_dsi post_disable
 | 
			
		||||
 | 
			
		||||
Post_disable was sending the D-PHY sequence to put any device
 | 
			
		||||
into ULPS suspend mode, and then cutting power to the DSI block.
 | 
			
		||||
The power-on reset state of the DSI block is for DSI to be in
 | 
			
		||||
an operational state, not ULPS, so it then never sent the sequence
 | 
			
		||||
for exiting ULPS. Any attached device that didn't have an external
 | 
			
		||||
reset therefore remained in ULPS / standby, and didn't function.
 | 
			
		||||
 | 
			
		||||
Use of ULPS isn't well specified in DRM, therefore remove entering
 | 
			
		||||
it to avoid the above situation.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_dsi.c | 2 --
 | 
			
		||||
 1 file changed, 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_dsi.c
 | 
			
		||||
@@ -813,8 +813,6 @@ static void vc4_dsi_bridge_post_disable(
 | 
			
		||||
 	struct vc4_dsi *dsi = bridge_to_vc4_dsi(bridge);
 | 
			
		||||
 	struct device *dev = &dsi->pdev->dev;
 | 
			
		||||
 
 | 
			
		||||
-	vc4_dsi_ulps(dsi, true);
 | 
			
		||||
-
 | 
			
		||||
 	clk_disable_unprepare(dsi->pll_phy_clock);
 | 
			
		||||
 	clk_disable_unprepare(dsi->escape_clock);
 | 
			
		||||
 	clk_disable_unprepare(dsi->pixel_clock);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,47 @@
 | 
			
		|||
From beb8ee0d475c6320eed3024686702d439db24f66 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Wed, 23 Feb 2022 15:36:56 +0000
 | 
			
		||||
Subject: [PATCH] drm/panel: Add prepare_upstream_first flag to drm_panel
 | 
			
		||||
 | 
			
		||||
Mapping to the drm_bridge flag pre_enable_upstream_first,
 | 
			
		||||
add a new flag prepare_upstream_first to drm_panel to allow
 | 
			
		||||
the panel driver to request that the upstream bridge should
 | 
			
		||||
be pre_enabled before the panel prepare.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/bridge/panel.c |  3 +++
 | 
			
		||||
 include/drm/drm_panel.h        | 10 ++++++++++
 | 
			
		||||
 2 files changed, 13 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/bridge/panel.c
 | 
			
		||||
+++ b/drivers/gpu/drm/bridge/panel.c
 | 
			
		||||
@@ -258,6 +258,9 @@ struct drm_bridge *drm_panel_bridge_add_
 | 
			
		||||
 	panel_bridge->bridge.ops = DRM_BRIDGE_OP_MODES;
 | 
			
		||||
 	panel_bridge->bridge.type = connector_type;
 | 
			
		||||
 
 | 
			
		||||
+	panel_bridge->bridge.pre_enable_upstream_first =
 | 
			
		||||
+						panel->prepare_upstream_first;
 | 
			
		||||
+
 | 
			
		||||
 	drm_bridge_add(&panel_bridge->bridge);
 | 
			
		||||
 
 | 
			
		||||
 	return &panel_bridge->bridge;
 | 
			
		||||
--- a/include/drm/drm_panel.h
 | 
			
		||||
+++ b/include/drm/drm_panel.h
 | 
			
		||||
@@ -196,6 +196,16 @@ struct drm_panel {
 | 
			
		||||
 	 * Panel entry in registry.
 | 
			
		||||
 	 */
 | 
			
		||||
 	struct list_head list;
 | 
			
		||||
+
 | 
			
		||||
+	/**
 | 
			
		||||
+	 * @prepare_upstream_first:
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * The upstream controller should be prepared first, before the prepare
 | 
			
		||||
+	 * for the panel is called. This is largely required for DSI panels
 | 
			
		||||
+	 * where the DSI host controller should be initialised to LP-11 before
 | 
			
		||||
+	 * the panel is powered up.
 | 
			
		||||
+	 */
 | 
			
		||||
+	bool prepare_upstream_first;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 void drm_panel_init(struct drm_panel *panel, struct device *dev,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
From 115fd0087451349c1e2761e89984545fe614c181 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 11 Mar 2022 17:24:37 +0000
 | 
			
		||||
Subject: [PATCH] drm: Include drm_connector.h from drm_panel.h
 | 
			
		||||
 | 
			
		||||
drm_panel.h wants to reference enum drm_panel_orientation which is defined
 | 
			
		||||
in drm_connector.h (despite the name).
 | 
			
		||||
Include drm_connector.h in drm_panel.h to avoid the rare situation where
 | 
			
		||||
drm_panel.h is used with drm_connector.h
 | 
			
		||||
 | 
			
		||||
https://github.com/raspberrypi/linux/issues/4919
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 include/drm/drm_panel.h | 3 +--
 | 
			
		||||
 1 file changed, 1 insertion(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/include/drm/drm_panel.h
 | 
			
		||||
+++ b/include/drm/drm_panel.h
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
 #ifndef __DRM_PANEL_H__
 | 
			
		||||
 #define __DRM_PANEL_H__
 | 
			
		||||
 
 | 
			
		||||
+#include <drm/drm_connector.h>
 | 
			
		||||
 #include <linux/err.h>
 | 
			
		||||
 #include <linux/errno.h>
 | 
			
		||||
 #include <linux/list.h>
 | 
			
		||||
@@ -36,8 +37,6 @@ struct drm_device;
 | 
			
		||||
 struct drm_panel;
 | 
			
		||||
 struct display_timing;
 | 
			
		||||
 
 | 
			
		||||
-enum drm_panel_orientation;
 | 
			
		||||
-
 | 
			
		||||
 /**
 | 
			
		||||
  * struct drm_panel_funcs - perform operations on a given panel
 | 
			
		||||
  *
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
From 4c5c0fa5ae4aeee2ca588935960aa48e666dafda Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Thu, 16 Dec 2021 15:33:43 +0000
 | 
			
		||||
Subject: [PATCH] drm/tc358762: Set the pre_enable_upstream_first flag to
 | 
			
		||||
 configure DSI host
 | 
			
		||||
 | 
			
		||||
TC358762 wants the DSI host to be prepared before it is powered up, so
 | 
			
		||||
set the flag to request that the upstream bridges have their
 | 
			
		||||
pre_enable called first.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/bridge/tc358762.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/bridge/tc358762.c
 | 
			
		||||
+++ b/drivers/gpu/drm/bridge/tc358762.c
 | 
			
		||||
@@ -229,6 +229,7 @@ static int tc358762_probe(struct mipi_ds
 | 
			
		||||
 	ctx->bridge.funcs = &tc358762_bridge_funcs;
 | 
			
		||||
 	ctx->bridge.type = DRM_MODE_CONNECTOR_DPI;
 | 
			
		||||
 	ctx->bridge.of_node = dev->of_node;
 | 
			
		||||
+	ctx->bridge.pre_enable_upstream_first = true;
 | 
			
		||||
 
 | 
			
		||||
 	drm_bridge_add(&ctx->bridge);
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,144 @@
 | 
			
		|||
From 5680572cb50065d522e64792a64f915cee0f6cfb Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Tue, 25 Jan 2022 17:28:18 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: Support zpos on all planes
 | 
			
		||||
 | 
			
		||||
Adds the zpos property to all planes, and creates the dlist
 | 
			
		||||
by placing the fragments in the correct order based on zpos.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c   | 43 +++++++++++++++++++++------------
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_kms.c   |  3 +--
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 22 ++++++++++++++---
 | 
			
		||||
 3 files changed, 48 insertions(+), 20 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -769,6 +769,8 @@ void vc4_hvs_atomic_flush(struct drm_crt
 | 
			
		||||
 	bool enable_bg_fill = false;
 | 
			
		||||
 	u32 __iomem *dlist_start = vc4->hvs->dlist + vc4_state->mm.start;
 | 
			
		||||
 	u32 __iomem *dlist_next = dlist_start;
 | 
			
		||||
+	unsigned int zpos = 0;
 | 
			
		||||
+	bool found = false;
 | 
			
		||||
 	int idx;
 | 
			
		||||
 
 | 
			
		||||
 	if (!drm_dev_enter(dev, &idx)) {
 | 
			
		||||
@@ -782,23 +784,34 @@ void vc4_hvs_atomic_flush(struct drm_crt
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* Copy all the active planes' dlist contents to the hardware dlist. */
 | 
			
		||||
-	drm_atomic_crtc_for_each_plane(plane, crtc) {
 | 
			
		||||
-		/* Is this the first active plane? */
 | 
			
		||||
-		if (dlist_next == dlist_start) {
 | 
			
		||||
-			/* We need to enable background fill when a plane
 | 
			
		||||
-			 * could be alpha blending from the background, i.e.
 | 
			
		||||
-			 * where no other plane is underneath. It suffices to
 | 
			
		||||
-			 * consider the first active plane here since we set
 | 
			
		||||
-			 * needs_bg_fill such that either the first plane
 | 
			
		||||
-			 * already needs it or all planes on top blend from
 | 
			
		||||
-			 * the first or a lower plane.
 | 
			
		||||
-			 */
 | 
			
		||||
-			vc4_plane_state = to_vc4_plane_state(plane->state);
 | 
			
		||||
-			enable_bg_fill = vc4_plane_state->needs_bg_fill;
 | 
			
		||||
+	do {
 | 
			
		||||
+		found = false;
 | 
			
		||||
+
 | 
			
		||||
+		drm_atomic_crtc_for_each_plane(plane, crtc) {
 | 
			
		||||
+			if (plane->state->normalized_zpos != zpos)
 | 
			
		||||
+				continue;
 | 
			
		||||
+
 | 
			
		||||
+			/* Is this the first active plane? */
 | 
			
		||||
+			if (dlist_next == dlist_start) {
 | 
			
		||||
+				/* We need to enable background fill when a plane
 | 
			
		||||
+				 * could be alpha blending from the background, i.e.
 | 
			
		||||
+				 * where no other plane is underneath. It suffices to
 | 
			
		||||
+				 * consider the first active plane here since we set
 | 
			
		||||
+				 * needs_bg_fill such that either the first plane
 | 
			
		||||
+				 * already needs it or all planes on top blend from
 | 
			
		||||
+				 * the first or a lower plane.
 | 
			
		||||
+				 */
 | 
			
		||||
+				vc4_plane_state = to_vc4_plane_state(plane->state);
 | 
			
		||||
+				enable_bg_fill = vc4_plane_state->needs_bg_fill;
 | 
			
		||||
+			}
 | 
			
		||||
+
 | 
			
		||||
+			dlist_next += vc4_plane_write_dlist(plane, dlist_next);
 | 
			
		||||
+
 | 
			
		||||
+			found = true;
 | 
			
		||||
 		}
 | 
			
		||||
 
 | 
			
		||||
-		dlist_next += vc4_plane_write_dlist(plane, dlist_next);
 | 
			
		||||
-	}
 | 
			
		||||
+		zpos++;
 | 
			
		||||
+	} while (found);
 | 
			
		||||
 
 | 
			
		||||
 	writel(SCALER_CTL0_END, dlist_next);
 | 
			
		||||
 	dlist_next++;
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_kms.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
 | 
			
		||||
@@ -1066,8 +1066,7 @@ int vc4_kms_load(struct drm_device *dev)
 | 
			
		||||
 	dev->mode_config.helper_private = &vc4_mode_config_helpers;
 | 
			
		||||
 	dev->mode_config.preferred_depth = 24;
 | 
			
		||||
 	dev->mode_config.async_page_flip = true;
 | 
			
		||||
-	if (vc4->firmware_kms)
 | 
			
		||||
-		dev->mode_config.normalize_zpos = true;
 | 
			
		||||
+	dev->mode_config.normalize_zpos = true;
 | 
			
		||||
 
 | 
			
		||||
 	ret = vc4_ctm_obj_init(vc4);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -1600,9 +1600,14 @@ struct drm_plane *vc4_plane_init(struct
 | 
			
		||||
 					  DRM_COLOR_YCBCR_BT709,
 | 
			
		||||
 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
 | 
			
		||||
 
 | 
			
		||||
+	if (type == DRM_PLANE_TYPE_PRIMARY)
 | 
			
		||||
+		drm_plane_create_zpos_immutable_property(plane, 0);
 | 
			
		||||
+
 | 
			
		||||
 	return plane;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+#define VC4_NUM_OVERLAY_PLANES	16
 | 
			
		||||
+
 | 
			
		||||
 int vc4_plane_create_additional_planes(struct drm_device *drm)
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_plane *cursor_plane;
 | 
			
		||||
@@ -1618,24 +1623,35 @@ int vc4_plane_create_additional_planes(s
 | 
			
		||||
 	 * modest number of planes to expose, that should hopefully
 | 
			
		||||
 	 * still cover any sane usecase.
 | 
			
		||||
 	 */
 | 
			
		||||
-	for (i = 0; i < 16; i++) {
 | 
			
		||||
+	for (i = 0; i < VC4_NUM_OVERLAY_PLANES; i++) {
 | 
			
		||||
 		struct drm_plane *plane =
 | 
			
		||||
 			vc4_plane_init(drm, DRM_PLANE_TYPE_OVERLAY,
 | 
			
		||||
 				       GENMASK(drm->mode_config.num_crtc - 1, 0));
 | 
			
		||||
 
 | 
			
		||||
 		if (IS_ERR(plane))
 | 
			
		||||
 			continue;
 | 
			
		||||
+
 | 
			
		||||
+		/* Create zpos property. Max of all the overlays + 1 primary +
 | 
			
		||||
+		 * 1 cursor plane on a crtc.
 | 
			
		||||
+		 */
 | 
			
		||||
+		drm_plane_create_zpos_property(plane, i + 1, 1,
 | 
			
		||||
+					       VC4_NUM_OVERLAY_PLANES + 1);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	drm_for_each_crtc(crtc, drm) {
 | 
			
		||||
 		/* Set up the legacy cursor after overlay initialization,
 | 
			
		||||
-		 * since we overlay planes on the CRTC in the order they were
 | 
			
		||||
-		 * initialized.
 | 
			
		||||
+		 * since the zpos fallback is that planes are rendered by plane
 | 
			
		||||
+		 * ID order, and that then puts the cursor on top.
 | 
			
		||||
 		 */
 | 
			
		||||
 		cursor_plane = vc4_plane_init(drm, DRM_PLANE_TYPE_CURSOR,
 | 
			
		||||
 					      drm_crtc_mask(crtc));
 | 
			
		||||
 		if (!IS_ERR(cursor_plane)) {
 | 
			
		||||
 			crtc->cursor = cursor_plane;
 | 
			
		||||
+
 | 
			
		||||
+			drm_plane_create_zpos_property(cursor_plane,
 | 
			
		||||
+						       VC4_NUM_OVERLAY_PLANES + 1,
 | 
			
		||||
+						       1,
 | 
			
		||||
+						       VC4_NUM_OVERLAY_PLANES + 1);
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,301 @@
 | 
			
		|||
From a363b78747ab3cbb671848c9d313deff4e3ef929 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 7 Mar 2022 15:19:38 +0000
 | 
			
		||||
Subject: [PATCH] drm/vc4: hdmi: Add CSC for BT601/709/2020 limited and full
 | 
			
		||||
 range output
 | 
			
		||||
 | 
			
		||||
The HVS always composes in the RGB domain, but there is a colourspace
 | 
			
		||||
conversion block on the output to allow for sending YCbCr over the
 | 
			
		||||
HDMI interface.
 | 
			
		||||
The colourspace on that link is configurable via the "Colorspace"
 | 
			
		||||
property on the connector, and that updates the infoframes. There
 | 
			
		||||
is also selection of limited or full range based on the mode selected
 | 
			
		||||
or an override.
 | 
			
		||||
 | 
			
		||||
Add code to update the CSC as well so that the metadata matches the
 | 
			
		||||
image data.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hdmi.c | 196 ++++++++++++++++++++++++---------
 | 
			
		||||
 1 file changed, 145 insertions(+), 51 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
 | 
			
		||||
@@ -158,8 +158,8 @@ static bool vc4_hdmi_mode_needs_scrambli
 | 
			
		||||
 	return clock > HDMI_14_MAX_TMDS_CLK;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static bool vc4_hdmi_is_full_range_rgb(struct vc4_hdmi *vc4_hdmi,
 | 
			
		||||
-				       const struct drm_display_mode *mode)
 | 
			
		||||
+static bool vc4_hdmi_is_full_range(struct vc4_hdmi *vc4_hdmi,
 | 
			
		||||
+				   const struct drm_display_mode *mode)
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_display_info *display = &vc4_hdmi->connector.display_info;
 | 
			
		||||
 
 | 
			
		||||
@@ -901,7 +901,7 @@ static void vc4_hdmi_set_avi_infoframe(s
 | 
			
		||||
 
 | 
			
		||||
 	drm_hdmi_avi_infoframe_quant_range(&frame.avi,
 | 
			
		||||
 					   connector, mode,
 | 
			
		||||
-					   vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode) ?
 | 
			
		||||
+					   vc4_hdmi_is_full_range(vc4_hdmi, mode) ?
 | 
			
		||||
 					   HDMI_QUANTIZATION_RANGE_FULL :
 | 
			
		||||
 					   HDMI_QUANTIZATION_RANGE_LIMITED);
 | 
			
		||||
 	drm_hdmi_avi_infoframe_colorimetry(&frame.avi, cstate);
 | 
			
		||||
@@ -1154,7 +1154,7 @@ static void vc4_hdmi_csc_setup(struct vc
 | 
			
		||||
 	csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
 | 
			
		||||
 				VC4_HD_CSC_CTL_ORDER);
 | 
			
		||||
 
 | 
			
		||||
-	if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode)) {
 | 
			
		||||
+	if (!vc4_hdmi_is_full_range(vc4_hdmi, mode)) {
 | 
			
		||||
 		/* CEA VICs other than #1 requre limited range RGB
 | 
			
		||||
 		 * output unless overridden by an AVI infoframe.
 | 
			
		||||
 		 * Apply a colorspace conversion to squash 0-255 down
 | 
			
		||||
@@ -1193,15 +1193,6 @@ static void vc4_hdmi_csc_setup(struct vc
 | 
			
		||||
  * [ 0      1      0      0]
 | 
			
		||||
  * [ 0      0      1      0]
 | 
			
		||||
  *
 | 
			
		||||
- * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 | 
			
		||||
- */
 | 
			
		||||
-static const u16 vc5_hdmi_csc_full_rgb_unity[3][4] = {
 | 
			
		||||
-	{ 0x2000, 0x0000, 0x0000, 0x0000 },
 | 
			
		||||
-	{ 0x0000, 0x2000, 0x0000, 0x0000 },
 | 
			
		||||
-	{ 0x0000, 0x0000, 0x2000, 0x0000 },
 | 
			
		||||
-};
 | 
			
		||||
-
 | 
			
		||||
-/*
 | 
			
		||||
  * CEA VICs other than #1 require limited range RGB output unless
 | 
			
		||||
  * overridden by an AVI infoframe. Apply a colorspace conversion to
 | 
			
		||||
  * squash 0-255 down to 16-235. The matrix here is:
 | 
			
		||||
@@ -1212,43 +1203,105 @@ static const u16 vc5_hdmi_csc_full_rgb_u
 | 
			
		||||
  *
 | 
			
		||||
  * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 | 
			
		||||
  */
 | 
			
		||||
-static const u16 vc5_hdmi_csc_full_rgb_to_limited_rgb[3][4] = {
 | 
			
		||||
-	{ 0x1b80, 0x0000, 0x0000, 0x0400 },
 | 
			
		||||
-	{ 0x0000, 0x1b80, 0x0000, 0x0400 },
 | 
			
		||||
-	{ 0x0000, 0x0000, 0x1b80, 0x0400 },
 | 
			
		||||
+static const u16 vc5_hdmi_csc_full_rgb_to_rgb[2][3][4] = {
 | 
			
		||||
+	{
 | 
			
		||||
+		/* Full range - unity */
 | 
			
		||||
+		{ 0x2000, 0x0000, 0x0000, 0x0000 },
 | 
			
		||||
+		{ 0x0000, 0x2000, 0x0000, 0x0000 },
 | 
			
		||||
+		{ 0x0000, 0x0000, 0x2000, 0x0000 },
 | 
			
		||||
+	}, {
 | 
			
		||||
+		/* Limited range */
 | 
			
		||||
+		{ 0x1b80, 0x0000, 0x0000, 0x0400 },
 | 
			
		||||
+		{ 0x0000, 0x1b80, 0x0000, 0x0400 },
 | 
			
		||||
+		{ 0x0000, 0x0000, 0x1b80, 0x0400 },
 | 
			
		||||
+	}
 | 
			
		||||
+};
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * Conversion between Full Range RGB and YUV using the BT.601 Colorspace
 | 
			
		||||
+ *
 | 
			
		||||
+ * Full range
 | 
			
		||||
+ * [    0.299000   0.587000   0.114000   0.000000 ]
 | 
			
		||||
+ * [   -0.168736  -0.331264   0.500000 128.000000 ]
 | 
			
		||||
+ * [    0.500000  -0.418688  -0.081312 128.000000 ]
 | 
			
		||||
+ *
 | 
			
		||||
+ * Limited range
 | 
			
		||||
+ * [    0.255785   0.502160   0.097523  16.000000 ]
 | 
			
		||||
+ * [   -0.147644  -0.289856   0.437500 128.000000 ]
 | 
			
		||||
+ * [    0.437500  -0.366352  -0.071148 128.000000 ]
 | 
			
		||||
+ *
 | 
			
		||||
+ * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 | 
			
		||||
+ */
 | 
			
		||||
+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt601[2][3][4] = {
 | 
			
		||||
+	{
 | 
			
		||||
+		/* Full range */
 | 
			
		||||
+		{ 0x0991, 0x12c9, 0x03a6, 0x0000 },
 | 
			
		||||
+		{ 0xfa9b, 0xf567, 0x1000, 0x2000 },
 | 
			
		||||
+		{ 0x1000, 0xf29b, 0xfd67, 0x2000 },
 | 
			
		||||
+	}, {
 | 
			
		||||
+		/* Limited range */
 | 
			
		||||
+		{ 0x082f, 0x1012, 0x031f, 0x0400 },
 | 
			
		||||
+		{ 0xfb48, 0xf6ba, 0x0e00, 0x2000 },
 | 
			
		||||
+		{ 0x0e00, 0xf448, 0xfdba, 0x2000 },
 | 
			
		||||
+	}
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
- * Conversion between Full Range RGB and Full Range YUV422 using the
 | 
			
		||||
- * BT.709 Colorspace
 | 
			
		||||
+ * Conversion between Full Range RGB and YUV using the BT.709 Colorspace
 | 
			
		||||
  *
 | 
			
		||||
+ * Full range
 | 
			
		||||
+ * [    0.212600   0.715200   0.072200   0.000000 ]
 | 
			
		||||
+ * [   -0.114572  -0.385428   0.500000 128.000000 ]
 | 
			
		||||
+ * [    0.500000  -0.454153  -0.045847 128.000000 ]
 | 
			
		||||
  *
 | 
			
		||||
- * [  0.181906  0.611804  0.061758  16  ]
 | 
			
		||||
- * [ -0.100268 -0.337232  0.437500  128 ]
 | 
			
		||||
- * [  0.437500 -0.397386 -0.040114  128 ]
 | 
			
		||||
+ * Limited range
 | 
			
		||||
+ * [    0.181873   0.611831   0.061765  16.000000 ]
 | 
			
		||||
+ * [   -0.100251  -0.337249   0.437500 128.000000 ]
 | 
			
		||||
+ * [    0.437500  -0.397384  -0.040116 128.000000 ]
 | 
			
		||||
  *
 | 
			
		||||
  * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 | 
			
		||||
  */
 | 
			
		||||
-static const u16 vc5_hdmi_csc_full_rgb_to_limited_yuv422_bt709[3][4] = {
 | 
			
		||||
-	{ 0x05d2, 0x1394, 0x01fa, 0x0400 },
 | 
			
		||||
-	{ 0xfccc, 0xf536, 0x0e00, 0x2000 },
 | 
			
		||||
-	{ 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
 | 
			
		||||
+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt709[2][3][4] = {
 | 
			
		||||
+	{
 | 
			
		||||
+		/* Full range */
 | 
			
		||||
+		{ 0x06ce, 0x16e3, 0x024f, 0x0000 },
 | 
			
		||||
+		{ 0xfc56, 0xf3ac, 0x1000, 0x2000 },
 | 
			
		||||
+		{ 0x1000, 0xf179, 0xfe89, 0x2000 },
 | 
			
		||||
+	}, {
 | 
			
		||||
+		/* Limited range	*/
 | 
			
		||||
+		{ 0x05d2, 0x1394, 0x01fa, 0x0400 },
 | 
			
		||||
+		{ 0xfccc, 0xf536, 0x0e00, 0x2000 },
 | 
			
		||||
+		{ 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
 | 
			
		||||
+	}
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
- * Conversion between Full Range RGB and Full Range YUV444 using the
 | 
			
		||||
- * BT.709 Colorspace
 | 
			
		||||
+ * Conversion between Full Range RGB and YUV using the BT.2020 Colorspace
 | 
			
		||||
  *
 | 
			
		||||
- * [ -0.100268 -0.337232  0.437500  128 ]
 | 
			
		||||
- * [  0.437500 -0.397386 -0.040114  128 ]
 | 
			
		||||
- * [  0.181906  0.611804  0.061758  16  ]
 | 
			
		||||
+ * Full range
 | 
			
		||||
+ * [    0.262700   0.678000   0.059300   0.000000 ]
 | 
			
		||||
+ * [   -0.139630  -0.360370   0.500000 128.000000 ]
 | 
			
		||||
+ * [    0.500000  -0.459786  -0.040214 128.000000 ]
 | 
			
		||||
+ *
 | 
			
		||||
+ * Limited range
 | 
			
		||||
+ * [    0.224732   0.580008   0.050729  16.000000 ]
 | 
			
		||||
+ * [   -0.122176  -0.315324   0.437500 128.000000 ]
 | 
			
		||||
+ * [    0.437500  -0.402312  -0.035188 128.000000 ]
 | 
			
		||||
  *
 | 
			
		||||
  * Matrix is signed 2p13 fixed point, with signed 9p6 offsets
 | 
			
		||||
  */
 | 
			
		||||
-static const u16 vc5_hdmi_csc_full_rgb_to_limited_yuv444_bt709[3][4] = {
 | 
			
		||||
-	{ 0xfccc, 0xf536, 0x0e00, 0x2000 },
 | 
			
		||||
-	{ 0x0e00, 0xf34a, 0xfeb8, 0x2000 },
 | 
			
		||||
-	{ 0x05d2, 0x1394, 0x01fa, 0x0400 },
 | 
			
		||||
+static const u16 vc5_hdmi_csc_full_rgb_to_yuv_bt2020[2][3][4] = {
 | 
			
		||||
+	{
 | 
			
		||||
+		/* Full range */
 | 
			
		||||
+		{ 0x0868, 0x15b2, 0x01e6, 0x0000 },
 | 
			
		||||
+		{ 0xfb89, 0xf479, 0x1000, 0x2000 },
 | 
			
		||||
+		{ 0x1000, 0xf14a, 0xfeb8, 0x2000 },
 | 
			
		||||
+	}, {
 | 
			
		||||
+		/* Limited range */
 | 
			
		||||
+		{ 0x0731, 0x128f, 0x01a0, 0x0400 },
 | 
			
		||||
+		{ 0xfc18, 0xf5ea, 0x0e00, 0x2000 },
 | 
			
		||||
+		{ 0x0e00, 0xf321, 0xfee1, 0x2000 },
 | 
			
		||||
+	}
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static void vc5_hdmi_set_csc_coeffs(struct vc4_hdmi *vc4_hdmi,
 | 
			
		||||
@@ -1264,6 +1317,20 @@ static void vc5_hdmi_set_csc_coeffs(stru
 | 
			
		||||
 	HDMI_WRITE(HDMI_CSC_34_33, (coeffs[2][3] << 16) | coeffs[2][2]);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void vc5_hdmi_set_csc_coeffs_swap(struct vc4_hdmi *vc4_hdmi,
 | 
			
		||||
+					 const u16 coeffs[3][4])
 | 
			
		||||
+{
 | 
			
		||||
+	lockdep_assert_held(&vc4_hdmi->hw_lock);
 | 
			
		||||
+
 | 
			
		||||
+	/* YUV444 needs the CSC matrices using the channels in a different order */
 | 
			
		||||
+	HDMI_WRITE(HDMI_CSC_12_11, (coeffs[2][1] << 16) | coeffs[2][0]);
 | 
			
		||||
+	HDMI_WRITE(HDMI_CSC_14_13, (coeffs[2][3] << 16) | coeffs[2][2]);
 | 
			
		||||
+	HDMI_WRITE(HDMI_CSC_22_21, (coeffs[0][1] << 16) | coeffs[0][0]);
 | 
			
		||||
+	HDMI_WRITE(HDMI_CSC_24_23, (coeffs[0][3] << 16) | coeffs[0][2]);
 | 
			
		||||
+	HDMI_WRITE(HDMI_CSC_32_31, (coeffs[1][1] << 16) | coeffs[1][0]);
 | 
			
		||||
+	HDMI_WRITE(HDMI_CSC_34_33, (coeffs[1][3] << 16) | coeffs[1][2]);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi,
 | 
			
		||||
 			       struct drm_connector_state *state,
 | 
			
		||||
 			       const struct drm_display_mode *mode)
 | 
			
		||||
@@ -1271,6 +1338,8 @@ static void vc5_hdmi_csc_setup(struct vc
 | 
			
		||||
 	struct drm_device *drm = vc4_hdmi->connector.dev;
 | 
			
		||||
 	struct vc4_hdmi_connector_state *vc4_state =
 | 
			
		||||
 		conn_state_to_vc4_hdmi_conn_state(state);
 | 
			
		||||
+	unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, mode) ? 0 : 1;
 | 
			
		||||
+	const u16 (*csc)[4];
 | 
			
		||||
 	unsigned long flags;
 | 
			
		||||
 	u32 if_cfg = 0;
 | 
			
		||||
 	u32 if_xbar = 0x543210;
 | 
			
		||||
@@ -1286,31 +1355,56 @@ static void vc5_hdmi_csc_setup(struct vc
 | 
			
		||||
 
 | 
			
		||||
 	switch (vc4_state->output_format) {
 | 
			
		||||
 	case VC4_HDMI_OUTPUT_YUV444:
 | 
			
		||||
-		vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_yuv444_bt709);
 | 
			
		||||
-		break;
 | 
			
		||||
-
 | 
			
		||||
 	case VC4_HDMI_OUTPUT_YUV422:
 | 
			
		||||
-		csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
 | 
			
		||||
-					 VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) |
 | 
			
		||||
-			VC5_MT_CP_CSC_CTL_USE_444_TO_422 |
 | 
			
		||||
-			VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION;
 | 
			
		||||
-
 | 
			
		||||
-		csc_chan_ctl |= VC4_SET_FIELD(VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE,
 | 
			
		||||
-					      VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP);
 | 
			
		||||
+		switch (state->colorspace) {
 | 
			
		||||
+		default:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_NO_DATA:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_BT709_YCC:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_XVYCC_709:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT:
 | 
			
		||||
+			csc = vc5_hdmi_csc_full_rgb_to_yuv_bt709[lim_range];
 | 
			
		||||
+			break;
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_SMPTE_170M_YCC:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_XVYCC_601:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_SYCC_601:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_OPYCC_601:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_BT601_YCC:
 | 
			
		||||
+			csc = vc5_hdmi_csc_full_rgb_to_yuv_bt601[lim_range];
 | 
			
		||||
+			break;
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_BT2020_CYCC:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_BT2020_YCC:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_BT2020_RGB:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_DCI_P3_RGB_D65:
 | 
			
		||||
+		case DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER:
 | 
			
		||||
+			csc = vc5_hdmi_csc_full_rgb_to_yuv_bt2020[lim_range];
 | 
			
		||||
+			break;
 | 
			
		||||
+		}
 | 
			
		||||
 
 | 
			
		||||
-		if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY,
 | 
			
		||||
-					VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422);
 | 
			
		||||
+		if (vc4_state->output_format == VC4_HDMI_OUTPUT_YUV422) {
 | 
			
		||||
+			csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD,
 | 
			
		||||
+						 VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) |
 | 
			
		||||
+				VC5_MT_CP_CSC_CTL_USE_444_TO_422 |
 | 
			
		||||
+				VC5_MT_CP_CSC_CTL_USE_RNG_SUPPRESSION;
 | 
			
		||||
+
 | 
			
		||||
+			csc_chan_ctl |= VC4_SET_FIELD(VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP_LEGACY_STYLE,
 | 
			
		||||
+						      VC5_MT_CP_CHANNEL_CTL_OUTPUT_REMAP);
 | 
			
		||||
+
 | 
			
		||||
+			if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY,
 | 
			
		||||
+						VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422);
 | 
			
		||||
+
 | 
			
		||||
+			vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc);
 | 
			
		||||
+		} else {
 | 
			
		||||
+			vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc);
 | 
			
		||||
+		}
 | 
			
		||||
 
 | 
			
		||||
-		vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_yuv422_bt709);
 | 
			
		||||
 		break;
 | 
			
		||||
 
 | 
			
		||||
 	case VC4_HDMI_OUTPUT_RGB:
 | 
			
		||||
 		if_xbar = 0x354021;
 | 
			
		||||
 
 | 
			
		||||
-		if (!vc4_hdmi_is_full_range_rgb(vc4_hdmi, mode))
 | 
			
		||||
-			vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_limited_rgb);
 | 
			
		||||
-		else
 | 
			
		||||
-			vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_unity);
 | 
			
		||||
+		vc5_hdmi_set_csc_coeffs(vc4_hdmi,
 | 
			
		||||
+					vc5_hdmi_csc_full_rgb_to_rgb[lim_range]);
 | 
			
		||||
 		break;
 | 
			
		||||
 
 | 
			
		||||
 	default:
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,212 @@
 | 
			
		|||
From 75f54e3341ac80fc7d9a25b70f18fd0c1f586fb0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Mon, 14 Mar 2022 17:56:10 +0000
 | 
			
		||||
Subject: [PATCH] vc4/drm: vc4_plane: Keep fractional source coords inside
 | 
			
		||||
 state
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_drv.h   |  2 +-
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 68 ++++++++++++++++-----------------
 | 
			
		||||
 2 files changed, 34 insertions(+), 36 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
@@ -384,7 +384,7 @@ struct vc4_plane_state {
 | 
			
		||||
 
 | 
			
		||||
 	/* Clipped coordinates of the plane on the display. */
 | 
			
		||||
 	int crtc_x, crtc_y, crtc_w, crtc_h;
 | 
			
		||||
-	/* Clipped area being scanned from in the FB. */
 | 
			
		||||
+	/* Clipped area being scanned from in the FB in u16.16 format */
 | 
			
		||||
 	u32 src_x, src_y;
 | 
			
		||||
 
 | 
			
		||||
 	u32 src_w[2], src_h[2];
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -183,9 +183,9 @@ static const struct hvs_format *vc4_get_
 | 
			
		||||
 
 | 
			
		||||
 static enum vc4_scaling_mode vc4_get_scaling_mode(u32 src, u32 dst)
 | 
			
		||||
 {
 | 
			
		||||
-	if (dst == src)
 | 
			
		||||
+	if (dst == src >> 16)
 | 
			
		||||
 		return VC4_SCALING_NONE;
 | 
			
		||||
-	if (3 * dst >= 2 * src)
 | 
			
		||||
+	if (3 * dst >= 2 * (src >> 16))
 | 
			
		||||
 		return VC4_SCALING_PPF;
 | 
			
		||||
 	else
 | 
			
		||||
 		return VC4_SCALING_TPZ;
 | 
			
		||||
@@ -394,15 +394,10 @@ static int vc4_plane_setup_clipping_and_
 | 
			
		||||
 		vc4_state->offsets[i] = bo->dma_addr + fb->offsets[i];
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * We don't support subpixel source positioning for scaling,
 | 
			
		||||
-	 * but fractional coordinates can be generated by clipping
 | 
			
		||||
-	 * so just round for now
 | 
			
		||||
-	 */
 | 
			
		||||
-	vc4_state->src_x = DIV_ROUND_CLOSEST(state->src.x1, 1 << 16);
 | 
			
		||||
-	vc4_state->src_y = DIV_ROUND_CLOSEST(state->src.y1, 1 << 16);
 | 
			
		||||
-	vc4_state->src_w[0] = DIV_ROUND_CLOSEST(state->src.x2, 1 << 16) - vc4_state->src_x;
 | 
			
		||||
-	vc4_state->src_h[0] = DIV_ROUND_CLOSEST(state->src.y2, 1 << 16) - vc4_state->src_y;
 | 
			
		||||
+	vc4_state->src_x = state->src.x1;
 | 
			
		||||
+	vc4_state->src_y = state->src.y1;
 | 
			
		||||
+	vc4_state->src_w[0] = state->src.x2 - vc4_state->src_x;
 | 
			
		||||
+	vc4_state->src_h[0] = state->src.y2 - vc4_state->src_y;
 | 
			
		||||
 
 | 
			
		||||
 	vc4_state->crtc_x = state->dst.x1;
 | 
			
		||||
 	vc4_state->crtc_y = state->dst.y1;
 | 
			
		||||
@@ -455,7 +450,7 @@ static void vc4_write_tpz(struct vc4_pla
 | 
			
		||||
 {
 | 
			
		||||
 	u32 scale, recip;
 | 
			
		||||
 
 | 
			
		||||
-	scale = (1 << 16) * src / dst;
 | 
			
		||||
+	scale = src / dst;
 | 
			
		||||
 
 | 
			
		||||
 	/* The specs note that while the reciprocal would be defined
 | 
			
		||||
 	 * as (1<<32)/scale, ~0 is close enough.
 | 
			
		||||
@@ -501,7 +496,7 @@ static u32 vc4_lbm_size(struct drm_plane
 | 
			
		||||
 	if (vc4_state->x_scaling[0] == VC4_SCALING_TPZ)
 | 
			
		||||
 		pix_per_line = vc4_state->crtc_w;
 | 
			
		||||
 	else
 | 
			
		||||
-		pix_per_line = vc4_state->src_w[0];
 | 
			
		||||
+		pix_per_line = vc4_state->src_w[0] >> 16;
 | 
			
		||||
 
 | 
			
		||||
 	if (!vc4_state->is_yuv) {
 | 
			
		||||
 		if (vc4_state->y_scaling[0] == VC4_SCALING_TPZ)
 | 
			
		||||
@@ -592,7 +587,8 @@ static void vc4_plane_calc_load(struct d
 | 
			
		||||
 	for (i = 0; i < fb->format->num_planes; i++) {
 | 
			
		||||
 		/* Even if the bandwidth/plane required for a single frame is
 | 
			
		||||
 		 *
 | 
			
		||||
-		 * vc4_state->src_w[i] * vc4_state->src_h[i] * cpp * vrefresh
 | 
			
		||||
+		 * (vc4_state->src_w[i] >> 16) * (vc4_state->src_h[i] >> 16) *
 | 
			
		||||
+		 *  cpp * vrefresh
 | 
			
		||||
 		 *
 | 
			
		||||
 		 * when downscaling, we have to read more pixels per line in
 | 
			
		||||
 		 * the time frame reserved for a single line, so the bandwidth
 | 
			
		||||
@@ -601,11 +597,11 @@ static void vc4_plane_calc_load(struct d
 | 
			
		||||
 		 * load by this number. We're likely over-estimating the read
 | 
			
		||||
 		 * demand, but that's better than under-estimating it.
 | 
			
		||||
 		 */
 | 
			
		||||
-		vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i],
 | 
			
		||||
+		vscale_factor = DIV_ROUND_UP(vc4_state->src_h[i] >> 16,
 | 
			
		||||
 					     vc4_state->crtc_h);
 | 
			
		||||
-		vc4_state->membus_load += vc4_state->src_w[i] *
 | 
			
		||||
-					  vc4_state->src_h[i] * vscale_factor *
 | 
			
		||||
-					  fb->format->cpp[i];
 | 
			
		||||
+		vc4_state->membus_load += (vc4_state->src_w[i] >> 16) *
 | 
			
		||||
+					  (vc4_state->src_h[i] >> 16) *
 | 
			
		||||
+					  vscale_factor * fb->format->cpp[i];
 | 
			
		||||
 		vc4_state->hvs_load += vc4_state->crtc_h * vc4_state->crtc_w;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -758,7 +754,8 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 	bool mix_plane_alpha;
 | 
			
		||||
 	bool covers_screen;
 | 
			
		||||
 	u32 scl0, scl1, pitch0;
 | 
			
		||||
-	u32 tiling, src_y;
 | 
			
		||||
+	u32 tiling, src_x, src_y;
 | 
			
		||||
+	u32 width, height;
 | 
			
		||||
 	u32 hvs_format = format->hvs;
 | 
			
		||||
 	unsigned int rotation;
 | 
			
		||||
 	int ret, i;
 | 
			
		||||
@@ -770,6 +767,9 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
+	width = vc4_state->src_w[0] >> 16;
 | 
			
		||||
+	height = vc4_state->src_h[0] >> 16;
 | 
			
		||||
+
 | 
			
		||||
 	/* SCL1 is used for Cb/Cr scaling of planar formats.  For RGB
 | 
			
		||||
 	 * and 4:4:4, scl1 should be set to scl0 so both channels of
 | 
			
		||||
 	 * the scaler do the same thing.  For YUV, the Y plane needs
 | 
			
		||||
@@ -790,9 +790,11 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 					 DRM_MODE_REFLECT_Y);
 | 
			
		||||
 
 | 
			
		||||
 	/* We must point to the last line when Y reflection is enabled. */
 | 
			
		||||
-	src_y = vc4_state->src_y;
 | 
			
		||||
+	src_y = vc4_state->src_y >> 16;
 | 
			
		||||
 	if (rotation & DRM_MODE_REFLECT_Y)
 | 
			
		||||
-		src_y += vc4_state->src_h[0] - 1;
 | 
			
		||||
+		src_y += height - 1;
 | 
			
		||||
+
 | 
			
		||||
+	src_x = vc4_state->src_x >> 16;
 | 
			
		||||
 
 | 
			
		||||
 	switch (base_format_mod) {
 | 
			
		||||
 	case DRM_FORMAT_MOD_LINEAR:
 | 
			
		||||
@@ -807,7 +809,7 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 						 (i ? v_subsample : 1) *
 | 
			
		||||
 						 fb->pitches[i];
 | 
			
		||||
 
 | 
			
		||||
-			vc4_state->offsets[i] += vc4_state->src_x /
 | 
			
		||||
+			vc4_state->offsets[i] += src_x /
 | 
			
		||||
 						 (i ? h_subsample : 1) *
 | 
			
		||||
 						 fb->format->cpp[i];
 | 
			
		||||
 		}
 | 
			
		||||
@@ -830,7 +832,7 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 		 *	pitch * tile_h == tile_size * tiles_per_row
 | 
			
		||||
 		 */
 | 
			
		||||
 		u32 tiles_w = fb->pitches[0] >> (tile_size_shift - tile_h_shift);
 | 
			
		||||
-		u32 tiles_l = vc4_state->src_x >> tile_w_shift;
 | 
			
		||||
+		u32 tiles_l = src_x >> tile_w_shift;
 | 
			
		||||
 		u32 tiles_r = tiles_w - tiles_l;
 | 
			
		||||
 		u32 tiles_t = src_y >> tile_h_shift;
 | 
			
		||||
 		/* Intra-tile offsets, which modify the base address (the
 | 
			
		||||
@@ -840,7 +842,7 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 		u32 tile_y = (src_y >> 4) & 1;
 | 
			
		||||
 		u32 subtile_y = (src_y >> 2) & 3;
 | 
			
		||||
 		u32 utile_y = src_y & 3;
 | 
			
		||||
-		u32 x_off = vc4_state->src_x & tile_w_mask;
 | 
			
		||||
+		u32 x_off = src_x & tile_w_mask;
 | 
			
		||||
 		u32 y_off = src_y & tile_h_mask;
 | 
			
		||||
 
 | 
			
		||||
 		/* When Y reflection is requested we must set the
 | 
			
		||||
@@ -936,7 +938,7 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 				 * of the 12-pixels in that 128-bit word is the
 | 
			
		||||
 				 * first pixel to be used
 | 
			
		||||
 				 */
 | 
			
		||||
-				u32 remaining_pixels = vc4_state->src_x % 96;
 | 
			
		||||
+				u32 remaining_pixels = src_x % 96;
 | 
			
		||||
 				u32 aligned = remaining_pixels / 12;
 | 
			
		||||
 				u32 last_bits = remaining_pixels % 12;
 | 
			
		||||
 
 | 
			
		||||
@@ -958,12 +960,12 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 					return -EINVAL;
 | 
			
		||||
 				}
 | 
			
		||||
 				pix_per_tile = tile_w / fb->format->cpp[0];
 | 
			
		||||
-				x_off = (vc4_state->src_x % pix_per_tile) /
 | 
			
		||||
+				x_off = (src_x % pix_per_tile) /
 | 
			
		||||
 					(i ? h_subsample : 1) *
 | 
			
		||||
 					fb->format->cpp[i];
 | 
			
		||||
 			}
 | 
			
		||||
 
 | 
			
		||||
-			tile = vc4_state->src_x / pix_per_tile;
 | 
			
		||||
+			tile = src_x / pix_per_tile;
 | 
			
		||||
 
 | 
			
		||||
 			vc4_state->offsets[i] += param * tile_w * tile;
 | 
			
		||||
 			vc4_state->offsets[i] += src_y /
 | 
			
		||||
@@ -1024,10 +1026,8 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 		vc4_dlist_write(vc4_state,
 | 
			
		||||
 				(mix_plane_alpha ? SCALER_POS2_ALPHA_MIX : 0) |
 | 
			
		||||
 				vc4_hvs4_get_alpha_blend_mode(state) |
 | 
			
		||||
-				VC4_SET_FIELD(vc4_state->src_w[0],
 | 
			
		||||
-					      SCALER_POS2_WIDTH) |
 | 
			
		||||
-				VC4_SET_FIELD(vc4_state->src_h[0],
 | 
			
		||||
-					      SCALER_POS2_HEIGHT));
 | 
			
		||||
+				VC4_SET_FIELD(width, SCALER_POS2_WIDTH) |
 | 
			
		||||
+				VC4_SET_FIELD(height, SCALER_POS2_HEIGHT));
 | 
			
		||||
 
 | 
			
		||||
 		/* Position Word 3: Context.  Written by the HVS. */
 | 
			
		||||
 		vc4_dlist_write(vc4_state, 0xc0c0c0c0);
 | 
			
		||||
@@ -1085,10 +1085,8 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 		/* Position Word 2: Source Image Size */
 | 
			
		||||
 		vc4_state->pos2_offset = vc4_state->dlist_count;
 | 
			
		||||
 		vc4_dlist_write(vc4_state,
 | 
			
		||||
-				VC4_SET_FIELD(vc4_state->src_w[0],
 | 
			
		||||
-					      SCALER5_POS2_WIDTH) |
 | 
			
		||||
-				VC4_SET_FIELD(vc4_state->src_h[0],
 | 
			
		||||
-					      SCALER5_POS2_HEIGHT));
 | 
			
		||||
+				VC4_SET_FIELD(width, SCALER5_POS2_WIDTH) |
 | 
			
		||||
+				VC4_SET_FIELD(height, SCALER5_POS2_HEIGHT));
 | 
			
		||||
 
 | 
			
		||||
 		/* Position Word 3: Context.  Written by the HVS. */
 | 
			
		||||
 		vc4_dlist_write(vc4_state, 0xc0c0c0c0);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
From 530def8213913d0726bd2084b9f868af6b4dfabd Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Fri, 9 Apr 2021 15:00:40 +0100
 | 
			
		||||
Subject: [PATCH] vc4/drm: Handle fractional coordinates using the phase field
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 61 ++++++++++++++++++++++++++++++---
 | 
			
		||||
 1 file changed, 56 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -464,14 +464,47 @@ static void vc4_write_tpz(struct vc4_pla
 | 
			
		||||
 			VC4_SET_FIELD(recip, SCALER_TPZ1_RECIP));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst)
 | 
			
		||||
+/* phase magnitude bits */
 | 
			
		||||
+#define PHASE_BITS 6
 | 
			
		||||
+
 | 
			
		||||
+static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, u32 xy, int channel)
 | 
			
		||||
 {
 | 
			
		||||
-	u32 scale = (1 << 16) * src / dst;
 | 
			
		||||
+	u32 scale = src / dst;
 | 
			
		||||
+	s32 offset, offset2;
 | 
			
		||||
+	s32 phase;
 | 
			
		||||
+
 | 
			
		||||
+	/* Start the phase at 1/2 pixel from the 1st pixel at src_x.
 | 
			
		||||
+	   1/4 pixel for YUV. */
 | 
			
		||||
+	if (channel) {
 | 
			
		||||
+		/* the phase is relative to scale_src->x, so shift it for display list's x value */
 | 
			
		||||
+		offset = (xy & 0x1ffff) >> (16 - PHASE_BITS) >> 1;
 | 
			
		||||
+		offset += -(1 << PHASE_BITS >> 2);
 | 
			
		||||
+	} else {
 | 
			
		||||
+		/* the phase is relative to scale_src->x, so shift it for display list's x value */
 | 
			
		||||
+		offset = (xy & 0xffff) >> (16 - PHASE_BITS);
 | 
			
		||||
+		offset += -(1 << PHASE_BITS >> 1);
 | 
			
		||||
+
 | 
			
		||||
+		/* This is a kludge to make sure the scaling factors are consitent with YUV's luma scaling.
 | 
			
		||||
+		   we lose 1bit precision because of this. */
 | 
			
		||||
+		scale &= ~1;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	/* There may be a also small error introduced by precision of scale.
 | 
			
		||||
+	   Add half of that as a compromise */
 | 
			
		||||
+	offset2 = src - dst * scale;
 | 
			
		||||
+	offset2 >>= 16 - PHASE_BITS;
 | 
			
		||||
+	phase = offset + (offset2 >> 1);
 | 
			
		||||
+
 | 
			
		||||
+	/* Ensure +ve values don't touch the sign bit, then truncate negative values */
 | 
			
		||||
+	if (phase >= 1 << PHASE_BITS)
 | 
			
		||||
+		phase = (1 << PHASE_BITS) - 1;
 | 
			
		||||
+
 | 
			
		||||
+	phase &= SCALER_PPF_IPHASE_MASK;
 | 
			
		||||
 
 | 
			
		||||
 	vc4_dlist_write(vc4_state,
 | 
			
		||||
 			SCALER_PPF_AGC |
 | 
			
		||||
 			VC4_SET_FIELD(scale, SCALER_PPF_SCALE) |
 | 
			
		||||
-			VC4_SET_FIELD(0, SCALER_PPF_IPHASE));
 | 
			
		||||
+			VC4_SET_FIELD(phase, SCALER_PPF_IPHASE));
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static u32 vc4_lbm_size(struct drm_plane_state *state)
 | 
			
		||||
@@ -530,13 +563,13 @@ static void vc4_write_scaling_parameters
 | 
			
		||||
 	/* Ch0 H-PPF Word 0: Scaling Parameters */
 | 
			
		||||
 	if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) {
 | 
			
		||||
 		vc4_write_ppf(vc4_state,
 | 
			
		||||
-			      vc4_state->src_w[channel], vc4_state->crtc_w);
 | 
			
		||||
+			      vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, channel);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
 | 
			
		||||
 	if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
 | 
			
		||||
 		vc4_write_ppf(vc4_state,
 | 
			
		||||
-			      vc4_state->src_h[channel], vc4_state->crtc_h);
 | 
			
		||||
+			      vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, channel);
 | 
			
		||||
 		vc4_dlist_write(vc4_state, 0xc0c0c0c0);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -984,6 +1017,24 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* fetch an extra pixel if we don't actually line up with the left edge. */
 | 
			
		||||
+	if ((vc4_state->src_x & 0xffff) && vc4_state->src_x < (state->fb->width << 16))
 | 
			
		||||
+		width++;
 | 
			
		||||
+
 | 
			
		||||
+	/* same for the right side */
 | 
			
		||||
+	if (((vc4_state->src_x + vc4_state->src_w[0]) & 0xffff) &&
 | 
			
		||||
+	       vc4_state->src_x + vc4_state->src_w[0] < (state->fb->width << 16))
 | 
			
		||||
+		width++;
 | 
			
		||||
+
 | 
			
		||||
+	/* now for the top */
 | 
			
		||||
+	if ((vc4_state->src_y & 0xffff) && vc4_state->src_y < (state->fb->height << 16))
 | 
			
		||||
+		height++;
 | 
			
		||||
+
 | 
			
		||||
+	/* and the bottom */
 | 
			
		||||
+	if (((vc4_state->src_y + vc4_state->src_h[0]) & 0xffff) &&
 | 
			
		||||
+	       vc4_state->src_y + vc4_state->src_h[0] < (state->fb->height << 16))
 | 
			
		||||
+		height++;
 | 
			
		||||
+
 | 
			
		||||
 	/* Don't waste cycles mixing with plane alpha if the set alpha
 | 
			
		||||
 	 * is opaque or there is no per-pixel alpha information.
 | 
			
		||||
 	 * In any case we use the alpha property value as the fixed alpha.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,170 @@
 | 
			
		|||
From 1772d6d383fe550ec9c8f7fa2526a114e036e3a9 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Wed, 26 Jan 2022 15:58:13 +0000
 | 
			
		||||
Subject: [PATCH] drm: Add chroma siting properties
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/drm_atomic_state_helper.c | 14 +++++++++
 | 
			
		||||
 drivers/gpu/drm/drm_atomic_uapi.c         |  8 +++++
 | 
			
		||||
 drivers/gpu/drm/drm_color_mgmt.c          | 36 +++++++++++++++++++++++
 | 
			
		||||
 include/drm/drm_color_mgmt.h              |  3 ++
 | 
			
		||||
 include/drm/drm_plane.h                   | 36 +++++++++++++++++++++++
 | 
			
		||||
 5 files changed, 97 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/drm_atomic_state_helper.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_atomic_state_helper.c
 | 
			
		||||
@@ -267,6 +267,20 @@ void __drm_atomic_helper_plane_state_res
 | 
			
		||||
 			plane_state->color_range = val;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (plane->chroma_siting_h_property) {
 | 
			
		||||
+		if (!drm_object_property_get_default_value(&plane->base,
 | 
			
		||||
+							   plane->chroma_siting_h_property,
 | 
			
		||||
+							   &val))
 | 
			
		||||
+			plane_state->chroma_siting_h = val;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	if (plane->chroma_siting_v_property) {
 | 
			
		||||
+		if (!drm_object_property_get_default_value(&plane->base,
 | 
			
		||||
+							   plane->chroma_siting_v_property,
 | 
			
		||||
+							   &val))
 | 
			
		||||
+			plane_state->chroma_siting_v = val;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	if (plane->zpos_property) {
 | 
			
		||||
 		if (!drm_object_property_get_default_value(&plane->base,
 | 
			
		||||
 							   plane->zpos_property,
 | 
			
		||||
--- a/drivers/gpu/drm/drm_atomic_uapi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
 | 
			
		||||
@@ -562,6 +562,10 @@ static int drm_atomic_plane_set_property
 | 
			
		||||
 		state->color_encoding = val;
 | 
			
		||||
 	} else if (property == plane->color_range_property) {
 | 
			
		||||
 		state->color_range = val;
 | 
			
		||||
+	} else if (property == plane->chroma_siting_h_property) {
 | 
			
		||||
+		state->chroma_siting_h = val;
 | 
			
		||||
+	} else if (property == plane->chroma_siting_v_property) {
 | 
			
		||||
+		state->chroma_siting_v = val;
 | 
			
		||||
 	} else if (property == config->prop_fb_damage_clips) {
 | 
			
		||||
 		ret = drm_atomic_replace_property_blob_from_id(dev,
 | 
			
		||||
 					&state->fb_damage_clips,
 | 
			
		||||
@@ -628,6 +632,10 @@ drm_atomic_plane_get_property(struct drm
 | 
			
		||||
 		*val = state->color_encoding;
 | 
			
		||||
 	} else if (property == plane->color_range_property) {
 | 
			
		||||
 		*val = state->color_range;
 | 
			
		||||
+	} else if (property == plane->chroma_siting_h_property) {
 | 
			
		||||
+		*val = state->chroma_siting_h;
 | 
			
		||||
+	} else if (property == plane->chroma_siting_v_property) {
 | 
			
		||||
+		*val = state->chroma_siting_v;
 | 
			
		||||
 	} else if (property == config->prop_fb_damage_clips) {
 | 
			
		||||
 		*val = (state->fb_damage_clips) ?
 | 
			
		||||
 			state->fb_damage_clips->base.id : 0;
 | 
			
		||||
--- a/drivers/gpu/drm/drm_color_mgmt.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_color_mgmt.c
 | 
			
		||||
@@ -591,6 +591,42 @@ int drm_plane_create_color_properties(st
 | 
			
		||||
 EXPORT_SYMBOL(drm_plane_create_color_properties);
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
+ * drm_plane_create_chroma_siting_properties - chroma siting related plane properties
 | 
			
		||||
+ * @plane: plane object
 | 
			
		||||
+ *
 | 
			
		||||
+ * Create and attach plane specific CHROMA_SITING
 | 
			
		||||
+ * properties to @plane.
 | 
			
		||||
+ */
 | 
			
		||||
+int drm_plane_create_chroma_siting_properties(struct drm_plane *plane,
 | 
			
		||||
+						int32_t default_chroma_siting_h,
 | 
			
		||||
+						int32_t default_chroma_siting_v)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_device *dev = plane->dev;
 | 
			
		||||
+	struct drm_property *prop;
 | 
			
		||||
+
 | 
			
		||||
+	prop = drm_property_create_range(dev, 0, "CHROMA_SITING_H",
 | 
			
		||||
+					0, 1<<16);
 | 
			
		||||
+	if (!prop)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+	plane->chroma_siting_h_property = prop;
 | 
			
		||||
+	drm_object_attach_property(&plane->base, prop, default_chroma_siting_h);
 | 
			
		||||
+
 | 
			
		||||
+	prop = drm_property_create_range(dev, 0, "CHROMA_SITING_V",
 | 
			
		||||
+					0, 1<<16);
 | 
			
		||||
+	if (!prop)
 | 
			
		||||
+		return -ENOMEM;
 | 
			
		||||
+	plane->chroma_siting_v_property = prop;
 | 
			
		||||
+	drm_object_attach_property(&plane->base, prop, default_chroma_siting_v);
 | 
			
		||||
+
 | 
			
		||||
+	if (plane->state) {
 | 
			
		||||
+		plane->state->chroma_siting_h = default_chroma_siting_h;
 | 
			
		||||
+		plane->state->chroma_siting_v = default_chroma_siting_v;
 | 
			
		||||
+	}
 | 
			
		||||
+	return 0;
 | 
			
		||||
+}
 | 
			
		||||
+EXPORT_SYMBOL(drm_plane_create_chroma_siting_properties);
 | 
			
		||||
+
 | 
			
		||||
+/**
 | 
			
		||||
  * drm_color_lut_check - check validity of lookup table
 | 
			
		||||
  * @lut: property blob containing LUT to check
 | 
			
		||||
  * @tests: bitmask of tests to run
 | 
			
		||||
--- a/include/drm/drm_color_mgmt.h
 | 
			
		||||
+++ b/include/drm/drm_color_mgmt.h
 | 
			
		||||
@@ -93,6 +93,9 @@ int drm_plane_create_color_properties(st
 | 
			
		||||
 				      enum drm_color_encoding default_encoding,
 | 
			
		||||
 				      enum drm_color_range default_range);
 | 
			
		||||
 
 | 
			
		||||
+int drm_plane_create_chroma_siting_properties(struct drm_plane *plane,
 | 
			
		||||
+						int32_t default_chroma_siting_h, int32_t default_chroma_siting_v);
 | 
			
		||||
+
 | 
			
		||||
 /**
 | 
			
		||||
  * enum drm_color_lut_tests - hw-specific LUT tests to perform
 | 
			
		||||
  *
 | 
			
		||||
--- a/include/drm/drm_plane.h
 | 
			
		||||
+++ b/include/drm/drm_plane.h
 | 
			
		||||
@@ -178,6 +178,24 @@ struct drm_plane_state {
 | 
			
		||||
 	enum drm_color_range color_range;
 | 
			
		||||
 
 | 
			
		||||
 	/**
 | 
			
		||||
+	 * @chroma_siting_h:
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * Location of chroma samples horizontally compared to luma
 | 
			
		||||
+	 * 0 means chroma is sited with left luma
 | 
			
		||||
+	 * 0x8000 is interstitial. 0x10000 is sited with right luma
 | 
			
		||||
+	 */
 | 
			
		||||
+	int32_t chroma_siting_h;
 | 
			
		||||
+
 | 
			
		||||
+	/**
 | 
			
		||||
+	 * @chroma_siting_v:
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * Location of chroma samples vertically compared to luma
 | 
			
		||||
+	 * 0 means chroma is sited with top luma
 | 
			
		||||
+	 * 0x8000 is interstitial. 0x10000 is sited with bottom luma
 | 
			
		||||
+	 */
 | 
			
		||||
+	int32_t chroma_siting_v;
 | 
			
		||||
+
 | 
			
		||||
+	/**
 | 
			
		||||
 	 * @fb_damage_clips:
 | 
			
		||||
 	 *
 | 
			
		||||
 	 * Blob representing damage (area in plane framebuffer that changed
 | 
			
		||||
@@ -748,6 +766,24 @@ struct drm_plane {
 | 
			
		||||
 	 * scaling.
 | 
			
		||||
 	 */
 | 
			
		||||
 	struct drm_property *scaling_filter_property;
 | 
			
		||||
+
 | 
			
		||||
+	/**
 | 
			
		||||
+	 * @chroma_siting_h_property:
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * Optional "CHROMA_SITING_H" property for specifying
 | 
			
		||||
+	 * chroma siting for YUV formats.
 | 
			
		||||
+	 * See drm_plane_create_chroma_siting_properties().
 | 
			
		||||
+	 */
 | 
			
		||||
+	struct drm_property *chroma_siting_h_property;
 | 
			
		||||
+
 | 
			
		||||
+	/**
 | 
			
		||||
+	 * @chroma_siting_v_property:
 | 
			
		||||
+	 *
 | 
			
		||||
+	 * Optional "CHROMA_SITING_V" property for specifying
 | 
			
		||||
+	 * chroma siting for YUV formats.
 | 
			
		||||
+	 * See drm_plane_create_chroma_siting_properties().
 | 
			
		||||
+	 */
 | 
			
		||||
+	struct drm_property *chroma_siting_v_property;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 #define obj_to_plane(x) container_of(x, struct drm_plane, base)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
From df674e66baf169f020b7d22450295df9bf16f007 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Thu, 27 Jan 2022 15:32:04 +0000
 | 
			
		||||
Subject: [PATCH] vc4/drm:plane: Make use of chroma siting parameter
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 13 +++++++++----
 | 
			
		||||
 1 file changed, 9 insertions(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -467,17 +467,18 @@ static void vc4_write_tpz(struct vc4_pla
 | 
			
		||||
 /* phase magnitude bits */
 | 
			
		||||
 #define PHASE_BITS 6
 | 
			
		||||
 
 | 
			
		||||
-static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, u32 xy, int channel)
 | 
			
		||||
+static void vc4_write_ppf(struct vc4_plane_state *vc4_state, u32 src, u32 dst, u32 xy, int channel, int chroma_offset)
 | 
			
		||||
 {
 | 
			
		||||
 	u32 scale = src / dst;
 | 
			
		||||
 	s32 offset, offset2;
 | 
			
		||||
 	s32 phase;
 | 
			
		||||
 
 | 
			
		||||
 	/* Start the phase at 1/2 pixel from the 1st pixel at src_x.
 | 
			
		||||
-	   1/4 pixel for YUV. */
 | 
			
		||||
+	   1/4 pixel for YUV, plus the offset for chroma siting */
 | 
			
		||||
 	if (channel) {
 | 
			
		||||
 		/* the phase is relative to scale_src->x, so shift it for display list's x value */
 | 
			
		||||
 		offset = (xy & 0x1ffff) >> (16 - PHASE_BITS) >> 1;
 | 
			
		||||
+		offset -= chroma_offset >> (17 - PHASE_BITS);
 | 
			
		||||
 		offset += -(1 << PHASE_BITS >> 2);
 | 
			
		||||
 	} else {
 | 
			
		||||
 		/* the phase is relative to scale_src->x, so shift it for display list's x value */
 | 
			
		||||
@@ -563,13 +564,15 @@ static void vc4_write_scaling_parameters
 | 
			
		||||
 	/* Ch0 H-PPF Word 0: Scaling Parameters */
 | 
			
		||||
 	if (vc4_state->x_scaling[channel] == VC4_SCALING_PPF) {
 | 
			
		||||
 		vc4_write_ppf(vc4_state,
 | 
			
		||||
-			      vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, channel);
 | 
			
		||||
+			      vc4_state->src_w[channel], vc4_state->crtc_w, vc4_state->src_x, channel,
 | 
			
		||||
+			      state->chroma_siting_h);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	/* Ch0 V-PPF Words 0-1: Scaling Parameters, Context */
 | 
			
		||||
 	if (vc4_state->y_scaling[channel] == VC4_SCALING_PPF) {
 | 
			
		||||
 		vc4_write_ppf(vc4_state,
 | 
			
		||||
-			      vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, channel);
 | 
			
		||||
+			      vc4_state->src_h[channel], vc4_state->crtc_h, vc4_state->src_y, channel,
 | 
			
		||||
+			      state->chroma_siting_v);
 | 
			
		||||
 		vc4_dlist_write(vc4_state, 0xc0c0c0c0);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1649,6 +1652,8 @@ struct drm_plane *vc4_plane_init(struct
 | 
			
		||||
 					  DRM_COLOR_YCBCR_BT709,
 | 
			
		||||
 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
 | 
			
		||||
 
 | 
			
		||||
+	drm_plane_create_chroma_siting_properties(plane, 0, 0);
 | 
			
		||||
+
 | 
			
		||||
 	if (type == DRM_PLANE_TYPE_PRIMARY)
 | 
			
		||||
 		drm_plane_create_zpos_immutable_property(plane, 0);
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
From 9d5169f533e9da2b3aac09b3c4e7cc35afa9d8bf Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 1 Apr 2022 11:31:38 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4: Force trigger of dlist update on margins change
 | 
			
		||||
 | 
			
		||||
When the margins are changed, the dlist needs to be regenerated
 | 
			
		||||
with the changed updated dest regions for each of the planes.
 | 
			
		||||
 | 
			
		||||
Setting the zpos_changed flag is sufficient to trigger that
 | 
			
		||||
without doing a full modeset, therefore set it should the
 | 
			
		||||
margins be changed.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_crtc.c | 14 ++++++++++----
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_drv.h  |  7 +------
 | 
			
		||||
 2 files changed, 11 insertions(+), 10 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
 | 
			
		||||
@@ -757,10 +757,16 @@ static int vc4_crtc_atomic_check(struct
 | 
			
		||||
 		if (conn_state->crtc != crtc)
 | 
			
		||||
 			continue;
 | 
			
		||||
 
 | 
			
		||||
-		vc4_state->margins.left = conn_state->tv.margins.left;
 | 
			
		||||
-		vc4_state->margins.right = conn_state->tv.margins.right;
 | 
			
		||||
-		vc4_state->margins.top = conn_state->tv.margins.top;
 | 
			
		||||
-		vc4_state->margins.bottom = conn_state->tv.margins.bottom;
 | 
			
		||||
+		if (memcmp(&vc4_state->margins, &conn_state->tv.margins,
 | 
			
		||||
+			   sizeof(vc4_state->margins))) {
 | 
			
		||||
+			memcpy(&vc4_state->margins, &conn_state->tv.margins,
 | 
			
		||||
+			       sizeof(vc4_state->margins));
 | 
			
		||||
+
 | 
			
		||||
+			/* Need to force the dlist entries for all planes to be
 | 
			
		||||
+			 * updated so that the dest rectangles are changed.
 | 
			
		||||
+			 */
 | 
			
		||||
+			crtc_state->zpos_changed = true;
 | 
			
		||||
+		}
 | 
			
		||||
 		break;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
 | 
			
		||||
@@ -581,12 +581,7 @@ struct vc4_crtc_state {
 | 
			
		||||
 	bool txp_armed;
 | 
			
		||||
 	unsigned int assigned_channel;
 | 
			
		||||
 
 | 
			
		||||
-	struct {
 | 
			
		||||
-		unsigned int left;
 | 
			
		||||
-		unsigned int right;
 | 
			
		||||
-		unsigned int top;
 | 
			
		||||
-		unsigned int bottom;
 | 
			
		||||
-	} margins;
 | 
			
		||||
+	struct drm_connector_tv_margins margins;
 | 
			
		||||
 
 | 
			
		||||
 	unsigned long hvs_load;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,121 @@
 | 
			
		|||
From 713e11c488cb9066e0c52c1d454773c495ba718f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Daniel Vetter <daniel.vetter@ffwll.ch>
 | 
			
		||||
Date: Fri, 23 Oct 2020 14:39:23 +0200
 | 
			
		||||
Subject: [PATCH] drm/atomic-helpers: remove legacy_cursor_update hacks
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
The stuff never really worked, and leads to lots of fun because it
 | 
			
		||||
out-of-order frees atomic states. Which upsets KASAN, among other
 | 
			
		||||
things.
 | 
			
		||||
 | 
			
		||||
For async updates we now have a more solid solution with the
 | 
			
		||||
->atomic_async_check and ->atomic_async_commit hooks. Support for that
 | 
			
		||||
for msm and vc4 landed. nouveau and i915 have their own commit
 | 
			
		||||
routines, doing something similar.
 | 
			
		||||
 | 
			
		||||
For everyone else it's probably better to remove the use-after-free
 | 
			
		||||
bug, and encourage folks to use the async support instead. The
 | 
			
		||||
affected drivers which register a legacy cursor plane and don't either
 | 
			
		||||
use the new async stuff or their own commit routine are: amdgpu,
 | 
			
		||||
atmel, mediatek, qxl, rockchip, sti, sun4i, tegra, virtio, and vmwgfx.
 | 
			
		||||
 | 
			
		||||
Inspired by an amdgpu bug report.
 | 
			
		||||
 | 
			
		||||
v2: Drop RFC, I think with amdgpu converted over to use
 | 
			
		||||
atomic_async_check/commit done in
 | 
			
		||||
 | 
			
		||||
commit 674e78acae0dfb4beb56132e41cbae5b60f7d662
 | 
			
		||||
Author: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
 | 
			
		||||
Date:   Wed Dec 5 14:59:07 2018 -0500
 | 
			
		||||
 | 
			
		||||
    drm/amd/display: Add fast path for cursor plane updates
 | 
			
		||||
 | 
			
		||||
we don't have any driver anymore where we have userspace expecting
 | 
			
		||||
solid legacy cursor support _and_ they are using the atomic helpers in
 | 
			
		||||
their fully glory. So we can retire this.
 | 
			
		||||
 | 
			
		||||
v3: Paper over msm and i915 regression. The complete_all is the only
 | 
			
		||||
thing missing afaict.
 | 
			
		||||
 | 
			
		||||
v4: Rebased on recent kernel, added extra link for vc4 bug.
 | 
			
		||||
 | 
			
		||||
Link: https://bugzilla.kernel.org/show_bug.cgi?id=199425
 | 
			
		||||
Link: https://lore.kernel.org/all/20220221134155.125447-9-maxime@cerno.tech/
 | 
			
		||||
Cc: mikita.lipski@amd.com
 | 
			
		||||
Cc: Michel Dänzer <michel@daenzer.net>
 | 
			
		||||
Cc: harry.wentland@amd.com
 | 
			
		||||
Cc: Rob Clark <robdclark@gmail.com>
 | 
			
		||||
Cc: "Kazlauskas, Nicholas" <nicholas.kazlauskas@amd.com>
 | 
			
		||||
Tested-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/drm_atomic_helper.c          | 13 -------------
 | 
			
		||||
 drivers/gpu/drm/i915/display/intel_display.c | 13 +++++++++++++
 | 
			
		||||
 drivers/gpu/drm/msm/msm_atomic.c             |  2 ++
 | 
			
		||||
 3 files changed, 15 insertions(+), 13 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/drm_atomic_helper.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_atomic_helper.c
 | 
			
		||||
@@ -1626,13 +1626,6 @@ drm_atomic_helper_wait_for_vblanks(struc
 | 
			
		||||
 	int i, ret;
 | 
			
		||||
 	unsigned int crtc_mask = 0;
 | 
			
		||||
 
 | 
			
		||||
-	 /*
 | 
			
		||||
-	  * Legacy cursor ioctls are completely unsynced, and userspace
 | 
			
		||||
-	  * relies on that (by doing tons of cursor updates).
 | 
			
		||||
-	  */
 | 
			
		||||
-	if (old_state->legacy_cursor_update)
 | 
			
		||||
-		return;
 | 
			
		||||
-
 | 
			
		||||
 	for_each_oldnew_crtc_in_state(old_state, crtc, old_crtc_state, new_crtc_state, i) {
 | 
			
		||||
 		if (!new_crtc_state->active)
 | 
			
		||||
 			continue;
 | 
			
		||||
@@ -2282,12 +2275,6 @@ int drm_atomic_helper_setup_commit(struc
 | 
			
		||||
 			complete_all(&commit->flip_done);
 | 
			
		||||
 			continue;
 | 
			
		||||
 		}
 | 
			
		||||
-
 | 
			
		||||
-		/* Legacy cursor updates are fully unsynced. */
 | 
			
		||||
-		if (state->legacy_cursor_update) {
 | 
			
		||||
-			complete_all(&commit->flip_done);
 | 
			
		||||
-			continue;
 | 
			
		||||
-		}
 | 
			
		||||
 
 | 
			
		||||
 		if (!new_crtc_state->event) {
 | 
			
		||||
 			commit->event = kzalloc(sizeof(*commit->event),
 | 
			
		||||
--- a/drivers/gpu/drm/i915/display/intel_display.c
 | 
			
		||||
+++ b/drivers/gpu/drm/i915/display/intel_display.c
 | 
			
		||||
@@ -7743,6 +7743,19 @@ static int intel_atomic_commit(struct dr
 | 
			
		||||
 				state->base.legacy_cursor_update = false;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * FIXME: Cut over to (async) commit helpers instead of hand-rolling
 | 
			
		||||
+	 * everything.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (state->base.legacy_cursor_update) {
 | 
			
		||||
+		struct intel_crtc_state *new_crtc_state;
 | 
			
		||||
+		struct intel_crtc *crtc;
 | 
			
		||||
+		int i;
 | 
			
		||||
+
 | 
			
		||||
+		for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i)
 | 
			
		||||
+			complete_all(&new_crtc_state->uapi.commit->flip_done);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	ret = intel_atomic_prepare_commit(state);
 | 
			
		||||
 	if (ret) {
 | 
			
		||||
 		drm_dbg_atomic(&dev_priv->drm,
 | 
			
		||||
--- a/drivers/gpu/drm/msm/msm_atomic.c
 | 
			
		||||
+++ b/drivers/gpu/drm/msm/msm_atomic.c
 | 
			
		||||
@@ -222,6 +222,8 @@ void msm_atomic_commit_tail(struct drm_a
 | 
			
		||||
 		/* async updates are limited to single-crtc updates: */
 | 
			
		||||
 		WARN_ON(crtc_mask != drm_crtc_mask(async_crtc));
 | 
			
		||||
 
 | 
			
		||||
+		complete_all(&async_crtc->state->commit->flip_done);
 | 
			
		||||
+
 | 
			
		||||
 		/*
 | 
			
		||||
 		 * Start timer if we don't already have an update pending
 | 
			
		||||
 		 * on this crtc:
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
From 8fd080d355a9af07751c2080151347132c8ad1f2 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Thu, 5 May 2022 18:50:04 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4_hdmi: Force a modeset when Broadcast RGB setting
 | 
			
		||||
 changes
 | 
			
		||||
 | 
			
		||||
Without this the change is not visible until the next modeset
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hdmi.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
 | 
			
		||||
@@ -536,14 +536,17 @@ static int vc4_hdmi_connector_atomic_che
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_connector_state *old_state =
 | 
			
		||||
 		drm_atomic_get_old_connector_state(state, connector);
 | 
			
		||||
+	struct vc4_hdmi_connector_state *old_vc4_state = conn_state_to_vc4_hdmi_conn_state(old_state);
 | 
			
		||||
 	struct drm_connector_state *new_state =
 | 
			
		||||
 		drm_atomic_get_new_connector_state(state, connector);
 | 
			
		||||
+	struct vc4_hdmi_connector_state *new_vc4_state = conn_state_to_vc4_hdmi_conn_state(new_state);
 | 
			
		||||
 	struct drm_crtc *crtc = new_state->crtc;
 | 
			
		||||
 
 | 
			
		||||
 	if (!crtc)
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
 	if (old_state->colorspace != new_state->colorspace ||
 | 
			
		||||
+	    old_vc4_state->broadcast_rgb != new_vc4_state->broadcast_rgb ||
 | 
			
		||||
 	    !drm_connector_atomic_hdr_metadata_equal(old_state, new_state)) {
 | 
			
		||||
 		struct drm_crtc_state *crtc_state;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,59 @@
 | 
			
		|||
From 34b66f9e18412ee70ff12b1030df625d7adf5a51 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 1 Apr 2022 17:10:37 +0100
 | 
			
		||||
Subject: [PATCH] drm/atomic: If margins are updated, update all planes.
 | 
			
		||||
 | 
			
		||||
Margins may be implemented by scaling the planes, but as there
 | 
			
		||||
is no way of intercepting the set_property for a standard property,
 | 
			
		||||
and all planes are checked in drm_atomic_check_only before the
 | 
			
		||||
connectors, there's now way to add the planes into the state
 | 
			
		||||
from the driver.
 | 
			
		||||
 | 
			
		||||
If the margin properties change, add all corresponding planes to
 | 
			
		||||
the state.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/drm_atomic_uapi.c | 11 +++++++++++
 | 
			
		||||
 1 file changed, 11 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/drm_atomic_uapi.c
 | 
			
		||||
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
 | 
			
		||||
@@ -679,6 +679,7 @@ static int drm_atomic_connector_set_prop
 | 
			
		||||
 {
 | 
			
		||||
 	struct drm_device *dev = connector->dev;
 | 
			
		||||
 	struct drm_mode_config *config = &dev->mode_config;
 | 
			
		||||
+	bool margins_updated = false;
 | 
			
		||||
 	bool replaced = false;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
@@ -698,12 +699,16 @@ static int drm_atomic_connector_set_prop
 | 
			
		||||
 		state->tv.subconnector = val;
 | 
			
		||||
 	} else if (property == config->tv_left_margin_property) {
 | 
			
		||||
 		state->tv.margins.left = val;
 | 
			
		||||
+		margins_updated = true;
 | 
			
		||||
 	} else if (property == config->tv_right_margin_property) {
 | 
			
		||||
 		state->tv.margins.right = val;
 | 
			
		||||
+		margins_updated = true;
 | 
			
		||||
 	} else if (property == config->tv_top_margin_property) {
 | 
			
		||||
 		state->tv.margins.top = val;
 | 
			
		||||
+		margins_updated = true;
 | 
			
		||||
 	} else if (property == config->tv_bottom_margin_property) {
 | 
			
		||||
 		state->tv.margins.bottom = val;
 | 
			
		||||
+		margins_updated = true;
 | 
			
		||||
 	} else if (property == config->tv_mode_property) {
 | 
			
		||||
 		state->tv.mode = val;
 | 
			
		||||
 	} else if (property == config->tv_brightness_property) {
 | 
			
		||||
@@ -784,6 +789,12 @@ static int drm_atomic_connector_set_prop
 | 
			
		||||
 		return -EINVAL;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (margins_updated && state->crtc) {
 | 
			
		||||
+		ret = drm_atomic_add_affected_planes(state->state, state->crtc);
 | 
			
		||||
+
 | 
			
		||||
+		return ret;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
From ee4cb8b3a707633e0f4aa547779c6f860cc61b18 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
Date: Mon, 6 Dec 2021 16:32:10 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4: hvs: Ignore atomic_flush if we're disabled
 | 
			
		||||
 | 
			
		||||
atomic_flush will be called for each CRTC even if they aren't enabled.
 | 
			
		||||
 | 
			
		||||
The whole code we have there will thus run without a properly affected
 | 
			
		||||
channel, which can then result in all sorts of weird behaviour.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -778,6 +778,9 @@ void vc4_hvs_atomic_flush(struct drm_crt
 | 
			
		||||
 		return;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (vc4_state->assigned_channel == VC4_HVS_CHANNEL_DISABLED)
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
 	if (debug_dump_regs) {
 | 
			
		||||
 		DRM_INFO("CRTC %d HVS before:\n", drm_crtc_index(crtc));
 | 
			
		||||
 		vc4_hvs_dump_state(hvs);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,118 @@
 | 
			
		|||
From 078bf356a2677a2bfb078aac5ac275e81c31d583 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 3 Jun 2022 16:49:09 +0100
 | 
			
		||||
Subject: [PATCH] drm: vc4: 0 is a valid value for pixel_order_hvs5, so fix
 | 
			
		||||
 conditionals
 | 
			
		||||
 | 
			
		||||
vc4_plane_mode_set for HVS5 was using pixel_order unless pixel_order_hvs5
 | 
			
		||||
was non-zero, except 0 is a valid value for the pixel_order.
 | 
			
		||||
 | 
			
		||||
Specify pixel_order_hvs5 for all formats and remove the conditional.
 | 
			
		||||
 | 
			
		||||
Reported-by: vrazzer <teamvraz@pipmail.net>
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 20 ++++++++++++++------
 | 
			
		||||
 1 file changed, 14 insertions(+), 6 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -65,11 +65,13 @@ static const struct hvs_format {
 | 
			
		||||
 		.drm = DRM_FORMAT_RGB565,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGB565,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XRGB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XRGB,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_BGR565,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGB565,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XBGR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XBGR,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_ARGB1555,
 | 
			
		||||
@@ -87,56 +89,67 @@ static const struct hvs_format {
 | 
			
		||||
 		.drm = DRM_FORMAT_RGB888,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGB888,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XRGB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XRGB,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_BGR888,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGB888,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XBGR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XBGR,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_YUV422,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_YVU422,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_3PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_YUV420,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_YVU420,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_3PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_NV12,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_NV21,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV420_2PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_NV16,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_NV61,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_YUV422_2PLANE,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCRCB,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_P030,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_10BIT,
 | 
			
		||||
 		.pixel_order = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
@@ -1087,15 +1100,10 @@ static int vc4_plane_mode_set(struct drm
 | 
			
		||||
 		vc4_dlist_write(vc4_state, 0xc0c0c0c0);
 | 
			
		||||
 
 | 
			
		||||
 	} else {
 | 
			
		||||
-		u32 hvs_pixel_order = format->pixel_order;
 | 
			
		||||
-
 | 
			
		||||
-		if (format->pixel_order_hvs5)
 | 
			
		||||
-			hvs_pixel_order = format->pixel_order_hvs5;
 | 
			
		||||
-
 | 
			
		||||
 		/* Control word */
 | 
			
		||||
 		vc4_dlist_write(vc4_state,
 | 
			
		||||
 				SCALER_CTL0_VALID |
 | 
			
		||||
-				(hvs_pixel_order << SCALER_CTL0_ORDER_SHIFT) |
 | 
			
		||||
+				(format->pixel_order_hvs5 << SCALER_CTL0_ORDER_SHIFT) |
 | 
			
		||||
 				(hvs_format << SCALER_CTL0_PIXEL_FORMAT_SHIFT) |
 | 
			
		||||
 				VC4_SET_FIELD(tiling, SCALER_CTL0_TILING) |
 | 
			
		||||
 				(vc4_state->is_unity ?
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
From aae9a991d857f49d28bd4b102bf2d41a9b941c21 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 6 Jun 2022 12:23:28 +0100
 | 
			
		||||
Subject: [PATCH] drm: vc4: Omit pixel_order from the hvs_format for hvs5 only
 | 
			
		||||
 formats
 | 
			
		||||
 | 
			
		||||
pixel_order is used for the earlier versions of the HVS, so is
 | 
			
		||||
redundant on the 10:10:10:2 and 10bit YUV formats that are only
 | 
			
		||||
supported on HVS5.
 | 
			
		||||
Remove the assignment from the table to avoid confusion.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 5 -----
 | 
			
		||||
 1 file changed, 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -148,35 +148,30 @@ static const struct hvs_format {
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_P030,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_YCBCR_10BIT,
 | 
			
		||||
-		.pixel_order = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 		.pixel_order_hvs5 = HVS_PIXEL_ORDER_XYCBCR,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_XRGB2101010,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
-		.pixel_order = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
 		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_ARGB2101010,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
-		.pixel_order = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
 		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_ABGR2101010,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
-		.pixel_order = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
 		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
 	{
 | 
			
		||||
 		.drm = DRM_FORMAT_XBGR2101010,
 | 
			
		||||
 		.hvs = HVS_PIXEL_FORMAT_RGBA1010102,
 | 
			
		||||
-		.pixel_order = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
 		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
From 0ced8286b5b6e49895dcaf4e25de2aef1df8073c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Fri, 3 Jun 2022 16:57:04 +0100
 | 
			
		||||
Subject: [PATCH] drm: vc4: Add 3:3:2 and 4:4:4:4 RGB/RGBX/RGBA formats
 | 
			
		||||
 | 
			
		||||
The hardware supports the 332 8bpp and 4:4:4:4 16bpp formats,
 | 
			
		||||
but the table of supported formats didn't include them.
 | 
			
		||||
Add them in.
 | 
			
		||||
 | 
			
		||||
In theory they are supported for T-format as well as linear,
 | 
			
		||||
but without a way to test them just add them as linear for now.
 | 
			
		||||
 | 
			
		||||
Suggested-by: vrazzer <teamvraz@pipmail.net>
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_plane.c | 70 +++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 70 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
 | 
			
		||||
@@ -175,6 +175,66 @@ static const struct hvs_format {
 | 
			
		||||
 		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
 		.hvs5_only = true,
 | 
			
		||||
 	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_RGB332,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGB332,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_BGR233,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGB332,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_XRGB4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_ARGB4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_XBGR4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_ABGR4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_ARGB,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_ABGR,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_BGRX4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_RGBA,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_BGRA,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_BGRA4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_RGBA,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_BGRA,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_RGBX4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_BGRA,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_RGBA,
 | 
			
		||||
+	},
 | 
			
		||||
+	{
 | 
			
		||||
+		.drm = DRM_FORMAT_RGBA4444,
 | 
			
		||||
+		.hvs = HVS_PIXEL_FORMAT_RGBA4444,
 | 
			
		||||
+		.pixel_order = HVS_PIXEL_ORDER_BGRA,
 | 
			
		||||
+		.pixel_order_hvs5 = HVS_PIXEL_ORDER_RGBA,
 | 
			
		||||
+	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static const struct hvs_format *vc4_get_hvs_format(u32 drm_format)
 | 
			
		||||
@@ -1575,6 +1635,16 @@ static bool vc4_format_mod_supported(str
 | 
			
		||||
 	case DRM_FORMAT_BGRX1010102:
 | 
			
		||||
 	case DRM_FORMAT_RGBA1010102:
 | 
			
		||||
 	case DRM_FORMAT_BGRA1010102:
 | 
			
		||||
+	case DRM_FORMAT_XRGB4444:
 | 
			
		||||
+	case DRM_FORMAT_ARGB4444:
 | 
			
		||||
+	case DRM_FORMAT_XBGR4444:
 | 
			
		||||
+	case DRM_FORMAT_ABGR4444:
 | 
			
		||||
+	case DRM_FORMAT_RGBX4444:
 | 
			
		||||
+	case DRM_FORMAT_RGBA4444:
 | 
			
		||||
+	case DRM_FORMAT_BGRX4444:
 | 
			
		||||
+	case DRM_FORMAT_BGRA4444:
 | 
			
		||||
+	case DRM_FORMAT_RGB332:
 | 
			
		||||
+	case DRM_FORMAT_BGR233:
 | 
			
		||||
 	case DRM_FORMAT_YUV422:
 | 
			
		||||
 	case DRM_FORMAT_YVU422:
 | 
			
		||||
 	case DRM_FORMAT_YUV420:
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
From 4f34c62b2e8672806287e789f126780cf7ecc93b Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Mon, 6 Jun 2022 14:53:56 +0100
 | 
			
		||||
Subject: [PATCH] drm: vc4: Add comments for which HVS_PIXEL_ORDER_xxx defines
 | 
			
		||||
 apply
 | 
			
		||||
 | 
			
		||||
The HVS_PIXEL_ORDER_xxx defines apply to specific HVS_PIXEL_FORMAT_xxx
 | 
			
		||||
modes, so add comments to make this obvious.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_regs.h | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_regs.h
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
 | 
			
		||||
@@ -870,16 +870,19 @@ enum hvs_pixel_format {
 | 
			
		||||
 /* Note: the LSB is the rightmost character shown.  Only valid for
 | 
			
		||||
  * HVS_PIXEL_FORMAT_RGB8888, not RGB888.
 | 
			
		||||
  */
 | 
			
		||||
+/* For modes 332, 4444, 555, 5551, 6666, 8888, 10:10:10:2 */
 | 
			
		||||
 #define HVS_PIXEL_ORDER_RGBA			0
 | 
			
		||||
 #define HVS_PIXEL_ORDER_BGRA			1
 | 
			
		||||
 #define HVS_PIXEL_ORDER_ARGB			2
 | 
			
		||||
 #define HVS_PIXEL_ORDER_ABGR			3
 | 
			
		||||
 
 | 
			
		||||
+/* For modes 666 and 888 (4 & 5) */
 | 
			
		||||
 #define HVS_PIXEL_ORDER_XBRG			0
 | 
			
		||||
 #define HVS_PIXEL_ORDER_XRBG			1
 | 
			
		||||
 #define HVS_PIXEL_ORDER_XRGB			2
 | 
			
		||||
 #define HVS_PIXEL_ORDER_XBGR			3
 | 
			
		||||
 
 | 
			
		||||
+/* For YCbCr modes (8-12, and 17) */
 | 
			
		||||
 #define HVS_PIXEL_ORDER_XYCBCR			0
 | 
			
		||||
 #define HVS_PIXEL_ORDER_XYCRCB			1
 | 
			
		||||
 #define HVS_PIXEL_ORDER_YXCBCR			2
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,87 @@
 | 
			
		|||
From e8bb5f7a69eeb3493659a72a6fc003eabfc005b1 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <8911409+pelwell@users.noreply.github.com>
 | 
			
		||||
Date: Wed, 24 Aug 2022 11:14:40 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4: Add async update support for cursor planes
 | 
			
		||||
 | 
			
		||||
Now that cursors are implemented as regular planes, all cursor
 | 
			
		||||
movements result in atomic updates. As the firmware-kms driver
 | 
			
		||||
doesn't support asynchronous updates, these are synchronous, which
 | 
			
		||||
limits the update rate to the screen refresh rate. Xorg seems unaware
 | 
			
		||||
of this (or at least of the effect of this), because if the mouse is
 | 
			
		||||
configured with a higher update rate than the screen then continuous
 | 
			
		||||
mouse movement results in an increasing backlog of mouse events -
 | 
			
		||||
cue extreme lag.
 | 
			
		||||
 | 
			
		||||
Add minimal support for asynchronous updates - limited to cursor
 | 
			
		||||
planes - to eliminate the lag.
 | 
			
		||||
 | 
			
		||||
See: https://github.com/raspberrypi/linux/pull/4971
 | 
			
		||||
     https://github.com/raspberrypi/linux/issues/4988
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_firmware_kms.c | 46 ++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 46 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_firmware_kms.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_firmware_kms.c
 | 
			
		||||
@@ -675,6 +675,50 @@ static int vc4_plane_atomic_check(struct
 | 
			
		||||
 	return vc4_plane_to_mb(plane, &vc4_plane->mb, new_plane_state);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static void vc4_plane_atomic_async_update(struct drm_plane *plane,
 | 
			
		||||
+					  struct drm_atomic_state *state)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_plane_state *new_plane_state =
 | 
			
		||||
+		drm_atomic_get_new_plane_state(state, plane);
 | 
			
		||||
+
 | 
			
		||||
+	swap(plane->state->fb, new_plane_state->fb);
 | 
			
		||||
+	plane->state->crtc_x = new_plane_state->crtc_x;
 | 
			
		||||
+	plane->state->crtc_y = new_plane_state->crtc_y;
 | 
			
		||||
+	plane->state->crtc_w = new_plane_state->crtc_w;
 | 
			
		||||
+	plane->state->crtc_h = new_plane_state->crtc_h;
 | 
			
		||||
+	plane->state->src_x = new_plane_state->src_x;
 | 
			
		||||
+	plane->state->src_y = new_plane_state->src_y;
 | 
			
		||||
+	plane->state->src_w = new_plane_state->src_w;
 | 
			
		||||
+	plane->state->src_h = new_plane_state->src_h;
 | 
			
		||||
+	plane->state->alpha = new_plane_state->alpha;
 | 
			
		||||
+	plane->state->pixel_blend_mode = new_plane_state->pixel_blend_mode;
 | 
			
		||||
+	plane->state->rotation = new_plane_state->rotation;
 | 
			
		||||
+	plane->state->zpos = new_plane_state->zpos;
 | 
			
		||||
+	plane->state->normalized_zpos = new_plane_state->normalized_zpos;
 | 
			
		||||
+	plane->state->color_encoding = new_plane_state->color_encoding;
 | 
			
		||||
+	plane->state->color_range = new_plane_state->color_range;
 | 
			
		||||
+	plane->state->src = new_plane_state->src;
 | 
			
		||||
+	plane->state->dst = new_plane_state->dst;
 | 
			
		||||
+	plane->state->visible = new_plane_state->visible;
 | 
			
		||||
+
 | 
			
		||||
+	vc4_plane_set_blank(plane, false);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static int vc4_plane_atomic_async_check(struct drm_plane *plane,
 | 
			
		||||
+					struct drm_atomic_state *state)
 | 
			
		||||
+{
 | 
			
		||||
+	struct drm_plane_state *new_plane_state =
 | 
			
		||||
+		drm_atomic_get_new_plane_state(state, plane);
 | 
			
		||||
+	int ret = -EINVAL;
 | 
			
		||||
+
 | 
			
		||||
+	if (plane->type == 2 &&
 | 
			
		||||
+	    plane->state->fb &&
 | 
			
		||||
+	    new_plane_state->crtc->state->active)
 | 
			
		||||
+		ret = 0;
 | 
			
		||||
+
 | 
			
		||||
+	return ret;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 /* Called during init to allocate the plane's atomic state. */
 | 
			
		||||
 static void vc4_plane_reset(struct drm_plane *plane)
 | 
			
		||||
 {
 | 
			
		||||
@@ -769,6 +813,8 @@ static const struct drm_plane_helper_fun
 | 
			
		||||
 	.atomic_check = vc4_plane_atomic_check,
 | 
			
		||||
 	.atomic_update = vc4_plane_atomic_update,
 | 
			
		||||
 	.atomic_disable = vc4_plane_atomic_disable,
 | 
			
		||||
+	.atomic_async_check = vc4_plane_atomic_async_check,
 | 
			
		||||
+	.atomic_async_update = vc4_plane_atomic_async_update,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static struct drm_plane *vc4_fkms_plane_init(struct drm_device *dev,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,96 @@
 | 
			
		|||
From 482f1cbc27b336c12cbea38360a580cc0c8a8e62 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Thu, 11 Aug 2022 13:49:16 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4: Configure the HVS COB allocations
 | 
			
		||||
 | 
			
		||||
The HVS Composite Output Buffer (COB) is the memory used to
 | 
			
		||||
generate the output pixel data.
 | 
			
		||||
Until now the vc4 driver has been relying on the firmware to
 | 
			
		||||
have set these to sensible values.
 | 
			
		||||
 | 
			
		||||
In testing triple screen support it has been noted that only
 | 
			
		||||
1 line was being assigned to HVS channel 2. Whilst that is fine
 | 
			
		||||
for the transposer (TXP), and indeed needed as only some pixels
 | 
			
		||||
have an alpha channel, it is insufficient to run a live display.
 | 
			
		||||
 | 
			
		||||
Split the COB more evenly between the 3 HVS channels.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
 | 
			
		||||
Revert vc4_regs change
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c | 56 ++++++++++++++++++++++++++++++++++-
 | 
			
		||||
 1 file changed, 55 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -1013,7 +1013,7 @@ static int vc4_hvs_bind(struct device *d
 | 
			
		||||
 	struct vc4_hvs *hvs = NULL;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 	u32 dispctrl;
 | 
			
		||||
-	u32 reg;
 | 
			
		||||
+	u32 reg, top;
 | 
			
		||||
 
 | 
			
		||||
 	hvs = drmm_kzalloc(drm, sizeof(*hvs), GFP_KERNEL);
 | 
			
		||||
 	if (!hvs)
 | 
			
		||||
@@ -1151,6 +1151,60 @@ static int vc4_hvs_bind(struct device *d
 | 
			
		||||
 
 | 
			
		||||
 	HVS_WRITE(SCALER_DISPCTRL, dispctrl);
 | 
			
		||||
 
 | 
			
		||||
+	/* Recompute Composite Output Buffer (COB) allocations for the displays
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (!vc4->is_vc5) {
 | 
			
		||||
+		/* The COB is 20736 pixels, or just over 10 lines at 2048 wide.
 | 
			
		||||
+		 * The bottom 2048 pixels are full 32bpp RGBA (intended for the
 | 
			
		||||
+		 * TXP composing RGBA to memory), whilst the remainder are only
 | 
			
		||||
+		 * 24bpp RGB.
 | 
			
		||||
+		 *
 | 
			
		||||
+		 * Assign 3 lines to channels 1 & 2, and just over 4 lines to
 | 
			
		||||
+		 * channel 0.
 | 
			
		||||
+		 */
 | 
			
		||||
+		#define VC4_COB_SIZE		20736
 | 
			
		||||
+		#define VC4_COB_LINE_WIDTH	2048
 | 
			
		||||
+		#define VC4_COB_NUM_LINES	3
 | 
			
		||||
+		reg = 0;
 | 
			
		||||
+		top = VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES;
 | 
			
		||||
+		reg |= (top - 1) << 16;
 | 
			
		||||
+		HVS_WRITE(SCALER_DISPBASE2, reg);
 | 
			
		||||
+		reg = top;
 | 
			
		||||
+		top += VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES;
 | 
			
		||||
+		reg |= (top - 1) << 16;
 | 
			
		||||
+		HVS_WRITE(SCALER_DISPBASE1, reg);
 | 
			
		||||
+		reg = top;
 | 
			
		||||
+		top = VC4_COB_SIZE;
 | 
			
		||||
+		reg |= (top - 1) << 16;
 | 
			
		||||
+		HVS_WRITE(SCALER_DISPBASE0, reg);
 | 
			
		||||
+	} else {
 | 
			
		||||
+		/* The COB is 44416 pixels, or 10.8 lines at 4096 wide.
 | 
			
		||||
+		 * The bottom 4096 pixels are full RGBA (intended for the TXP
 | 
			
		||||
+		 * composing RGBA to memory), whilst the remainder are only
 | 
			
		||||
+		 * RGB. Addressing is always pixel wide.
 | 
			
		||||
+		 *
 | 
			
		||||
+		 * Assign 3 lines of 4096 to channels 1 & 2, and just over 4
 | 
			
		||||
+		 * lines. to channel 0.
 | 
			
		||||
+		 */
 | 
			
		||||
+		#define VC5_COB_SIZE		44416
 | 
			
		||||
+		#define VC5_COB_LINE_WIDTH	4096
 | 
			
		||||
+		#define VC5_COB_NUM_LINES	3
 | 
			
		||||
+		reg = 0;
 | 
			
		||||
+		top = VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES;
 | 
			
		||||
+		reg |= top << 16;
 | 
			
		||||
+		HVS_WRITE(SCALER_DISPBASE2, reg);
 | 
			
		||||
+		top += 16;
 | 
			
		||||
+		reg = top;
 | 
			
		||||
+		top += VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES;
 | 
			
		||||
+		reg |= top << 16;
 | 
			
		||||
+		HVS_WRITE(SCALER_DISPBASE1, reg);
 | 
			
		||||
+		top += 16;
 | 
			
		||||
+		reg = top;
 | 
			
		||||
+		top = VC5_COB_SIZE;
 | 
			
		||||
+		reg |= top << 16;
 | 
			
		||||
+		HVS_WRITE(SCALER_DISPBASE0, reg);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	ret = devm_request_irq(dev, platform_get_irq(pdev, 0),
 | 
			
		||||
 			       vc4_hvs_irq_handler, 0, "vc4 hvs", drm);
 | 
			
		||||
 	if (ret)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
From 87fed1718f9ce64127dea253c37a9f13ec987ee0 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
Date: Thu, 11 Aug 2022 13:59:34 +0100
 | 
			
		||||
Subject: [PATCH] drm/vc4: Set AXI panic modes for the HVS
 | 
			
		||||
 | 
			
		||||
The HVS can change AXI request mode based on how full the COB
 | 
			
		||||
FIFOs are.
 | 
			
		||||
Until now the vc4 driver has been relying on the firmware to
 | 
			
		||||
have set these to sensible values.
 | 
			
		||||
 | 
			
		||||
With HVS channel 2 now being used for live video, change the
 | 
			
		||||
panic mode for all channels to be explicitly set by the driver,
 | 
			
		||||
and the same for all channels.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c | 11 +++++++++++
 | 
			
		||||
 1 file changed, 11 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -1149,6 +1149,17 @@ static int vc4_hvs_bind(struct device *d
 | 
			
		||||
 	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
 | 
			
		||||
 	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
 | 
			
		||||
 
 | 
			
		||||
+	/* Set AXI panic mode.
 | 
			
		||||
+	 * VC4 panics when < 2 lines in FIFO.
 | 
			
		||||
+	 * VC5 panics when less than 1 line in the FIFO.
 | 
			
		||||
+	 */
 | 
			
		||||
+	dispctrl &= ~(SCALER_DISPCTRL_PANIC0_MASK |
 | 
			
		||||
+		      SCALER_DISPCTRL_PANIC1_MASK |
 | 
			
		||||
+		      SCALER_DISPCTRL_PANIC2_MASK);
 | 
			
		||||
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC0);
 | 
			
		||||
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC1);
 | 
			
		||||
+	dispctrl |= VC4_SET_FIELD(2, SCALER_DISPCTRL_PANIC2);
 | 
			
		||||
+
 | 
			
		||||
 	HVS_WRITE(SCALER_DISPCTRL, dispctrl);
 | 
			
		||||
 
 | 
			
		||||
 	/* Recompute Composite Output Buffer (COB) allocations for the displays
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
From 816a2693d6dd7058f96b0f8d089ec1ece8b6db14 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
Date: Mon, 11 Jul 2022 10:38:25 +0200
 | 
			
		||||
Subject: [PATCH] drm/vc4: hvs: Skip DebugFS Registration for FKMS
 | 
			
		||||
 | 
			
		||||
FKMS doesn't have an HVS and it's expected. Return from the debugfs init
 | 
			
		||||
function immediately if we're running with fkms.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 drivers/gpu/drm/vc4/vc4_hvs.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
 | 
			
		||||
@@ -975,6 +975,9 @@ int vc4_hvs_debugfs_init(struct drm_mino
 | 
			
		||||
 	struct vc4_hvs *hvs = vc4->hvs;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
+	if (vc4->firmware_kms)
 | 
			
		||||
+		return 0;
 | 
			
		||||
+
 | 
			
		||||
 	if (!vc4->hvs)
 | 
			
		||||
 		return -ENODEV;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
From e2339bd2c4fd484b8be3e2b662bfaf514834e3c7 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
Date: Mon, 15 Aug 2022 13:34:02 +0200
 | 
			
		||||
Subject: [PATCH] media: uapi: Add some RGB bus formats for VC4 DPI output
 | 
			
		||||
 | 
			
		||||
The VC4 DPI controller can output more RGB formats that aren't described
 | 
			
		||||
through a media bus format yet, so let's add them.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 include/uapi/linux/media-bus-format.h | 5 ++++-
 | 
			
		||||
 1 file changed, 4 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/include/uapi/linux/media-bus-format.h
 | 
			
		||||
+++ b/include/uapi/linux/media-bus-format.h
 | 
			
		||||
@@ -34,19 +34,22 @@
 | 
			
		||||
 
 | 
			
		||||
 #define MEDIA_BUS_FMT_FIXED			0x0001
 | 
			
		||||
 
 | 
			
		||||
-/* RGB - next is	0x1022 */
 | 
			
		||||
+/* RGB - next is	0x1025 */
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB444_1X12		0x1016
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE	0x1001
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE	0x1002
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE	0x1003
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE	0x1004
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB565_1X16		0x1017
 | 
			
		||||
+#define MEDIA_BUS_FMT_RGB565_1X24_CPADHI	0x1022
 | 
			
		||||
 #define MEDIA_BUS_FMT_BGR565_2X8_BE		0x1005
 | 
			
		||||
 #define MEDIA_BUS_FMT_BGR565_2X8_LE		0x1006
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB565_2X8_BE		0x1007
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB565_2X8_LE		0x1008
 | 
			
		||||
+#define MEDIA_BUS_FMT_BGR666_1X18		0x1023
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB666_1X18		0x1009
 | 
			
		||||
 #define MEDIA_BUS_FMT_RBG888_1X24		0x100e
 | 
			
		||||
+#define MEDIA_BUS_FMT_BGR666_1X24_CPADHI	0x1024
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB666_1X24_CPADHI	0x1015
 | 
			
		||||
 #define MEDIA_BUS_FMT_RGB666_1X7X3_SPWG		0x1010
 | 
			
		||||
 #define MEDIA_BUS_FMT_BGR888_1X24		0x1013
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
From f4f85afe1641fc846b011dff80ef5c0b6b206258 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Thu, 7 Apr 2022 18:23:07 +0100
 | 
			
		||||
Subject: [PATCH] raspberrypi-firmware: Update mailbox commands
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 include/soc/bcm2835/raspberrypi-firmware.h | 28 +++++++++++++++++++++-
 | 
			
		||||
 1 file changed, 27 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/include/soc/bcm2835/raspberrypi-firmware.h
 | 
			
		||||
+++ b/include/soc/bcm2835/raspberrypi-firmware.h
 | 
			
		||||
@@ -36,6 +36,8 @@ struct rpi_firmware_property_tag_header
 | 
			
		||||
 enum rpi_firmware_property_tag {
 | 
			
		||||
 	RPI_FIRMWARE_PROPERTY_END =                           0,
 | 
			
		||||
 	RPI_FIRMWARE_GET_FIRMWARE_REVISION =                  0x00000001,
 | 
			
		||||
+	RPI_FIRMWARE_GET_FIRMWARE_VARIANT =                   0x00000002,
 | 
			
		||||
+	RPI_FIRMWARE_GET_FIRMWARE_HASH =                      0x00000003,
 | 
			
		||||
 
 | 
			
		||||
 	RPI_FIRMWARE_SET_CURSOR_INFO =                        0x00008010,
 | 
			
		||||
 	RPI_FIRMWARE_SET_CURSOR_STATE =                       0x00008011,
 | 
			
		||||
@@ -71,6 +73,7 @@ enum rpi_firmware_property_tag {
 | 
			
		||||
 	RPI_FIRMWARE_GET_DISPMANX_RESOURCE_MEM_HANDLE =       0x00030014,
 | 
			
		||||
 	RPI_FIRMWARE_GET_EDID_BLOCK =                         0x00030020,
 | 
			
		||||
 	RPI_FIRMWARE_GET_CUSTOMER_OTP =                       0x00030021,
 | 
			
		||||
+	RPI_FIRMWARE_GET_EDID_BLOCK_DISPLAY =                 0x00030023,
 | 
			
		||||
 	RPI_FIRMWARE_GET_DOMAIN_STATE =                       0x00030030,
 | 
			
		||||
 	RPI_FIRMWARE_GET_THROTTLED =                          0x00030046,
 | 
			
		||||
 	RPI_FIRMWARE_GET_CLOCK_MEASURED =                     0x00030047,
 | 
			
		||||
@@ -89,8 +92,11 @@ enum rpi_firmware_property_tag {
 | 
			
		||||
 	RPI_FIRMWARE_GET_PERIPH_REG =                         0x00030045,
 | 
			
		||||
 	RPI_FIRMWARE_SET_PERIPH_REG =                         0x00038045,
 | 
			
		||||
 	RPI_FIRMWARE_GET_POE_HAT_VAL =                        0x00030049,
 | 
			
		||||
-	RPI_FIRMWARE_SET_POE_HAT_VAL =                        0x00030050,
 | 
			
		||||
+	RPI_FIRMWARE_SET_POE_HAT_VAL =                        0x00038049,
 | 
			
		||||
+	RPI_FIRMWARE_SET_POE_HAT_VAL_OLD =                    0x00030050,
 | 
			
		||||
 	RPI_FIRMWARE_NOTIFY_XHCI_RESET =                      0x00030058,
 | 
			
		||||
+	RPI_FIRMWARE_GET_REBOOT_FLAGS =                       0x00030064,
 | 
			
		||||
+	RPI_FIRMWARE_SET_REBOOT_FLAGS =                       0x00038064,
 | 
			
		||||
 	RPI_FIRMWARE_NOTIFY_DISPLAY_DONE =                    0x00030066,
 | 
			
		||||
 
 | 
			
		||||
 	/* Dispmanx TAGS */
 | 
			
		||||
@@ -105,9 +111,16 @@ enum rpi_firmware_property_tag {
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_GET_VIRTUAL_OFFSET =         0x00040009,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_GET_OVERSCAN =               0x0004000a,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_GET_PALETTE =                0x0004000b,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_GET_LAYER =                  0x0004000c,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_GET_TRANSFORM =              0x0004000d,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_GET_VSYNC =                  0x0004000e,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_GET_TOUCHBUF =               0x0004000f,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_GET_GPIOVIRTBUF =            0x00040010,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_RELEASE =                    0x00048001,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_ID =             0x00040016,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM =            0x00048013,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS =           0x00040013,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS =       0x00040014,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_PHYSICAL_WIDTH_HEIGHT = 0x00044003,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_WIDTH_HEIGHT =  0x00044004,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_DEPTH =                 0x00044005,
 | 
			
		||||
@@ -116,26 +129,39 @@ enum rpi_firmware_property_tag {
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_VIRTUAL_OFFSET =        0x00044009,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_OVERSCAN =              0x0004400a,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_PALETTE =               0x0004400b,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_TEST_LAYER =                 0x0004400c,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_TEST_TRANSFORM =             0x0004400d,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_TEST_VSYNC =                 0x0004400e,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT =  0x00048003,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT =   0x00048004,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH =                  0x00048005,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_PIXEL_ORDER =            0x00048006,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_ALPHA_MODE =             0x00048007,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH =                  0x00048008,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET =         0x00048009,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_OVERSCAN =               0x0004800a,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_PALETTE =                0x0004800b,
 | 
			
		||||
+
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF =               0x0004801f,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_GPIOVIRTBUF =            0x00048020,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_VSYNC =                  0x0004800e,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_SET_LAYER =                  0x0004800c,
 | 
			
		||||
+	RPI_FIRMWARE_FRAMEBUFFER_SET_TRANSFORM =              0x0004800d,
 | 
			
		||||
 	RPI_FIRMWARE_FRAMEBUFFER_SET_BACKLIGHT =              0x0004800f,
 | 
			
		||||
 
 | 
			
		||||
 	RPI_FIRMWARE_VCHIQ_INIT =                             0x00048010,
 | 
			
		||||
 
 | 
			
		||||
+	RPI_FIRMWARE_SET_PLANE =                              0x00048015,
 | 
			
		||||
+	RPI_FIRMWARE_GET_DISPLAY_TIMING =                     0x00040017,
 | 
			
		||||
+	RPI_FIRMWARE_SET_TIMING =                             0x00048017,
 | 
			
		||||
+	RPI_FIRMWARE_GET_DISPLAY_CFG =                        0x00040018,
 | 
			
		||||
+	RPI_FIRMWARE_SET_DISPLAY_POWER =		      0x00048019,
 | 
			
		||||
 	RPI_FIRMWARE_GET_COMMAND_LINE =                       0x00050001,
 | 
			
		||||
 	RPI_FIRMWARE_GET_DMA_CHANNELS =                       0x00060001,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+#define GET_DISPLAY_SETTINGS_PAYLOAD_SIZE 64
 | 
			
		||||
+
 | 
			
		||||
 #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE)
 | 
			
		||||
 int rpi_firmware_property(struct rpi_firmware *fw,
 | 
			
		||||
 			  u32 tag, void *data, size_t len);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,70 @@
 | 
			
		|||
From e8d0e03fcc00e871ecf963838d99b91b992252ea Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
Date: Mon, 11 Jul 2022 15:58:36 +0200
 | 
			
		||||
Subject: [PATCH] clk: bcm: rpi: Create helper to retrieve private data
 | 
			
		||||
 | 
			
		||||
The RaspberryPi firmware clocks driver uses in several instances a
 | 
			
		||||
container_of to retrieve the struct raspberrypi_clk_data from a pointer
 | 
			
		||||
to struct clk_hw. Let's create a small function to avoid duplicating it
 | 
			
		||||
all over the place.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-raspberrypi.c | 18 ++++++++++--------
 | 
			
		||||
 1 file changed, 10 insertions(+), 8 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-raspberrypi.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-raspberrypi.c
 | 
			
		||||
@@ -75,6 +75,12 @@ struct raspberrypi_clk_data {
 | 
			
		||||
 	struct raspberrypi_clk *rpi;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static inline
 | 
			
		||||
+const struct raspberrypi_clk_data *clk_hw_to_data(const struct clk_hw *hw)
 | 
			
		||||
+{
 | 
			
		||||
+	return container_of(hw, struct raspberrypi_clk_data, hw);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 struct raspberrypi_clk_variant {
 | 
			
		||||
 	bool		export;
 | 
			
		||||
 	char		*clkdev;
 | 
			
		||||
@@ -187,8 +193,7 @@ static int raspberrypi_clock_property(st
 | 
			
		||||
 
 | 
			
		||||
 static int raspberrypi_fw_is_prepared(struct clk_hw *hw)
 | 
			
		||||
 {
 | 
			
		||||
-	struct raspberrypi_clk_data *data =
 | 
			
		||||
-		container_of(hw, struct raspberrypi_clk_data, hw);
 | 
			
		||||
+	const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
 | 
			
		||||
 	struct raspberrypi_clk *rpi = data->rpi;
 | 
			
		||||
 	u32 val = 0;
 | 
			
		||||
 	int ret;
 | 
			
		||||
@@ -205,8 +210,7 @@ static int raspberrypi_fw_is_prepared(st
 | 
			
		||||
 static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw,
 | 
			
		||||
 					     unsigned long parent_rate)
 | 
			
		||||
 {
 | 
			
		||||
-	struct raspberrypi_clk_data *data =
 | 
			
		||||
-		container_of(hw, struct raspberrypi_clk_data, hw);
 | 
			
		||||
+	const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
 | 
			
		||||
 	struct raspberrypi_clk *rpi = data->rpi;
 | 
			
		||||
 	u32 val = 0;
 | 
			
		||||
 	int ret;
 | 
			
		||||
@@ -222,8 +226,7 @@ static unsigned long raspberrypi_fw_get_
 | 
			
		||||
 static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
 | 
			
		||||
 				   unsigned long parent_rate)
 | 
			
		||||
 {
 | 
			
		||||
-	struct raspberrypi_clk_data *data =
 | 
			
		||||
-		container_of(hw, struct raspberrypi_clk_data, hw);
 | 
			
		||||
+	const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
 | 
			
		||||
 	struct raspberrypi_clk *rpi = data->rpi;
 | 
			
		||||
 	u32 _rate = rate;
 | 
			
		||||
 	int ret;
 | 
			
		||||
@@ -240,8 +243,7 @@ static int raspberrypi_fw_set_rate(struc
 | 
			
		||||
 static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
 | 
			
		||||
 					      struct clk_rate_request *req)
 | 
			
		||||
 {
 | 
			
		||||
-	struct raspberrypi_clk_data *data =
 | 
			
		||||
-		container_of(hw, struct raspberrypi_clk_data, hw);
 | 
			
		||||
+	const struct raspberrypi_clk_data *data = clk_hw_to_data(hw);
 | 
			
		||||
 	struct raspberrypi_clk_variant *variant = data->variant;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From 59af37c19b6ceb1caa4f8aa144d114c30667961b Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
Date: Mon, 6 Jun 2022 11:02:16 +0200
 | 
			
		||||
Subject: [PATCH] arm64: setup: Fix build warning
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Maxime Ripard <maxime@cerno.tech>
 | 
			
		||||
---
 | 
			
		||||
 arch/arm64/kernel/setup.c | 4 ++--
 | 
			
		||||
 1 file changed, 2 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/arm64/kernel/setup.c
 | 
			
		||||
+++ b/arch/arm64/kernel/setup.c
 | 
			
		||||
@@ -222,9 +222,9 @@ static void __init request_standard_reso
 | 
			
		||||
 	size_t res_size;
 | 
			
		||||
 
 | 
			
		||||
 	kernel_code.start   = __pa_symbol(_stext);
 | 
			
		||||
-	kernel_code.end     = __pa_symbol(__init_begin - 1);
 | 
			
		||||
+	kernel_code.end     = __pa_symbol(__init_begin) - 1;
 | 
			
		||||
 	kernel_data.start   = __pa_symbol(_sdata);
 | 
			
		||||
-	kernel_data.end     = __pa_symbol(_end - 1);
 | 
			
		||||
+	kernel_data.end     = __pa_symbol(_end) - 1;
 | 
			
		||||
 	insert_resource(&iomem_resource, &kernel_code);
 | 
			
		||||
 	insert_resource(&iomem_resource, &kernel_data);
 | 
			
		||||
 
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
From e83914825e59198988203f5ed879a64f3557b280 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Tue, 12 Apr 2022 20:07:20 +0100
 | 
			
		||||
Subject: [PATCH] clk-raspberrypi: Add ISP to exported clocks
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-raspberrypi.c | 3 +++
 | 
			
		||||
 1 file changed, 3 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-raspberrypi.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-raspberrypi.c
 | 
			
		||||
@@ -143,6 +143,9 @@ raspberrypi_clk_variants[RPI_FIRMWARE_NU
 | 
			
		||||
 	[RPI_FIRMWARE_HEVC_CLK_ID] = {
 | 
			
		||||
 		.export = true,
 | 
			
		||||
 	},
 | 
			
		||||
+	[RPI_FIRMWARE_ISP_CLK_ID] = {
 | 
			
		||||
+		.export = true,
 | 
			
		||||
+	},
 | 
			
		||||
 	[RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = {
 | 
			
		||||
 		.export = true,
 | 
			
		||||
 	},
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
From ae2e43a22f1044d9a1d5ea1f9c23871a8a2e1ae8 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Martin Sperl <kernel@martin.sperl.org>
 | 
			
		||||
Date: Fri, 2 Sep 2016 16:45:27 +0100
 | 
			
		||||
Subject: [PATCH] Register the clocks early during the boot process, so that
 | 
			
		||||
 special/critical clocks can get enabled early on in the boot process avoiding
 | 
			
		||||
 the risk of disabling a clock, pll_divider or pll when a claiming driver
 | 
			
		||||
 fails to install propperly - maybe it needs to defer.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 15 +++++++++++++--
 | 
			
		||||
 1 file changed, 13 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -2319,8 +2319,15 @@ static int bcm2835_clk_probe(struct plat
 | 
			
		||||
 	if (ret)
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
-	return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
 | 
			
		||||
+	ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
 | 
			
		||||
 				      &cprman->onecell);
 | 
			
		||||
+	if (ret)
 | 
			
		||||
+		return ret;
 | 
			
		||||
+
 | 
			
		||||
+	/* note that we have registered all the clocks */
 | 
			
		||||
+	dev_dbg(dev, "registered %d clocks\n", asize);
 | 
			
		||||
+
 | 
			
		||||
+	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static const struct cprman_plat_data cprman_bcm2835_plat_data = {
 | 
			
		||||
@@ -2346,7 +2353,11 @@ static struct platform_driver bcm2835_cl
 | 
			
		||||
 	.probe          = bcm2835_clk_probe,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
-builtin_platform_driver(bcm2835_clk_driver);
 | 
			
		||||
+static int __init __bcm2835_clk_driver_init(void)
 | 
			
		||||
+{
 | 
			
		||||
+	return platform_driver_register(&bcm2835_clk_driver);
 | 
			
		||||
+}
 | 
			
		||||
+core_initcall(__bcm2835_clk_driver_init);
 | 
			
		||||
 
 | 
			
		||||
 MODULE_AUTHOR("Eric Anholt <eric@anholt.net>");
 | 
			
		||||
 MODULE_DESCRIPTION("BCM2835 clock driver");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
From 2f4b354fedfd33cd996d261f66c887a87cbee641 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Mon, 13 Feb 2017 17:20:08 +0000
 | 
			
		||||
Subject: [PATCH] clk-bcm2835: Mark used PLLs and dividers CRITICAL
 | 
			
		||||
 | 
			
		||||
The VPU configures and relies on several PLLs and dividers. Mark all
 | 
			
		||||
enabled dividers and their PLLs as CRITICAL to prevent the kernel from
 | 
			
		||||
switching them off.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 5 +++++
 | 
			
		||||
 1 file changed, 5 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -1407,6 +1407,11 @@ bcm2835_register_pll_divider(struct bcm2
 | 
			
		||||
 	divider->div.hw.init = &init;
 | 
			
		||||
 	divider->div.table = NULL;
 | 
			
		||||
 
 | 
			
		||||
+	if (!(cprman_read(cprman, divider_data->cm_reg) & divider_data->hold_mask)) {
 | 
			
		||||
+		init.flags |= CLK_IS_CRITICAL;
 | 
			
		||||
+		divider->div.flags |= CLK_IS_CRITICAL;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	divider->cprman = cprman;
 | 
			
		||||
 	divider->data = divider_data;
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,118 @@
 | 
			
		|||
From 2bd63288dcd33f32b529ef073e9b716444846e48 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Mon, 13 Feb 2017 17:20:08 +0000
 | 
			
		||||
Subject: [PATCH] clk-bcm2835: Add claim-clocks property
 | 
			
		||||
 | 
			
		||||
The claim-clocks property can be used to prevent PLLs and dividers
 | 
			
		||||
from being marked as critical. It contains a vector of clock IDs,
 | 
			
		||||
as defined by dt-bindings/clock/bcm2835.h.
 | 
			
		||||
 | 
			
		||||
Use this mechanism to claim PLLD_DSI0, PLLD_DSI1, PLLH_AUX and
 | 
			
		||||
PLLH_PIX for the vc4_kms_v3d driver.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 43 +++++++++++++++++++++++++++++++++--
 | 
			
		||||
 1 file changed, 41 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -1335,6 +1335,8 @@ static const struct clk_ops bcm2835_vpu_
 | 
			
		||||
 	.debug_init = bcm2835_clock_debug_init,
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static bool bcm2835_clk_is_claimed(const char *name);
 | 
			
		||||
+
 | 
			
		||||
 static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
 | 
			
		||||
 					   const void *data)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1352,6 +1354,9 @@ static struct clk_hw *bcm2835_register_p
 | 
			
		||||
 	init.ops = &bcm2835_pll_clk_ops;
 | 
			
		||||
 	init.flags = pll_data->flags | CLK_IGNORE_UNUSED;
 | 
			
		||||
 
 | 
			
		||||
+	if (!bcm2835_clk_is_claimed(pll_data->name))
 | 
			
		||||
+		init.flags |= CLK_IS_CRITICAL;
 | 
			
		||||
+
 | 
			
		||||
 	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 | 
			
		||||
 	if (!pll)
 | 
			
		||||
 		return NULL;
 | 
			
		||||
@@ -1408,8 +1413,10 @@ bcm2835_register_pll_divider(struct bcm2
 | 
			
		||||
 	divider->div.table = NULL;
 | 
			
		||||
 
 | 
			
		||||
 	if (!(cprman_read(cprman, divider_data->cm_reg) & divider_data->hold_mask)) {
 | 
			
		||||
-		init.flags |= CLK_IS_CRITICAL;
 | 
			
		||||
-		divider->div.flags |= CLK_IS_CRITICAL;
 | 
			
		||||
+		if (!bcm2835_clk_is_claimed(divider_data->source_pll))
 | 
			
		||||
+			init.flags |= CLK_IS_CRITICAL;
 | 
			
		||||
+		if (!bcm2835_clk_is_claimed(divider_data->name))
 | 
			
		||||
+			divider->div.flags |= CLK_IS_CRITICAL;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	divider->cprman = cprman;
 | 
			
		||||
@@ -1466,6 +1473,15 @@ static struct clk_hw *bcm2835_register_c
 | 
			
		||||
 	init.flags = clock_data->flags | CLK_IGNORE_UNUSED;
 | 
			
		||||
 
 | 
			
		||||
 	/*
 | 
			
		||||
+	 * Some GPIO clocks for ethernet/wifi PLLs are marked as
 | 
			
		||||
+	 * critical (since some platforms use them), but if the
 | 
			
		||||
+	 * firmware didn't have them turned on then they clearly
 | 
			
		||||
+	 * aren't actually critical.
 | 
			
		||||
+	 */
 | 
			
		||||
+	if ((cprman_read(cprman, clock_data->ctl_reg) & CM_ENABLE) == 0)
 | 
			
		||||
+		init.flags &= ~CLK_IS_CRITICAL;
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
 	 * Pass the CLK_SET_RATE_PARENT flag if we are allowed to propagate
 | 
			
		||||
 	 * rate changes on at least of the parents.
 | 
			
		||||
 	 */
 | 
			
		||||
@@ -2245,6 +2261,8 @@ static const struct bcm2835_clk_desc clk
 | 
			
		||||
 		.ctl_reg = CM_PERIICTL),
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
+static bool bcm2835_clk_claimed[ARRAY_SIZE(clk_desc_array)];
 | 
			
		||||
+
 | 
			
		||||
 /*
 | 
			
		||||
  * Permanently take a reference on the parent of the SDRAM clock.
 | 
			
		||||
  *
 | 
			
		||||
@@ -2264,6 +2282,19 @@ static int bcm2835_mark_sdc_parent_criti
 | 
			
		||||
 	return clk_prepare_enable(parent);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static bool bcm2835_clk_is_claimed(const char *name)
 | 
			
		||||
+{
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	for (i = 0; i < ARRAY_SIZE(clk_desc_array); i++) {
 | 
			
		||||
+		const char *clk_name = *(const char **)(clk_desc_array[i].data);
 | 
			
		||||
+		if (!strcmp(name, clk_name))
 | 
			
		||||
+		    return bcm2835_clk_claimed[i];
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return false;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static int bcm2835_clk_probe(struct platform_device *pdev)
 | 
			
		||||
 {
 | 
			
		||||
 	struct device *dev = &pdev->dev;
 | 
			
		||||
@@ -2273,6 +2304,7 @@ static int bcm2835_clk_probe(struct plat
 | 
			
		||||
 	const size_t asize = ARRAY_SIZE(clk_desc_array);
 | 
			
		||||
 	const struct cprman_plat_data *pdata;
 | 
			
		||||
 	size_t i;
 | 
			
		||||
+	u32 clk_id;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
 	pdata = of_device_get_match_data(&pdev->dev);
 | 
			
		||||
@@ -2291,6 +2323,13 @@ static int bcm2835_clk_probe(struct plat
 | 
			
		||||
 	if (IS_ERR(cprman->regs))
 | 
			
		||||
 		return PTR_ERR(cprman->regs);
 | 
			
		||||
 
 | 
			
		||||
+	memset(bcm2835_clk_claimed, 0, sizeof(bcm2835_clk_claimed));
 | 
			
		||||
+	for (i = 0;
 | 
			
		||||
+	     !of_property_read_u32_index(pdev->dev.of_node, "claim-clocks",
 | 
			
		||||
+					 i, &clk_id);
 | 
			
		||||
+	     i++)
 | 
			
		||||
+		bcm2835_clk_claimed[clk_id]= true;
 | 
			
		||||
+
 | 
			
		||||
 	memcpy(cprman->real_parent_names, cprman_parent_names,
 | 
			
		||||
 	       sizeof(cprman_parent_names));
 | 
			
		||||
 	of_clk_parent_fill(dev->of_node, cprman->real_parent_names,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,115 @@
 | 
			
		|||
From 34a1764a301c3a18ec016f4331ba104d7cd38f26 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Mon, 6 Mar 2017 09:06:18 +0000
 | 
			
		||||
Subject: [PATCH] clk-bcm2835: Read max core clock from firmware
 | 
			
		||||
 | 
			
		||||
The VPU is responsible for managing the core clock, usually under
 | 
			
		||||
direction from the bcm2835-cpufreq driver but not via the clk-bcm2835
 | 
			
		||||
driver. Since the core frequency can change without warning, it is
 | 
			
		||||
safer to report the maximum clock rate to users of the core clock -
 | 
			
		||||
I2C, SPI and the mini UART - to err on the safe side when calculating
 | 
			
		||||
clock divisors.
 | 
			
		||||
 | 
			
		||||
If the DT node for the clock driver includes a reference to the
 | 
			
		||||
firmware node, use the firmware API to query the maximum core clock
 | 
			
		||||
instead of reading the divider registers.
 | 
			
		||||
 | 
			
		||||
Prior to this patch, a "100KHz" I2C bus was sometimes clocked at about
 | 
			
		||||
160KHz. In particular, switching to the 4.9 kernel was likely to break
 | 
			
		||||
SenseHAT usage on a Pi3.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 39 ++++++++++++++++++++++++++++++++++-
 | 
			
		||||
 1 file changed, 38 insertions(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -36,6 +36,7 @@
 | 
			
		||||
 #include <linux/platform_device.h>
 | 
			
		||||
 #include <linux/slab.h>
 | 
			
		||||
 #include <dt-bindings/clock/bcm2835.h>
 | 
			
		||||
+#include <soc/bcm2835/raspberrypi-firmware.h>
 | 
			
		||||
 
 | 
			
		||||
 #define CM_PASSWORD		0x5a000000
 | 
			
		||||
 
 | 
			
		||||
@@ -296,6 +297,8 @@
 | 
			
		||||
 #define SOC_BCM2711		BIT(1)
 | 
			
		||||
 #define SOC_ALL			(SOC_BCM2835 | SOC_BCM2711)
 | 
			
		||||
 
 | 
			
		||||
+#define VCMSG_ID_CORE_CLOCK     4
 | 
			
		||||
+
 | 
			
		||||
 /*
 | 
			
		||||
  * Names of clocks used within the driver that need to be replaced
 | 
			
		||||
  * with an external parent's name.  This array is in the order that
 | 
			
		||||
@@ -314,6 +317,7 @@ static const char *const cprman_parent_n
 | 
			
		||||
 struct bcm2835_cprman {
 | 
			
		||||
 	struct device *dev;
 | 
			
		||||
 	void __iomem *regs;
 | 
			
		||||
+	struct rpi_firmware *fw;
 | 
			
		||||
 	spinlock_t regs_lock; /* spinlock for all clocks */
 | 
			
		||||
 	unsigned int soc;
 | 
			
		||||
 
 | 
			
		||||
@@ -1039,6 +1043,30 @@ static unsigned long bcm2835_clock_get_r
 | 
			
		||||
 	return rate;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static unsigned long bcm2835_clock_get_rate_vpu(struct clk_hw *hw,
 | 
			
		||||
+						unsigned long parent_rate)
 | 
			
		||||
+{
 | 
			
		||||
+	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
 | 
			
		||||
+	struct bcm2835_cprman *cprman = clock->cprman;
 | 
			
		||||
+
 | 
			
		||||
+	if (cprman->fw) {
 | 
			
		||||
+		struct {
 | 
			
		||||
+			u32 id;
 | 
			
		||||
+			u32 val;
 | 
			
		||||
+		} packet;
 | 
			
		||||
+
 | 
			
		||||
+		packet.id = VCMSG_ID_CORE_CLOCK;
 | 
			
		||||
+		packet.val = 0;
 | 
			
		||||
+
 | 
			
		||||
+		if (!rpi_firmware_property(cprman->fw,
 | 
			
		||||
+					   RPI_FIRMWARE_GET_MAX_CLOCK_RATE,
 | 
			
		||||
+					   &packet, sizeof(packet)))
 | 
			
		||||
+			return packet.val;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	return bcm2835_clock_get_rate(hw, parent_rate);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void bcm2835_clock_wait_busy(struct bcm2835_clock *clock)
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcm2835_cprman *cprman = clock->cprman;
 | 
			
		||||
@@ -1327,7 +1355,7 @@ static int bcm2835_vpu_clock_is_on(struc
 | 
			
		||||
  */
 | 
			
		||||
 static const struct clk_ops bcm2835_vpu_clock_clk_ops = {
 | 
			
		||||
 	.is_prepared = bcm2835_vpu_clock_is_on,
 | 
			
		||||
-	.recalc_rate = bcm2835_clock_get_rate,
 | 
			
		||||
+	.recalc_rate = bcm2835_clock_get_rate_vpu,
 | 
			
		||||
 	.set_rate = bcm2835_clock_set_rate,
 | 
			
		||||
 	.determine_rate = bcm2835_clock_determine_rate,
 | 
			
		||||
 	.set_parent = bcm2835_clock_set_parent,
 | 
			
		||||
@@ -2303,6 +2331,7 @@ static int bcm2835_clk_probe(struct plat
 | 
			
		||||
 	const struct bcm2835_clk_desc *desc;
 | 
			
		||||
 	const size_t asize = ARRAY_SIZE(clk_desc_array);
 | 
			
		||||
 	const struct cprman_plat_data *pdata;
 | 
			
		||||
+	struct device_node *fw_node;
 | 
			
		||||
 	size_t i;
 | 
			
		||||
 	u32 clk_id;
 | 
			
		||||
 	int ret;
 | 
			
		||||
@@ -2323,6 +2352,14 @@ static int bcm2835_clk_probe(struct plat
 | 
			
		||||
 	if (IS_ERR(cprman->regs))
 | 
			
		||||
 		return PTR_ERR(cprman->regs);
 | 
			
		||||
 
 | 
			
		||||
+	fw_node = of_parse_phandle(dev->of_node, "firmware", 0);
 | 
			
		||||
+	if (fw_node) {
 | 
			
		||||
+		struct rpi_firmware *fw = rpi_firmware_get(NULL);
 | 
			
		||||
+		if (!fw)
 | 
			
		||||
+			return -EPROBE_DEFER;
 | 
			
		||||
+		cprman->fw = fw;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	memset(bcm2835_clk_claimed, 0, sizeof(bcm2835_clk_claimed));
 | 
			
		||||
 	for (i = 0;
 | 
			
		||||
 	     !of_property_read_u32_index(pdev->dev.of_node, "claim-clocks",
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From 06e0ba66373d40aa76f1a927b8228b66ecac07d4 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dave Stevenson <dave.stevenson@raspberrypi.org>
 | 
			
		||||
Date: Thu, 24 Jan 2019 15:09:28 +0000
 | 
			
		||||
Subject: [PATCH] clk: clk-bcm2835: Use %zd when printing size_t
 | 
			
		||||
 | 
			
		||||
The debug text for how many clocks have been registered
 | 
			
		||||
uses "%d" with a size_t. Correct it to "%zd".
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -2406,7 +2406,7 @@ static int bcm2835_clk_probe(struct plat
 | 
			
		||||
 		return ret;
 | 
			
		||||
 
 | 
			
		||||
 	/* note that we have registered all the clocks */
 | 
			
		||||
-	dev_dbg(dev, "registered %d clocks\n", asize);
 | 
			
		||||
+	dev_dbg(dev, "registered %zd clocks\n", asize);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,38 @@
 | 
			
		|||
From 9c849cd78ee9d78443303af3b55cc3fc6318f31f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Wed, 23 Jan 2019 16:11:50 +0000
 | 
			
		||||
Subject: [PATCH] clk-bcm2835: Don't wait for pllh lock
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 18 ++++++++++--------
 | 
			
		||||
 1 file changed, 10 insertions(+), 8 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -647,15 +647,17 @@ static int bcm2835_pll_on(struct clk_hw
 | 
			
		||||
 	spin_unlock(&cprman->regs_lock);
 | 
			
		||||
 
 | 
			
		||||
 	/* Wait for the PLL to lock. */
 | 
			
		||||
-	timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
 | 
			
		||||
-	while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) {
 | 
			
		||||
-		if (ktime_after(ktime_get(), timeout)) {
 | 
			
		||||
-			dev_err(cprman->dev, "%s: couldn't lock PLL\n",
 | 
			
		||||
-				clk_hw_get_name(hw));
 | 
			
		||||
-			return -ETIMEDOUT;
 | 
			
		||||
-		}
 | 
			
		||||
+	if (strcmp(data->name, "pllh")) {
 | 
			
		||||
+		timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
 | 
			
		||||
+		while (!(cprman_read(cprman, CM_LOCK) & data->lock_mask)) {
 | 
			
		||||
+			if (ktime_after(ktime_get(), timeout)) {
 | 
			
		||||
+				dev_err(cprman->dev, "%s: couldn't lock PLL\n",
 | 
			
		||||
+					clk_hw_get_name(hw));
 | 
			
		||||
+				return -ETIMEDOUT;
 | 
			
		||||
+			}
 | 
			
		||||
 
 | 
			
		||||
-		cpu_relax();
 | 
			
		||||
+			cpu_relax();
 | 
			
		||||
+		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	cprman_write(cprman, data->a2w_ctrl_reg,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
From c5a0182a6aec56695354cfe10bb5536a6a38c5f3 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Anholt <eric@anholt.net>
 | 
			
		||||
Date: Thu, 2 May 2019 15:11:05 -0700
 | 
			
		||||
Subject: [PATCH] clk: bcm2835: Add support for setting leaf clock rates while
 | 
			
		||||
 running.
 | 
			
		||||
 | 
			
		||||
As long as you wait for !BUSY, you can do glitch-free updates of clock
 | 
			
		||||
rate while the clock is running.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Eric Anholt <eric@anholt.net>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 22 +++++++++++++---------
 | 
			
		||||
 1 file changed, 13 insertions(+), 9 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -1138,15 +1138,19 @@ static int bcm2835_clock_set_rate(struct
 | 
			
		||||
 
 | 
			
		||||
 	spin_lock(&cprman->regs_lock);
 | 
			
		||||
 
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * Setting up frac support
 | 
			
		||||
-	 *
 | 
			
		||||
-	 * In principle it is recommended to stop/start the clock first,
 | 
			
		||||
-	 * but as we set CLK_SET_RATE_GATE during registration of the
 | 
			
		||||
-	 * clock this requirement should be take care of by the
 | 
			
		||||
-	 * clk-framework.
 | 
			
		||||
+	ctl = cprman_read(cprman, data->ctl_reg);
 | 
			
		||||
+
 | 
			
		||||
+	/* If the clock is running, we have to pause clock generation while
 | 
			
		||||
+	 * updating the control and div regs.  This is glitchless (no clock
 | 
			
		||||
+	 * signals generated faster than the rate) but each reg access is two
 | 
			
		||||
+	 * OSC cycles so the clock will slow down for a moment.
 | 
			
		||||
 	 */
 | 
			
		||||
-	ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
 | 
			
		||||
+	if (ctl & CM_ENABLE) {
 | 
			
		||||
+		cprman_write(cprman, data->ctl_reg, ctl & ~CM_ENABLE);
 | 
			
		||||
+		bcm2835_clock_wait_busy(clock);
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
+	ctl &= ~CM_FRAC;
 | 
			
		||||
 	ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
 | 
			
		||||
 	cprman_write(cprman, data->ctl_reg, ctl);
 | 
			
		||||
 
 | 
			
		||||
@@ -1522,7 +1526,7 @@ static struct clk_hw *bcm2835_register_c
 | 
			
		||||
 		init.ops = &bcm2835_vpu_clock_clk_ops;
 | 
			
		||||
 	} else {
 | 
			
		||||
 		init.ops = &bcm2835_clock_clk_ops;
 | 
			
		||||
-		init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
 | 
			
		||||
+		init.flags |= CLK_SET_PARENT_GATE;
 | 
			
		||||
 
 | 
			
		||||
 		/* If the clock wasn't actually enabled at boot, it's not
 | 
			
		||||
 		 * critical.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,71 @@
 | 
			
		|||
From a9f709127c1a912517bd4e1160360bb4ab3e1498 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Eric Anholt <eric@anholt.net>
 | 
			
		||||
Date: Thu, 2 May 2019 15:24:04 -0700
 | 
			
		||||
Subject: [PATCH] clk: bcm2835: Allow reparenting leaf clocks while they're
 | 
			
		||||
 running.
 | 
			
		||||
 | 
			
		||||
This falls under the same "we can reprogram glitch-free as long as we
 | 
			
		||||
pause generation" rule as updating the div/frac fields.  This can be
 | 
			
		||||
used for runtime reclocking of V3D to manage power leakage.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Eric Anholt <eric@anholt.net>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 19 ++++++++++++++++---
 | 
			
		||||
 1 file changed, 16 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -1127,8 +1127,10 @@ static int bcm2835_clock_on(struct clk_h
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static int bcm2835_clock_set_rate(struct clk_hw *hw,
 | 
			
		||||
-				  unsigned long rate, unsigned long parent_rate)
 | 
			
		||||
+static int bcm2835_clock_set_rate_and_parent(struct clk_hw *hw,
 | 
			
		||||
+					     unsigned long rate,
 | 
			
		||||
+					     unsigned long parent_rate,
 | 
			
		||||
+					     u8 parent)
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
 | 
			
		||||
 	struct bcm2835_cprman *cprman = clock->cprman;
 | 
			
		||||
@@ -1150,6 +1152,11 @@ static int bcm2835_clock_set_rate(struct
 | 
			
		||||
 		bcm2835_clock_wait_busy(clock);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (parent != 0xff) {
 | 
			
		||||
+		ctl &= ~(CM_SRC_MASK << CM_SRC_SHIFT);
 | 
			
		||||
+		ctl |= parent << CM_SRC_SHIFT;
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	ctl &= ~CM_FRAC;
 | 
			
		||||
 	ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
 | 
			
		||||
 	cprman_write(cprman, data->ctl_reg, ctl);
 | 
			
		||||
@@ -1161,6 +1168,12 @@ static int bcm2835_clock_set_rate(struct
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static int bcm2835_clock_set_rate(struct clk_hw *hw,
 | 
			
		||||
+				  unsigned long rate, unsigned long parent_rate)
 | 
			
		||||
+{
 | 
			
		||||
+	return bcm2835_clock_set_rate_and_parent(hw, rate, parent_rate, 0xff);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static bool
 | 
			
		||||
 bcm2835_clk_is_pllc(struct clk_hw *hw)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1344,6 +1357,7 @@ static const struct clk_ops bcm2835_cloc
 | 
			
		||||
 	.unprepare = bcm2835_clock_off,
 | 
			
		||||
 	.recalc_rate = bcm2835_clock_get_rate,
 | 
			
		||||
 	.set_rate = bcm2835_clock_set_rate,
 | 
			
		||||
+	.set_rate_and_parent = bcm2835_clock_set_rate_and_parent,
 | 
			
		||||
 	.determine_rate = bcm2835_clock_determine_rate,
 | 
			
		||||
 	.set_parent = bcm2835_clock_set_parent,
 | 
			
		||||
 	.get_parent = bcm2835_clock_get_parent,
 | 
			
		||||
@@ -1526,7 +1540,6 @@ static struct clk_hw *bcm2835_register_c
 | 
			
		||||
 		init.ops = &bcm2835_vpu_clock_clk_ops;
 | 
			
		||||
 	} else {
 | 
			
		||||
 		init.ops = &bcm2835_clock_clk_ops;
 | 
			
		||||
-		init.flags |= CLK_SET_PARENT_GATE;
 | 
			
		||||
 
 | 
			
		||||
 		/* If the clock wasn't actually enabled at boot, it's not
 | 
			
		||||
 		 * critical.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
From 1c9ad88925bb574d8623477c441d586d0756a91e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
Date: Tue, 6 Aug 2019 15:23:14 +0100
 | 
			
		||||
Subject: [PATCH] clk-bcm2835: Avoid null pointer exception
 | 
			
		||||
 | 
			
		||||
clk_desc_array[BCM2835_PLLB] doesn't exist so we dereference null when iterating
 | 
			
		||||
 | 
			
		||||
Signed-off-by: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 8 +++++---
 | 
			
		||||
 1 file changed, 5 insertions(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -2334,9 +2334,11 @@ static bool bcm2835_clk_is_claimed(const
 | 
			
		||||
 	int i;
 | 
			
		||||
 
 | 
			
		||||
 	for (i = 0; i < ARRAY_SIZE(clk_desc_array); i++) {
 | 
			
		||||
-		const char *clk_name = *(const char **)(clk_desc_array[i].data);
 | 
			
		||||
-		if (!strcmp(name, clk_name))
 | 
			
		||||
-		    return bcm2835_clk_claimed[i];
 | 
			
		||||
+		if (clk_desc_array[i].data) {
 | 
			
		||||
+			const char *clk_name = *(const char **)(clk_desc_array[i].data);
 | 
			
		||||
+			if (!strcmp(name, clk_name))
 | 
			
		||||
+				return bcm2835_clk_claimed[i];
 | 
			
		||||
+		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,58 @@
 | 
			
		|||
From bcca26f6e384cfb43bcdcf36873e85476de9fab1 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
Date: Tue, 3 Sep 2019 20:28:00 +0100
 | 
			
		||||
Subject: [PATCH] clk-bcm2835: Disable v3d clock
 | 
			
		||||
 | 
			
		||||
This is controlled by firmware, see clk-raspberrypi.c
 | 
			
		||||
 | 
			
		||||
Signed-off-by: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 30 ++++++++++++------------------
 | 
			
		||||
 1 file changed, 12 insertions(+), 18 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -1764,16 +1764,12 @@ static const struct bcm2835_clk_desc clk
 | 
			
		||||
 		.hold_mask = CM_PLLA_HOLDCORE,
 | 
			
		||||
 		.fixed_divider = 1,
 | 
			
		||||
 		.flags = CLK_SET_RATE_PARENT),
 | 
			
		||||
-	[BCM2835_PLLA_PER]	= REGISTER_PLL_DIV(
 | 
			
		||||
-		SOC_ALL,
 | 
			
		||||
-		.name = "plla_per",
 | 
			
		||||
-		.source_pll = "plla",
 | 
			
		||||
-		.cm_reg = CM_PLLA,
 | 
			
		||||
-		.a2w_reg = A2W_PLLA_PER,
 | 
			
		||||
-		.load_mask = CM_PLLA_LOADPER,
 | 
			
		||||
-		.hold_mask = CM_PLLA_HOLDPER,
 | 
			
		||||
-		.fixed_divider = 1,
 | 
			
		||||
-		.flags = CLK_SET_RATE_PARENT),
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * PLLA_PER is used for gpu clocks. Controlled by firmware, see
 | 
			
		||||
+	 * clk-raspberrypi.c.
 | 
			
		||||
+	 */
 | 
			
		||||
+
 | 
			
		||||
 	[BCM2835_PLLA_DSI0]	= REGISTER_PLL_DIV(
 | 
			
		||||
 		SOC_ALL,
 | 
			
		||||
 		.name = "plla_dsi0",
 | 
			
		||||
@@ -2074,14 +2070,12 @@ static const struct bcm2835_clk_desc clk
 | 
			
		||||
 		.int_bits = 6,
 | 
			
		||||
 		.frac_bits = 0,
 | 
			
		||||
 		.tcnt_mux = 3),
 | 
			
		||||
-	[BCM2835_CLOCK_V3D]	= REGISTER_VPU_CLK(
 | 
			
		||||
-		SOC_ALL,
 | 
			
		||||
-		.name = "v3d",
 | 
			
		||||
-		.ctl_reg = CM_V3DCTL,
 | 
			
		||||
-		.div_reg = CM_V3DDIV,
 | 
			
		||||
-		.int_bits = 4,
 | 
			
		||||
-		.frac_bits = 8,
 | 
			
		||||
-		.tcnt_mux = 4),
 | 
			
		||||
+
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * CLOCK_V3D is used for v3d clock. Controlled by firmware, see
 | 
			
		||||
+	 * clk-raspberrypi.c.
 | 
			
		||||
+	 */
 | 
			
		||||
+
 | 
			
		||||
 	/*
 | 
			
		||||
 	 * VPU clock.  This doesn't have an enable bit, since it drives
 | 
			
		||||
 	 * the bus for everything else, and is special so it doesn't need
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From 83438d9e501ae9439b951f225d3d81bea7930568 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
Date: Thu, 8 Jul 2021 09:37:10 +0100
 | 
			
		||||
Subject: [PATCH] clk: bcm2835: Pass DT node to rpi_firmware_get
 | 
			
		||||
 | 
			
		||||
The fw_node pointer has already been retrieved, and using it allows
 | 
			
		||||
us to remove a downstream patch to the firmware driver.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -2369,7 +2369,7 @@ static int bcm2835_clk_probe(struct plat
 | 
			
		||||
 
 | 
			
		||||
 	fw_node = of_parse_phandle(dev->of_node, "firmware", 0);
 | 
			
		||||
 	if (fw_node) {
 | 
			
		||||
-		struct rpi_firmware *fw = rpi_firmware_get(NULL);
 | 
			
		||||
+		struct rpi_firmware *fw = rpi_firmware_get(fw_node);
 | 
			
		||||
 		if (!fw)
 | 
			
		||||
 			return -EPROBE_DEFER;
 | 
			
		||||
 		cprman->fw = fw;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,34 @@
 | 
			
		|||
From 88c07badc7a952682f5914abeb0bb789015b67c6 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Tue, 19 Oct 2021 14:14:55 +0100
 | 
			
		||||
Subject: [PATCH] clk-bcm2835: Remove VEC clock support
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/clk/bcm/clk-bcm2835.c | 15 ---------------
 | 
			
		||||
 1 file changed, 15 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
+++ b/drivers/clk/bcm/clk-bcm2835.c
 | 
			
		||||
@@ -2238,21 +2238,6 @@ static const struct bcm2835_clk_desc clk
 | 
			
		||||
 		.tcnt_mux = 28,
 | 
			
		||||
 		.round_up = true),
 | 
			
		||||
 
 | 
			
		||||
-	/* TV encoder clock.  Only operating frequency is 108Mhz.  */
 | 
			
		||||
-	[BCM2835_CLOCK_VEC]	= REGISTER_PER_CLK(
 | 
			
		||||
-		SOC_ALL,
 | 
			
		||||
-		.name = "vec",
 | 
			
		||||
-		.ctl_reg = CM_VECCTL,
 | 
			
		||||
-		.div_reg = CM_VECDIV,
 | 
			
		||||
-		.int_bits = 4,
 | 
			
		||||
-		.frac_bits = 0,
 | 
			
		||||
-		/*
 | 
			
		||||
-		 * Allow rate change propagation only on PLLH_AUX which is
 | 
			
		||||
-		 * assigned index 7 in the parent array.
 | 
			
		||||
-		 */
 | 
			
		||||
-		.set_rate_parent = BIT(7),
 | 
			
		||||
-		.tcnt_mux = 29),
 | 
			
		||||
-
 | 
			
		||||
 	/* dsi clocks */
 | 
			
		||||
 	[BCM2835_CLOCK_DSI0E]	= REGISTER_PER_CLK(
 | 
			
		||||
 		SOC_ALL,
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
From 3f58295a84a9a9eb5c6aa06e7c0c93fe9959afe9 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dan Pasanen <dan.pasanen@gmail.com>
 | 
			
		||||
Date: Thu, 21 Sep 2017 09:55:42 -0500
 | 
			
		||||
Subject: [PATCH] arm: partially revert
 | 
			
		||||
 702b94bff3c50542a6e4ab9a4f4cef093262fe65
 | 
			
		||||
 | 
			
		||||
* Re-expose some dmi APIs for use in VCSM
 | 
			
		||||
---
 | 
			
		||||
 arch/arm/include/asm/cacheflush.h | 21 +++++++++++++++++++++
 | 
			
		||||
 arch/arm/include/asm/glue-cache.h |  2 ++
 | 
			
		||||
 arch/arm/mm/proc-macros.S         |  2 ++
 | 
			
		||||
 arch/arm/mm/proc-syms.c           |  3 +++
 | 
			
		||||
 4 files changed, 28 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/arch/arm/include/asm/cacheflush.h
 | 
			
		||||
+++ b/arch/arm/include/asm/cacheflush.h
 | 
			
		||||
@@ -91,6 +91,21 @@
 | 
			
		||||
  *	DMA Cache Coherency
 | 
			
		||||
  *	===================
 | 
			
		||||
  *
 | 
			
		||||
+ *	dma_inv_range(start, end)
 | 
			
		||||
+ *
 | 
			
		||||
+ *		Invalidate (discard) the specified virtual address range.
 | 
			
		||||
+ *		May not write back any entries.  If 'start' or 'end'
 | 
			
		||||
+ *		are not cache line aligned, those lines must be written
 | 
			
		||||
+ *		back.
 | 
			
		||||
+ *		- start  - virtual start address
 | 
			
		||||
+ *		- end    - virtual end address
 | 
			
		||||
+ *
 | 
			
		||||
+ *	dma_clean_range(start, end)
 | 
			
		||||
+ *
 | 
			
		||||
+ *		Clean (write back) the specified virtual address range.
 | 
			
		||||
+ *		- start  - virtual start address
 | 
			
		||||
+ *		- end    - virtual end address
 | 
			
		||||
+ *
 | 
			
		||||
  *	dma_flush_range(start, end)
 | 
			
		||||
  *
 | 
			
		||||
  *		Clean and invalidate the specified virtual address range.
 | 
			
		||||
@@ -112,6 +127,8 @@ struct cpu_cache_fns {
 | 
			
		||||
 	void (*dma_map_area)(const void *, size_t, int);
 | 
			
		||||
 	void (*dma_unmap_area)(const void *, size_t, int);
 | 
			
		||||
 
 | 
			
		||||
+	void (*dma_inv_range)(const void *, const void *);
 | 
			
		||||
+	void (*dma_clean_range)(const void *, const void *);
 | 
			
		||||
 	void (*dma_flush_range)(const void *, const void *);
 | 
			
		||||
 } __no_randomize_layout;
 | 
			
		||||
 
 | 
			
		||||
@@ -137,6 +154,8 @@ extern struct cpu_cache_fns cpu_cache;
 | 
			
		||||
  * is visible to DMA, or data written by DMA to system memory is
 | 
			
		||||
  * visible to the CPU.
 | 
			
		||||
  */
 | 
			
		||||
+#define dmac_inv_range			cpu_cache.dma_inv_range
 | 
			
		||||
+#define dmac_clean_range		cpu_cache.dma_clean_range
 | 
			
		||||
 #define dmac_flush_range		cpu_cache.dma_flush_range
 | 
			
		||||
 
 | 
			
		||||
 #else
 | 
			
		||||
@@ -156,6 +175,8 @@ extern void __cpuc_flush_dcache_area(voi
 | 
			
		||||
  * is visible to DMA, or data written by DMA to system memory is
 | 
			
		||||
  * visible to the CPU.
 | 
			
		||||
  */
 | 
			
		||||
+extern void dmac_inv_range(const void *, const void *);
 | 
			
		||||
+extern void dmac_clean_range(const void *, const void *);
 | 
			
		||||
 extern void dmac_flush_range(const void *, const void *);
 | 
			
		||||
 
 | 
			
		||||
 #endif
 | 
			
		||||
--- a/arch/arm/include/asm/glue-cache.h
 | 
			
		||||
+++ b/arch/arm/include/asm/glue-cache.h
 | 
			
		||||
@@ -155,6 +155,8 @@ static inline void nop_dma_unmap_area(co
 | 
			
		||||
 #define __cpuc_coherent_user_range	__glue(_CACHE,_coherent_user_range)
 | 
			
		||||
 #define __cpuc_flush_dcache_area	__glue(_CACHE,_flush_kern_dcache_area)
 | 
			
		||||
 
 | 
			
		||||
+#define dmac_inv_range			__glue(_CACHE,_dma_inv_range)
 | 
			
		||||
+#define dmac_clean_range		__glue(_CACHE,_dma_clean_range)
 | 
			
		||||
 #define dmac_flush_range		__glue(_CACHE,_dma_flush_range)
 | 
			
		||||
 #endif
 | 
			
		||||
 
 | 
			
		||||
--- a/arch/arm/mm/proc-macros.S
 | 
			
		||||
+++ b/arch/arm/mm/proc-macros.S
 | 
			
		||||
@@ -333,6 +333,8 @@ ENTRY(\name\()_cache_fns)
 | 
			
		||||
 	.long	\name\()_flush_kern_dcache_area
 | 
			
		||||
 	.long	\name\()_dma_map_area
 | 
			
		||||
 	.long	\name\()_dma_unmap_area
 | 
			
		||||
+	.long	\name\()_dma_inv_range
 | 
			
		||||
+	.long	\name\()_dma_clean_range
 | 
			
		||||
 	.long	\name\()_dma_flush_range
 | 
			
		||||
 	.size	\name\()_cache_fns, . - \name\()_cache_fns
 | 
			
		||||
 .endm
 | 
			
		||||
--- a/arch/arm/mm/proc-syms.c
 | 
			
		||||
+++ b/arch/arm/mm/proc-syms.c
 | 
			
		||||
@@ -27,6 +27,9 @@ EXPORT_SYMBOL(__cpuc_flush_user_all);
 | 
			
		||||
 EXPORT_SYMBOL(__cpuc_flush_user_range);
 | 
			
		||||
 EXPORT_SYMBOL(__cpuc_coherent_kern_range);
 | 
			
		||||
 EXPORT_SYMBOL(__cpuc_flush_dcache_area);
 | 
			
		||||
+EXPORT_SYMBOL(dmac_inv_range);
 | 
			
		||||
+EXPORT_SYMBOL(dmac_clean_range);
 | 
			
		||||
+EXPORT_SYMBOL(dmac_flush_range);
 | 
			
		||||
 #else
 | 
			
		||||
 EXPORT_SYMBOL(cpu_cache);
 | 
			
		||||
 #endif
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,53 @@
 | 
			
		|||
From 2d2b074c9a029ad9dfc1c62376a478be4d7b1c75 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
Date: Fri, 25 Aug 2017 19:18:13 +0100
 | 
			
		||||
Subject: [PATCH] cache: export clean and invalidate
 | 
			
		||||
 | 
			
		||||
hack: cache: Fix linker error
 | 
			
		||||
---
 | 
			
		||||
 arch/arm/mm/cache-v6.S | 4 ++--
 | 
			
		||||
 arch/arm/mm/cache-v7.S | 6 ++++--
 | 
			
		||||
 2 files changed, 6 insertions(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/arm/mm/cache-v6.S
 | 
			
		||||
+++ b/arch/arm/mm/cache-v6.S
 | 
			
		||||
@@ -198,7 +198,7 @@ ENTRY(v6_flush_kern_dcache_area)
 | 
			
		||||
  *	- start   - virtual start address of region
 | 
			
		||||
  *	- end     - virtual end address of region
 | 
			
		||||
  */
 | 
			
		||||
-v6_dma_inv_range:
 | 
			
		||||
+ENTRY(v6_dma_inv_range)
 | 
			
		||||
 #ifdef CONFIG_DMA_CACHE_RWFO
 | 
			
		||||
 	ldrb	r2, [r0]			@ read for ownership
 | 
			
		||||
 	strb	r2, [r0]			@ write for ownership
 | 
			
		||||
@@ -243,7 +243,7 @@ v6_dma_inv_range:
 | 
			
		||||
  *	- start   - virtual start address of region
 | 
			
		||||
  *	- end     - virtual end address of region
 | 
			
		||||
  */
 | 
			
		||||
-v6_dma_clean_range:
 | 
			
		||||
+ENTRY(v6_dma_clean_range)
 | 
			
		||||
 	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
 | 
			
		||||
 1:
 | 
			
		||||
 #ifdef CONFIG_DMA_CACHE_RWFO
 | 
			
		||||
--- a/arch/arm/mm/cache-v7.S
 | 
			
		||||
+++ b/arch/arm/mm/cache-v7.S
 | 
			
		||||
@@ -359,7 +359,8 @@ ENDPROC(v7_flush_kern_dcache_area)
 | 
			
		||||
  *	- start   - virtual start address of region
 | 
			
		||||
  *	- end     - virtual end address of region
 | 
			
		||||
  */
 | 
			
		||||
-v7_dma_inv_range:
 | 
			
		||||
+ENTRY(b15_dma_inv_range)
 | 
			
		||||
+ENTRY(v7_dma_inv_range)
 | 
			
		||||
 	dcache_line_size r2, r3
 | 
			
		||||
 	sub	r3, r2, #1
 | 
			
		||||
 	tst	r0, r3
 | 
			
		||||
@@ -389,7 +390,8 @@ ENDPROC(v7_dma_inv_range)
 | 
			
		||||
  *	- start   - virtual start address of region
 | 
			
		||||
  *	- end     - virtual end address of region
 | 
			
		||||
  */
 | 
			
		||||
-v7_dma_clean_range:
 | 
			
		||||
+ENTRY(b15_dma_clean_range)
 | 
			
		||||
+ENTRY(v7_dma_clean_range)
 | 
			
		||||
 	dcache_line_size r2, r3
 | 
			
		||||
 	sub	r3, r2, #1
 | 
			
		||||
 	bic	r0, r0, r3
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,32 @@
 | 
			
		|||
From 3f93e06e535477cdb96d8056f8309288744a3a8d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
Date: Mon, 20 Apr 2020 13:41:10 +0100
 | 
			
		||||
Subject: [PATCH] Revert "spi: spidev: Fix CS polarity if GPIO descriptors are
 | 
			
		||||
 used"
 | 
			
		||||
 | 
			
		||||
This reverts commit 83b2a8fe43bda0c11981ad6afa5dd0104d78be28.
 | 
			
		||||
---
 | 
			
		||||
 drivers/spi/spidev.c | 5 -----
 | 
			
		||||
 1 file changed, 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/spi/spidev.c
 | 
			
		||||
+++ b/drivers/spi/spidev.c
 | 
			
		||||
@@ -414,7 +414,6 @@ spidev_ioctl(struct file *filp, unsigned
 | 
			
		||||
 		else
 | 
			
		||||
 			retval = get_user(tmp, (u32 __user *)arg);
 | 
			
		||||
 		if (retval == 0) {
 | 
			
		||||
-			struct spi_controller *ctlr = spi->controller;
 | 
			
		||||
 			u32	save = spi->mode;
 | 
			
		||||
 
 | 
			
		||||
 			if (tmp & ~SPI_MODE_MASK) {
 | 
			
		||||
@@ -422,10 +421,6 @@ spidev_ioctl(struct file *filp, unsigned
 | 
			
		||||
 				break;
 | 
			
		||||
 			}
 | 
			
		||||
 
 | 
			
		||||
-			if (ctlr->use_gpio_descriptors && ctlr->cs_gpiods &&
 | 
			
		||||
-			    ctlr->cs_gpiods[spi->chip_select])
 | 
			
		||||
-				tmp |= SPI_CS_HIGH;
 | 
			
		||||
-
 | 
			
		||||
 			tmp |= spi->mode & ~SPI_MODE_MASK;
 | 
			
		||||
 			spi->mode = tmp & SPI_MODE_USER_MASK;
 | 
			
		||||
 			retval = spi_setup(spi);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
From 6e0505463b9e5c402d9b7fb340c599537f9d1bb8 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
Date: Mon, 1 Mar 2021 09:12:44 +0000
 | 
			
		||||
Subject: [PATCH] Revert "Bluetooth: Always request for user confirmation for
 | 
			
		||||
 Just Works (LE SC)"
 | 
			
		||||
 | 
			
		||||
This reverts commit ffee202a78c2980688bc5d2f7d56480e69a5e0c9.
 | 
			
		||||
 | 
			
		||||
The commit "Bluetooth: Always request for user confirmation for Just
 | 
			
		||||
Works" prevents BLE devices pairing in (at least) the Raspberry Pi OS
 | 
			
		||||
GUI. After reverting it, pairing works again. Although this companion
 | 
			
		||||
commit ("... (LE SC)") has not been demonstrated to be problematic,
 | 
			
		||||
it follows the same logic and therefore could affect some use cases.
 | 
			
		||||
 | 
			
		||||
If another solution to the problem is found then this reversion will
 | 
			
		||||
be removed.
 | 
			
		||||
 | 
			
		||||
See: https://github.com/raspberrypi/linux/issues/4139
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 net/bluetooth/smp.c | 5 +----
 | 
			
		||||
 1 file changed, 1 insertion(+), 4 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/net/bluetooth/smp.c
 | 
			
		||||
+++ b/net/bluetooth/smp.c
 | 
			
		||||
@@ -2207,7 +2207,7 @@ mackey_and_ltk:
 | 
			
		||||
 	if (err)
 | 
			
		||||
 		return SMP_UNSPECIFIED;
 | 
			
		||||
 
 | 
			
		||||
-	if (smp->method == REQ_OOB) {
 | 
			
		||||
+	if (smp->method == JUST_WORKS || smp->method == REQ_OOB) {
 | 
			
		||||
 		if (hcon->out) {
 | 
			
		||||
 			sc_dhkey_check(smp);
 | 
			
		||||
 			SMP_ALLOW_CMD(smp, SMP_CMD_DHKEY_CHECK);
 | 
			
		||||
@@ -2222,9 +2222,6 @@ mackey_and_ltk:
 | 
			
		||||
 	confirm_hint = 0;
 | 
			
		||||
 
 | 
			
		||||
 confirm:
 | 
			
		||||
-	if (smp->method == JUST_WORKS)
 | 
			
		||||
-		confirm_hint = 1;
 | 
			
		||||
-
 | 
			
		||||
 	err = mgmt_user_confirm_request(hcon->hdev, &hcon->dst, hcon->type,
 | 
			
		||||
 					hcon->dst_type, passkey, confirm_hint);
 | 
			
		||||
 	if (err)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
From a7def069d38b0f6b4304d6019c99e364ee1ad297 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
Date: Mon, 1 Mar 2021 09:14:35 +0000
 | 
			
		||||
Subject: [PATCH] Revert "Bluetooth: Always request for user confirmation for
 | 
			
		||||
 Just Works"
 | 
			
		||||
 | 
			
		||||
This reverts commit 92516cd97fd4d8ad5b1421a0d51771044f453a5f.
 | 
			
		||||
 | 
			
		||||
Thi commit "Bluetooth: Always request for user confirmation for Just
 | 
			
		||||
Works" prevents BLE devices pairing in (at least) the Raspberry Pi OS
 | 
			
		||||
GUI. After reverting it, pairing works again.
 | 
			
		||||
 | 
			
		||||
If another solution to the problem is found then this reversion will
 | 
			
		||||
be removed.
 | 
			
		||||
 | 
			
		||||
See: https://github.com/raspberrypi/linux/issues/4139
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 net/bluetooth/smp.c | 11 ++---------
 | 
			
		||||
 1 file changed, 2 insertions(+), 9 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/net/bluetooth/smp.c
 | 
			
		||||
+++ b/net/bluetooth/smp.c
 | 
			
		||||
@@ -883,16 +883,9 @@ static int tk_request(struct l2cap_conn
 | 
			
		||||
 	    hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT)
 | 
			
		||||
 		smp->method = JUST_WORKS;
 | 
			
		||||
 
 | 
			
		||||
-	/* If Just Works, Continue with Zero TK and ask user-space for
 | 
			
		||||
-	 * confirmation */
 | 
			
		||||
+	/* If Just Works, Continue with Zero TK */
 | 
			
		||||
 	if (smp->method == JUST_WORKS) {
 | 
			
		||||
-		ret = mgmt_user_confirm_request(hcon->hdev, &hcon->dst,
 | 
			
		||||
-						hcon->type,
 | 
			
		||||
-						hcon->dst_type,
 | 
			
		||||
-						passkey, 1);
 | 
			
		||||
-		if (ret)
 | 
			
		||||
-			return ret;
 | 
			
		||||
-		set_bit(SMP_FLAG_WAIT_USER, &smp->flags);
 | 
			
		||||
+		set_bit(SMP_FLAG_TK_VALID, &smp->flags);
 | 
			
		||||
 		return 0;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
From c0ef0339d77fc9f5919ac06b9b961289f5c865cc Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
Date: Mon, 7 Mar 2022 16:18:55 +0000
 | 
			
		||||
Subject: [PATCH] Revert "net: bcmgenet: Request APD, DLL disable and IDDQ-SR"
 | 
			
		||||
 | 
			
		||||
This reverts commit c3a4c69360ab43560f212eed326c9d8bde35b14c, which
 | 
			
		||||
broke rebooting when network booting.
 | 
			
		||||
 | 
			
		||||
See: https://github.com/raspberrypi/rpi-eeprom/issues/417
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/ethernet/broadcom/genet/bcmmii.c | 4 +---
 | 
			
		||||
 1 file changed, 1 insertion(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/ethernet/broadcom/genet/bcmmii.c
 | 
			
		||||
+++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c
 | 
			
		||||
@@ -290,9 +290,7 @@ int bcmgenet_mii_probe(struct net_device
 | 
			
		||||
 	struct device_node *dn = kdev->of_node;
 | 
			
		||||
 	phy_interface_t phy_iface = priv->phy_interface;
 | 
			
		||||
 	struct phy_device *phydev;
 | 
			
		||||
-	u32 phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE |
 | 
			
		||||
-			PHY_BRCM_DIS_TXCRXC_NOENRGY |
 | 
			
		||||
-			PHY_BRCM_IDDQ_SUSPEND;
 | 
			
		||||
+	u32 phy_flags = 0;
 | 
			
		||||
 	int ret;
 | 
			
		||||
 
 | 
			
		||||
 	/* Communicate the integrated PHY revision */
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,47 @@
 | 
			
		|||
From 5811c0719511310ea778259dc83dffd1ee0e3e1c Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Steve Glendinning <steve.glendinning@smsc.com>
 | 
			
		||||
Date: Thu, 19 Feb 2015 18:47:12 +0000
 | 
			
		||||
Subject: [PATCH] smsx95xx: fix crimes against truesize
 | 
			
		||||
 | 
			
		||||
smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings.
 | 
			
		||||
 | 
			
		||||
This patch stops smsc95xx from changing truesize.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/usb/smsc95xx.c | 10 ++++++++--
 | 
			
		||||
 1 file changed, 8 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/usb/smsc95xx.c
 | 
			
		||||
+++ b/drivers/net/usb/smsc95xx.c
 | 
			
		||||
@@ -79,6 +79,10 @@ static bool turbo_mode = true;
 | 
			
		||||
 module_param(turbo_mode, bool, 0644);
 | 
			
		||||
 MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
 | 
			
		||||
 
 | 
			
		||||
+static bool truesize_mode = false;
 | 
			
		||||
+module_param(truesize_mode, bool, 0644);
 | 
			
		||||
+MODULE_PARM_DESC(truesize_mode, "Report larger truesize value");
 | 
			
		||||
+
 | 
			
		||||
 static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
 | 
			
		||||
 					  u32 *data)
 | 
			
		||||
 {
 | 
			
		||||
@@ -1870,7 +1874,8 @@ static int smsc95xx_rx_fixup(struct usbn
 | 
			
		||||
 				if (dev->net->features & NETIF_F_RXCSUM)
 | 
			
		||||
 					smsc95xx_rx_csum_offload(skb);
 | 
			
		||||
 				skb_trim(skb, skb->len - 4); /* remove fcs */
 | 
			
		||||
-				skb->truesize = size + sizeof(struct sk_buff);
 | 
			
		||||
+				if (truesize_mode)
 | 
			
		||||
+					skb->truesize = size + sizeof(struct sk_buff);
 | 
			
		||||
 
 | 
			
		||||
 				return 1;
 | 
			
		||||
 			}
 | 
			
		||||
@@ -1888,7 +1893,8 @@ static int smsc95xx_rx_fixup(struct usbn
 | 
			
		||||
 			if (dev->net->features & NETIF_F_RXCSUM)
 | 
			
		||||
 				smsc95xx_rx_csum_offload(ax_skb);
 | 
			
		||||
 			skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
 | 
			
		||||
-			ax_skb->truesize = size + sizeof(struct sk_buff);
 | 
			
		||||
+			if (truesize_mode)
 | 
			
		||||
+				ax_skb->truesize = size + sizeof(struct sk_buff);
 | 
			
		||||
 
 | 
			
		||||
 			usbnet_skb_return(dev, ax_skb);
 | 
			
		||||
 		}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,43 @@
 | 
			
		|||
From a9b5e24cb96753cbc74090246239e83ba53569da Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Sam Nazarko <email@samnazarko.co.uk>
 | 
			
		||||
Date: Fri, 1 Apr 2016 17:27:21 +0100
 | 
			
		||||
Subject: [PATCH] smsc95xx: Experimental: Enable turbo_mode and packetsize=2560
 | 
			
		||||
 by default
 | 
			
		||||
 | 
			
		||||
See: http://forum.kodi.tv/showthread.php?tid=285288
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/usb/smsc95xx.c | 14 +++++++++-----
 | 
			
		||||
 1 file changed, 9 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/usb/smsc95xx.c
 | 
			
		||||
+++ b/drivers/net/usb/smsc95xx.c
 | 
			
		||||
@@ -83,6 +83,10 @@ static bool truesize_mode = false;
 | 
			
		||||
 module_param(truesize_mode, bool, 0644);
 | 
			
		||||
 MODULE_PARM_DESC(truesize_mode, "Report larger truesize value");
 | 
			
		||||
 
 | 
			
		||||
+static int packetsize = 2560;
 | 
			
		||||
+module_param(packetsize, int, 0644);
 | 
			
		||||
+MODULE_PARM_DESC(packetsize, "Override the RX URB packet size");
 | 
			
		||||
+
 | 
			
		||||
 static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
 | 
			
		||||
 					  u32 *data)
 | 
			
		||||
 {
 | 
			
		||||
@@ -936,13 +940,13 @@ static int smsc95xx_reset(struct usbnet
 | 
			
		||||
 
 | 
			
		||||
 	if (!turbo_mode) {
 | 
			
		||||
 		burst_cap = 0;
 | 
			
		||||
-		dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
 | 
			
		||||
+		dev->rx_urb_size = packetsize ? packetsize : MAX_SINGLE_PACKET_SIZE;
 | 
			
		||||
 	} else if (dev->udev->speed == USB_SPEED_HIGH) {
 | 
			
		||||
-		burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
 | 
			
		||||
-		dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
 | 
			
		||||
+		dev->rx_urb_size = packetsize ? packetsize : DEFAULT_HS_BURST_CAP_SIZE;
 | 
			
		||||
+		burst_cap = dev->rx_urb_size / HS_USB_PKT_SIZE;
 | 
			
		||||
 	} else {
 | 
			
		||||
-		burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
 | 
			
		||||
-		dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
 | 
			
		||||
+		dev->rx_urb_size = packetsize ? packetsize : DEFAULT_FS_BURST_CAP_SIZE;
 | 
			
		||||
+		burst_cap = dev->rx_urb_size / FS_USB_PKT_SIZE;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
 	netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
From 429531c0dc5f4e495658320b45a5164c6668a533 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
Date: Tue, 26 Mar 2013 17:26:38 +0000
 | 
			
		||||
Subject: [PATCH] Allow mac address to be set in smsc95xx
 | 
			
		||||
 | 
			
		||||
Signed-off-by: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
 | 
			
		||||
SQUASH: smsc95xx: Use dev_mod_addr to set MAC addr
 | 
			
		||||
 | 
			
		||||
Since adeef3e32146 ("net: constify netdev->dev_addr") it has been
 | 
			
		||||
illegal to write to the dev_addr MAC address field. Later commits
 | 
			
		||||
have added explicit checks that it hasn't been modified by nefarious
 | 
			
		||||
means. The dev_addr_mod helper function is the accepted way to change
 | 
			
		||||
the dev_addr field, so use it.
 | 
			
		||||
 | 
			
		||||
Squash with 96c1def63ee1 ("Allow mac address to be set in smsc95xx").
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
 | 
			
		||||
---
 | 
			
		||||
 drivers/net/usb/smsc95xx.c | 54 ++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 54 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/net/usb/smsc95xx.c
 | 
			
		||||
+++ b/drivers/net/usb/smsc95xx.c
 | 
			
		||||
@@ -87,6 +87,10 @@ static int packetsize = 2560;
 | 
			
		||||
 module_param(packetsize, int, 0644);
 | 
			
		||||
 MODULE_PARM_DESC(packetsize, "Override the RX URB packet size");
 | 
			
		||||
 
 | 
			
		||||
+static char *macaddr = ":";
 | 
			
		||||
+module_param(macaddr, charp, 0);
 | 
			
		||||
+MODULE_PARM_DESC(macaddr, "MAC address");
 | 
			
		||||
+
 | 
			
		||||
 static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
 | 
			
		||||
 					  u32 *data)
 | 
			
		||||
 {
 | 
			
		||||
@@ -809,6 +813,52 @@ static int smsc95xx_ioctl(struct net_dev
 | 
			
		||||
 	return phy_mii_ioctl(netdev->phydev, rq, cmd);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+/* Check the macaddr module parameter for a MAC address */
 | 
			
		||||
+static int smsc95xx_is_macaddr_param(struct usbnet *dev, struct net_device *nd)
 | 
			
		||||
+{
 | 
			
		||||
+       int i, j, got_num, num;
 | 
			
		||||
+       u8 mtbl[ETH_ALEN];
 | 
			
		||||
+
 | 
			
		||||
+       if (macaddr[0] == ':')
 | 
			
		||||
+               return 0;
 | 
			
		||||
+
 | 
			
		||||
+       i = 0;
 | 
			
		||||
+       j = 0;
 | 
			
		||||
+       num = 0;
 | 
			
		||||
+       got_num = 0;
 | 
			
		||||
+       while (j < ETH_ALEN) {
 | 
			
		||||
+               if (macaddr[i] && macaddr[i] != ':') {
 | 
			
		||||
+                       got_num++;
 | 
			
		||||
+                       if ('0' <= macaddr[i] && macaddr[i] <= '9')
 | 
			
		||||
+                               num = num * 16 + macaddr[i] - '0';
 | 
			
		||||
+                       else if ('A' <= macaddr[i] && macaddr[i] <= 'F')
 | 
			
		||||
+                               num = num * 16 + 10 + macaddr[i] - 'A';
 | 
			
		||||
+                       else if ('a' <= macaddr[i] && macaddr[i] <= 'f')
 | 
			
		||||
+                               num = num * 16 + 10 + macaddr[i] - 'a';
 | 
			
		||||
+                       else
 | 
			
		||||
+                               break;
 | 
			
		||||
+                       i++;
 | 
			
		||||
+               } else if (got_num == 2) {
 | 
			
		||||
+                       mtbl[j++] = (u8) num;
 | 
			
		||||
+                       num = 0;
 | 
			
		||||
+                       got_num = 0;
 | 
			
		||||
+                       i++;
 | 
			
		||||
+               } else {
 | 
			
		||||
+                       break;
 | 
			
		||||
+               }
 | 
			
		||||
+       }
 | 
			
		||||
+
 | 
			
		||||
+       if (j == ETH_ALEN) {
 | 
			
		||||
+               netif_dbg(dev, ifup, dev->net, "Overriding MAC address with: "
 | 
			
		||||
+               "%02x:%02x:%02x:%02x:%02x:%02x\n", mtbl[0], mtbl[1], mtbl[2],
 | 
			
		||||
+                                               mtbl[3], mtbl[4], mtbl[5]);
 | 
			
		||||
+	       dev_addr_mod(nd, 0, mtbl, ETH_ALEN);
 | 
			
		||||
+               return 1;
 | 
			
		||||
+       } else {
 | 
			
		||||
+               return 0;
 | 
			
		||||
+       }
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void smsc95xx_init_mac_address(struct usbnet *dev)
 | 
			
		||||
 {
 | 
			
		||||
 	u8 addr[ETH_ALEN];
 | 
			
		||||
@@ -832,6 +882,10 @@ static void smsc95xx_init_mac_address(st
 | 
			
		||||
 		}
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* Check module parameters */
 | 
			
		||||
+	if (smsc95xx_is_macaddr_param(dev, dev->net))
 | 
			
		||||
+		return;
 | 
			
		||||
+
 | 
			
		||||
 	/* no useful static MAC address found. generate a random one */
 | 
			
		||||
 	eth_hw_addr_random(dev->net);
 | 
			
		||||
 	netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,85 @@
 | 
			
		|||
From b2670b95c0cbe7b6ba038a7615725d87ad59af4f Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Mon, 27 Nov 2017 17:14:54 +0000
 | 
			
		||||
Subject: [PATCH] cgroup: Disable cgroup "memory" by default
 | 
			
		||||
 | 
			
		||||
Some Raspberry Pis have limited RAM and most users won't use the
 | 
			
		||||
cgroup memory support so it is disabled by default. Enable with:
 | 
			
		||||
 | 
			
		||||
    cgroup_enable=memory
 | 
			
		||||
 | 
			
		||||
See: https://github.com/raspberrypi/linux/issues/1950
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 kernel/cgroup/cgroup.c | 38 ++++++++++++++++++++++++++++++++++++++
 | 
			
		||||
 1 file changed, 38 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/kernel/cgroup/cgroup.c
 | 
			
		||||
+++ b/kernel/cgroup/cgroup.c
 | 
			
		||||
@@ -6061,6 +6061,9 @@ int __init cgroup_init_early(void)
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
+static u16 cgroup_enable_mask __initdata;
 | 
			
		||||
+static int __init cgroup_disable(char *str);
 | 
			
		||||
+
 | 
			
		||||
 /**
 | 
			
		||||
  * cgroup_init - cgroup initialization
 | 
			
		||||
  *
 | 
			
		||||
@@ -6094,6 +6097,12 @@ int __init cgroup_init(void)
 | 
			
		||||
 
 | 
			
		||||
 	cgroup_unlock();
 | 
			
		||||
 
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * Apply an implicit disable, knowing that an explicit enable will
 | 
			
		||||
+	 * prevent if from doing anything.
 | 
			
		||||
+	 */
 | 
			
		||||
+	cgroup_disable("memory");
 | 
			
		||||
+
 | 
			
		||||
 	for_each_subsys(ss, ssid) {
 | 
			
		||||
 		if (ss->early_init) {
 | 
			
		||||
 			struct cgroup_subsys_state *css =
 | 
			
		||||
@@ -6734,6 +6743,10 @@ static int __init cgroup_disable(char *s
 | 
			
		||||
 			    strcmp(token, ss->legacy_name))
 | 
			
		||||
 				continue;
 | 
			
		||||
 
 | 
			
		||||
+			/* An explicit cgroup_enable overrides a disable */
 | 
			
		||||
+			if (cgroup_enable_mask & (1 << i))
 | 
			
		||||
+				continue;
 | 
			
		||||
+
 | 
			
		||||
 			static_branch_disable(cgroup_subsys_enabled_key[i]);
 | 
			
		||||
 			pr_info("Disabling %s control group subsystem\n",
 | 
			
		||||
 				ss->name);
 | 
			
		||||
@@ -6752,6 +6765,31 @@ static int __init cgroup_disable(char *s
 | 
			
		||||
 }
 | 
			
		||||
 __setup("cgroup_disable=", cgroup_disable);
 | 
			
		||||
 
 | 
			
		||||
+static int __init cgroup_enable(char *str)
 | 
			
		||||
+{
 | 
			
		||||
+	struct cgroup_subsys *ss;
 | 
			
		||||
+	char *token;
 | 
			
		||||
+	int i;
 | 
			
		||||
+
 | 
			
		||||
+	while ((token = strsep(&str, ",")) != NULL) {
 | 
			
		||||
+		if (!*token)
 | 
			
		||||
+			continue;
 | 
			
		||||
+
 | 
			
		||||
+		for_each_subsys(ss, i) {
 | 
			
		||||
+			if (strcmp(token, ss->name) &&
 | 
			
		||||
+			    strcmp(token, ss->legacy_name))
 | 
			
		||||
+				continue;
 | 
			
		||||
+
 | 
			
		||||
+			cgroup_enable_mask |= 1 << i;
 | 
			
		||||
+			static_branch_enable(cgroup_subsys_enabled_key[i]);
 | 
			
		||||
+			pr_info("Enabling %s control group subsystem\n",
 | 
			
		||||
+				ss->name);
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+	return 1;
 | 
			
		||||
+}
 | 
			
		||||
+__setup("cgroup_enable=", cgroup_enable);
 | 
			
		||||
+
 | 
			
		||||
 void __init __weak enable_debug_cgroup(void) { }
 | 
			
		||||
 
 | 
			
		||||
 static int __init enable_cgroup_debug(char *str)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
From 600eecf6486e7bd0f752863800296f99fe6ab05a Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Fri, 13 Mar 2015 12:43:36 +0000
 | 
			
		||||
Subject: [PATCH] Protect __release_resource against resources without parents
 | 
			
		||||
 | 
			
		||||
Without this patch, removing a device tree overlay can crash here.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 kernel/resource.c | 6 ++++++
 | 
			
		||||
 1 file changed, 6 insertions(+)
 | 
			
		||||
 | 
			
		||||
--- a/kernel/resource.c
 | 
			
		||||
+++ b/kernel/resource.c
 | 
			
		||||
@@ -200,6 +200,12 @@ static int __release_resource(struct res
 | 
			
		||||
 {
 | 
			
		||||
 	struct resource *tmp, **p, *chd;
 | 
			
		||||
 
 | 
			
		||||
+	if (!old->parent) {
 | 
			
		||||
+		WARN(old->sibling, "sibling but no parent");
 | 
			
		||||
+		if (old->sibling)
 | 
			
		||||
+			return -EINVAL;
 | 
			
		||||
+		return 0;
 | 
			
		||||
+	}
 | 
			
		||||
 	p = &old->parent->child;
 | 
			
		||||
 	for (;;) {
 | 
			
		||||
 		tmp = *p;
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From b22008959b2e03d2946e0e7e825cdda079baebb4 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Thu, 9 Feb 2017 14:33:30 +0000
 | 
			
		||||
Subject: [PATCH] irq-bcm2836: Avoid "Invalid trigger warning"
 | 
			
		||||
 | 
			
		||||
Initialise the level for each IRQ to avoid a warning from the
 | 
			
		||||
arm arch timer code.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/irqchip/irq-bcm2836.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/irqchip/irq-bcm2836.c
 | 
			
		||||
+++ b/drivers/irqchip/irq-bcm2836.c
 | 
			
		||||
@@ -128,7 +128,7 @@ static int bcm2836_map(struct irq_domain
 | 
			
		||||
 	irq_set_percpu_devid(irq);
 | 
			
		||||
 	irq_domain_set_info(d, irq, hw, chip, d->host_data,
 | 
			
		||||
 			    handle_percpu_devid_irq, NULL, NULL);
 | 
			
		||||
-	irq_set_status_flags(irq, IRQ_NOAUTOEN);
 | 
			
		||||
+	irq_set_status_flags(irq, IRQ_NOAUTOEN | IRQ_TYPE_LEVEL_LOW);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,127 @@
 | 
			
		|||
From 94d16d548bce05e1c330842f3e6ba9370d522b05 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
 | 
			
		||||
Date: Fri, 12 Jun 2015 19:01:05 +0200
 | 
			
		||||
Subject: [PATCH] irqchip: bcm2835: Add FIQ support
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Add a duplicate irq range with an offset on the hwirq's so the
 | 
			
		||||
driver can detect that enable_fiq() is used.
 | 
			
		||||
Tested with downstream dwc_otg USB controller driver.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
 | 
			
		||||
Reviewed-by: Eric Anholt <eric@anholt.net>
 | 
			
		||||
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
 | 
			
		||||
---
 | 
			
		||||
 arch/arm/mach-bcm/Kconfig     |  1 +
 | 
			
		||||
 drivers/irqchip/irq-bcm2835.c | 51 +++++++++++++++++++++++++++++++----
 | 
			
		||||
 2 files changed, 47 insertions(+), 5 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/arm/mach-bcm/Kconfig
 | 
			
		||||
+++ b/arch/arm/mach-bcm/Kconfig
 | 
			
		||||
@@ -159,6 +159,7 @@ config ARCH_BCM2835
 | 
			
		||||
 	select ARM_TIMER_SP804
 | 
			
		||||
 	select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
 | 
			
		||||
 	select BCM2835_TIMER
 | 
			
		||||
+	select FIQ
 | 
			
		||||
 	select PINCTRL
 | 
			
		||||
 	select PINCTRL_BCM2835
 | 
			
		||||
 	select MFD_CORE
 | 
			
		||||
--- a/drivers/irqchip/irq-bcm2835.c
 | 
			
		||||
+++ b/drivers/irqchip/irq-bcm2835.c
 | 
			
		||||
@@ -45,7 +45,7 @@
 | 
			
		||||
 #include <asm/exception.h>
 | 
			
		||||
 
 | 
			
		||||
 /* Put the bank and irq (32 bits) into the hwirq */
 | 
			
		||||
-#define MAKE_HWIRQ(b, n)	((b << 5) | (n))
 | 
			
		||||
+#define MAKE_HWIRQ(b, n)	(((b) << 5) | (n))
 | 
			
		||||
 #define HWIRQ_BANK(i)		(i >> 5)
 | 
			
		||||
 #define HWIRQ_BIT(i)		BIT(i & 0x1f)
 | 
			
		||||
 
 | 
			
		||||
@@ -62,9 +62,13 @@
 | 
			
		||||
 
 | 
			
		||||
 #define REG_FIQ_CONTROL		0x0c
 | 
			
		||||
 #define FIQ_CONTROL_ENABLE	BIT(7)
 | 
			
		||||
+#define REG_FIQ_ENABLE		FIQ_CONTROL_ENABLE
 | 
			
		||||
+#define REG_FIQ_DISABLE	0
 | 
			
		||||
 
 | 
			
		||||
 #define NR_BANKS		3
 | 
			
		||||
 #define IRQS_PER_BANK		32
 | 
			
		||||
+#define NUMBER_IRQS		MAKE_HWIRQ(NR_BANKS, 0)
 | 
			
		||||
+#define FIQ_START		(NR_IRQS_BANK0 + MAKE_HWIRQ(NR_BANKS - 1, 0))
 | 
			
		||||
 
 | 
			
		||||
 static const int reg_pending[] __initconst = { 0x00, 0x04, 0x08 };
 | 
			
		||||
 static const int reg_enable[] __initconst = { 0x18, 0x10, 0x14 };
 | 
			
		||||
@@ -89,14 +93,38 @@ static void __exception_irq_entry bcm283
 | 
			
		||||
 	struct pt_regs *regs);
 | 
			
		||||
 static void bcm2836_chained_handle_irq(struct irq_desc *desc);
 | 
			
		||||
 
 | 
			
		||||
+static inline unsigned int hwirq_to_fiq(unsigned long hwirq)
 | 
			
		||||
+{
 | 
			
		||||
+	hwirq -= NUMBER_IRQS;
 | 
			
		||||
+	/*
 | 
			
		||||
+	 * The hwirq numbering used in this driver is:
 | 
			
		||||
+	 *   BASE (0-7) GPU1 (32-63) GPU2 (64-95).
 | 
			
		||||
+	 * This differ from the one used in the FIQ register:
 | 
			
		||||
+	 *   GPU1 (0-31) GPU2 (32-63) BASE (64-71)
 | 
			
		||||
+	 */
 | 
			
		||||
+	if (hwirq >= 32)
 | 
			
		||||
+		return hwirq - 32;
 | 
			
		||||
+
 | 
			
		||||
+	return hwirq + 64;
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
 static void armctrl_mask_irq(struct irq_data *d)
 | 
			
		||||
 {
 | 
			
		||||
-	writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]);
 | 
			
		||||
+	if (d->hwirq >= NUMBER_IRQS)
 | 
			
		||||
+		writel_relaxed(REG_FIQ_DISABLE, intc.base + REG_FIQ_CONTROL);
 | 
			
		||||
+	else
 | 
			
		||||
+		writel_relaxed(HWIRQ_BIT(d->hwirq),
 | 
			
		||||
+			       intc.disable[HWIRQ_BANK(d->hwirq)]);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static void armctrl_unmask_irq(struct irq_data *d)
 | 
			
		||||
 {
 | 
			
		||||
-	writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]);
 | 
			
		||||
+	if (d->hwirq >= NUMBER_IRQS)
 | 
			
		||||
+		writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
 | 
			
		||||
+			       intc.base + REG_FIQ_CONTROL);
 | 
			
		||||
+	else
 | 
			
		||||
+		writel_relaxed(HWIRQ_BIT(d->hwirq),
 | 
			
		||||
+			       intc.enable[HWIRQ_BANK(d->hwirq)]);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static struct irq_chip armctrl_chip = {
 | 
			
		||||
@@ -142,8 +170,9 @@ static int __init armctrl_of_init(struct
 | 
			
		||||
 	if (!base)
 | 
			
		||||
 		panic("%pOF: unable to map IC registers\n", node);
 | 
			
		||||
 
 | 
			
		||||
-	intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0),
 | 
			
		||||
-			&armctrl_ops, NULL);
 | 
			
		||||
+	intc.base = base;
 | 
			
		||||
+	intc.domain = irq_domain_add_linear(node, NUMBER_IRQS * 2,
 | 
			
		||||
+					    &armctrl_ops, NULL);
 | 
			
		||||
 	if (!intc.domain)
 | 
			
		||||
 		panic("%pOF: unable to create IRQ domain\n", node);
 | 
			
		||||
 
 | 
			
		||||
@@ -186,6 +215,18 @@ static int __init armctrl_of_init(struct
 | 
			
		||||
 		set_handle_irq(bcm2835_handle_irq);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* Make a duplicate irq range which is used to enable FIQ */
 | 
			
		||||
+	for (b = 0; b < NR_BANKS; b++) {
 | 
			
		||||
+		for (i = 0; i < bank_irqs[b]; i++) {
 | 
			
		||||
+			irq = irq_create_mapping(intc.domain,
 | 
			
		||||
+					MAKE_HWIRQ(b, i) + NUMBER_IRQS);
 | 
			
		||||
+			BUG_ON(irq <= 0);
 | 
			
		||||
+			irq_set_chip(irq, &armctrl_chip);
 | 
			
		||||
+			set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+	init_FIQ(FIQ_START);
 | 
			
		||||
+
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,99 @@
 | 
			
		|||
From b4e8413bf340d2b79e72fc002872a92a93433c75 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
 | 
			
		||||
Date: Fri, 23 Oct 2015 16:26:55 +0200
 | 
			
		||||
Subject: [PATCH] irqchip: irq-bcm2835: Add 2836 FIQ support
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/irqchip/irq-bcm2835.c | 43 +++++++++++++++++++++++++++++++++--
 | 
			
		||||
 1 file changed, 41 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/irqchip/irq-bcm2835.c
 | 
			
		||||
+++ b/drivers/irqchip/irq-bcm2835.c
 | 
			
		||||
@@ -41,8 +41,11 @@
 | 
			
		||||
 #include <linux/of_irq.h>
 | 
			
		||||
 #include <linux/irqchip.h>
 | 
			
		||||
 #include <linux/irqdomain.h>
 | 
			
		||||
+#include <linux/mfd/syscon.h>
 | 
			
		||||
+#include <linux/regmap.h>
 | 
			
		||||
 
 | 
			
		||||
 #include <asm/exception.h>
 | 
			
		||||
+#include <asm/mach/irq.h>
 | 
			
		||||
 
 | 
			
		||||
 /* Put the bank and irq (32 bits) into the hwirq */
 | 
			
		||||
 #define MAKE_HWIRQ(b, n)	(((b) << 5) | (n))
 | 
			
		||||
@@ -60,6 +63,9 @@
 | 
			
		||||
 #define BANK0_VALID_MASK	(BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \
 | 
			
		||||
 					| SHORTCUT1_MASK | SHORTCUT2_MASK)
 | 
			
		||||
 
 | 
			
		||||
+#undef ARM_LOCAL_GPU_INT_ROUTING
 | 
			
		||||
+#define ARM_LOCAL_GPU_INT_ROUTING 0x0c
 | 
			
		||||
+
 | 
			
		||||
 #define REG_FIQ_CONTROL		0x0c
 | 
			
		||||
 #define FIQ_CONTROL_ENABLE	BIT(7)
 | 
			
		||||
 #define REG_FIQ_ENABLE		FIQ_CONTROL_ENABLE
 | 
			
		||||
@@ -86,6 +92,7 @@ struct armctrl_ic {
 | 
			
		||||
 	void __iomem *enable[NR_BANKS];
 | 
			
		||||
 	void __iomem *disable[NR_BANKS];
 | 
			
		||||
 	struct irq_domain *domain;
 | 
			
		||||
+	struct regmap *local_regmap;
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
 static struct armctrl_ic intc __read_mostly;
 | 
			
		||||
@@ -119,12 +126,35 @@ static void armctrl_mask_irq(struct irq_
 | 
			
		||||
 
 | 
			
		||||
 static void armctrl_unmask_irq(struct irq_data *d)
 | 
			
		||||
 {
 | 
			
		||||
-	if (d->hwirq >= NUMBER_IRQS)
 | 
			
		||||
+	if (d->hwirq >= NUMBER_IRQS) {
 | 
			
		||||
+		if (num_online_cpus() > 1) {
 | 
			
		||||
+			unsigned int data;
 | 
			
		||||
+			int ret;
 | 
			
		||||
+
 | 
			
		||||
+			if (!intc.local_regmap) {
 | 
			
		||||
+				pr_err("FIQ is disabled due to missing regmap\n");
 | 
			
		||||
+				return;
 | 
			
		||||
+			}
 | 
			
		||||
+
 | 
			
		||||
+			ret = regmap_read(intc.local_regmap,
 | 
			
		||||
+					  ARM_LOCAL_GPU_INT_ROUTING, &data);
 | 
			
		||||
+			if (ret) {
 | 
			
		||||
+				pr_err("Failed to read int routing %d\n", ret);
 | 
			
		||||
+				return;
 | 
			
		||||
+			}
 | 
			
		||||
+
 | 
			
		||||
+			data &= ~0xc;
 | 
			
		||||
+			data |= (1 << 2);
 | 
			
		||||
+			regmap_write(intc.local_regmap,
 | 
			
		||||
+				     ARM_LOCAL_GPU_INT_ROUTING, data);
 | 
			
		||||
+		}
 | 
			
		||||
+
 | 
			
		||||
 		writel_relaxed(REG_FIQ_ENABLE | hwirq_to_fiq(d->hwirq),
 | 
			
		||||
 			       intc.base + REG_FIQ_CONTROL);
 | 
			
		||||
-	else
 | 
			
		||||
+	} else {
 | 
			
		||||
 		writel_relaxed(HWIRQ_BIT(d->hwirq),
 | 
			
		||||
 			       intc.enable[HWIRQ_BANK(d->hwirq)]);
 | 
			
		||||
+	}
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static struct irq_chip armctrl_chip = {
 | 
			
		||||
@@ -215,6 +245,15 @@ static int __init armctrl_of_init(struct
 | 
			
		||||
 		set_handle_irq(bcm2835_handle_irq);
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	if (is_2836) {
 | 
			
		||||
+		intc.local_regmap =
 | 
			
		||||
+			syscon_regmap_lookup_by_compatible("brcm,bcm2836-arm-local");
 | 
			
		||||
+		if (IS_ERR(intc.local_regmap)) {
 | 
			
		||||
+			pr_err("Failed to get local register map. FIQ is disabled for cpus > 1\n");
 | 
			
		||||
+			intc.local_regmap = NULL;
 | 
			
		||||
+		}
 | 
			
		||||
+	}
 | 
			
		||||
+
 | 
			
		||||
 	/* Make a duplicate irq range which is used to enable FIQ */
 | 
			
		||||
 	for (b = 0; b < NR_BANKS; b++) {
 | 
			
		||||
 		for (i = 0; i < bank_irqs[b]; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
From 3e8d60e56b3274521715183e76ce6d9c326537b2 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Dom Cobley <popcornmix@gmail.com>
 | 
			
		||||
Date: Mon, 24 Jan 2022 13:41:16 +0000
 | 
			
		||||
Subject: [PATCH] spi: spidev: Completely disable the spidev warning
 | 
			
		||||
 | 
			
		||||
An alternative strategy would be to use "rpi,spidev" instead, but that
 | 
			
		||||
would require many Raspberry Pi Device Tree changes.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/spi/spidev.c | 2 +-
 | 
			
		||||
 1 file changed, 1 insertion(+), 1 deletion(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/spi/spidev.c
 | 
			
		||||
+++ b/drivers/spi/spidev.c
 | 
			
		||||
@@ -707,7 +707,7 @@ MODULE_DEVICE_TABLE(spi, spidev_spi_ids)
 | 
			
		||||
  */
 | 
			
		||||
 static int spidev_of_check(struct device *dev)
 | 
			
		||||
 {
 | 
			
		||||
-	if (device_property_match_string(dev, "compatible", "spidev") < 0)
 | 
			
		||||
+	if (1 || device_property_match_string(dev, "compatible", "spidev") < 0)
 | 
			
		||||
 		return 0;
 | 
			
		||||
 
 | 
			
		||||
 	dev_err(dev, "spidev listed directly in DT is not supported\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,100 @@
 | 
			
		|||
From 3b7845accab532c7324e2ecd9dab278ade4af19d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
 | 
			
		||||
Date: Sat, 3 Oct 2015 22:22:55 +0200
 | 
			
		||||
Subject: [PATCH] dmaengine: bcm2835: Load driver early and support legacy API
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
Load driver early since at least bcm2708_fb doesn't support deferred
 | 
			
		||||
probing and even if it did, we don't want the video driver deferred.
 | 
			
		||||
Support the legacy DMA API which is needed by bcm2708_fb.
 | 
			
		||||
Don't mask out channel 2.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/dma/Kconfig       |  2 +-
 | 
			
		||||
 drivers/dma/bcm2835-dma.c | 26 +++++++++++++++++++++++++-
 | 
			
		||||
 2 files changed, 26 insertions(+), 2 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/dma/Kconfig
 | 
			
		||||
+++ b/drivers/dma/Kconfig
 | 
			
		||||
@@ -135,7 +135,7 @@ config BCM_SBA_RAID
 | 
			
		||||
 
 | 
			
		||||
 config DMA_BCM2835
 | 
			
		||||
 	tristate "BCM2835 DMA engine support"
 | 
			
		||||
-	depends on ARCH_BCM2835
 | 
			
		||||
+	depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709
 | 
			
		||||
 	select DMA_ENGINE
 | 
			
		||||
 	select DMA_VIRTUAL_CHANNELS
 | 
			
		||||
 
 | 
			
		||||
--- a/drivers/dma/bcm2835-dma.c
 | 
			
		||||
+++ b/drivers/dma/bcm2835-dma.c
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
 #include <linux/interrupt.h>
 | 
			
		||||
 #include <linux/list.h>
 | 
			
		||||
 #include <linux/module.h>
 | 
			
		||||
+#include <linux/platform_data/dma-bcm2708.h>
 | 
			
		||||
 #include <linux/platform_device.h>
 | 
			
		||||
 #include <linux/slab.h>
 | 
			
		||||
 #include <linux/io.h>
 | 
			
		||||
@@ -36,6 +37,7 @@
 | 
			
		||||
 
 | 
			
		||||
 #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14
 | 
			
		||||
 #define BCM2835_DMA_CHAN_NAME_SIZE 8
 | 
			
		||||
+#define BCM2835_DMA_BULK_MASK  BIT(0)
 | 
			
		||||
 
 | 
			
		||||
 /**
 | 
			
		||||
  * struct bcm2835_dmadev - BCM2835 DMA controller
 | 
			
		||||
@@ -906,6 +908,9 @@ static int bcm2835_dma_probe(struct plat
 | 
			
		||||
 	base = devm_ioremap_resource(&pdev->dev, res);
 | 
			
		||||
 	if (IS_ERR(base))
 | 
			
		||||
 		return PTR_ERR(base);
 | 
			
		||||
+	rc = bcm_dmaman_probe(pdev, base, BCM2835_DMA_BULK_MASK);
 | 
			
		||||
+	if (rc)
 | 
			
		||||
+		dev_err(&pdev->dev, "Failed to initialize the legacy API\n");
 | 
			
		||||
 
 | 
			
		||||
 	od->base = base;
 | 
			
		||||
 
 | 
			
		||||
@@ -951,6 +956,9 @@ static int bcm2835_dma_probe(struct plat
 | 
			
		||||
 		goto err_no_dma;
 | 
			
		||||
 	}
 | 
			
		||||
 
 | 
			
		||||
+	/* Channel 0 is used by the legacy API */
 | 
			
		||||
+	chans_available &= ~BCM2835_DMA_BULK_MASK;
 | 
			
		||||
+
 | 
			
		||||
 	/* get irqs for each channel that we support */
 | 
			
		||||
 	for (i = 0; i <= BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED; i++) {
 | 
			
		||||
 		/* skip masked out channels */
 | 
			
		||||
@@ -1025,6 +1033,7 @@ static int bcm2835_dma_remove(struct pla
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcm2835_dmadev *od = platform_get_drvdata(pdev);
 | 
			
		||||
 
 | 
			
		||||
+	bcm_dmaman_remove(pdev);
 | 
			
		||||
 	dma_async_device_unregister(&od->ddev);
 | 
			
		||||
 	bcm2835_dma_free(od);
 | 
			
		||||
 
 | 
			
		||||
@@ -1040,7 +1049,22 @@ static struct platform_driver bcm2835_dm
 | 
			
		||||
 	},
 | 
			
		||||
 };
 | 
			
		||||
 
 | 
			
		||||
-module_platform_driver(bcm2835_dma_driver);
 | 
			
		||||
+static int bcm2835_dma_init(void)
 | 
			
		||||
+{
 | 
			
		||||
+	return platform_driver_register(&bcm2835_dma_driver);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+static void bcm2835_dma_exit(void)
 | 
			
		||||
+{
 | 
			
		||||
+	platform_driver_unregister(&bcm2835_dma_driver);
 | 
			
		||||
+}
 | 
			
		||||
+
 | 
			
		||||
+/*
 | 
			
		||||
+ * Load after serial driver (arch_initcall) so we see the messages if it fails,
 | 
			
		||||
+ * but before drivers (module_init) that need a DMA channel.
 | 
			
		||||
+ */
 | 
			
		||||
+subsys_initcall(bcm2835_dma_init);
 | 
			
		||||
+module_exit(bcm2835_dma_exit);
 | 
			
		||||
 
 | 
			
		||||
 MODULE_ALIAS("platform:bcm2835-dma");
 | 
			
		||||
 MODULE_DESCRIPTION("BCM2835 DMA engine driver");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,20 @@
 | 
			
		|||
From dfdd1db51e019b0960ce337e10ef854ac317282d Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: Phil Elwell <phil@raspberrypi.org>
 | 
			
		||||
Date: Wed, 15 Jun 2016 16:48:41 +0100
 | 
			
		||||
Subject: [PATCH] rtc: Add SPI alias for pcf2123 driver
 | 
			
		||||
 | 
			
		||||
Without this alias, Device Tree won't cause the driver
 | 
			
		||||
to be loaded.
 | 
			
		||||
 | 
			
		||||
See: https://github.com/raspberrypi/linux/pull/1510
 | 
			
		||||
---
 | 
			
		||||
 drivers/rtc/rtc-pcf2123.c | 1 +
 | 
			
		||||
 1 file changed, 1 insertion(+)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/rtc/rtc-pcf2123.c
 | 
			
		||||
+++ b/drivers/rtc/rtc-pcf2123.c
 | 
			
		||||
@@ -474,3 +474,4 @@ module_spi_driver(pcf2123_driver);
 | 
			
		||||
 MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
 | 
			
		||||
 MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
 | 
			
		||||
 MODULE_LICENSE("GPL");
 | 
			
		||||
+MODULE_ALIAS("spi:rtc-pcf2123");
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,102 @@
 | 
			
		|||
From 16e876906575f53df3ac9bf8d0cea3a456d1a150 Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
 | 
			
		||||
Date: Fri, 7 Oct 2016 16:50:59 +0200
 | 
			
		||||
Subject: [PATCH] watchdog: bcm2835: Support setting reboot partition
 | 
			
		||||
MIME-Version: 1.0
 | 
			
		||||
Content-Type: text/plain; charset=UTF-8
 | 
			
		||||
Content-Transfer-Encoding: 8bit
 | 
			
		||||
 | 
			
		||||
The Raspberry Pi firmware looks at the RSTS register to know which
 | 
			
		||||
partition to boot from. The reboot syscall command
 | 
			
		||||
LINUX_REBOOT_CMD_RESTART2 supports passing in a string argument.
 | 
			
		||||
 | 
			
		||||
Add support for passing in a partition number 0..63 to boot from.
 | 
			
		||||
Partition 63 is a special partiton indicating halt.
 | 
			
		||||
If the partition doesn't exist, the firmware falls back to partition 0.
 | 
			
		||||
 | 
			
		||||
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
 | 
			
		||||
---
 | 
			
		||||
 drivers/watchdog/bcm2835_wdt.c | 49 +++++++++++++++++++---------------
 | 
			
		||||
 1 file changed, 27 insertions(+), 22 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/drivers/watchdog/bcm2835_wdt.c
 | 
			
		||||
+++ b/drivers/watchdog/bcm2835_wdt.c
 | 
			
		||||
@@ -32,13 +32,7 @@
 | 
			
		||||
 #define PM_RSTC_WRCFG_SET		0x00000030
 | 
			
		||||
 #define PM_RSTC_WRCFG_FULL_RESET	0x00000020
 | 
			
		||||
 #define PM_RSTC_RESET			0x00000102
 | 
			
		||||
-
 | 
			
		||||
-/*
 | 
			
		||||
- * The Raspberry Pi firmware uses the RSTS register to know which partition
 | 
			
		||||
- * to boot from. The partition value is spread into bits 0, 2, 4, 6, 8, 10.
 | 
			
		||||
- * Partition 63 is a special partition used by the firmware to indicate halt.
 | 
			
		||||
- */
 | 
			
		||||
-#define PM_RSTS_RASPBERRYPI_HALT	0x555
 | 
			
		||||
+#define PM_RSTS_PARTITION_CLR          0xfffffaaa
 | 
			
		||||
 
 | 
			
		||||
 #define SECS_TO_WDOG_TICKS(x) ((x) << 16)
 | 
			
		||||
 #define WDOG_TICKS_TO_SECS(x) ((x) >> 16)
 | 
			
		||||
@@ -97,9 +91,24 @@ static unsigned int bcm2835_wdt_get_time
 | 
			
		||||
 	return WDOG_TICKS_TO_SECS(ret & PM_WDOG_TIME_SET);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
-static void __bcm2835_restart(struct bcm2835_wdt *wdt)
 | 
			
		||||
+/*
 | 
			
		||||
+ * The Raspberry Pi firmware uses the RSTS register to know which partiton
 | 
			
		||||
+ * to boot from. The partiton value is spread into bits 0, 2, 4, 6, 8, 10.
 | 
			
		||||
+ * Partiton 63 is a special partition used by the firmware to indicate halt.
 | 
			
		||||
+ */
 | 
			
		||||
+
 | 
			
		||||
+static void __bcm2835_restart(struct bcm2835_wdt *wdt, u8 partition)
 | 
			
		||||
 {
 | 
			
		||||
-	u32 val;
 | 
			
		||||
+	u32 val, rsts;
 | 
			
		||||
+
 | 
			
		||||
+	rsts = (partition & BIT(0)) | ((partition & BIT(1)) << 1) |
 | 
			
		||||
+	       ((partition & BIT(2)) << 2) | ((partition & BIT(3)) << 3) |
 | 
			
		||||
+	       ((partition & BIT(4)) << 4) | ((partition & BIT(5)) << 5);
 | 
			
		||||
+
 | 
			
		||||
+	val = readl_relaxed(wdt->base + PM_RSTS);
 | 
			
		||||
+	val &= PM_RSTS_PARTITION_CLR;
 | 
			
		||||
+	val |= PM_PASSWORD | rsts;
 | 
			
		||||
+	writel_relaxed(val, wdt->base + PM_RSTS);
 | 
			
		||||
 
 | 
			
		||||
 	/* use a timeout of 10 ticks (~150us) */
 | 
			
		||||
 	writel_relaxed(10 | PM_PASSWORD, wdt->base + PM_WDOG);
 | 
			
		||||
@@ -117,7 +126,13 @@ static int bcm2835_restart(struct watchd
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcm2835_wdt *wdt = watchdog_get_drvdata(wdog);
 | 
			
		||||
 
 | 
			
		||||
-	__bcm2835_restart(wdt);
 | 
			
		||||
+	unsigned long long val;
 | 
			
		||||
+	u8 partition = 0;
 | 
			
		||||
+
 | 
			
		||||
+	if (data && !kstrtoull(data, 0, &val) && val <= 63)
 | 
			
		||||
+		partition = val;
 | 
			
		||||
+
 | 
			
		||||
+	__bcm2835_restart(wdt, partition);
 | 
			
		||||
 
 | 
			
		||||
 	return 0;
 | 
			
		||||
 }
 | 
			
		||||
@@ -152,19 +167,9 @@ static struct watchdog_device bcm2835_wd
 | 
			
		||||
 static void bcm2835_power_off(void)
 | 
			
		||||
 {
 | 
			
		||||
 	struct bcm2835_wdt *wdt = bcm2835_power_off_wdt;
 | 
			
		||||
-	u32 val;
 | 
			
		||||
-
 | 
			
		||||
-	/*
 | 
			
		||||
-	 * We set the watchdog hard reset bit here to distinguish this reset
 | 
			
		||||
-	 * from the normal (full) reset. bootcode.bin will not reboot after a
 | 
			
		||||
-	 * hard reset.
 | 
			
		||||
-	 */
 | 
			
		||||
-	val = readl_relaxed(wdt->base + PM_RSTS);
 | 
			
		||||
-	val |= PM_PASSWORD | PM_RSTS_RASPBERRYPI_HALT;
 | 
			
		||||
-	writel_relaxed(val, wdt->base + PM_RSTS);
 | 
			
		||||
 
 | 
			
		||||
-	/* Continue with normal reset mechanism */
 | 
			
		||||
-	__bcm2835_restart(wdt);
 | 
			
		||||
+	/* Partition 63 tells the firmware that this is a halt */
 | 
			
		||||
+	__bcm2835_restart(wdt, 63);
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 static int bcm2835_wdt_probe(struct platform_device *pdev)
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,23 @@
 | 
			
		|||
From 900d45ec28bcc58c12314555038b1a31f5add91e Mon Sep 17 00:00:00 2001
 | 
			
		||||
From: popcornmix <popcornmix@gmail.com>
 | 
			
		||||
Date: Tue, 5 Apr 2016 19:40:12 +0100
 | 
			
		||||
Subject: [PATCH] reboot: Use power off rather than busy spinning when halt is
 | 
			
		||||
 requested
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 arch/arm/kernel/reboot.c | 4 +---
 | 
			
		||||
 1 file changed, 1 insertion(+), 3 deletions(-)
 | 
			
		||||
 | 
			
		||||
--- a/arch/arm/kernel/reboot.c
 | 
			
		||||
+++ b/arch/arm/kernel/reboot.c
 | 
			
		||||
@@ -102,9 +102,7 @@ void machine_shutdown(void)
 | 
			
		||||
  */
 | 
			
		||||
 void machine_halt(void)
 | 
			
		||||
 {
 | 
			
		||||
-	local_irq_disable();
 | 
			
		||||
-	smp_send_stop();
 | 
			
		||||
-	while (1);
 | 
			
		||||
+	machine_power_off();
 | 
			
		||||
 }
 | 
			
		||||
 
 | 
			
		||||
 /*
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue