Prepare v2022.01-rc4
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEEGjx/cOCPqxcHgJu/FHw5/5Y0tywFAmHArDwACgkQFHw5/5Y0 tyzxyAv/SjZjoEwG8nu7ptVZqTsZfm+tVwwWmQEBAA40MXy/KSccDtbUwB5GCO6f Uvk+qFFDbCkbGZh5VKbQusMmUoB02Xu9zUoSxKxcXL4WfC6Bg5GV/UWN9s8G3Tm6 4wcP0l8WFcQjjr89UfXugiZH58psvFu6PBbWVY4rMH9gZ5ds0AkNOF0L+HbdVmMR a5HBfrcySRY2kiTQuKF+RVlMW6BtaOqJp/XIyy8w6bH09ykMomj/u7z3JP3y9ZzL w3FXqCLlIEnvdDcqfWvfjoJ/gm0WcLulgSVpTFGS0jgJpnbeAURtZcuVgj6aPRUW FRon+u0tj3wpFjibs2cpyXWd+gw/bLLFpDXx78AUAPjxG31tEKbnR1j8R8wBZJ0B TqWZ3pCne/LPOT90y2KW2z6ty2n/yEn6qEFFT9MN9R4L0N+U0er//sYJC/nn/e6u fjvQ9OPLbnAfHVrad3ZeIkePrLOIF6XYwNQpsjt9aE2kU9IvV5sTa8TxZuQgasBU A46FgXtC =MEG2 -----END PGP SIGNATURE----- Merge tag 'v2022.01-rc4' into next Prepare v2022.01-rc4
This commit is contained in:
		
						commit
						4afab30cae
					
				|  | @ -728,8 +728,11 @@ W:	https://u-boot.readthedocs.io/en/latest/develop/uefi/u-boot_on_efi.html | ||||||
| F:	board/efi/efi-x86_app | F:	board/efi/efi-x86_app | ||||||
| F:	configs/efi-x86_app* | F:	configs/efi-x86_app* | ||||||
| F:	doc/develop/uefi/u-boot_on_efi.rst | F:	doc/develop/uefi/u-boot_on_efi.rst | ||||||
|  | F:	drivers/block/efi-media-uclass.c | ||||||
|  | F:	drivers/block/sb_efi_media.c | ||||||
| F:	lib/efi/efi_app.c | F:	lib/efi/efi_app.c | ||||||
| F:	scripts/build-efi.sh | F:	scripts/build-efi.sh | ||||||
|  | F:	test/dm/efi_media.c | ||||||
| 
 | 
 | ||||||
| EFI PAYLOAD | EFI PAYLOAD | ||||||
| M:	Heinrich Schuchardt <xypron.glpk@gmx.de> | M:	Heinrich Schuchardt <xypron.glpk@gmx.de> | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							|  | @ -3,7 +3,7 @@ | ||||||
| VERSION = 2022 | VERSION = 2022 | ||||||
| PATCHLEVEL = 01 | PATCHLEVEL = 01 | ||||||
| SUBLEVEL = | SUBLEVEL = | ||||||
| EXTRAVERSION = -rc3 | EXTRAVERSION = -rc4 | ||||||
| NAME = | NAME = | ||||||
| 
 | 
 | ||||||
| # *DOCUMENTATION*
 | # *DOCUMENTATION*
 | ||||||
|  |  | ||||||
|  | @ -197,6 +197,14 @@ | ||||||
| 		compatible = "audio-graph-card"; | 		compatible = "audio-graph-card"; | ||||||
| 		label = "rcar-sound"; | 		label = "rcar-sound"; | ||||||
| 		dais = <&rsnd_port0>, <&rsnd_port1>; | 		dais = <&rsnd_port0>, <&rsnd_port1>; | ||||||
|  | 		widgets = "Microphone", "Mic Jack", | ||||||
|  | 			  "Line", "Line In Jack", | ||||||
|  | 			  "Headphone", "Headphone Jack"; | ||||||
|  | 		mic-det-gpio = <&gpio0 2 GPIO_ACTIVE_LOW>; | ||||||
|  | 		routing = "Headphone Jack", "HPOUTL", | ||||||
|  | 			 "Headphone Jack", "HPOUTR", | ||||||
|  | 			 "IN3R", "MICBIAS", | ||||||
|  | 			 "Mic Jack", "IN3R"; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	vccq_sdhi0: regulator-vccq-sdhi0 { | 	vccq_sdhi0: regulator-vccq-sdhi0 { | ||||||
|  | @ -271,12 +279,12 @@ | ||||||
| &ehci0 { | &ehci0 { | ||||||
| 	dr_mode = "otg"; | 	dr_mode = "otg"; | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>; | 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| &ehci1 { | &ehci1 { | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>; | 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&usb2_clksel>, <&versaclock5 3>; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| &hdmi0 { | &hdmi0 { | ||||||
|  | @ -615,7 +623,7 @@ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| &rcar_sound { | &rcar_sound { | ||||||
| 	pinctrl-0 = <&sound_pins &sound_clk_pins>; | 	pinctrl-0 = <&sound_pins>, <&sound_clk_pins>; | ||||||
| 	pinctrl-names = "default"; | 	pinctrl-names = "default"; | ||||||
| 
 | 
 | ||||||
| 	/* Single DAI */ | 	/* Single DAI */ | ||||||
|  | @ -639,7 +647,7 @@ | ||||||
| 				bitclock-master = <&rsnd_endpoint0>; | 				bitclock-master = <&rsnd_endpoint0>; | ||||||
| 				frame-master = <&rsnd_endpoint0>; | 				frame-master = <&rsnd_endpoint0>; | ||||||
| 
 | 
 | ||||||
| 				playback = <&ssi1 &dvc1 &src1>; | 				playback = <&ssi1>, <&dvc1>, <&src1>; | ||||||
| 				capture = <&ssi0>; | 				capture = <&ssi0>; | ||||||
| 			}; | 			}; | ||||||
| 		}; | 		}; | ||||||
|  |  | ||||||
|  | @ -7,19 +7,10 @@ | ||||||
| #include <dt-bindings/clk/versaclock.h> | #include <dt-bindings/clk/versaclock.h> | ||||||
| 
 | 
 | ||||||
| / { | / { | ||||||
| 	aliases { |  | ||||||
| 		spi0 = &rpc; |  | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	memory@48000000 { | 	memory@48000000 { | ||||||
| 		device_type = "memory"; | 		device_type = "memory"; | ||||||
| 		/* first 128MB is reserved for secure area. */ | 		/* first 128MB is reserved for secure area. */ | ||||||
| 		reg = <0x0 0x48000000 0x0 0xc000000>; | 		reg = <0x0 0x48000000 0x0 0x78000000>; | ||||||
| 	}; |  | ||||||
| 
 |  | ||||||
| 	memory@57000000 { |  | ||||||
| 		device_type = "memory"; |  | ||||||
| 		reg = <0x0 0x57000000 0x0 0x29000000>; |  | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	osc_32k: osc_32k { | 	osc_32k: osc_32k { | ||||||
|  | @ -59,12 +50,17 @@ | ||||||
| &avb { | &avb { | ||||||
| 	pinctrl-0 = <&avb_pins>; | 	pinctrl-0 = <&avb_pins>; | ||||||
| 	pinctrl-names = "default"; | 	pinctrl-names = "default"; | ||||||
|  | 	phy-mode = "rgmii-rxid"; | ||||||
| 	phy-handle = <&phy0>; | 	phy-handle = <&phy0>; | ||||||
| 	rx-internal-delay-ps = <1800>; | 	rx-internal-delay-ps = <1800>; | ||||||
| 	tx-internal-delay-ps = <2000>; | 	tx-internal-delay-ps = <2000>; | ||||||
|  | 	clocks = <&cpg CPG_MOD 812>, <&versaclock5 4>; | ||||||
|  | 	clock-names = "fck", "refclk"; | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| 
 | 
 | ||||||
| 	phy0: ethernet-phy@0 { | 	phy0: ethernet-phy@0 { | ||||||
|  | 		compatible = "ethernet-phy-id004d.d074", | ||||||
|  | 			     "ethernet-phy-ieee802.3-c22"; | ||||||
| 		reg = <0>; | 		reg = <0>; | ||||||
| 		interrupt-parent = <&gpio2>; | 		interrupt-parent = <&gpio2>; | ||||||
| 		interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | 		interrupts = <11 IRQ_TYPE_LEVEL_LOW>; | ||||||
|  | @ -153,7 +149,7 @@ | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	eeprom@50 { | 	eeprom@50 { | ||||||
| 		compatible = "microchip,at24c64", "atmel,24c64"; | 		compatible = "microchip,24c64", "atmel,24c64"; | ||||||
| 		pagesize = <32>; | 		pagesize = <32>; | ||||||
| 		read-only;	/* Manufacturing EEPROM programmed at factory */ | 		read-only;	/* Manufacturing EEPROM programmed at factory */ | ||||||
| 		reg = <0x50>; | 		reg = <0x50>; | ||||||
|  | @ -279,25 +275,6 @@ | ||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| &rpc { |  | ||||||
| 	compatible = "renesas,rcar-gen3-rpc"; |  | ||||||
| 	num-cs = <1>; |  | ||||||
| 	spi-max-frequency = <40000000>; |  | ||||||
| 	#address-cells = <1>; |  | ||||||
| 	#size-cells = <0>; |  | ||||||
| 	status = "okay"; |  | ||||||
| 
 |  | ||||||
| 	flash0: spi-flash@0 { |  | ||||||
| 		#address-cells = <1>; |  | ||||||
| 		#size-cells = <1>; |  | ||||||
| 		reg = <0>; |  | ||||||
| 		compatible = "spi-flash", "jedec,spi-nor"; |  | ||||||
| 		spi-max-frequency = <40000000>; |  | ||||||
| 		spi-tx-bus-width = <1>; |  | ||||||
| 		spi-rx-bus-width = <1>; |  | ||||||
| 	}; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &scif_clk { | &scif_clk { | ||||||
| 	clock-frequency = <14745600>; | 	clock-frequency = <14745600>; | ||||||
| }; | }; | ||||||
|  | @ -340,17 +317,17 @@ | ||||||
| 	vqmmc-supply = <®_1p8v>; | 	vqmmc-supply = <®_1p8v>; | ||||||
| 	bus-width = <8>; | 	bus-width = <8>; | ||||||
| 	mmc-hs200-1_8v; | 	mmc-hs200-1_8v; | ||||||
|  | 	no-sd; | ||||||
|  | 	no-sdio; | ||||||
| 	non-removable; | 	non-removable; | ||||||
| 	fixed-emmc-driver-type = <1>; | 	fixed-emmc-driver-type = <1>; | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| &usb2_clksel { | &usb2_clksel { | ||||||
| 	status = "okay"; |  | ||||||
| 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, | 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, | ||||||
| 		  <&versaclock5 3>, <&usb3s0_clk>; | 		  <&versaclock5 3>, <&usb3s0_clk>; | ||||||
| 	clock-names = "ehci_ohci", "hs-usb-if", | 	status = "okay"; | ||||||
| 		      "usb_extal", "usb_xtal"; |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| &usb3s0_clk { | &usb3s0_clk { | ||||||
|  |  | ||||||
|  | @ -1,34 +1,6 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0 | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright 2020 Compass Electronics Group, LLC |  * Copyright 2021 LogicPD dba Beacon EmbeddedWorks | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| / { | #include "rz-g2-beacon-u-boot.dtsi" | ||||||
| 	soc { |  | ||||||
| 		u-boot,dm-pre-reloc; |  | ||||||
| 	}; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &cpg { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &extal_clk { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &prr { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &extalr_clk { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &sdhi0 { |  | ||||||
| 	/delete-property/ cd-gpios; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &sdhi2 { |  | ||||||
| 	status = "disabled"; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  | @ -21,6 +21,9 @@ | ||||||
| 		serial4 = &hscif2; | 		serial4 = &hscif2; | ||||||
| 		serial5 = &scif5; | 		serial5 = &scif5; | ||||||
| 		ethernet0 = &avb; | 		ethernet0 = &avb; | ||||||
|  | 		mmc0 = &sdhi3; | ||||||
|  | 		mmc1 = &sdhi0; | ||||||
|  | 		mmc2 = &sdhi2; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	chosen { | 	chosen { | ||||||
|  |  | ||||||
|  | @ -1,34 +1,6 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0 | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright 2020 Compass Electronics Group, LLC |  * Copyright 2021 LogicPD dba Beacon EmbeddedWorks | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| / { | #include "rz-g2-beacon-u-boot.dtsi" | ||||||
| 	soc { |  | ||||||
| 		u-boot,dm-pre-reloc; |  | ||||||
| 	}; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &cpg { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &extal_clk { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &prr { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &extalr_clk { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &sdhi0 { |  | ||||||
| 	/delete-property/ cd-gpios; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &sdhi2 { |  | ||||||
| 	status = "disabled"; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  | @ -22,6 +22,9 @@ | ||||||
| 		serial5 = &scif5; | 		serial5 = &scif5; | ||||||
| 		serial6 = &scif4; | 		serial6 = &scif4; | ||||||
| 		ethernet0 = &avb; | 		ethernet0 = &avb; | ||||||
|  | 		mmc0 = &sdhi3; | ||||||
|  | 		mmc1 = &sdhi0; | ||||||
|  | 		mmc2 = &sdhi2; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	chosen { | 	chosen { | ||||||
|  |  | ||||||
|  | @ -1,44 +1,6 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0 | // SPDX-License-Identifier: GPL-2.0 | ||||||
| /* | /* | ||||||
|  * Copyright 2020 Compass Electronics Group, LLC |  * Copyright 2021 LogicPD dba Beacon EmbeddedWorks | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| / { | #include "rz-g2-beacon-u-boot.dtsi" | ||||||
| 	soc { |  | ||||||
| 		u-boot,dm-pre-reloc; |  | ||||||
| 	}; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &cpg { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &extal_clk { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &prr { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &extalr_clk { |  | ||||||
| 	u-boot,dm-pre-reloc; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &sdhi0 { |  | ||||||
| 	/delete-property/ cd-gpios; |  | ||||||
| 	sd-uhs-sdr12; |  | ||||||
| 	sd-uhs-sdr25; |  | ||||||
| 	sd-uhs-sdr104; |  | ||||||
| 	max-frequency = <208000000>; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &sdhi2 { |  | ||||||
| 	status = "disabled"; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| &sdhi3 { |  | ||||||
| 	mmc-ddr-1_8v; |  | ||||||
| 	mmc-hs200-1_8v; |  | ||||||
| 	mmc-hs400-1_8v; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
|  | @ -22,6 +22,9 @@ | ||||||
| 		serial5 = &scif5; | 		serial5 = &scif5; | ||||||
| 		serial6 = &scif4; | 		serial6 = &scif4; | ||||||
| 		ethernet0 = &avb; | 		ethernet0 = &avb; | ||||||
|  | 		mmc0 = &sdhi3; | ||||||
|  | 		mmc1 = &sdhi0; | ||||||
|  | 		mmc2 = &sdhi2; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	chosen { | 	chosen { | ||||||
|  |  | ||||||
|  | @ -0,0 +1,75 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0 | ||||||
|  | /* | ||||||
|  |  * Copyright 2021 LogicPD dba Beacon EmbeddedWorks | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | / { | ||||||
|  | 	aliases { | ||||||
|  | 		spi0 = &rpc; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	soc { | ||||||
|  | 		u-boot,dm-pre-reloc; | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &cpg { | ||||||
|  | 	u-boot,dm-pre-reloc; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &ehci0 { | ||||||
|  | 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &ehci1 { | ||||||
|  | 	clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>, <&versaclock5 3>; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &extal_clk { | ||||||
|  | 	u-boot,dm-pre-reloc; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &extalr_clk { | ||||||
|  | 	u-boot,dm-pre-reloc; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &prr { | ||||||
|  | 	u-boot,dm-pre-reloc; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &rpc { | ||||||
|  | 	compatible = "renesas,rcar-gen3-rpc"; | ||||||
|  | 	num-cs = <1>; | ||||||
|  | 	spi-max-frequency = <40000000>; | ||||||
|  | 	#address-cells = <1>; | ||||||
|  | 	#size-cells = <0>; | ||||||
|  | 	status = "okay"; | ||||||
|  | 
 | ||||||
|  | 	flash0: spi-flash@0 { | ||||||
|  | 		#address-cells = <1>; | ||||||
|  | 		#size-cells = <1>; | ||||||
|  | 		reg = <0>; | ||||||
|  | 		compatible = "spi-flash", "jedec,spi-nor"; | ||||||
|  | 		spi-max-frequency = <40000000>; | ||||||
|  | 		spi-tx-bus-width = <1>; | ||||||
|  | 		spi-rx-bus-width = <1>; | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &sdhi0 { | ||||||
|  | 	/delete-property/ cd-gpios; | ||||||
|  | 	sd-uhs-sdr12; | ||||||
|  | 	sd-uhs-sdr25; | ||||||
|  | 	sd-uhs-sdr104; | ||||||
|  | 	max-frequency = <208000000>; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &sdhi2 { | ||||||
|  | 	status = "disabled"; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | &sdhi3 { | ||||||
|  | 	mmc-ddr-1_8v; | ||||||
|  | 	mmc-hs200-1_8v; | ||||||
|  | 	mmc-hs400-1_8v; | ||||||
|  | }; | ||||||
|  | @ -13,7 +13,7 @@ | ||||||
| / { | / { | ||||||
| 	aliases { | 	aliases { | ||||||
| 		mmc0 = &mmc0; | 		mmc0 = &mmc0; | ||||||
| #if CONFIG_MMC_SUNXI_EXTRA_SLOT == 2 | #if CONFIG_MMC_SUNXI_SLOT_EXTRA == 2 | ||||||
| 		mmc1 = &mmc2; | 		mmc1 = &mmc2; | ||||||
| #endif | #endif | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| /* SPDX-License-Identifier: GPL-2.0 */ | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (C) 2016-2017 Intel Corporation |  * Copyright (C) 2016-2021 Intel Corporation | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef _SOCFPGA_MISC_H_ | #ifndef _SOCFPGA_MISC_H_ | ||||||
|  | @ -45,7 +45,12 @@ int is_fpga_config_ready(void); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| void do_bridge_reset(int enable, unsigned int mask); | void do_bridge_reset(int enable, unsigned int mask); | ||||||
|  | void force_periph_program(unsigned int status); | ||||||
|  | bool is_regular_boot_valid(void); | ||||||
|  | bool is_periph_program_force(void); | ||||||
|  | void set_regular_boot(unsigned int status); | ||||||
| void socfpga_pl310_clear(void); | void socfpga_pl310_clear(void); | ||||||
| void socfpga_get_managers_addr(void); | void socfpga_get_managers_addr(void); | ||||||
|  | int qspi_flash_software_reset(void); | ||||||
| 
 | 
 | ||||||
| #endif /* _SOCFPGA_MISC_H_ */ | #endif /* _SOCFPGA_MISC_H_ */ | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| /* SPDX-License-Identifier: GPL-2.0 */ | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (C) 2016-2017 Intel Corporation |  * Copyright (C) 2016-2021 Intel Corporation | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef _RESET_MANAGER_ARRIA10_H_ | #ifndef _RESET_MANAGER_ARRIA10_H_ | ||||||
|  | @ -22,6 +22,7 @@ int socfpga_bridges_reset(void); | ||||||
| #define RSTMGR_A10_PER1MODRST	0x28 | #define RSTMGR_A10_PER1MODRST	0x28 | ||||||
| #define RSTMGR_A10_BRGMODRST	0x2c | #define RSTMGR_A10_BRGMODRST	0x2c | ||||||
| #define RSTMGR_A10_SYSMODRST	0x30 | #define RSTMGR_A10_SYSMODRST	0x30 | ||||||
|  | #define RSTMGR_A10_SYSWARMMASK	0x50 | ||||||
| 
 | 
 | ||||||
| #define RSTMGR_CTRL		RSTMGR_A10_CTRL | #define RSTMGR_CTRL		RSTMGR_A10_CTRL | ||||||
| 
 | 
 | ||||||
|  | @ -115,4 +116,7 @@ int socfpga_bridges_reset(void); | ||||||
| #define ALT_RSTMGR_HDSKEN_FPGAHSEN_SET_MSK	BIT(2) | #define ALT_RSTMGR_HDSKEN_FPGAHSEN_SET_MSK	BIT(2) | ||||||
| #define ALT_RSTMGR_HDSKEN_ETRSTALLEN_SET_MSK	BIT(3) | #define ALT_RSTMGR_HDSKEN_ETRSTALLEN_SET_MSK	BIT(3) | ||||||
| 
 | 
 | ||||||
|  | #define ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK	BIT(3) | ||||||
|  | #define ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK	BIT(4) | ||||||
|  | 
 | ||||||
| #endif /* _RESET_MANAGER_ARRIA10_H_ */ | #endif /* _RESET_MANAGER_ARRIA10_H_ */ | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| /* SPDX-License-Identifier: GPL-2.0 */ | /* SPDX-License-Identifier: GPL-2.0 */ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (C) 2016-2017 Intel Corporation <www.intel.com> |  * Copyright (C) 2016-2021 Intel Corporation <www.intel.com> | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #ifndef _SYSTEM_MANAGER_ARRIA10_H_ | #ifndef _SYSTEM_MANAGER_ARRIA10_H_ | ||||||
|  | @ -31,6 +31,11 @@ | ||||||
| #define SYSMGR_A10_NOC_IDLEACK			0xd0 | #define SYSMGR_A10_NOC_IDLEACK			0xd0 | ||||||
| #define SYSMGR_A10_NOC_IDLESTATUS		0xd4 | #define SYSMGR_A10_NOC_IDLESTATUS		0xd4 | ||||||
| #define SYSMGR_A10_FPGA2SOC_CTRL		0xd8 | #define SYSMGR_A10_FPGA2SOC_CTRL		0xd8 | ||||||
|  | #define SYSMGR_A10_ROMCODE_CTRL			0x204 | ||||||
|  | #define SYSMGR_A10_ROMCODE_INITSWSTATE	0x20C | ||||||
|  | #define SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND	0x208 | ||||||
|  | #define SYSMGR_A10_ISW_HANDOFF_BASE		0x230 | ||||||
|  | #define SYSMGR_A10_ISW_HANDOFF_7		0x1c | ||||||
| 
 | 
 | ||||||
| #define SYSMGR_SDMMC				SYSMGR_A10_SDMMC | #define SYSMGR_SDMMC				SYSMGR_A10_SDMMC | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0
 | // SPDX-License-Identifier: GPL-2.0
 | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (C) 2016-2017 Intel Corporation |  * Copyright (C) 2016-2021 Intel Corporation | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <altera.h> | #include <altera.h> | ||||||
|  | @ -11,6 +11,7 @@ | ||||||
| #include <miiphy.h> | #include <miiphy.h> | ||||||
| #include <netdev.h> | #include <netdev.h> | ||||||
| #include <ns16550.h> | #include <ns16550.h> | ||||||
|  | #include <spi_flash.h> | ||||||
| #include <watchdog.h> | #include <watchdog.h> | ||||||
| #include <asm/arch/misc.h> | #include <asm/arch/misc.h> | ||||||
| #include <asm/arch/pinmux.h> | #include <asm/arch/pinmux.h> | ||||||
|  | @ -21,6 +22,7 @@ | ||||||
| #include <asm/arch/nic301.h> | #include <asm/arch/nic301.h> | ||||||
| #include <asm/io.h> | #include <asm/io.h> | ||||||
| #include <asm/pl310.h> | #include <asm/pl310.h> | ||||||
|  | #include <linux/sizes.h> | ||||||
| 
 | 
 | ||||||
| #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3	0x08 | #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3	0x08 | ||||||
| #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11	0x58 | #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11	0x58 | ||||||
|  | @ -29,6 +31,13 @@ | ||||||
| #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7	0x78 | #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7	0x78 | ||||||
| #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3	0x98 | #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3	0x98 | ||||||
| 
 | 
 | ||||||
|  | #define REGULAR_BOOT_MAGIC	0xd15ea5e | ||||||
|  | #define PERIPH_RBF_PROG_FORCE	0x50455249 | ||||||
|  | 
 | ||||||
|  | #define QSPI_S25FL_SOFT_RESET_COMMAND	0x00f0ff82 | ||||||
|  | #define QSPI_N25_SOFT_RESET_COMMAND	0x00000001 | ||||||
|  | #define QSPI_NO_SOFT_RESET		0x00000000 | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * FPGA programming support for SoC FPGA Arria 10 |  * FPGA programming support for SoC FPGA Arria 10 | ||||||
|  */ |  */ | ||||||
|  | @ -122,3 +131,118 @@ void do_bridge_reset(int enable, unsigned int mask) | ||||||
| 	else | 	else | ||||||
| 		socfpga_bridges_reset(); | 		socfpga_bridges_reset(); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This function set/unset flag with number "0x50455249" to | ||||||
|  |  * handoff register isw_handoff[7] - 0xffd0624c | ||||||
|  |  * This flag is used to force periph RBF program regardless FPGA status | ||||||
|  |  * and double periph RBF config are needed on some devices or boards to | ||||||
|  |  * stabilize the IO config system. | ||||||
|  |  */ | ||||||
|  | void force_periph_program(unsigned int status) | ||||||
|  | { | ||||||
|  | 	if (status) | ||||||
|  | 		writel(PERIPH_RBF_PROG_FORCE, socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | ||||||
|  | 	else | ||||||
|  | 		writel(0, socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This function is used to check whether | ||||||
|  |  * handoff register isw_handoff[7] contains | ||||||
|  |  * flag for forcing the periph RBF program "0x50455249". | ||||||
|  |  */ | ||||||
|  | bool is_periph_program_force(void) | ||||||
|  | { | ||||||
|  | 	unsigned int status; | ||||||
|  | 
 | ||||||
|  | 	status = readl(socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | ||||||
|  | 
 | ||||||
|  | 	if (status == PERIPH_RBF_PROG_FORCE) | ||||||
|  | 		return true; | ||||||
|  | 	else | ||||||
|  | 		return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This function set/unset magic number "0xd15ea5e" to | ||||||
|  |  * handoff register isw_handoff[7] - 0xffd0624c | ||||||
|  |  * This magic number is part of boot progress tracking | ||||||
|  |  * and it's required for warm reset workaround on MPFE hang issue. | ||||||
|  |  */ | ||||||
|  | void set_regular_boot(unsigned int status) | ||||||
|  | { | ||||||
|  | 	if (status) | ||||||
|  | 		writel(REGULAR_BOOT_MAGIC, socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | ||||||
|  | 	else | ||||||
|  | 		writel(0, socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * This function is used to check whether | ||||||
|  |  * handoff register isw_handoff[7] contains | ||||||
|  |  * magic number "0xd15ea5e". | ||||||
|  |  */ | ||||||
|  | bool is_regular_boot_valid(void) | ||||||
|  | { | ||||||
|  | 	unsigned int status; | ||||||
|  | 
 | ||||||
|  | 	status = readl(socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); | ||||||
|  | 
 | ||||||
|  | 	if (status == REGULAR_BOOT_MAGIC) | ||||||
|  | 		return true; | ||||||
|  | 	else | ||||||
|  | 		return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #if IS_ENABLED(CONFIG_CADENCE_QSPI) | ||||||
|  | /* This function is used to trigger software reset
 | ||||||
|  |  * to the QSPI flash. On some boards, the QSPI flash reset may | ||||||
|  |  * not be connected to the HPS warm reset. | ||||||
|  |  */ | ||||||
|  | int qspi_flash_software_reset(void) | ||||||
|  | { | ||||||
|  | 	struct udevice *flash; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	/* Get the flash info */ | ||||||
|  | 	ret = spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS, | ||||||
|  | 				     CONFIG_SF_DEFAULT_CS, | ||||||
|  | 				     CONFIG_SF_DEFAULT_SPEED, | ||||||
|  | 				     CONFIG_SF_DEFAULT_MODE, | ||||||
|  | 				     &flash); | ||||||
|  | 
 | ||||||
|  | 	if (ret) { | ||||||
|  | 		debug("Failed to initialize SPI flash at "); | ||||||
|  | 		debug("%u:%u (error %d)\n", CONFIG_SF_DEFAULT_BUS, | ||||||
|  | 		      CONFIG_SF_DEFAULT_CS, ret); | ||||||
|  | 		return -ENODEV; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (!flash) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * QSPI flash software reset command, for the case where | ||||||
|  | 	 * no HPS reset connected to QSPI flash reset | ||||||
|  | 	 */ | ||||||
|  | 	if (!memcmp(flash->name, "N25", SZ_1 + SZ_2)) | ||||||
|  | 		writel(QSPI_N25_SOFT_RESET_COMMAND, socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); | ||||||
|  | 	else if (!memcmp(flash->name, "S25FL", SZ_1 + SZ_4)) | ||||||
|  | 		writel(QSPI_S25FL_SOFT_RESET_COMMAND, | ||||||
|  | 		       socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); | ||||||
|  | 	else /* No software reset */ | ||||||
|  | 		writel(QSPI_NO_SOFT_RESET, socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| // SPDX-License-Identifier: GPL-2.0+
 | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
| /*
 | /*
 | ||||||
|  *  Copyright (C) 2012-2019 Altera Corporation <www.altera.com> |  *  Copyright (C) 2012-2021 Altera Corporation <www.altera.com> | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
|  | @ -30,8 +30,13 @@ | ||||||
| #include <asm/arch/fpga_manager.h> | #include <asm/arch/fpga_manager.h> | ||||||
| #include <mmc.h> | #include <mmc.h> | ||||||
| #include <memalign.h> | #include <memalign.h> | ||||||
|  | #include <linux/delay.h> | ||||||
| 
 | 
 | ||||||
| #define FPGA_BUFSIZ	16 * 1024 | #define FPGA_BUFSIZ	16 * 1024 | ||||||
|  | #define FSBL_IMAGE_IS_VALID	0x49535756 | ||||||
|  | 
 | ||||||
|  | #define FSBL_IMAGE_IS_INVALID	0x0 | ||||||
|  | #define BOOTROM_CONFIGURES_IO_PINMUX	0x3 | ||||||
| 
 | 
 | ||||||
| DECLARE_GLOBAL_DATA_PTR; | DECLARE_GLOBAL_DATA_PTR; | ||||||
| 
 | 
 | ||||||
|  | @ -106,6 +111,8 @@ u32 spl_mmc_boot_mode(const u32 boot_device) | ||||||
| 
 | 
 | ||||||
| void spl_board_init(void) | void spl_board_init(void) | ||||||
| { | { | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
| 	ALLOC_CACHE_ALIGN_BUFFER(char, buf, FPGA_BUFSIZ); | 	ALLOC_CACHE_ALIGN_BUFFER(char, buf, FPGA_BUFSIZ); | ||||||
| 
 | 
 | ||||||
| 	/* enable console uart printing */ | 	/* enable console uart printing */ | ||||||
|  | @ -116,8 +123,7 @@ void spl_board_init(void) | ||||||
| 
 | 
 | ||||||
| 	/* If the full FPGA is already loaded, ie.from EPCQ, config fpga pins */ | 	/* If the full FPGA is already loaded, ie.from EPCQ, config fpga pins */ | ||||||
| 	if (is_fpgamgr_user_mode()) { | 	if (is_fpgamgr_user_mode()) { | ||||||
| 		int ret = config_pins(gd->fdt_blob, "shared"); | 		ret = config_pins(gd->fdt_blob, "shared"); | ||||||
| 
 |  | ||||||
| 		if (ret) | 		if (ret) | ||||||
| 			return; | 			return; | ||||||
| 
 | 
 | ||||||
|  | @ -127,11 +133,110 @@ void spl_board_init(void) | ||||||
| 	} else if (!is_fpgamgr_early_user_mode()) { | 	} else if (!is_fpgamgr_early_user_mode()) { | ||||||
| 		/* Program IOSSM(early IO release) or full FPGA */ | 		/* Program IOSSM(early IO release) or full FPGA */ | ||||||
| 		fpgamgr_program(buf, FPGA_BUFSIZ, 0); | 		fpgamgr_program(buf, FPGA_BUFSIZ, 0); | ||||||
|  | 
 | ||||||
|  | 		/* Skipping double program for combined RBF */ | ||||||
|  | 		if (!is_fpgamgr_user_mode()) { | ||||||
|  | 			/*
 | ||||||
|  | 			 * Expect FPGA entered early user mode, so | ||||||
|  | 			 * the flag is set to re-program IOSSM | ||||||
|  | 			 */ | ||||||
|  | 			force_periph_program(true); | ||||||
|  | 
 | ||||||
|  | 			/* Re-program IOSSM to stabilize IO system */ | ||||||
|  | 			fpgamgr_program(buf, FPGA_BUFSIZ, 0); | ||||||
|  | 
 | ||||||
|  | 			force_periph_program(false); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* If the IOSSM/full FPGA is already loaded, start DDR */ | 	/* If the IOSSM/full FPGA is already loaded, start DDR */ | ||||||
| 	if (is_fpgamgr_early_user_mode() || is_fpgamgr_user_mode()) | 	if (is_fpgamgr_early_user_mode() || is_fpgamgr_user_mode()) { | ||||||
|  | 		if (!is_regular_boot_valid()) { | ||||||
|  | 			/*
 | ||||||
|  | 			 * Ensure all signals in stable state before triggering | ||||||
|  | 			 * warm reset. This value is recommended from stress | ||||||
|  | 			 * test. | ||||||
|  | 			 */ | ||||||
|  | 			mdelay(10); | ||||||
|  | 
 | ||||||
|  | #if IS_ENABLED(CONFIG_CADENCE_QSPI) | ||||||
|  | 			/*
 | ||||||
|  | 			 * Trigger software reset to QSPI flash. | ||||||
|  | 			 * On some boards, the QSPI flash reset may not be | ||||||
|  | 			 * connected to the HPS warm reset. | ||||||
|  | 			 */ | ||||||
|  | 			qspi_flash_software_reset(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | 			ret = readl(socfpga_get_rstmgr_addr() + | ||||||
|  | 				    RSTMGR_A10_SYSWARMMASK); | ||||||
|  | 			/*
 | ||||||
|  | 			 * Masking s2f & FPGA manager module reset from warm | ||||||
|  | 			 * reset | ||||||
|  | 			 */ | ||||||
|  | 			writel(ret & (~(ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK | | ||||||
|  | 			       ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK)), | ||||||
|  | 			       socfpga_get_rstmgr_addr() + | ||||||
|  | 			       RSTMGR_A10_SYSWARMMASK); | ||||||
|  | 
 | ||||||
|  | 			/*
 | ||||||
|  | 			 * BootROM will configure both IO and pin mux after a | ||||||
|  | 			 * warm reset | ||||||
|  | 			 */ | ||||||
|  | 			ret = readl(socfpga_get_sysmgr_addr() + | ||||||
|  | 				    SYSMGR_A10_ROMCODE_CTRL); | ||||||
|  | 			writel(ret | BOOTROM_CONFIGURES_IO_PINMUX, | ||||||
|  | 			       socfpga_get_sysmgr_addr() + | ||||||
|  | 			       SYSMGR_A10_ROMCODE_CTRL); | ||||||
|  | 
 | ||||||
|  | 			/*
 | ||||||
|  | 			 * Up to here, image is considered valid and should be | ||||||
|  | 			 * set as valid before warm reset is triggered | ||||||
|  | 			 */ | ||||||
|  | 			writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() + | ||||||
|  | 			       SYSMGR_A10_ROMCODE_INITSWSTATE); | ||||||
|  | 
 | ||||||
|  | 			/*
 | ||||||
|  | 			 * Set this flag to scratch register, so that a proper | ||||||
|  | 			 * boot progress before / after warm reset can be | ||||||
|  | 			 * tracked by FSBL | ||||||
|  | 			 */ | ||||||
|  | 			set_regular_boot(true); | ||||||
|  | 
 | ||||||
|  | 			WATCHDOG_RESET(); | ||||||
|  | 
 | ||||||
|  | 			reset_cpu(); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * Reset this flag to scratch register, so that a proper | ||||||
|  | 		 * boot progress before / after warm reset can be | ||||||
|  | 		 * tracked by FSBL | ||||||
|  | 		 */ | ||||||
|  | 		set_regular_boot(false); | ||||||
|  | 
 | ||||||
|  | 		ret = readl(socfpga_get_rstmgr_addr() + | ||||||
|  | 			    RSTMGR_A10_SYSWARMMASK); | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * Unmasking s2f & FPGA manager module reset from warm | ||||||
|  | 		 * reset | ||||||
|  | 		 */ | ||||||
|  | 		writel(ret | ALT_RSTMGR_SYSWARMMASK_S2F_SET_MSK | | ||||||
|  | 			ALT_RSTMGR_FPGAMGRWARMMASK_S2F_SET_MSK, | ||||||
|  | 			socfpga_get_rstmgr_addr() + RSTMGR_A10_SYSWARMMASK); | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * Up to here, MPFE hang workaround is considered done and | ||||||
|  | 		 * should be reset as invalid until FSBL successfully loading | ||||||
|  | 		 * SSBL, and prepare jumping to SSBL, then only setting as | ||||||
|  | 		 * valid | ||||||
|  | 		 */ | ||||||
|  | 		writel(FSBL_IMAGE_IS_INVALID, socfpga_get_sysmgr_addr() + | ||||||
|  | 		       SYSMGR_A10_ROMCODE_INITSWSTATE); | ||||||
|  | 
 | ||||||
| 		ddr_calibration_sequence(); | 		ddr_calibration_sequence(); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!is_fpgamgr_user_mode()) | 	if (!is_fpgamgr_user_mode()) | ||||||
| 		fpgamgr_program(buf, FPGA_BUFSIZ, 0); | 		fpgamgr_program(buf, FPGA_BUFSIZ, 0); | ||||||
|  | @ -169,3 +274,10 @@ void board_init_f(ulong dummy) | ||||||
| 	config_dedicated_pins(gd->fdt_blob); | 	config_dedicated_pins(gd->fdt_blob); | ||||||
| 	WATCHDOG_RESET(); | 	WATCHDOG_RESET(); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | /* board specific function prior loading SSBL / U-Boot proper */ | ||||||
|  | void spl_board_prepare_for_boot(void) | ||||||
|  | { | ||||||
|  | 	writel(FSBL_IMAGE_IS_VALID, socfpga_get_sysmgr_addr() + | ||||||
|  | 	       SYSMGR_A10_ROMCODE_INITSWSTATE); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -40,3 +40,16 @@ config SIFIVE_FU740 | ||||||
| 	imply DM_I2C | 	imply DM_I2C | ||||||
| 	imply SYS_I2C_OCORES | 	imply SYS_I2C_OCORES | ||||||
| 	imply SPL_I2C | 	imply SPL_I2C | ||||||
|  | 
 | ||||||
|  | if ENV_IS_IN_SPI_FLASH | ||||||
|  | 
 | ||||||
|  | config ENV_OFFSET | ||||||
|  | 	default 0x505000 | ||||||
|  | 
 | ||||||
|  | config ENV_SIZE | ||||||
|  | 	default 0x20000 | ||||||
|  | 
 | ||||||
|  | config ENV_SECT_SIZE | ||||||
|  | 	default 0x10000 | ||||||
|  | 
 | ||||||
|  | endif # ENV_IS_IN_SPI_FLASH | ||||||
|  |  | ||||||
|  | @ -16,6 +16,10 @@ | ||||||
| 		u-boot,dm-spl; | 		u-boot,dm-spl; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	config { | ||||||
|  | 		u-boot,spl-payload-offset = <0x105000>; /* loader2 @1044KB */ | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| 	hfclk { | 	hfclk { | ||||||
| 		u-boot,dm-spl; | 		u-boot,dm-spl; | ||||||
| 	}; | 	}; | ||||||
|  | @ -30,6 +34,13 @@ | ||||||
| 	clocks = <&rtcclk>; | 	clocks = <&rtcclk>; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | &qspi0 { | ||||||
|  | 	u-boot,dm-spl; | ||||||
|  | 	flash@0 { | ||||||
|  | 		u-boot,dm-spl; | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| &spi0 { | &spi0 { | ||||||
| 	mmc@0 { | 	mmc@0 { | ||||||
| 		u-boot,dm-spl; | 		u-boot,dm-spl; | ||||||
|  |  | ||||||
|  | @ -1,348 +1,131 @@ | ||||||
| // SPDX-License-Identifier: (GPL-2.0 OR MIT) | // SPDX-License-Identifier: (GPL-2.0+ OR MIT) | ||||||
| /* Copyright (c) 2020 Microchip Technology Inc */ | /* | ||||||
|  |  * Copyright (C) 2021 Microchip Technology Inc. | ||||||
|  |  * Padmarao Begari <padmarao.begari@microchip.com> | ||||||
|  |  */ | ||||||
| 
 | 
 | ||||||
| /dts-v1/; | /dts-v1/; | ||||||
| #include "dt-bindings/clock/microchip-mpfs-clock.h" | 
 | ||||||
|  | #include "microchip-mpfs.dtsi" | ||||||
| 
 | 
 | ||||||
| /* Clock frequency (in Hz) of the rtcclk */ | /* Clock frequency (in Hz) of the rtcclk */ | ||||||
| #define RTCCLK_FREQ		1000000 | #define RTCCLK_FREQ		1000000 | ||||||
| 
 | 
 | ||||||
| / { | / { | ||||||
| 	#address-cells = <2>; | 	model = "Microchip PolarFire-SoC Icicle Kit"; | ||||||
| 	#size-cells = <2>; | 	compatible = "microchip,mpfs-icicle-kit", "microchip,mpfs"; | ||||||
| 	model = "Microchip MPFS Icicle Kit"; |  | ||||||
| 	compatible = "microchip,mpfs-icicle-kit"; |  | ||||||
| 
 | 
 | ||||||
| 	aliases { | 	aliases { | ||||||
| 		serial0 = &uart0; | 		serial1 = &uart1; | ||||||
| 		ethernet0 = &emac1; | 		ethernet0 = &mac1; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	chosen { | 	chosen { | ||||||
| 		stdout-path = "serial0"; | 		stdout-path = "serial1"; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	cpucomplex: cpus { | 	cpus { | ||||||
| 		#address-cells = <1>; |  | ||||||
| 		#size-cells = <0>; |  | ||||||
| 		timebase-frequency = <RTCCLK_FREQ>; | 		timebase-frequency = <RTCCLK_FREQ>; | ||||||
| 		cpu0: cpu@0 { |  | ||||||
| 			clocks = <&clkcfg CLK_CPU>; |  | ||||||
| 			compatible = "sifive,e51", "sifive,rocket0", "riscv"; |  | ||||||
| 			device_type = "cpu"; |  | ||||||
| 			i-cache-block-size = <64>; |  | ||||||
| 			i-cache-sets = <128>; |  | ||||||
| 			i-cache-size = <16384>; |  | ||||||
| 			reg = <0>; |  | ||||||
| 			riscv,isa = "rv64imac"; |  | ||||||
| 			status = "disabled"; |  | ||||||
| 			operating-points = < |  | ||||||
| 				/* kHz	uV */ |  | ||||||
| 				600000  1100000 |  | ||||||
| 				300000   950000 |  | ||||||
| 				150000   750000 |  | ||||||
| 			>; |  | ||||||
| 			cpu0intc: interrupt-controller { |  | ||||||
| 				#interrupt-cells = <1>; |  | ||||||
| 				compatible = "riscv,cpu-intc"; |  | ||||||
| 				interrupt-controller; |  | ||||||
| 	}; | 	}; | ||||||
| 		}; | 
 | ||||||
| 		cpu1: cpu@1 { | 	reserved-memory { | ||||||
| 			clocks = <&clkcfg CLK_CPU>; |  | ||||||
| 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; |  | ||||||
| 			d-cache-block-size = <64>; |  | ||||||
| 			d-cache-sets = <64>; |  | ||||||
| 			d-cache-size = <32768>; |  | ||||||
| 			d-tlb-sets = <1>; |  | ||||||
| 			d-tlb-size = <32>; |  | ||||||
| 			device_type = "cpu"; |  | ||||||
| 			i-cache-block-size = <64>; |  | ||||||
| 			i-cache-sets = <64>; |  | ||||||
| 			i-cache-size = <32768>; |  | ||||||
| 			i-tlb-sets = <1>; |  | ||||||
| 			i-tlb-size = <32>; |  | ||||||
| 			mmu-type = "riscv,sv39"; |  | ||||||
| 			reg = <1>; |  | ||||||
| 			riscv,isa = "rv64imafdc"; |  | ||||||
| 			tlb-split; |  | ||||||
| 			status = "okay"; |  | ||||||
| 			operating-points = < |  | ||||||
| 				/* kHz	uV */ |  | ||||||
| 				600000  1100000 |  | ||||||
| 				300000   950000 |  | ||||||
| 				150000   750000 |  | ||||||
| 			>; |  | ||||||
| 			cpu1intc: interrupt-controller { |  | ||||||
| 				#interrupt-cells = <1>; |  | ||||||
| 				compatible = "riscv,cpu-intc"; |  | ||||||
| 				interrupt-controller; |  | ||||||
| 			}; |  | ||||||
| 		}; |  | ||||||
| 		cpu2: cpu@2 { |  | ||||||
| 			clocks = <&clkcfg CLK_CPU>; |  | ||||||
| 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; |  | ||||||
| 			d-cache-block-size = <64>; |  | ||||||
| 			d-cache-sets = <64>; |  | ||||||
| 			d-cache-size = <32768>; |  | ||||||
| 			d-tlb-sets = <1>; |  | ||||||
| 			d-tlb-size = <32>; |  | ||||||
| 			device_type = "cpu"; |  | ||||||
| 			i-cache-block-size = <64>; |  | ||||||
| 			i-cache-sets = <64>; |  | ||||||
| 			i-cache-size = <32768>; |  | ||||||
| 			i-tlb-sets = <1>; |  | ||||||
| 			i-tlb-size = <32>; |  | ||||||
| 			mmu-type = "riscv,sv39"; |  | ||||||
| 			reg = <2>; |  | ||||||
| 			riscv,isa = "rv64imafdc"; |  | ||||||
| 			tlb-split; |  | ||||||
| 			status = "okay"; |  | ||||||
| 			operating-points = < |  | ||||||
| 				/* kHz	uV */ |  | ||||||
| 				600000  1100000 |  | ||||||
| 				300000   950000 |  | ||||||
| 				150000   750000 |  | ||||||
| 			>; |  | ||||||
| 			cpu2intc: interrupt-controller { |  | ||||||
| 				#interrupt-cells = <1>; |  | ||||||
| 				compatible = "riscv,cpu-intc"; |  | ||||||
| 				interrupt-controller; |  | ||||||
| 			}; |  | ||||||
| 		}; |  | ||||||
| 		cpu3: cpu@3 { |  | ||||||
| 			clocks = <&clkcfg CLK_CPU>; |  | ||||||
| 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; |  | ||||||
| 			d-cache-block-size = <64>; |  | ||||||
| 			d-cache-sets = <64>; |  | ||||||
| 			d-cache-size = <32768>; |  | ||||||
| 			d-tlb-sets = <1>; |  | ||||||
| 			d-tlb-size = <32>; |  | ||||||
| 			device_type = "cpu"; |  | ||||||
| 			i-cache-block-size = <64>; |  | ||||||
| 			i-cache-sets = <64>; |  | ||||||
| 			i-cache-size = <32768>; |  | ||||||
| 			i-tlb-sets = <1>; |  | ||||||
| 			i-tlb-size = <32>; |  | ||||||
| 			mmu-type = "riscv,sv39"; |  | ||||||
| 			reg = <3>; |  | ||||||
| 			riscv,isa = "rv64imafdc"; |  | ||||||
| 			tlb-split; |  | ||||||
| 			status = "okay"; |  | ||||||
| 			operating-points = < |  | ||||||
| 				/* kHz	uV */ |  | ||||||
| 				600000  1100000 |  | ||||||
| 				300000   950000 |  | ||||||
| 				150000   750000 |  | ||||||
| 			>; |  | ||||||
| 			cpu3intc: interrupt-controller { |  | ||||||
| 				#interrupt-cells = <1>; |  | ||||||
| 				compatible = "riscv,cpu-intc"; |  | ||||||
| 				interrupt-controller; |  | ||||||
| 			}; |  | ||||||
| 		}; |  | ||||||
| 		cpu4: cpu@4 { |  | ||||||
| 			clocks = <&clkcfg CLK_CPU>; |  | ||||||
| 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; |  | ||||||
| 			d-cache-block-size = <64>; |  | ||||||
| 			d-cache-sets = <64>; |  | ||||||
| 			d-cache-size = <32768>; |  | ||||||
| 			d-tlb-sets = <1>; |  | ||||||
| 			d-tlb-size = <32>; |  | ||||||
| 			device_type = "cpu"; |  | ||||||
| 			i-cache-block-size = <64>; |  | ||||||
| 			i-cache-sets = <64>; |  | ||||||
| 			i-cache-size = <32768>; |  | ||||||
| 			i-tlb-sets = <1>; |  | ||||||
| 			i-tlb-size = <32>; |  | ||||||
| 			mmu-type = "riscv,sv39"; |  | ||||||
| 			reg = <4>; |  | ||||||
| 			riscv,isa = "rv64imafdc"; |  | ||||||
| 			tlb-split; |  | ||||||
| 			status = "okay"; |  | ||||||
| 			operating-points = < |  | ||||||
| 				/* kHz	uV */ |  | ||||||
| 				600000  1100000 |  | ||||||
| 				300000   950000 |  | ||||||
| 				150000   750000 |  | ||||||
| 			>; |  | ||||||
| 			cpu4intc: interrupt-controller { |  | ||||||
| 				#interrupt-cells = <1>; |  | ||||||
| 				compatible = "riscv,cpu-intc"; |  | ||||||
| 				interrupt-controller; |  | ||||||
| 			}; |  | ||||||
| 		}; |  | ||||||
| 	}; |  | ||||||
| 	refclk: refclk { |  | ||||||
| 		compatible = "fixed-clock"; |  | ||||||
| 		#clock-cells = <0>; |  | ||||||
| 		clock-frequency = <600000000>; |  | ||||||
| 		clock-output-names = "msspllclk"; |  | ||||||
| 	}; |  | ||||||
| 	ddr: memory@80000000 { |  | ||||||
| 		device_type = "memory"; |  | ||||||
| 		reg = <0x0 0x80000000 0x0 0x40000000>; |  | ||||||
| 		clocks = <&clkcfg CLK_DDRC>; |  | ||||||
| 	}; |  | ||||||
| 	soc: soc { |  | ||||||
| 		#address-cells = <2>; |  | ||||||
| 		#size-cells = <2>; |  | ||||||
| 		compatible = "microchip,mpfs-icicle-kit", "simple-bus"; |  | ||||||
| 		ranges; | 		ranges; | ||||||
| 		clint0: clint@2000000 { | 		#size-cells = <2>; | ||||||
| 			compatible = "riscv,clint0"; | 		#address-cells = <2>; | ||||||
| 			interrupts-extended = <&cpu0intc 3 &cpu0intc 7 | 
 | ||||||
| 						&cpu1intc 3 &cpu1intc 7 | 		fabricbuf0: fabricbuf@0 { | ||||||
| 						&cpu2intc 3 &cpu2intc 7 | 			compatible = "shared-dma-pool"; | ||||||
| 						&cpu3intc 3 &cpu3intc 7 | 			reg = <0x0 0xae000000 0x0 0x2000000>; | ||||||
| 						&cpu4intc 3 &cpu4intc 7>; | 			label = "fabricbuf0-ddr-c"; | ||||||
| 			reg = <0x0 0x2000000 0x0 0x10000>; |  | ||||||
| 			reg-names = "control"; |  | ||||||
| 			clock-frequency = <RTCCLK_FREQ>; |  | ||||||
| 		}; | 		}; | ||||||
| 		cachecontroller: cache-controller@2010000 { | 
 | ||||||
| 			compatible = "sifive,fu540-c000-ccache", "cache"; | 		fabricbuf1: fabricbuf@1 { | ||||||
| 			cache-block-size = <64>; | 			compatible = "shared-dma-pool"; | ||||||
| 			cache-level = <2>; | 			reg = <0x0 0xc0000000 0x0 0x8000000>; | ||||||
| 			cache-sets = <1024>; | 			label = "fabricbuf1-ddr-nc"; | ||||||
| 			cache-size = <2097152>; |  | ||||||
| 			cache-unified; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <1 2 3>; |  | ||||||
| 			reg = <0x0 0x2010000 0x0 0x1000>; |  | ||||||
| 		}; | 		}; | ||||||
| 		plic: interrupt-controller@c000000 { | 
 | ||||||
| 			#interrupt-cells = <1>; | 		fabricbuf2: fabricbuf@2 { | ||||||
| 			compatible = "sifive,plic-1.0.0"; | 			compatible = "shared-dma-pool"; | ||||||
| 			reg = <0x0 0xc000000 0x0 0x4000000>; | 			reg = <0x0 0xd8000000 0x0 0x8000000>; | ||||||
| 			riscv,max-priority = <7>; | 			label = "fabricbuf2-ddr-nc-wcb"; | ||||||
| 			riscv,ndev = <186>; |  | ||||||
| 			interrupt-controller; |  | ||||||
| 			interrupts-extended = < |  | ||||||
| 				&cpu0intc 11 |  | ||||||
| 				&cpu1intc 11 &cpu1intc 9 |  | ||||||
| 				&cpu2intc 11 &cpu2intc 9 |  | ||||||
| 				&cpu3intc 11 &cpu3intc 9 |  | ||||||
| 				&cpu4intc 11 &cpu4intc 9>; |  | ||||||
| 		}; | 		}; | ||||||
| 		uart0: serial@20000000 { | 	}; | ||||||
| 			compatible = "ns16550a"; | 
 | ||||||
| 			reg = <0x0 0x20000000 0x0 0x400>; | 	udmabuf0 { | ||||||
| 			reg-io-width = <4>; | 		compatible = "ikwzm,u-dma-buf"; | ||||||
| 			reg-shift = <2>; | 		device-name = "udmabuf-ddr-c0"; | ||||||
| 			interrupt-parent = <&plic>; | 		minor-number = <0>; | ||||||
| 			interrupts = <90>; | 		size = <0x0 0x2000000>; | ||||||
| 			clocks = <&clkcfg CLK_MMUART0>; | 		memory-region = <&fabricbuf0>; | ||||||
|  | 		sync-mode = <3>; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	udmabuf1 { | ||||||
|  | 		compatible = "ikwzm,u-dma-buf"; | ||||||
|  | 		device-name = "udmabuf-ddr-nc0"; | ||||||
|  | 		minor-number = <1>; | ||||||
|  | 		size = <0x0 0x8000000>; | ||||||
|  | 		memory-region = <&fabricbuf1>; | ||||||
|  | 		sync-mode = <3>; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	udmabuf2 { | ||||||
|  | 		compatible = "ikwzm,u-dma-buf"; | ||||||
|  | 		device-name = "udmabuf-ddr-nc-wcb0"; | ||||||
|  | 		minor-number = <2>; | ||||||
|  | 		size = <0x0 0x8000000>; | ||||||
|  | 		memory-region = <&fabricbuf2>; | ||||||
|  | 		sync-mode = <3>; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	ddrc_cache_lo: memory@80000000 { | ||||||
|  | 		device_type = "memory"; | ||||||
|  | 		reg = <0x0 0x80000000 0x0 0x2e000000>; | ||||||
|  | 		clocks = <&clkcfg CLK_DDRC>; | ||||||
| 		status = "okay"; | 		status = "okay"; | ||||||
| 	}; | 	}; | ||||||
| 		clkcfg: clkcfg@20002000 { | 
 | ||||||
| 			compatible = "microchip,mpfs-clkcfg"; | 	ddrc_cache_hi: memory@1000000000 { | ||||||
| 			reg = <0x0 0x20002000 0x0 0x1000>; | 		device_type = "memory"; | ||||||
| 			reg-names = "mss_sysreg"; | 		reg = <0x10 0x0 0x0 0x40000000>; | ||||||
| 			clocks = <&refclk>; | 		clocks = <&clkcfg CLK_DDRC>; | ||||||
| 			#clock-cells = <1>; |  | ||||||
| 			clock-output-names = "cpu", "axi", "ahb", "envm", |  | ||||||
| 					"mac0", "mac1", "mmc", "timer", |  | ||||||
| 					"mmuart0", "mmuart1", "mmuart2", |  | ||||||
| 					"mmuart3", "mmuart4", "spi0", "spi1", |  | ||||||
| 					"i2c0",	"i2c1", "can0", "can1", "usb", |  | ||||||
| 					"reserved", "rtc", "qspi", "gpio0", |  | ||||||
| 					"gpio1", "gpio2", "ddrc", "fic0", |  | ||||||
| 					"fic1", "fic2", "fic3", "athena", |  | ||||||
| 					"cfm"; |  | ||||||
| 		}; |  | ||||||
| 		emmc: mmc@20008000 { |  | ||||||
| 			compatible = "cdns,sd4hc"; |  | ||||||
| 			reg = <0x0 0x20008000 0x0 0x1000>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <88 89>; |  | ||||||
| 			pinctrl-names = "default"; |  | ||||||
| 			clocks = <&clkcfg CLK_MMC>; |  | ||||||
| 			bus-width = <4>; |  | ||||||
| 			cap-mmc-highspeed; |  | ||||||
| 			mmc-ddr-3_3v; |  | ||||||
| 			max-frequency = <200000000>; |  | ||||||
| 			non-removable; |  | ||||||
| 			no-sd; |  | ||||||
| 			no-sdio; |  | ||||||
| 			voltage-ranges = <3300 3300>; |  | ||||||
| 		status = "okay"; | 		status = "okay"; | ||||||
| 	}; | 	}; | ||||||
| 		sdcard: sd@20008000 { | }; | ||||||
| 			compatible = "cdns,sd4hc"; | 
 | ||||||
| 			reg = <0x0 0x20008000 0x0 0x1000>; | &uart1 { | ||||||
| 			interrupt-parent = <&plic>; | 	status = "okay"; | ||||||
| 			interrupts = <88>; | }; | ||||||
| 			pinctrl-names = "default"; | 
 | ||||||
| 			clocks = <&clkcfg CLK_MMC>; | &mmc { | ||||||
|  | 	status = "okay"; | ||||||
|  | 
 | ||||||
| 	bus-width = <4>; | 	bus-width = <4>; | ||||||
| 	disable-wp; | 	disable-wp; | ||||||
|  | 	cap-mmc-highspeed; | ||||||
| 	cap-sd-highspeed; | 	cap-sd-highspeed; | ||||||
| 	card-detect-delay = <200>; | 	card-detect-delay = <200>; | ||||||
|  | 	mmc-ddr-1_8v; | ||||||
|  | 	mmc-hs200-1_8v; | ||||||
| 	sd-uhs-sdr12; | 	sd-uhs-sdr12; | ||||||
| 	sd-uhs-sdr25; | 	sd-uhs-sdr25; | ||||||
| 	sd-uhs-sdr50; | 	sd-uhs-sdr50; | ||||||
| 	sd-uhs-sdr104; | 	sd-uhs-sdr104; | ||||||
| 			max-frequency = <200000000>; | }; | ||||||
| 			status = "disabled"; | 
 | ||||||
| 		}; | &i2c1 { | ||||||
| 		uart1: serial@20100000 { |  | ||||||
| 			compatible = "ns16550a"; |  | ||||||
| 			reg = <0x0 0x20100000 0x0 0x400>; |  | ||||||
| 			reg-io-width = <4>; |  | ||||||
| 			reg-shift = <2>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <91>; |  | ||||||
| 			clocks = <&clkcfg CLK_MMUART1>; |  | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| 		}; | 	clock-frequency = <100000>; | ||||||
| 		uart2: serial@20102000 { | 
 | ||||||
| 			compatible = "ns16550a"; | 	pac193x: pac193x@10 { | ||||||
| 			reg = <0x0 0x20102000 0x0 0x400>; |  | ||||||
| 			reg-io-width = <4>; |  | ||||||
| 			reg-shift = <2>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <92>; |  | ||||||
| 			clocks = <&clkcfg CLK_MMUART2>; |  | ||||||
| 			status = "okay"; |  | ||||||
| 		}; |  | ||||||
| 		uart3: serial@20104000 { |  | ||||||
| 			compatible = "ns16550a"; |  | ||||||
| 			reg = <0x0 0x20104000 0x0 0x400>; |  | ||||||
| 			reg-io-width = <4>; |  | ||||||
| 			reg-shift = <2>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <93>; |  | ||||||
| 			clocks = <&clkcfg CLK_MMUART3>; |  | ||||||
| 			status = "okay"; |  | ||||||
| 		}; |  | ||||||
| 		i2c0: i2c@2010a000 { |  | ||||||
| 			#address-cells = <1>; |  | ||||||
| 			#size-cells = <0>; |  | ||||||
| 			compatible = "microchip,mpfs-mss-i2c"; |  | ||||||
| 			reg = <0x0 0x2010a000 0x0 0x1000>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <58>; |  | ||||||
| 			clocks = <&clkcfg CLK_I2C0>; |  | ||||||
| 			status = "disabled"; |  | ||||||
| 		}; |  | ||||||
| 		i2c1: i2c@2010b000 { |  | ||||||
| 			#address-cells = <1>; |  | ||||||
| 			#size-cells = <0>; |  | ||||||
| 			compatible = "microchip,mpfs-mss-i2c"; |  | ||||||
| 			reg = <0x0 0x2010b000 0x0 0x1000>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <61>; |  | ||||||
| 			clocks = <&clkcfg CLK_I2C1>; |  | ||||||
| 			status = "disabled"; |  | ||||||
| 			pac193x@10 { |  | ||||||
| 		compatible = "microchip,pac1934"; | 		compatible = "microchip,pac1934"; | ||||||
| 		reg = <0x10>; | 		reg = <0x10>; | ||||||
| 		samp-rate = <64>; | 		samp-rate = <64>; | ||||||
| 				status = "disabled"; | 		status = "okay"; | ||||||
| 		ch1: channel0 { | 		ch1: channel0 { | ||||||
| 			uohms-shunt-res = <10000>; | 			uohms-shunt-res = <10000>; | ||||||
| 					rail-name = "VDD"; | 			rail-name = "VDDREG"; | ||||||
| 			channel_enabled; | 			channel_enabled; | ||||||
| 		}; | 		}; | ||||||
| 		ch2: channel1 { | 		ch2: channel1 { | ||||||
|  | @ -357,61 +140,18 @@ | ||||||
| 		}; | 		}; | ||||||
| 		ch4: channel3 { | 		ch4: channel3 { | ||||||
| 			uohms-shunt-res = <10000>; | 			uohms-shunt-res = <10000>; | ||||||
| 					rail-name = "VDDA"; | 			rail-name = "VDDA_REG"; | ||||||
| 			channel_enabled; | 			channel_enabled; | ||||||
| 		}; | 		}; | ||||||
| 	}; | 	}; | ||||||
| 		}; | }; | ||||||
| 		emac0: ethernet@20110000 { |  | ||||||
| 			compatible = "microchip,mpfs-mss-gem"; |  | ||||||
| 			reg = <0x0 0x20110000 0x0 0x2000>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <64 65 66 67>; |  | ||||||
| 			local-mac-address = [56 34 00 FC 00 02]; |  | ||||||
| 			phy-mode = "sgmii"; |  | ||||||
| 			clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AXI>; |  | ||||||
| 			clock-names = "pclk", "hclk"; |  | ||||||
| 			status = "disabled"; |  | ||||||
| 
 | 
 | ||||||
| 			#address-cells = <1>; | &mac1 { | ||||||
| 			#size-cells = <0>; |  | ||||||
| 			phy-handle = <&phy0>; |  | ||||||
| 			phy0: ethernet-phy@8 { |  | ||||||
| 				reg = <8>; |  | ||||||
| 				ti,fifo-depth = <0x01>; |  | ||||||
| 			}; |  | ||||||
| 		}; |  | ||||||
| 		emac1: ethernet@20112000 { |  | ||||||
| 			compatible = "microchip,mpfs-mss-gem"; |  | ||||||
| 			reg = <0x0 0x20112000 0x0 0x2000>; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <70 71 72 73>; |  | ||||||
| 			local-mac-address = [00 00 00 00 00 00]; |  | ||||||
| 			phy-mode = "sgmii"; |  | ||||||
| 			clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>; |  | ||||||
| 			clock-names = "pclk", "hclk"; |  | ||||||
| 	status = "okay"; | 	status = "okay"; | ||||||
| 
 | 	phy-mode = "sgmii"; | ||||||
| 			#address-cells = <1>; |  | ||||||
| 			#size-cells = <0>; |  | ||||||
| 	phy-handle = <&phy1>; | 	phy-handle = <&phy1>; | ||||||
| 	phy1: ethernet-phy@9 { | 	phy1: ethernet-phy@9 { | ||||||
| 		reg = <9>; | 		reg = <9>; | ||||||
| 				ti,fifo-depth = <0x01>; | 		ti,fifo-depth = <0x1>; | ||||||
| 			}; |  | ||||||
| 		}; |  | ||||||
| 		gpio: gpio@20122000 { |  | ||||||
| 			compatible = "microchip,mpfs-mss-gpio"; |  | ||||||
| 			interrupt-parent = <&plic>; |  | ||||||
| 			interrupts = <13 14 15 16 17 18 19 20 21 22 23 24 25 26 |  | ||||||
| 					27 28 29 30 31 32 33 34 35 36 37 38 39 |  | ||||||
| 					40 41 42 43 44>; |  | ||||||
| 			gpio-controller; |  | ||||||
| 			clocks = <&clkcfg CLK_GPIO2>; |  | ||||||
| 			reg = <0x00 0x20122000 0x0 0x1000>; |  | ||||||
| 			reg-names = "control"; |  | ||||||
| 			#gpio-cells = <2>; |  | ||||||
| 			status = "disabled"; |  | ||||||
| 		}; |  | ||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,571 @@ | ||||||
|  | // SPDX-License-Identifier: (GPL-2.0+ OR MIT) | ||||||
|  | /* Copyright (c) 2020-2021 Microchip Technology Inc */ | ||||||
|  | 
 | ||||||
|  | #include "dt-bindings/clock/microchip-mpfs-clock.h" | ||||||
|  | #include "dt-bindings/interrupt-controller/microchip-mpfs-plic.h" | ||||||
|  | #include "dt-bindings/interrupt-controller/riscv-hart.h" | ||||||
|  | 
 | ||||||
|  | / { | ||||||
|  | 	#address-cells = <2>; | ||||||
|  | 	#size-cells = <2>; | ||||||
|  | 	model = "Microchip PolarFire SoC"; | ||||||
|  | 	compatible = "microchip,mpfs"; | ||||||
|  | 
 | ||||||
|  | 	chosen { | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	cpus { | ||||||
|  | 		#address-cells = <1>; | ||||||
|  | 		#size-cells = <0>; | ||||||
|  | 
 | ||||||
|  | 		cpu0: cpu@0 { | ||||||
|  | 			compatible = "sifive,e51", "sifive,rocket0", "riscv"; | ||||||
|  | 			device_type = "cpu"; | ||||||
|  | 			i-cache-block-size = <64>; | ||||||
|  | 			i-cache-sets = <128>; | ||||||
|  | 			i-cache-size = <16384>; | ||||||
|  | 			reg = <0>; | ||||||
|  | 			riscv,isa = "rv64imac"; | ||||||
|  | 			clocks = <&clkcfg CLK_CPU>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 			operating-points = < | ||||||
|  | 				/* kHz	uV */ | ||||||
|  | 				600000  1100000 | ||||||
|  | 				300000   950000 | ||||||
|  | 				150000   750000 | ||||||
|  | 			>; | ||||||
|  | 			cpu0_intc: interrupt-controller { | ||||||
|  | 				#interrupt-cells = <1>; | ||||||
|  | 				compatible = "riscv,cpu-intc"; | ||||||
|  | 				interrupt-controller; | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		cpu1: cpu@1 { | ||||||
|  | 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; | ||||||
|  | 			d-cache-block-size = <64>; | ||||||
|  | 			d-cache-sets = <64>; | ||||||
|  | 			d-cache-size = <32768>; | ||||||
|  | 			d-tlb-sets = <1>; | ||||||
|  | 			d-tlb-size = <32>; | ||||||
|  | 			device_type = "cpu"; | ||||||
|  | 			i-cache-block-size = <64>; | ||||||
|  | 			i-cache-sets = <64>; | ||||||
|  | 			i-cache-size = <32768>; | ||||||
|  | 			i-tlb-sets = <1>; | ||||||
|  | 			i-tlb-size = <32>; | ||||||
|  | 			mmu-type = "riscv,sv39"; | ||||||
|  | 			reg = <1>; | ||||||
|  | 			riscv,isa = "rv64imafdc"; | ||||||
|  | 			clocks = <&clkcfg CLK_CPU>; | ||||||
|  | 			tlb-split; | ||||||
|  | 			status = "okay"; | ||||||
|  | 			operating-points = < | ||||||
|  | 				/* kHz	uV */ | ||||||
|  | 				600000  1100000 | ||||||
|  | 				300000   950000 | ||||||
|  | 				150000   750000 | ||||||
|  | 			>; | ||||||
|  | 			cpu1_intc: interrupt-controller { | ||||||
|  | 				#interrupt-cells = <1>; | ||||||
|  | 				compatible = "riscv,cpu-intc"; | ||||||
|  | 				interrupt-controller; | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		cpu2: cpu@2 { | ||||||
|  | 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; | ||||||
|  | 			d-cache-block-size = <64>; | ||||||
|  | 			d-cache-sets = <64>; | ||||||
|  | 			d-cache-size = <32768>; | ||||||
|  | 			d-tlb-sets = <1>; | ||||||
|  | 			d-tlb-size = <32>; | ||||||
|  | 			device_type = "cpu"; | ||||||
|  | 			i-cache-block-size = <64>; | ||||||
|  | 			i-cache-sets = <64>; | ||||||
|  | 			i-cache-size = <32768>; | ||||||
|  | 			i-tlb-sets = <1>; | ||||||
|  | 			i-tlb-size = <32>; | ||||||
|  | 			mmu-type = "riscv,sv39"; | ||||||
|  | 			reg = <2>; | ||||||
|  | 			riscv,isa = "rv64imafdc"; | ||||||
|  | 			clocks = <&clkcfg CLK_CPU>; | ||||||
|  | 			tlb-split; | ||||||
|  | 			status = "okay"; | ||||||
|  | 			operating-points = < | ||||||
|  | 				/* kHz	uV */ | ||||||
|  | 				600000  1100000 | ||||||
|  | 				300000   950000 | ||||||
|  | 				150000   750000 | ||||||
|  | 			>; | ||||||
|  | 			cpu2_intc: interrupt-controller { | ||||||
|  | 				#interrupt-cells = <1>; | ||||||
|  | 				compatible = "riscv,cpu-intc"; | ||||||
|  | 				interrupt-controller; | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		cpu3: cpu@3 { | ||||||
|  | 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; | ||||||
|  | 			d-cache-block-size = <64>; | ||||||
|  | 			d-cache-sets = <64>; | ||||||
|  | 			d-cache-size = <32768>; | ||||||
|  | 			d-tlb-sets = <1>; | ||||||
|  | 			d-tlb-size = <32>; | ||||||
|  | 			device_type = "cpu"; | ||||||
|  | 			i-cache-block-size = <64>; | ||||||
|  | 			i-cache-sets = <64>; | ||||||
|  | 			i-cache-size = <32768>; | ||||||
|  | 			i-tlb-sets = <1>; | ||||||
|  | 			i-tlb-size = <32>; | ||||||
|  | 			mmu-type = "riscv,sv39"; | ||||||
|  | 			reg = <3>; | ||||||
|  | 			riscv,isa = "rv64imafdc"; | ||||||
|  | 			clocks = <&clkcfg CLK_CPU>; | ||||||
|  | 			tlb-split; | ||||||
|  | 			status = "okay"; | ||||||
|  | 			operating-points = < | ||||||
|  | 				/* kHz	uV */ | ||||||
|  | 				600000  1100000 | ||||||
|  | 				300000   950000 | ||||||
|  | 				150000   750000 | ||||||
|  | 			>; | ||||||
|  | 			cpu3_intc: interrupt-controller { | ||||||
|  | 				#interrupt-cells = <1>; | ||||||
|  | 				compatible = "riscv,cpu-intc"; | ||||||
|  | 				interrupt-controller; | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		cpu4: cpu@4 { | ||||||
|  | 			compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; | ||||||
|  | 			d-cache-block-size = <64>; | ||||||
|  | 			d-cache-sets = <64>; | ||||||
|  | 			d-cache-size = <32768>; | ||||||
|  | 			d-tlb-sets = <1>; | ||||||
|  | 			d-tlb-size = <32>; | ||||||
|  | 			device_type = "cpu"; | ||||||
|  | 			i-cache-block-size = <64>; | ||||||
|  | 			i-cache-sets = <64>; | ||||||
|  | 			i-cache-size = <32768>; | ||||||
|  | 			i-tlb-sets = <1>; | ||||||
|  | 			i-tlb-size = <32>; | ||||||
|  | 			mmu-type = "riscv,sv39"; | ||||||
|  | 			reg = <4>; | ||||||
|  | 			riscv,isa = "rv64imafdc"; | ||||||
|  | 			clocks = <&clkcfg CLK_CPU>; | ||||||
|  | 			tlb-split; | ||||||
|  | 			status = "okay"; | ||||||
|  | 			operating-points = < | ||||||
|  | 				/* kHz	uV */ | ||||||
|  | 				600000  1100000 | ||||||
|  | 				300000   950000 | ||||||
|  | 				150000   750000 | ||||||
|  | 			>; | ||||||
|  | 			cpu4_intc: interrupt-controller { | ||||||
|  | 				#interrupt-cells = <1>; | ||||||
|  | 				compatible = "riscv,cpu-intc"; | ||||||
|  | 				interrupt-controller; | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	soc { | ||||||
|  | 		#address-cells = <2>; | ||||||
|  | 		#size-cells = <2>; | ||||||
|  | 		compatible = "microchip,mpfs-soc", "simple-bus"; | ||||||
|  | 		ranges; | ||||||
|  | 
 | ||||||
|  | 		clint: clint@2000000 { | ||||||
|  | 			compatible = "sifive,clint0"; | ||||||
|  | 			reg = <0x0 0x2000000 0x0 0xC000>; | ||||||
|  | 			interrupts-extended = | ||||||
|  | 					<&cpu0_intc HART_INT_M_SOFT &cpu0_intc HART_INT_M_TIMER | ||||||
|  | 					 &cpu1_intc HART_INT_M_SOFT &cpu1_intc HART_INT_M_TIMER | ||||||
|  | 					 &cpu2_intc HART_INT_M_SOFT &cpu2_intc HART_INT_M_TIMER | ||||||
|  | 					 &cpu3_intc HART_INT_M_SOFT &cpu3_intc HART_INT_M_TIMER | ||||||
|  | 					 &cpu4_intc HART_INT_M_SOFT &cpu4_intc HART_INT_M_TIMER>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		cachecontroller: cache-controller@2010000 { | ||||||
|  | 			compatible = "sifive,fu540-c000-ccache", "cache"; | ||||||
|  | 			reg = <0x0 0x2010000 0x0 0x1000>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_L2_METADATA_CORR | ||||||
|  | 				PLIC_INT_L2_METADATA_UNCORR | ||||||
|  | 				PLIC_INT_L2_DATA_CORR>; | ||||||
|  | 			cache-block-size = <64>; | ||||||
|  | 			cache-level = <2>; | ||||||
|  | 			cache-sets = <1024>; | ||||||
|  | 			cache-size = <2097152>; | ||||||
|  | 			cache-unified; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		pdma: pdma@3000000 { | ||||||
|  | 			compatible = "microchip,mpfs-pdma-uio","sifive,fu540-c000-pdma"; | ||||||
|  | 			reg = <0x0 0x3000000 0x0 0x8000>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_DMA_CH0_DONE PLIC_INT_DMA_CH0_ERR | ||||||
|  | 				PLIC_INT_DMA_CH1_DONE PLIC_INT_DMA_CH1_ERR | ||||||
|  | 				PLIC_INT_DMA_CH2_DONE PLIC_INT_DMA_CH2_ERR | ||||||
|  | 				PLIC_INT_DMA_CH3_DONE PLIC_INT_DMA_CH3_ERR>; | ||||||
|  | 			#dma-cells = <1>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		plic: interrupt-controller@c000000 { | ||||||
|  | 			compatible = "sifive,plic-1.0.0"; | ||||||
|  | 			reg = <0x0 0xc000000 0x0 0x4000000>; | ||||||
|  | 			#interrupt-cells = <1>; | ||||||
|  | 			riscv,ndev = <186>; | ||||||
|  | 			interrupt-controller; | ||||||
|  | 			interrupts-extended = <&cpu0_intc HART_INT_M_EXT | ||||||
|  | 					&cpu1_intc HART_INT_M_EXT &cpu1_intc HART_INT_S_EXT | ||||||
|  | 					&cpu2_intc HART_INT_M_EXT &cpu2_intc HART_INT_S_EXT | ||||||
|  | 					&cpu3_intc HART_INT_M_EXT &cpu3_intc HART_INT_S_EXT | ||||||
|  | 					&cpu4_intc HART_INT_M_EXT &cpu4_intc HART_INT_S_EXT>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		refclk: refclk { | ||||||
|  | 			compatible = "fixed-clock"; | ||||||
|  | 			#clock-cells = <0>; | ||||||
|  | 			clock-frequency = <600000000>; | ||||||
|  | 			clock-output-names = "msspllclk"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		clkcfg: clkcfg@20002000 { | ||||||
|  | 			compatible = "microchip,mpfs-clkcfg"; | ||||||
|  | 			reg = <0x0 0x20002000 0x0 0x1000>; | ||||||
|  | 			reg-names = "mss_sysreg"; | ||||||
|  | 			clocks = <&refclk>; | ||||||
|  | 			#clock-cells = <1>; | ||||||
|  | 			clock-output-names = "cpu", "axi", "ahb", "envm",	/* 0-3   */ | ||||||
|  | 				"mac0", "mac1", "mmc", "timer",				/* 4-7   */ | ||||||
|  | 				"mmuart0", "mmuart1", "mmuart2", "mmuart3",	/* 8-11  */ | ||||||
|  | 				"mmuart4", "spi0", "spi1", "i2c0",			/* 12-15 */ | ||||||
|  | 				"i2c1", "can0", "can1", "usb",				/* 16-19 */ | ||||||
|  | 				"rsvd", "rtc", "qspi", "gpio0",				/* 20-23 */ | ||||||
|  | 				"gpio1", "gpio2", "ddrc", "fic0",			/* 24-27 */ | ||||||
|  | 				"fic1", "fic2", "fic3", "athena", "cfm";	/* 28-32 */ | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		/* Common node entry for eMMC/SD */ | ||||||
|  | 		mmc: mmc@20008000 { | ||||||
|  | 			compatible = "microchip,mpfs-sd4hc","cdns,sd4hc"; | ||||||
|  | 			reg = <0x0 0x20008000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_MMC>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MMC_MAIN PLIC_INT_MMC_WAKEUP>; | ||||||
|  | 			max-frequency = <200000000>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		uart0: serial@20000000 { | ||||||
|  | 			compatible = "ns16550a"; | ||||||
|  | 			reg = <0x0 0x20000000 0x0 0x400>; | ||||||
|  | 			reg-io-width = <4>; | ||||||
|  | 			reg-shift = <2>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MMUART0>; | ||||||
|  | 			clocks = <&clkcfg CLK_MMUART0>; | ||||||
|  | 			status = "disabled"; /* Reserved for the HSS */ | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		uart1: serial@20100000 { | ||||||
|  | 			compatible = "ns16550a"; | ||||||
|  | 			reg = <0x0 0x20100000 0x0 0x400>; | ||||||
|  | 			reg-io-width = <4>; | ||||||
|  | 			reg-shift = <2>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MMUART1>; | ||||||
|  | 			clocks = <&clkcfg CLK_MMUART1>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		uart2: serial@20102000 { | ||||||
|  | 			compatible = "ns16550a"; | ||||||
|  | 			reg = <0x0 0x20102000 0x0 0x400>; | ||||||
|  | 			reg-io-width = <4>; | ||||||
|  | 			reg-shift = <2>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MMUART2>; | ||||||
|  | 			clocks = <&clkcfg CLK_MMUART2>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		uart3: serial@20104000 { | ||||||
|  | 			compatible = "ns16550a"; | ||||||
|  | 			reg = <0x0 0x20104000 0x0 0x400>; | ||||||
|  | 			reg-io-width = <4>; | ||||||
|  | 			reg-shift = <2>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MMUART3>; | ||||||
|  | 			clocks = <&clkcfg CLK_MMUART3>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		uart4: serial@20106000 { | ||||||
|  | 			compatible = "ns16550a"; | ||||||
|  | 			reg = <0x0 0x20106000 0x0 0x400>; | ||||||
|  | 			reg-io-width = <4>; | ||||||
|  | 			reg-shift = <2>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MMUART4>; | ||||||
|  | 			clocks = <&clkcfg CLK_MMUART4>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		spi0: spi@20108000 { | ||||||
|  | 			compatible = "microchip,mpfs-spi"; | ||||||
|  | 			reg = <0x0 0x20108000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_SPI0>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_SPI0>; | ||||||
|  | 			num-cs = <8>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		spi1: spi@20109000 { | ||||||
|  | 			compatible = "microchip,mpfs-spi"; | ||||||
|  | 			reg = <0x0 0x20109000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_SPI1>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_SPI1>; | ||||||
|  | 			num-cs = <8>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		i2c0: i2c@2010a000 { | ||||||
|  | 			compatible = "microchip,mpfs-i2c"; | ||||||
|  | 			reg = <0x0 0x2010a000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_I2C0>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_I2C0_MAIN>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		i2c1: i2c@2010b000 { | ||||||
|  | 			compatible = "microchip,mpfs-i2c"; | ||||||
|  | 			reg = <0x0 0x2010b000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_I2C1>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_I2C1_MAIN>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		can0: can@2010c000 { | ||||||
|  | 			compatible = "microchip,mpfs-can-uio"; | ||||||
|  | 			reg = <0x0 0x2010c000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_CAN0>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_CAN0>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		can1: can@2010d000 { | ||||||
|  | 			compatible = "microchip,mpfs-can-uio"; | ||||||
|  | 			reg = <0x0 0x2010d000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_CAN1>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_CAN1>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		mac0: ethernet@20110000 { | ||||||
|  | 			compatible = "cdns,macb"; | ||||||
|  | 			reg = <0x0 0x20110000 0x0 0x2000>; | ||||||
|  | 			clocks = <&clkcfg CLK_MAC0>, <&clkcfg CLK_AHB>; | ||||||
|  | 			clock-names = "pclk", "hclk"; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MAC0_INT | ||||||
|  | 				PLIC_INT_MAC0_QUEUE1 | ||||||
|  | 				PLIC_INT_MAC0_QUEUE2 | ||||||
|  | 				PLIC_INT_MAC0_QUEUE3 | ||||||
|  | 				PLIC_INT_MAC0_EMAC | ||||||
|  | 				PLIC_INT_MAC0_MMSL>; | ||||||
|  | 			local-mac-address = [00 00 00 00 00 00]; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		mac1: ethernet@20112000 { | ||||||
|  | 			compatible = "cdns,macb"; | ||||||
|  | 			reg = <0x0 0x20112000 0x0 0x2000>; | ||||||
|  | 			clocks = <&clkcfg CLK_MAC1>, <&clkcfg CLK_AHB>; | ||||||
|  | 			clock-names = "pclk", "hclk"; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_MAC1_INT | ||||||
|  | 				PLIC_INT_MAC1_QUEUE1 | ||||||
|  | 				PLIC_INT_MAC1_QUEUE2 | ||||||
|  | 				PLIC_INT_MAC1_QUEUE3 | ||||||
|  | 				PLIC_INT_MAC1_EMAC | ||||||
|  | 				PLIC_INT_MAC1_MMSL>; | ||||||
|  | 			local-mac-address = [00 00 00 00 00 00]; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		gpio0: gpio@20120000 { | ||||||
|  | 			compatible = "microchip,mpfs-gpio"; | ||||||
|  | 			reg = <0x0 0x20120000 0x0 0x1000>; | ||||||
|  | 			reg-names = "control"; | ||||||
|  | 			clocks = <&clkcfg CLK_GPIO0>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			gpio-controller; | ||||||
|  | 			#gpio-cells = <2>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		gpio1: gpio@20121000 { | ||||||
|  | 			compatible = "microchip,mpfs-gpio"; | ||||||
|  | 			reg = <000 0x20121000 0x0 0x1000>; | ||||||
|  | 			reg-names = "control"; | ||||||
|  | 			clocks = <&clkcfg CLK_GPIO1>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			gpio-controller; | ||||||
|  | 			#gpio-cells = <2>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		gpio2: gpio@20122000 { | ||||||
|  | 			compatible = "microchip,mpfs-gpio"; | ||||||
|  | 			reg = <0x0 0x20122000 0x0 0x1000>; | ||||||
|  | 			reg-names = "control"; | ||||||
|  | 			clocks = <&clkcfg CLK_GPIO2>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			gpio-controller; | ||||||
|  | 			#gpio-cells = <2>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		rtc: rtc@20124000 { | ||||||
|  | 			compatible = "microchip,mpfs-rtc"; | ||||||
|  | 			reg = <0x0 0x20124000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_RTC>; | ||||||
|  | 			clock-names = "rtc"; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_RTC_WAKEUP PLIC_INT_RTC_MATCH>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		usb: usb@20201000 { | ||||||
|  | 			compatible = "microchip,mpfs-usb-host"; | ||||||
|  | 			reg = <0x0 0x20201000 0x0 0x1000>; | ||||||
|  | 			reg-names = "mc","control"; | ||||||
|  | 			clocks = <&clkcfg CLK_USB>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_USB_DMA PLIC_INT_USB_MC>; | ||||||
|  | 			interrupt-names = "dma","mc"; | ||||||
|  | 			dr_mode = "host"; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		qspi: qspi@21000000 { | ||||||
|  | 			compatible = "microchip,mpfs-qspi"; | ||||||
|  | 			reg = <0x0 0x21000000 0x0 0x1000>; | ||||||
|  | 			clocks = <&clkcfg CLK_QSPI>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_QSPI>; | ||||||
|  | 			num-cs = <8>; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		mbox: mailbox@37020000 { | ||||||
|  | 			compatible = "microchip,mpfs-mailbox"; | ||||||
|  | 			reg = <0x0 0x37020000 0x0 0x1000>, <0x0 0x2000318C 0x0 0x40>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_G5C_MESSAGE>; | ||||||
|  | 			#mbox-cells = <1>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		pcie: pcie@2000000000 { | ||||||
|  | 			compatible = "microchip,pcie-host-1.0"; | ||||||
|  | 			#address-cells = <0x3>; | ||||||
|  | 			#interrupt-cells = <0x1>; | ||||||
|  | 			#size-cells = <0x2>; | ||||||
|  | 			device_type = "pci"; | ||||||
|  | 			reg = <0x20 0x0 0x0 0x8000000 0x0 0x43000000 0x0 0x10000>; | ||||||
|  | 			reg-names = "cfg", "apb"; | ||||||
|  | 			clocks = <&clkcfg CLK_FIC0>, <&clkcfg CLK_FIC1>, <&clkcfg CLK_FIC3>; | ||||||
|  | 			clock-names = "fic0", "fic1", "fic3"; | ||||||
|  | 			bus-range = <0x0 0x7f>; | ||||||
|  | 			interrupt-parent = <&plic>; | ||||||
|  | 			interrupts = <PLIC_INT_FABRIC_F2H_2>; | ||||||
|  | 			interrupt-map = <0 0 0 1 &pcie_intc 0>, | ||||||
|  | 					<0 0 0 2 &pcie_intc 1>, | ||||||
|  | 					<0 0 0 3 &pcie_intc 2>, | ||||||
|  | 					<0 0 0 4 &pcie_intc 3>; | ||||||
|  | 			interrupt-map-mask = <0 0 0 7>; | ||||||
|  | 			ranges = <0x3000000 0x0 0x8000000 0x20 0x8000000 0x0 0x80000000>; | ||||||
|  | 			msi-parent = <&pcie>; | ||||||
|  | 			msi-controller; | ||||||
|  | 			mchp,axi-m-atr0 = <0x10 0x0>; | ||||||
|  | 			status = "disabled"; | ||||||
|  | 			pcie_intc: legacy-interrupt-controller { | ||||||
|  | 				#address-cells = <0>; | ||||||
|  | 				#interrupt-cells = <1>; | ||||||
|  | 				interrupt-controller; | ||||||
|  | 			}; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		syscontroller: syscontroller { | ||||||
|  | 			compatible = "microchip,mpfs-sys-controller"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <1>; | ||||||
|  | 			mboxes = <&mbox 0>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		hwrandom: hwrandom { | ||||||
|  | 			compatible = "microchip,mpfs-rng"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <1>; | ||||||
|  | 			syscontroller = <&syscontroller>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		serialnum: serialnum { | ||||||
|  | 			compatible = "microchip,mpfs-serial-number"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <1>; | ||||||
|  | 			syscontroller = <&syscontroller>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		fpgadigest: fpgadigest { | ||||||
|  | 			compatible = "microchip,mpfs-digest"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <1>; | ||||||
|  | 			syscontroller = <&syscontroller>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		devicecert: cert { | ||||||
|  | 			compatible = "microchip,mpfs-device-cert"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <1>; | ||||||
|  | 			syscontroller = <&syscontroller>; | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		signature: signature { | ||||||
|  | 			compatible = "microchip,mpfs-signature"; | ||||||
|  | 			#address-cells = <1>; | ||||||
|  | 			#size-cells = <1>; | ||||||
|  | 			syscontroller = <&syscontroller>; | ||||||
|  | 		}; | ||||||
|  | 	}; | ||||||
|  | }; | ||||||
|  | @ -499,6 +499,10 @@ | ||||||
| 		compatible = "sandbox,clk-ccf"; | 		compatible = "sandbox,clk-ccf"; | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
|  | 	efi-media { | ||||||
|  | 		compatible = "sandbox,efi-media"; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
| 	eth@10002000 { | 	eth@10002000 { | ||||||
| 		compatible = "sandbox,eth"; | 		compatible = "sandbox,eth"; | ||||||
| 		reg = <0x10002000 0x1000>; | 		reg = <0x10002000 0x1000>; | ||||||
|  |  | ||||||
|  | @ -43,6 +43,23 @@ DECLARE_GLOBAL_DATA_PTR; | ||||||
| #define OMNIA_I2C_EEPROM_CHIP_LEN	2 | #define OMNIA_I2C_EEPROM_CHIP_LEN	2 | ||||||
| #define OMNIA_I2C_EEPROM_MAGIC		0x0341a034 | #define OMNIA_I2C_EEPROM_MAGIC		0x0341a034 | ||||||
| 
 | 
 | ||||||
|  | #define SYS_RSTOUT_MASK			MVEBU_REGISTER(0x18260) | ||||||
|  | #define   SYS_RSTOUT_MASK_WD		BIT(10) | ||||||
|  | 
 | ||||||
|  | #define A385_WDT_GLOBAL_CTRL		MVEBU_REGISTER(0x20300) | ||||||
|  | #define   A385_WDT_GLOBAL_RATIO_MASK	GENMASK(18, 16) | ||||||
|  | #define   A385_WDT_GLOBAL_RATIO_SHIFT	16 | ||||||
|  | #define   A385_WDT_GLOBAL_25MHZ		BIT(10) | ||||||
|  | #define   A385_WDT_GLOBAL_ENABLE	BIT(8) | ||||||
|  | 
 | ||||||
|  | #define A385_WDT_GLOBAL_STATUS		MVEBU_REGISTER(0x20304) | ||||||
|  | #define   A385_WDT_GLOBAL_EXPIRED	BIT(31) | ||||||
|  | 
 | ||||||
|  | #define A385_WDT_DURATION		MVEBU_REGISTER(0x20334) | ||||||
|  | 
 | ||||||
|  | #define A385_WD_RSTOUT_UNMASK		MVEBU_REGISTER(0x20704) | ||||||
|  | #define   A385_WD_RSTOUT_UNMASK_GLOBAL	BIT(8) | ||||||
|  | 
 | ||||||
| enum mcu_commands { | enum mcu_commands { | ||||||
| 	CMD_GET_STATUS_WORD	= 0x01, | 	CMD_GET_STATUS_WORD	= 0x01, | ||||||
| 	CMD_GET_RESET		= 0x09, | 	CMD_GET_RESET		= 0x09, | ||||||
|  | @ -141,6 +158,47 @@ static int omnia_mcu_write(u8 cmd, const void *buf, int len) | ||||||
| 	return dm_i2c_write(chip, cmd, buf, len); | 	return dm_i2c_write(chip, cmd, buf, len); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void enable_a385_watchdog(unsigned int timeout_minutes) | ||||||
|  | { | ||||||
|  | 	struct sar_freq_modes sar_freq; | ||||||
|  | 	u32 watchdog_freq; | ||||||
|  | 
 | ||||||
|  | 	printf("Enabling A385 watchdog with %u minutes timeout...\n", | ||||||
|  | 	       timeout_minutes); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Use NBCLK clock (a.k.a. L2 clock) as watchdog input clock with | ||||||
|  | 	 * its maximal ratio 7 instead of default fixed 25 MHz clock. | ||||||
|  | 	 * It allows to set watchdog duration up to the 22 minutes. | ||||||
|  | 	 */ | ||||||
|  | 	clrsetbits_32(A385_WDT_GLOBAL_CTRL, | ||||||
|  | 		      A385_WDT_GLOBAL_25MHZ | A385_WDT_GLOBAL_RATIO_MASK, | ||||||
|  | 		      7 << A385_WDT_GLOBAL_RATIO_SHIFT); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Calculate watchdog clock frequency. It is defined by formula: | ||||||
|  | 	 *   freq = NBCLK / 2 / (2 ^ ratio) | ||||||
|  | 	 * We set ratio to the maximal possible value 7. | ||||||
|  | 	 */ | ||||||
|  | 	get_sar_freq(&sar_freq); | ||||||
|  | 	watchdog_freq = sar_freq.nb_clk * 1000000 / 2 / (1 << 7); | ||||||
|  | 
 | ||||||
|  | 	/* Set watchdog duration */ | ||||||
|  | 	writel(timeout_minutes * 60 * watchdog_freq, A385_WDT_DURATION); | ||||||
|  | 
 | ||||||
|  | 	/* Clear the watchdog expiration bit */ | ||||||
|  | 	clrbits_32(A385_WDT_GLOBAL_STATUS, A385_WDT_GLOBAL_EXPIRED); | ||||||
|  | 
 | ||||||
|  | 	/* Enable watchdog timer */ | ||||||
|  | 	setbits_32(A385_WDT_GLOBAL_CTRL, A385_WDT_GLOBAL_ENABLE); | ||||||
|  | 
 | ||||||
|  | 	/* Enable reset on watchdog */ | ||||||
|  | 	setbits_32(A385_WD_RSTOUT_UNMASK, A385_WD_RSTOUT_UNMASK_GLOBAL); | ||||||
|  | 
 | ||||||
|  | 	/* Unmask reset for watchdog */ | ||||||
|  | 	clrbits_32(SYS_RSTOUT_MASK, SYS_RSTOUT_MASK_WD); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static bool disable_mcu_watchdog(void) | static bool disable_mcu_watchdog(void) | ||||||
| { | { | ||||||
| 	int ret; | 	int ret; | ||||||
|  | @ -423,10 +481,13 @@ void spl_board_init(void) | ||||||
| { | { | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * If booting from UART, disable MCU watchdog in SPL, since uploading | 	 * If booting from UART, disable MCU watchdog in SPL, since uploading | ||||||
| 	 * U-Boot proper can take too much time and trigger it. | 	 * U-Boot proper can take too much time and trigger it. Instead enable | ||||||
|  | 	 * A385 watchdog with very high timeout (10 minutes) to prevent hangup. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (get_boot_device() == BOOT_DEVICE_UART) | 	if (get_boot_device() == BOOT_DEVICE_UART) { | ||||||
|  | 		enable_a385_watchdog(10); | ||||||
| 		disable_mcu_watchdog(); | 		disable_mcu_watchdog(); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int board_init(void) | int board_init(void) | ||||||
|  |  | ||||||
|  | @ -4,3 +4,13 @@ S:	Maintained | ||||||
| F:	board/beacon/beacon-rzg2m/ | F:	board/beacon/beacon-rzg2m/ | ||||||
| F:	include/configs/beacon-rzg2m.h | F:	include/configs/beacon-rzg2m.h | ||||||
| F:	configs/rzg2_beacon_defconfig | F:	configs/rzg2_beacon_defconfig | ||||||
|  | F:	arch/arm/dts/beacon-renesom-baseboard.dtsi | ||||||
|  | F:	arch/arm/dts/beacon-renesom-som.dtsi | ||||||
|  | F:	arch/arm/dts/r8a774a1-beacon-rzg2m-kit.dts | ||||||
|  | F:	arch/arm/dts/r8a774b1-beacon-rzg2n-kit.dts | ||||||
|  | F:	arch/arm/dts/r8a774e1-beacon-rzg2h-kit.dts | ||||||
|  | F:	arch/arm/dts/r8a774a1-beacon-rzg2m-kit-u-boot.dtsi | ||||||
|  | F:	arch/arm/dts/r8a774b1-beacon-rzg2n-kit-u-boot.dtsi | ||||||
|  | F:	arch/arm/dts/r8a774e1-beacon-rzg2h-kit-u-boot.dtsi | ||||||
|  | F:	arch/arm/dts/rz-g2-beacon-u-boot.dtsi | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -45,5 +45,10 @@ config BOARD_SPECIFIC_OPTIONS # dummy | ||||||
| 	imply MMC_WRITE | 	imply MMC_WRITE | ||||||
| 	imply MMC_SDHCI | 	imply MMC_SDHCI | ||||||
| 	imply MMC_SDHCI_CADENCE | 	imply MMC_SDHCI_CADENCE | ||||||
|  | 	imply MMC_SDHCI_ADMA | ||||||
|  | 	imply MMC_HS200_SUPPORT | ||||||
|  | 	imply CMD_I2C | ||||||
|  | 	imply DM_I2C | ||||||
|  | 	imply SYS_I2C_MICROCHIP | ||||||
| 
 | 
 | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | @ -119,7 +119,22 @@ int board_late_init(void) | ||||||
| 		if (icicle_mac_addr[idx] == ':') | 		if (icicle_mac_addr[idx] == ':') | ||||||
| 			icicle_mac_addr[idx] = ' '; | 			icicle_mac_addr[idx] = ' '; | ||||||
| 	} | 	} | ||||||
| 	env_set("icicle_mac_addr", icicle_mac_addr); | 	env_set("icicle_mac_addr0", icicle_mac_addr); | ||||||
|  | 
 | ||||||
|  | 	mac_addr[5] = device_serial_number[0] + 1; | ||||||
|  | 
 | ||||||
|  | 	icicle_mac_addr[0] = '['; | ||||||
|  | 
 | ||||||
|  | 	sprintf(&icicle_mac_addr[1], "%pM", mac_addr); | ||||||
|  | 
 | ||||||
|  | 	icicle_mac_addr[18] = ']'; | ||||||
|  | 	icicle_mac_addr[19] = '\0'; | ||||||
|  | 
 | ||||||
|  | 	for (idx = 0; idx < 20; idx++) { | ||||||
|  | 		if (icicle_mac_addr[idx] == ':') | ||||||
|  | 			icicle_mac_addr[idx] = ' '; | ||||||
|  | 	} | ||||||
|  | 	env_set("icicle_mac_addr1", icicle_mac_addr); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -72,7 +72,7 @@ struct msg_get_clock_rate { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
 |  * https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#raspberry-pi-revision-codes
 | ||||||
|  */ |  */ | ||||||
| struct rpi_model { | struct rpi_model { | ||||||
| 	const char *name; | 	const char *name; | ||||||
|  | @ -157,6 +157,11 @@ static const struct rpi_model rpi_models_new_scheme[] = { | ||||||
| 		DTB_DIR "bcm2711-rpi-4-b.dtb", | 		DTB_DIR "bcm2711-rpi-4-b.dtb", | ||||||
| 		true, | 		true, | ||||||
| 	}, | 	}, | ||||||
|  | 	[0x12] = { | ||||||
|  | 		"Zero 2 W", | ||||||
|  | 		DTB_DIR "bcm2837-rpi-zero-2.dtb", | ||||||
|  | 		false, | ||||||
|  | 	}, | ||||||
| 	[0x13] = { | 	[0x13] = { | ||||||
| 		"400", | 		"400", | ||||||
| 		DTB_DIR "bcm2711-rpi-400.dtb", | 		DTB_DIR "bcm2711-rpi-400.dtb", | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ config SPL_OPENSBI_LOAD_ADDR | ||||||
| config BOARD_SPECIFIC_OPTIONS # dummy | config BOARD_SPECIFIC_OPTIONS # dummy | ||||||
| 	def_bool y | 	def_bool y | ||||||
| 	select SIFIVE_FU740 | 	select SIFIVE_FU740 | ||||||
|  | 	select ENV_IS_IN_SPI_FLASH | ||||||
| 	select SUPPORT_SPL | 	select SUPPORT_SPL | ||||||
| 	select RESET_SIFIVE | 	select RESET_SIFIVE | ||||||
| 	select BINMAN | 	select BINMAN | ||||||
|  |  | ||||||
|  | @ -22,6 +22,7 @@ | ||||||
| #define GEM_PHY_RESET	SIFIVE_GENERIC_GPIO_NR(0, 12) | #define GEM_PHY_RESET	SIFIVE_GENERIC_GPIO_NR(0, 12) | ||||||
| 
 | 
 | ||||||
| #define MODE_SELECT_REG		0x1000 | #define MODE_SELECT_REG		0x1000 | ||||||
|  | #define MODE_SELECT_SPI		0x6 | ||||||
| #define MODE_SELECT_SD		0xb | #define MODE_SELECT_SD		0xb | ||||||
| #define MODE_SELECT_MASK	GENMASK(3, 0) | #define MODE_SELECT_MASK	GENMASK(3, 0) | ||||||
| 
 | 
 | ||||||
|  | @ -123,6 +124,8 @@ u32 spl_boot_device(void) | ||||||
| 	u32 boot_device = mode_select & MODE_SELECT_MASK; | 	u32 boot_device = mode_select & MODE_SELECT_MASK; | ||||||
| 
 | 
 | ||||||
| 	switch (boot_device) { | 	switch (boot_device) { | ||||||
|  | 	case MODE_SELECT_SPI: | ||||||
|  | 		return BOOT_DEVICE_SPI; | ||||||
| 	case MODE_SELECT_SD: | 	case MODE_SELECT_SD: | ||||||
| 		return BOOT_DEVICE_MMC1; | 		return BOOT_DEVICE_MMC1; | ||||||
| 	default: | 	default: | ||||||
|  |  | ||||||
|  | @ -698,13 +698,7 @@ int g_dnl_board_usb_cable_connected(void) | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret = sun4i_usb_phy_vbus_detect(&phy); | 	return sun4i_usb_phy_vbus_detect(&phy); | ||||||
| 	if (ret == 1) { |  | ||||||
| 		pr_err("A charger is plugged into the OTG\n"); |  | ||||||
| 		return -ENODEV; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return ret; |  | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -27,6 +27,7 @@ | ||||||
| 
 | 
 | ||||||
| DECLARE_GLOBAL_DATA_PTR; | DECLARE_GLOBAL_DATA_PTR; | ||||||
| 
 | 
 | ||||||
|  | #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) | ||||||
| /**
 | /**
 | ||||||
|  * image_get_ramdisk - get and verify ramdisk image |  * image_get_ramdisk - get and verify ramdisk image | ||||||
|  * @rd_addr: ramdisk image start address |  * @rd_addr: ramdisk image start address | ||||||
|  | @ -85,6 +86,7 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch, | ||||||
| 
 | 
 | ||||||
| 	return rd_hdr; | 	return rd_hdr; | ||||||
| } | } | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| /*****************************************************************************/ | /*****************************************************************************/ | ||||||
| /* Shared dual-format routines */ | /* Shared dual-format routines */ | ||||||
|  | @ -325,18 +327,16 @@ int genimg_has_config(bootm_headers_t *images) | ||||||
| static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, | static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, | ||||||
| 			  ulong *rd_datap, ulong *rd_lenp) | 			  ulong *rd_datap, ulong *rd_lenp) | ||||||
| { | { | ||||||
| 	ulong rd_addr = 0; | 	ulong rd_addr; | ||||||
| 	char *buf; | 	char *buf; | ||||||
|  | 
 | ||||||
|  | #if CONFIG_IS_ENABLED(FIT) | ||||||
| 		const char *fit_uname_config = images->fit_uname_cfg; | 		const char *fit_uname_config = images->fit_uname_cfg; | ||||||
| 		const char *fit_uname_ramdisk = NULL; | 		const char *fit_uname_ramdisk = NULL; | ||||||
| 	bool processed; |  | ||||||
| 		int rd_noffset; | 		int rd_noffset; | ||||||
| 
 | 
 | ||||||
| 		if (select) { | 		if (select) { | ||||||
| 			ulong default_addr; | 			ulong default_addr; | ||||||
| 		bool done = true; |  | ||||||
| 
 |  | ||||||
| 		if (CONFIG_IS_ENABLED(FIT)) { |  | ||||||
| 			/*
 | 			/*
 | ||||||
| 			 * If the init ramdisk comes from the FIT image and | 			 * If the init ramdisk comes from the FIT image and | ||||||
| 			 * the FIT image address is omitted in the command | 			 * the FIT image address is omitted in the command | ||||||
|  | @ -348,8 +348,8 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, | ||||||
| 			else | 			else | ||||||
| 				default_addr = image_load_addr; | 				default_addr = image_load_addr; | ||||||
| 
 | 
 | ||||||
| 			if (fit_parse_conf(select, default_addr, &rd_addr, | 			if (fit_parse_conf(select, default_addr, | ||||||
| 					   &fit_uname_config)) { | 					   &rd_addr, &fit_uname_config)) { | ||||||
| 				debug("*  ramdisk: config '%s' from image at 0x%08lx\n", | 				debug("*  ramdisk: config '%s' from image at 0x%08lx\n", | ||||||
| 				      fit_uname_config, rd_addr); | 				      fit_uname_config, rd_addr); | ||||||
| 			} else if (fit_parse_subimage(select, default_addr, | 			} else if (fit_parse_subimage(select, default_addr, | ||||||
|  | @ -357,28 +357,29 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, | ||||||
| 						      &fit_uname_ramdisk)) { | 						      &fit_uname_ramdisk)) { | ||||||
| 				debug("*  ramdisk: subimage '%s' from image at 0x%08lx\n", | 				debug("*  ramdisk: subimage '%s' from image at 0x%08lx\n", | ||||||
| 				      fit_uname_ramdisk, rd_addr); | 				      fit_uname_ramdisk, rd_addr); | ||||||
| 			} else { | 			} else | ||||||
| 				done = false; | #endif | ||||||
| 			} | 			{ | ||||||
| 		} |  | ||||||
| 		if (!done) { |  | ||||||
| 				rd_addr = hextoul(select, NULL); | 				rd_addr = hextoul(select, NULL); | ||||||
| 				debug("*  ramdisk: cmdline image address = 0x%08lx\n", | 				debug("*  ramdisk: cmdline image address = 0x%08lx\n", | ||||||
| 				      rd_addr); | 				      rd_addr); | ||||||
| 			} | 			} | ||||||
| 	} else if (CONFIG_IS_ENABLED(FIT)) { | #if CONFIG_IS_ENABLED(FIT) | ||||||
|  | 		} else { | ||||||
| 			/* use FIT configuration provided in first bootm
 | 			/* use FIT configuration provided in first bootm
 | ||||||
| 			 * command argument. If the property is not defined, | 			 * command argument. If the property is not defined, | ||||||
| 		 * quit silently (with -ENOPKG	) | 			 * quit silently (with -ENOPKG) | ||||||
| 			 */ | 			 */ | ||||||
| 			rd_addr = map_to_sysmem(images->fit_hdr_os); | 			rd_addr = map_to_sysmem(images->fit_hdr_os); | ||||||
| 		rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP, | 			rd_noffset = fit_get_node_from_config(images, | ||||||
|  | 							      FIT_RAMDISK_PROP, | ||||||
| 							      rd_addr); | 							      rd_addr); | ||||||
| 			if (rd_noffset == -ENOENT) | 			if (rd_noffset == -ENOENT) | ||||||
| 				return -ENOPKG; | 				return -ENOPKG; | ||||||
| 			else if (rd_noffset < 0) | 			else if (rd_noffset < 0) | ||||||
| 				return rd_noffset; | 				return rd_noffset; | ||||||
| 		} | 		} | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 		/*
 | 		/*
 | ||||||
| 		 * Check if there is an initrd image at the | 		 * Check if there is an initrd image at the | ||||||
|  | @ -386,29 +387,30 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, | ||||||
| 		 * check image type, for FIT images get FIT node. | 		 * check image type, for FIT images get FIT node. | ||||||
| 		 */ | 		 */ | ||||||
| 		buf = map_sysmem(rd_addr, 0); | 		buf = map_sysmem(rd_addr, 0); | ||||||
| 	processed = false; |  | ||||||
| 		switch (genimg_get_format(buf)) { | 		switch (genimg_get_format(buf)) { | ||||||
| 	case IMAGE_FORMAT_LEGACY: | #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) | ||||||
| 		if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { | 		case IMAGE_FORMAT_LEGACY: { | ||||||
| 			const image_header_t *rd_hdr; | 			const image_header_t *rd_hdr; | ||||||
| 
 | 
 | ||||||
| 			printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", | 			printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", | ||||||
| 			       rd_addr); | 			       rd_addr); | ||||||
| 
 | 
 | ||||||
| 			bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); | 			bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); | ||||||
| 			rd_hdr = image_get_ramdisk(rd_addr, arch, images->verify); | 			rd_hdr = image_get_ramdisk(rd_addr, arch, | ||||||
|  | 						   images->verify); | ||||||
|  | 
 | ||||||
| 			if (!rd_hdr) | 			if (!rd_hdr) | ||||||
| 				return -ENOENT; | 				return -ENOENT; | ||||||
| 
 | 
 | ||||||
| 			*rd_datap = image_get_data(rd_hdr); | 			*rd_datap = image_get_data(rd_hdr); | ||||||
| 			*rd_lenp = image_get_data_size(rd_hdr); | 			*rd_lenp = image_get_data_size(rd_hdr); | ||||||
| 			processed = true; |  | ||||||
| 		} |  | ||||||
| 			break; | 			break; | ||||||
|  | 		} | ||||||
|  | #endif | ||||||
|  | #if CONFIG_IS_ENABLED(FIT) | ||||||
| 		case IMAGE_FORMAT_FIT: | 		case IMAGE_FORMAT_FIT: | ||||||
| 		if (CONFIG_IS_ENABLED(FIT)) { | 			rd_noffset = fit_image_load(images, | ||||||
| 			rd_noffset = fit_image_load(images, rd_addr, | 						    rd_addr, &fit_uname_ramdisk, | ||||||
| 						    &fit_uname_ramdisk, |  | ||||||
| 						    &fit_uname_config, arch, | 						    &fit_uname_config, arch, | ||||||
| 						    IH_TYPE_RAMDISK, | 						    IH_TYPE_RAMDISK, | ||||||
| 						    BOOTSTAGE_ID_FIT_RD_START, | 						    BOOTSTAGE_ID_FIT_RD_START, | ||||||
|  | @ -420,19 +422,15 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, | ||||||
| 			images->fit_hdr_rd = map_sysmem(rd_addr, 0); | 			images->fit_hdr_rd = map_sysmem(rd_addr, 0); | ||||||
| 			images->fit_uname_rd = fit_uname_ramdisk; | 			images->fit_uname_rd = fit_uname_ramdisk; | ||||||
| 			images->fit_noffset_rd = rd_noffset; | 			images->fit_noffset_rd = rd_noffset; | ||||||
| 			processed = true; |  | ||||||
| 		} |  | ||||||
| 			break; | 			break; | ||||||
|  | #endif | ||||||
|  | #ifdef CONFIG_ANDROID_BOOT_IMAGE | ||||||
| 		case IMAGE_FORMAT_ANDROID: | 		case IMAGE_FORMAT_ANDROID: | ||||||
| 		if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { |  | ||||||
| 			android_image_get_ramdisk((void *)images->os.start, | 			android_image_get_ramdisk((void *)images->os.start, | ||||||
| 						  rd_datap, rd_lenp); | 						  rd_datap, rd_lenp); | ||||||
| 			processed = true; |  | ||||||
| 		} |  | ||||||
| 			break; | 			break; | ||||||
| 	} | #endif | ||||||
| 
 | 		default: | ||||||
| 	if (!processed) { |  | ||||||
| 			if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { | 			if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { | ||||||
| 				char *end = NULL; | 				char *end = NULL; | ||||||
| 
 | 
 | ||||||
|  | @ -441,15 +439,12 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, | ||||||
| 				if (end) { | 				if (end) { | ||||||
| 					*rd_lenp = hextoul(++end, NULL); | 					*rd_lenp = hextoul(++end, NULL); | ||||||
| 					*rd_datap = rd_addr; | 					*rd_datap = rd_addr; | ||||||
| 				processed = true; | 					break; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 		if (!processed) { |  | ||||||
| 			puts("Wrong Ramdisk Image Format\n"); | 			puts("Wrong Ramdisk Image Format\n"); | ||||||
| 			return -EINVAL; | 			return -EINVAL; | ||||||
| 		} | 		} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -151,7 +151,8 @@ static int do_tpm_pcr_read(struct cmd_tbl *cmdtp, int flag, int argc, | ||||||
| 
 | 
 | ||||||
| 	data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0); | 	data = map_sysmem(simple_strtoul(argv[2], NULL, 0), 0); | ||||||
| 
 | 
 | ||||||
| 	rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, data, &updates); | 	rc = tpm2_pcr_read(dev, index, priv->pcr_select_min, TPM2_ALG_SHA256, | ||||||
|  | 			   data, TPM2_DIGEST_LEN, &updates); | ||||||
| 	if (!rc) { | 	if (!rc) { | ||||||
| 		printf("PCR #%u content (%u known updates):\n", index, updates); | 		printf("PCR #%u content (%u known updates):\n", index, updates); | ||||||
| 		print_byte_string(data, TPM2_DIGEST_LEN); | 		print_byte_string(data, TPM2_DIGEST_LEN); | ||||||
|  |  | ||||||
|  | @ -6,7 +6,6 @@ CONFIG_DEFAULT_DEVICE_TREE="microchip-mpfs-icicle-kit" | ||||||
| CONFIG_TARGET_MICROCHIP_ICICLE=y | CONFIG_TARGET_MICROCHIP_ICICLE=y | ||||||
| CONFIG_ARCH_RV64I=y | CONFIG_ARCH_RV64I=y | ||||||
| CONFIG_RISCV_SMODE=y | CONFIG_RISCV_SMODE=y | ||||||
| CONFIG_SBI_V01=y |  | ||||||
| CONFIG_DISTRO_DEFAULTS=y | CONFIG_DISTRO_DEFAULTS=y | ||||||
| CONFIG_SYS_LOAD_ADDR=0x80200000 | CONFIG_SYS_LOAD_ADDR=0x80200000 | ||||||
| CONFIG_FIT=y | CONFIG_FIT=y | ||||||
|  |  | ||||||
|  | @ -26,6 +26,7 @@ CONFIG_CMD_DFU=y | ||||||
| CONFIG_CMD_MTD=y | CONFIG_CMD_MTD=y | ||||||
| CONFIG_CMD_PCI=y | CONFIG_CMD_PCI=y | ||||||
| CONFIG_CMD_USB=y | CONFIG_CMD_USB=y | ||||||
|  | CONFIG_CMD_TPM=y | ||||||
| CONFIG_CMD_MTDPARTS=y | CONFIG_CMD_MTDPARTS=y | ||||||
| CONFIG_OF_BOARD=y | CONFIG_OF_BOARD=y | ||||||
| CONFIG_ENV_IS_IN_FLASH=y | CONFIG_ENV_IS_IN_FLASH=y | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ CONFIG_CMD_DFU=y | ||||||
| CONFIG_CMD_MTD=y | CONFIG_CMD_MTD=y | ||||||
| CONFIG_CMD_PCI=y | CONFIG_CMD_PCI=y | ||||||
| CONFIG_CMD_USB=y | CONFIG_CMD_USB=y | ||||||
|  | CONFIG_CMD_TPM=y | ||||||
| CONFIG_CMD_MTDPARTS=y | CONFIG_CMD_MTDPARTS=y | ||||||
| CONFIG_OF_BOARD=y | CONFIG_OF_BOARD=y | ||||||
| CONFIG_ENV_IS_IN_FLASH=y | CONFIG_ENV_IS_IN_FLASH=y | ||||||
|  |  | ||||||
|  | @ -41,7 +41,6 @@ CONFIG_MULTI_DTB_FIT_LZO=y | ||||||
| CONFIG_MULTI_DTB_FIT_USER_DEFINED_AREA=y | CONFIG_MULTI_DTB_FIT_USER_DEFINED_AREA=y | ||||||
| CONFIG_ENV_OVERWRITE=y | CONFIG_ENV_OVERWRITE=y | ||||||
| CONFIG_ENV_IS_IN_MMC=y | CONFIG_ENV_IS_IN_MMC=y | ||||||
| CONFIG_SYS_MMC_ENV_DEV=1 |  | ||||||
| CONFIG_SYS_MMC_ENV_PART=2 | CONFIG_SYS_MMC_ENV_PART=2 | ||||||
| CONFIG_VERSION_VARIABLE=y | CONFIG_VERSION_VARIABLE=y | ||||||
| CONFIG_REGMAP=y | CONFIG_REGMAP=y | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ CONFIG_SPL_DM_SPI=y | ||||||
| CONFIG_DEFAULT_DEVICE_TREE="hifive-unmatched-a00" | CONFIG_DEFAULT_DEVICE_TREE="hifive-unmatched-a00" | ||||||
| CONFIG_SPL_MMC=y | CONFIG_SPL_MMC=y | ||||||
| CONFIG_SPL=y | CONFIG_SPL=y | ||||||
|  | CONFIG_SPL_SPI_FLASH_SUPPORT=y | ||||||
| CONFIG_SPL_SPI=y | CONFIG_SPL_SPI=y | ||||||
| CONFIG_AHCI=y | CONFIG_AHCI=y | ||||||
| CONFIG_TARGET_SIFIVE_UNMATCHED=y | CONFIG_TARGET_SIFIVE_UNMATCHED=y | ||||||
|  | @ -23,17 +24,22 @@ CONFIG_DISPLAY_BOARDINFO=y | ||||||
| CONFIG_DISPLAY_BOARDINFO_LATE=y | CONFIG_DISPLAY_BOARDINFO_LATE=y | ||||||
| CONFIG_ID_EEPROM=y | CONFIG_ID_EEPROM=y | ||||||
| CONFIG_SPL_SEPARATE_BSS=y | CONFIG_SPL_SEPARATE_BSS=y | ||||||
|  | CONFIG_SPL_DM_SPI_FLASH=y | ||||||
| CONFIG_SPL_DM_RESET=y | CONFIG_SPL_DM_RESET=y | ||||||
|  | CONFIG_SPL_SPI_LOAD=y | ||||||
| CONFIG_CMD_EEPROM=y | CONFIG_CMD_EEPROM=y | ||||||
| CONFIG_CMD_MEMINFO=y | CONFIG_CMD_MEMINFO=y | ||||||
| CONFIG_CMD_PWM=y | CONFIG_CMD_PWM=y | ||||||
| CONFIG_CMD_GPT_RENAME=y | CONFIG_CMD_GPT_RENAME=y | ||||||
| CONFIG_CMD_PCI=y | CONFIG_CMD_PCI=y | ||||||
| CONFIG_CMD_USB=y | CONFIG_CMD_USB=y | ||||||
|  | CONFIG_USE_ENV_SPI_BUS=y | ||||||
|  | CONFIG_ENV_SPI_BUS=1 | ||||||
| CONFIG_SYS_RELOC_GD_ENV_ADDR=y | CONFIG_SYS_RELOC_GD_ENV_ADDR=y | ||||||
| CONFIG_SCSI_AHCI=y | CONFIG_SCSI_AHCI=y | ||||||
| CONFIG_AHCI_PCI=y | CONFIG_AHCI_PCI=y | ||||||
| CONFIG_SPL_CLK=y | CONFIG_SPL_CLK=y | ||||||
|  | CONFIG_SPI_FLASH_ISSI=y | ||||||
| CONFIG_SYS_I2C_EEPROM_ADDR=0x54 | CONFIG_SYS_I2C_EEPROM_ADDR=0x54 | ||||||
| CONFIG_E1000=y | CONFIG_E1000=y | ||||||
| CONFIG_NVME=y | CONFIG_NVME=y | ||||||
|  |  | ||||||
|  | @ -296,8 +296,11 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc) | ||||||
| 	case IF_TYPE_VIRTIO: | 	case IF_TYPE_VIRTIO: | ||||||
| 		puts("VirtIO"); | 		puts("VirtIO"); | ||||||
| 		break; | 		break; | ||||||
|  | 	case IF_TYPE_EFI_MEDIA: | ||||||
|  | 		puts("EFI"); | ||||||
|  | 		break; | ||||||
| 	default: | 	default: | ||||||
| 		puts ("UNKNOWN"); | 		puts("UNKNOWN"); | ||||||
| 		break; | 		break; | ||||||
| 	} | 	} | ||||||
| 	printf (" device %d  --   Partition Type: %s\n\n", | 	printf (" device %d  --   Partition Type: %s\n\n", | ||||||
|  | @ -427,6 +430,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, | ||||||
| 	 * Always should be done, otherwise hw partition 0 will return stale | 	 * Always should be done, otherwise hw partition 0 will return stale | ||||||
| 	 * data after displaying a non-zero hw partition. | 	 * data after displaying a non-zero hw partition. | ||||||
| 	 */ | 	 */ | ||||||
|  | 	if ((*dev_desc)->if_type == IF_TYPE_MMC) | ||||||
| 		part_init(*dev_desc); | 		part_init(*dev_desc); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -65,7 +65,8 @@ can be enabled with the following command line parameters: | ||||||
| 
 | 
 | ||||||
| - To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.:: | - To add a Serial ATA disk via an Intel ICH9 AHCI controller, pass e.g.:: | ||||||
| 
 | 
 | ||||||
|     -drive if=none,file=disk.img,id=mydisk -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0 |     -drive if=none,file=disk.img,format=raw,id=mydisk \ | ||||||
|  |     -device ich9-ahci,id=ahci -device ide-drive,drive=mydisk,bus=ahci.0 | ||||||
| 
 | 
 | ||||||
| - To add an Intel E1000 network adapter, pass e.g.:: | - To add an Intel E1000 network adapter, pass e.g.:: | ||||||
| 
 | 
 | ||||||
|  | @ -75,10 +76,14 @@ can be enabled with the following command line parameters: | ||||||
| 
 | 
 | ||||||
|     -device usb-ehci,id=ehci |     -device usb-ehci,id=ehci | ||||||
| 
 | 
 | ||||||
| - To add a NVMe disk, pass e.g.:: | - To add an NVMe disk, pass e.g.:: | ||||||
| 
 | 
 | ||||||
|     -drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo |     -drive if=none,file=disk.img,id=mydisk -device nvme,drive=mydisk,serial=foo | ||||||
| 
 | 
 | ||||||
|  | - To add a random number generator, pass e.g.:: | ||||||
|  | 
 | ||||||
|  |     -device virtio-rng-pci | ||||||
|  | 
 | ||||||
| These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well. | These have been tested in QEMU 2.9.0 but should work in at least 2.5.0 as well. | ||||||
| 
 | 
 | ||||||
| Enabling TPMv2 support | Enabling TPMv2 support | ||||||
|  |  | ||||||
|  | @ -0,0 +1,78 @@ | ||||||
|  | Calxeda Highbank/Midway board support | ||||||
|  | ===================================== | ||||||
|  | 
 | ||||||
|  | The Calxeda ECX-1000 ("Highbank") and ECX-2000 ("Midway") were ARM based | ||||||
|  | servers, providing high-density cluster systems. A single motherboard could | ||||||
|  | host between 12 and 48 nodes, each with their own quad-core ARMv7 | ||||||
|  | processor, private DRAM and peripherals, connected through a high-bandwith | ||||||
|  | and low-latency "fabric" network. Multiple motherboards could be connected | ||||||
|  | together, to extend this fabric. | ||||||
|  | 
 | ||||||
|  | For the purpose of U-Boot we just care about a single node, this can be | ||||||
|  | used as a single system, just using the fabric to connect to some Ethernet | ||||||
|  | network. Each node boots on its own, either from a local hard disk, or | ||||||
|  | via the network. | ||||||
|  | 
 | ||||||
|  | The earlier ECX-1000 nodes ("Highbank") contain four ARM Cortex-A9 cores, | ||||||
|  | a Cortex-M3 system controller, three 10GBit/s MACs and five SATA | ||||||
|  | controllers. The DRAM is limited to 4GB. | ||||||
|  | 
 | ||||||
|  | The later ECX-2000 nodes ("Midway") use four Cortex-A15 cores, alongside | ||||||
|  | two Cortex-A7 management cores, and support up to 32GB of DRAM, while | ||||||
|  | keeping the other peripherals. | ||||||
|  | 
 | ||||||
|  | For the purpose of U-Boot those two SoCs are very similar, so we offer | ||||||
|  | one build target. The subtle differences are handled at runtime. | ||||||
|  | Calxeda as a company is long defunct, and the remaining systems are | ||||||
|  | considered legacy at this point. | ||||||
|  | 
 | ||||||
|  | Bgilding U-Boot | ||||||
|  | --------------- | ||||||
|  | There is only one defconfig to cover both systems:: | ||||||
|  | 
 | ||||||
|  |     $ make highbank_defconfig | ||||||
|  |     $ make | ||||||
|  | 
 | ||||||
|  | This will create ``u-boot.bin``, which could become part of the firmware update | ||||||
|  | package, or could be chainloaded by the existing U-Boot, see below for more | ||||||
|  | details. | ||||||
|  | 
 | ||||||
|  | Boot process | ||||||
|  | ------------ | ||||||
|  | Upon powering up a node (which would be controlled by some BMC style | ||||||
|  | management controller on the motherboard), the system controller ("ECME") | ||||||
|  | would start and do some system initialisation (fabric registration, | ||||||
|  | DRAM init, clock setup). It would load the device tree binary, some secure | ||||||
|  | monitor code (``a9boot``/``a15boot``) and a U-Boot binary from SPI flash | ||||||
|  | into DRAM, then power up the actual application cores (ARM Cortex-A9/A15). | ||||||
|  | They would start executing ``a9boot``/``a15boot``, registering the PSCI SMC | ||||||
|  | handlers, then dropping into U-Boot, but in non-secure state (HYP mode on | ||||||
|  | the A15s). | ||||||
|  | 
 | ||||||
|  | U-Boot would act as a mere loader, trying to find some ``boot.scr`` file on | ||||||
|  | the local hard disks, or reverting to PXE boot. | ||||||
|  | 
 | ||||||
|  | Updating U-Boot | ||||||
|  | --------------- | ||||||
|  | The U-Boot binary is loaded from SPI flash, which is controlled exclusively | ||||||
|  | by the ECME. This can be reached via IPMI using the LANplus transport protocol. | ||||||
|  | Updating the SPI flash content requires vendor specific additions to the | ||||||
|  | IPMI protocol, support for which was never upstreamed to ipmitool or | ||||||
|  | FreeIPMI. Some older repositories for `ipmitool`_, the `pyipmi`_ library and | ||||||
|  | a Python `management script`_ to update the SPI flash can be found on Github. | ||||||
|  | 
 | ||||||
|  | A simpler and safer way to get an up-to-date U-Boot running, is chainloading | ||||||
|  | it via the legacy U-Boot:: | ||||||
|  | 
 | ||||||
|  |     $ mkimage -A arm -O u-boot -T standalone -C none -a 0x8000 -e 0x8000 \ | ||||||
|  |       -n U-Boot -d u-boot.bin u-boot-highbank.img | ||||||
|  | 
 | ||||||
|  | Then load this image file, either from hard disk, or via TFTP, from the | ||||||
|  | existing U-Boot, and execute it with bootm:: | ||||||
|  | 
 | ||||||
|  |     => tftpboot 0x8000 u-boot-highbank.img | ||||||
|  |     => bootm | ||||||
|  | 
 | ||||||
|  | .. _`ipmitool`: https://github.com/Cynerva/ipmitool | ||||||
|  | .. _`pyipmi`: https://pypi.org/project/pyipmi/ | ||||||
|  | .. _`management script`: https://github.com/Cynerva/cxmanage | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | .. SPDX-License-Identifier: GPL-2.0+ | ||||||
|  | 
 | ||||||
|  | Highbank | ||||||
|  | ======== | ||||||
|  | 
 | ||||||
|  | .. toctree:: | ||||||
|  |    :maxdepth: 2 | ||||||
|  | 
 | ||||||
|  |    highbank | ||||||
|  | @ -16,6 +16,7 @@ Board-specific doc | ||||||
|    coreboot/index |    coreboot/index | ||||||
|    emulation/index |    emulation/index | ||||||
|    google/index |    google/index | ||||||
|  |    highbank/index | ||||||
|    intel/index |    intel/index | ||||||
|    kontron/index |    kontron/index | ||||||
|    microchip/index |    microchip/index | ||||||
|  |  | ||||||
|  | @ -20,6 +20,7 @@ The support for following drivers are already enabled: | ||||||
| 2. Microchip Clock Driver. | 2. Microchip Clock Driver. | ||||||
| 3. Cadence MACB ethernet driver for networking support. | 3. Cadence MACB ethernet driver for networking support. | ||||||
| 4. Cadence MMC Driver for eMMC/SD support. | 4. Cadence MMC Driver for eMMC/SD support. | ||||||
|  | 5. Microchip I2C Driver. | ||||||
| 
 | 
 | ||||||
| Booting from eMMC using HSS | Booting from eMMC using HSS | ||||||
| --------------------------- | --------------------------- | ||||||
|  | @ -214,7 +215,8 @@ GPT partition. | ||||||
| Booting | Booting | ||||||
| ~~~~~~~ | ~~~~~~~ | ||||||
| 
 | 
 | ||||||
| You should see the U-Boot prompt on UART0. | You should see the U-Boot prompt on UART1. | ||||||
|  | (Note: UART0 is reserved for HSS) | ||||||
| 
 | 
 | ||||||
| Sample boot log from MPFS Icicle Kit | Sample boot log from MPFS Icicle Kit | ||||||
| '''''''''''''''''''''''''''''''''''' | '''''''''''''''''''''''''''''''''''' | ||||||
|  | @ -451,7 +453,8 @@ copied payload and Linux image. | ||||||
| 
 | 
 | ||||||
|     sudo dd if=<payload_binary> of=/dev/sdX2 bs=512 |     sudo dd if=<payload_binary> of=/dev/sdX2 bs=512 | ||||||
| 
 | 
 | ||||||
| You should see the U-Boot prompt on UART0. | You should see the U-Boot prompt on UART1. | ||||||
|  | (Note: UART0 is reserved for HSS) | ||||||
| 
 | 
 | ||||||
| GUID type | GUID type | ||||||
| ~~~~~~~~~ | ~~~~~~~~~ | ||||||
|  |  | ||||||
|  | @ -534,3 +534,34 @@ Sample boot log from HiFive Unmatched board | ||||||
| 	OpenEmbedded nodistro.0 unmatched ttySIF0 | 	OpenEmbedded nodistro.0 unmatched ttySIF0 | ||||||
| 
 | 
 | ||||||
| 	unmatched login: | 	unmatched login: | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Booting from SPI | ||||||
|  | ---------------- | ||||||
|  | 
 | ||||||
|  | Use Building steps from "Booting from uSD using U-Boot SPL" section. | ||||||
|  | 
 | ||||||
|  | Partition the SPI in Linux via mtdblock.  The partition types here are | ||||||
|  | "HiFive Unleashed FSBL", "HiFive Unleashed BBL", and "U-Boot environment" | ||||||
|  | for partitions one through three respectively. | ||||||
|  | 
 | ||||||
|  | .. code-block:: none | ||||||
|  | 
 | ||||||
|  | 	sgdisk --clear -a 1 \ | ||||||
|  | 	    --new=1:40:2087     --change-name=1:spl   --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \ | ||||||
|  | 	    --new=2:2088:10279  --change-name=2:uboot --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 \ | ||||||
|  | 	    --new=3:10280:10535 --change-name=3:env   --typecode=3:3DE21764-95BD-54BD-A5C3-4ABE786F38A8 \ | ||||||
|  | 	    /dev/mtdblock0 | ||||||
|  | 
 | ||||||
|  | Write U-boot SPL and U-boot to their partitions. | ||||||
|  | 
 | ||||||
|  | .. code-block:: none | ||||||
|  | 
 | ||||||
|  | 	dd if=u-boot-spl.bin of=/dev/mtdblock0 bs=4096 seek=5 conv=sync | ||||||
|  | 	dd if=u-boot.itb  of=/dev/mtdblock0 bs=4096 seek=261 conv=sync | ||||||
|  | 
 | ||||||
|  | Power off the board. | ||||||
|  | 
 | ||||||
|  | Change DIP switches MSEL[3:0] to 0110. | ||||||
|  | 
 | ||||||
|  | Power up the board. | ||||||
|  |  | ||||||
|  | @ -620,12 +620,12 @@ EFI_DRIVER_BINDING_PROTOCOL implementation for the UEFI drivers. | ||||||
| 
 | 
 | ||||||
| A linker created list is used to keep track of the UEFI drivers. To create an | A linker created list is used to keep track of the UEFI drivers. To create an | ||||||
| entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying | entry in the list the UEFI driver uses the U_BOOT_DRIVER macro specifying | ||||||
| UCLASS_EFI as the ID of its uclass, e.g:: | UCLASS_EFI_LOADER as the ID of its uclass, e.g:: | ||||||
| 
 | 
 | ||||||
|     /* Identify as UEFI driver */ |     /* Identify as UEFI driver */ | ||||||
|     U_BOOT_DRIVER(efi_block) = { |     U_BOOT_DRIVER(efi_block) = { | ||||||
|         .name  = "EFI block driver", |         .name  = "EFI block driver", | ||||||
|         .id    = UCLASS_EFI, |         .id    = UCLASS_EFI_LOADER, | ||||||
|         .ops   = &driver_ops, |         .ops   = &driver_ops, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  | @ -651,8 +651,8 @@ UEFI block IO driver | ||||||
| The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL. | The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL. | ||||||
| 
 | 
 | ||||||
| When connected it creates a new U-Boot block IO device with interface type | When connected it creates a new U-Boot block IO device with interface type | ||||||
| IF_TYPE_EFI, adds child controllers mapping the partitions, and installs the | IF_TYPE_EFI_LOADER, adds child controllers mapping the partitions, and installs | ||||||
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the | the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the | ||||||
| software iPXE to boot from iSCSI network drives [4]. | software iPXE to boot from iSCSI network drives [4]. | ||||||
| 
 | 
 | ||||||
| This driver is only available if U-Boot is configured with:: | This driver is only available if U-Boot is configured with:: | ||||||
|  |  | ||||||
|  | @ -102,7 +102,7 @@ Manually Loading and Applying Overlays | ||||||
| 
 | 
 | ||||||
| :: | :: | ||||||
| 
 | 
 | ||||||
|     => fdtaddr $fdtaddr |     => fdt addr $fdtaddr | ||||||
| 
 | 
 | ||||||
| 4. Grow it enough so it can encompass all applied overlays | 4. Grow it enough so it can encompass all applied overlays | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -61,6 +61,39 @@ config TPL_BLOCK_CACHE | ||||||
| 	help | 	help | ||||||
| 	  This option enables the disk-block cache in TPL | 	  This option enables the disk-block cache in TPL | ||||||
| 
 | 
 | ||||||
|  | config EFI_MEDIA | ||||||
|  | 	bool "Support EFI media drivers" | ||||||
|  | 	default y if EFI || SANDBOX | ||||||
|  | 	help | ||||||
|  | 	  Enable this to support media devices on top of UEFI. This enables | ||||||
|  | 	  just the uclass so you also need a specific driver to make this do | ||||||
|  | 	  anything. | ||||||
|  | 
 | ||||||
|  | 	  For sandbox there is a test driver. | ||||||
|  | 
 | ||||||
|  | if EFI_MEDIA | ||||||
|  | 
 | ||||||
|  | config EFI_MEDIA_SANDBOX | ||||||
|  | 	bool "Sandbox EFI media driver" | ||||||
|  | 	depends on SANDBOX | ||||||
|  | 	default y | ||||||
|  | 	help | ||||||
|  | 	  Enables a simple sandbox media driver, used for testing just the | ||||||
|  | 	  EFI_MEDIA uclass. It does not do anything useful, since sandbox does | ||||||
|  | 	  not actually support running on top of UEFI. | ||||||
|  | 
 | ||||||
|  | config EFI_MEDIA_BLK | ||||||
|  | 	bool "EFI media block driver" | ||||||
|  | 	depends on EFI_APP | ||||||
|  | 	default y | ||||||
|  | 	help | ||||||
|  | 	  Enables a block driver for providing access to UEFI devices. This | ||||||
|  | 	  allows use of block devices detected by the underlying UEFI | ||||||
|  | 	  implementation. With this it is possible to use filesystems on these | ||||||
|  | 	  devices, for example. | ||||||
|  | 
 | ||||||
|  | endif  # EFI_MEDIA | ||||||
|  | 
 | ||||||
| config IDE | config IDE | ||||||
| 	bool "Support IDE controllers" | 	bool "Support IDE controllers" | ||||||
| 	select HAVE_BLOCK_DEVICE | 	select HAVE_BLOCK_DEVICE | ||||||
|  |  | ||||||
|  | @ -14,3 +14,7 @@ obj-$(CONFIG_IDE) += ide.o | ||||||
| endif | endif | ||||||
| obj-$(CONFIG_SANDBOX) += sandbox.o | obj-$(CONFIG_SANDBOX) += sandbox.o | ||||||
| obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o | obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o | ||||||
|  | 
 | ||||||
|  | obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o | ||||||
|  | obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o | ||||||
|  | obj-$(CONFIG_EFI_MEDIA_BLK) += efi_blk.o | ||||||
|  |  | ||||||
|  | @ -28,7 +28,8 @@ static const char *if_typename_str[IF_TYPE_COUNT] = { | ||||||
| 	[IF_TYPE_SATA]		= "sata", | 	[IF_TYPE_SATA]		= "sata", | ||||||
| 	[IF_TYPE_HOST]		= "host", | 	[IF_TYPE_HOST]		= "host", | ||||||
| 	[IF_TYPE_NVME]		= "nvme", | 	[IF_TYPE_NVME]		= "nvme", | ||||||
| 	[IF_TYPE_EFI]		= "efi", | 	[IF_TYPE_EFI_MEDIA]	= "efi", | ||||||
|  | 	[IF_TYPE_EFI_LOADER]	= "efiloader", | ||||||
| 	[IF_TYPE_VIRTIO]	= "virtio", | 	[IF_TYPE_VIRTIO]	= "virtio", | ||||||
| 	[IF_TYPE_PVBLOCK]	= "pvblock", | 	[IF_TYPE_PVBLOCK]	= "pvblock", | ||||||
| }; | }; | ||||||
|  | @ -44,7 +45,8 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { | ||||||
| 	[IF_TYPE_SATA]		= UCLASS_AHCI, | 	[IF_TYPE_SATA]		= UCLASS_AHCI, | ||||||
| 	[IF_TYPE_HOST]		= UCLASS_ROOT, | 	[IF_TYPE_HOST]		= UCLASS_ROOT, | ||||||
| 	[IF_TYPE_NVME]		= UCLASS_NVME, | 	[IF_TYPE_NVME]		= UCLASS_NVME, | ||||||
| 	[IF_TYPE_EFI]		= UCLASS_EFI, | 	[IF_TYPE_EFI_MEDIA]	= UCLASS_EFI_MEDIA, | ||||||
|  | 	[IF_TYPE_EFI_LOADER]	= UCLASS_EFI_LOADER, | ||||||
| 	[IF_TYPE_VIRTIO]	= UCLASS_VIRTIO, | 	[IF_TYPE_VIRTIO]	= UCLASS_VIRTIO, | ||||||
| 	[IF_TYPE_PVBLOCK]	= UCLASS_PVBLOCK, | 	[IF_TYPE_PVBLOCK]	= UCLASS_PVBLOCK, | ||||||
| }; | }; | ||||||
|  | @ -670,6 +672,19 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | int blk_probe_or_unbind(struct udevice *dev) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = device_probe(dev); | ||||||
|  | 	if (ret) { | ||||||
|  | 		log_debug("probing %s failed\n", dev->name); | ||||||
|  | 		device_unbind(dev); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int blk_unbind_all(int if_type) | int blk_unbind_all(int if_type) | ||||||
| { | { | ||||||
| 	struct uclass *uc; | 	struct uclass *uc; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,15 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
|  | /*
 | ||||||
|  |  * Uclass for EFI media devices | ||||||
|  |  * | ||||||
|  |  * Copyright 2021 Google LLC | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <dm.h> | ||||||
|  | 
 | ||||||
|  | UCLASS_DRIVER(efi_media) = { | ||||||
|  | 	.id		= UCLASS_EFI_MEDIA, | ||||||
|  | 	.name		= "efi_media", | ||||||
|  | 	.flags		= DM_UC_FLAG_SEQ_ALIAS, | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,115 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
|  | /*
 | ||||||
|  |  * Block driver for EFI devices | ||||||
|  |  * This supports a media driver of UCLASS_EFI with a child UCLASS_BLK | ||||||
|  |  * It allows block-level access to EFI devices made available via EFI boot | ||||||
|  |  * services | ||||||
|  |  * | ||||||
|  |  * Copyright 2021 Google LLC | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <blk.h> | ||||||
|  | #include <dm.h> | ||||||
|  | #include <efi.h> | ||||||
|  | #include <efi_api.h> | ||||||
|  | 
 | ||||||
|  | struct efi_block_plat { | ||||||
|  | 	struct efi_block_io *blkio; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Read from block device | ||||||
|  |  * | ||||||
|  |  * @dev:	device | ||||||
|  |  * @blknr:	first block to be read | ||||||
|  |  * @blkcnt:	number of blocks to read | ||||||
|  |  * @buffer:	output buffer | ||||||
|  |  * Return:	number of blocks transferred | ||||||
|  |  */ | ||||||
|  | static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, | ||||||
|  | 			 void *buffer) | ||||||
|  | { | ||||||
|  | 	struct efi_block_plat *plat = dev_get_plat(dev); | ||||||
|  | 	struct efi_block_io *io = plat->blkio; | ||||||
|  | 	efi_status_t ret; | ||||||
|  | 
 | ||||||
|  | 	log_debug("read buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr, | ||||||
|  | 		  (ulong)blkcnt); | ||||||
|  | 	ret = io->read_blocks(io, io->media->media_id, blknr, | ||||||
|  | 			      blkcnt * io->media->block_size, buffer); | ||||||
|  | 	log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK, | ||||||
|  | 		  ret & ~EFI_ERROR_MASK); | ||||||
|  | 	if (ret) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	return blkcnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Write to block device | ||||||
|  |  * | ||||||
|  |  * @dev:	device | ||||||
|  |  * @blknr:	first block to be write | ||||||
|  |  * @blkcnt:	number of blocks to write | ||||||
|  |  * @buffer:	input buffer | ||||||
|  |  * Return:	number of blocks transferred | ||||||
|  |  */ | ||||||
|  | static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, | ||||||
|  | 			  const void *buffer) | ||||||
|  | { | ||||||
|  | 	struct efi_block_plat *plat = dev_get_plat(dev); | ||||||
|  | 	struct efi_block_io *io = plat->blkio; | ||||||
|  | 	efi_status_t ret; | ||||||
|  | 
 | ||||||
|  | 	log_debug("write buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr, | ||||||
|  | 		  (ulong)blkcnt); | ||||||
|  | 	ret = io->write_blocks(io, io->media->media_id, blknr, | ||||||
|  | 			       blkcnt * io->media->block_size, (void *)buffer); | ||||||
|  | 	log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK, | ||||||
|  | 		  ret & ~EFI_ERROR_MASK); | ||||||
|  | 	if (ret) | ||||||
|  | 		return 0; | ||||||
|  | 
 | ||||||
|  | 	return blkcnt; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Block device driver operators */ | ||||||
|  | static const struct blk_ops efi_blk_ops = { | ||||||
|  | 	.read	= efi_bl_read, | ||||||
|  | 	.write	= efi_bl_write, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | U_BOOT_DRIVER(efi_block) = { | ||||||
|  | 	.name		= "efi_block", | ||||||
|  | 	.id		= UCLASS_BLK, | ||||||
|  | 	.ops		= &efi_blk_ops, | ||||||
|  | 	.plat_auto	= sizeof(struct efi_block_plat), | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static int efi_media_bind(struct udevice *dev) | ||||||
|  | { | ||||||
|  | 	struct efi_media_plat *plat = dev_get_plat(dev); | ||||||
|  | 	struct efi_block_plat *blk_plat; | ||||||
|  | 	struct udevice *blk; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = blk_create_devicef(dev, "efi_block", "blk", IF_TYPE_EFI_MEDIA, | ||||||
|  | 				 dev_seq(dev), plat->blkio->media->block_size, | ||||||
|  | 				 plat->blkio->media->last_block, &blk); | ||||||
|  | 	if (ret) { | ||||||
|  | 		debug("Cannot create block device\n"); | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  | 	blk_plat = dev_get_plat(blk); | ||||||
|  | 	blk_plat->blkio = plat->blkio; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | U_BOOT_DRIVER(efi_media) = { | ||||||
|  | 	.name		= "efi_media", | ||||||
|  | 	.id		= UCLASS_EFI_MEDIA, | ||||||
|  | 	.bind		= efi_media_bind, | ||||||
|  | 	.plat_auto	= sizeof(struct efi_media_plat), | ||||||
|  | }; | ||||||
|  | @ -0,0 +1,20 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
|  | /*
 | ||||||
|  |  * EFI_MEDIA driver for sandbox | ||||||
|  |  * | ||||||
|  |  * Copyright 2021 Google LLC | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <dm.h> | ||||||
|  | 
 | ||||||
|  | static const struct udevice_id sandbox_efi_media_ids[] = { | ||||||
|  | 	{ .compatible = "sandbox,efi-media" }, | ||||||
|  | 	{ } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | U_BOOT_DRIVER(sandbox_efi_media) = { | ||||||
|  | 	.name		= "sandbox_efi_media", | ||||||
|  | 	.id		= UCLASS_EFI_MEDIA, | ||||||
|  | 	.of_match	= sandbox_efi_media_ids, | ||||||
|  | }; | ||||||
|  | @ -4,14 +4,17 @@ | ||||||
|  * Copyright 2019 NXP |  * Copyright 2019 NXP | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <asm/io.h> | #include <clk.h> | ||||||
| #include <malloc.h> |  | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
|  | #include <log.h> | ||||||
|  | #include <malloc.h> | ||||||
|  | #include <asm/io.h> | ||||||
| #include <dm/device.h> | #include <dm/device.h> | ||||||
| #include <dm/devres.h> | #include <dm/devres.h> | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
| #include <clk.h> |  | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
| 
 | 
 | ||||||
| #include "clk.h" | #include "clk.h" | ||||||
|  |  | ||||||
|  | @ -9,14 +9,18 @@ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <asm/io.h> | #include <asm/io.h> | ||||||
| #include <malloc.h> | #include <malloc.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
|  | #include <log.h> | ||||||
| #include <dm/device.h> | #include <dm/device.h> | ||||||
| #include <dm/devres.h> | #include <dm/devres.h> | ||||||
| #include <dm/uclass.h> | #include <dm/uclass.h> | ||||||
| #include <dm/lists.h> | #include <dm/lists.h> | ||||||
|  | #include <dm/device_compat.h> | ||||||
| #include <dm/device-internal.h> | #include <dm/device-internal.h> | ||||||
| #include <linux/bug.h> | #include <linux/bug.h> | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
|  | @ -190,7 +194,7 @@ static struct clk *_register_divider(struct device *dev, const char *name, | ||||||
| 
 | 
 | ||||||
| 	if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { | 	if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) { | ||||||
| 		if (width + shift > 16) { | 		if (width + shift > 16) { | ||||||
| 			pr_warn("divider value exceeds LOWORD field\n"); | 			dev_warn(dev, "divider value exceeds LOWORD field\n"); | ||||||
| 			return ERR_PTR(-EINVAL); | 			return ERR_PTR(-EINVAL); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -5,17 +5,22 @@ | ||||||
|  * |  * | ||||||
|  * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> |  * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | ||||||
|  */ |  */ | ||||||
|  | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <malloc.h> | #include <clk.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
|  | #include <div64.h> | ||||||
|  | #include <log.h> | ||||||
|  | #include <malloc.h> | ||||||
| #include <dm/device.h> | #include <dm/device.h> | ||||||
| #include <dm/devres.h> | #include <dm/devres.h> | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
| #include <div64.h> |  | ||||||
| #include <clk.h> |  | ||||||
| #include "clk.h" |  | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
| 
 | 
 | ||||||
|  | #include "clk.h" | ||||||
|  | 
 | ||||||
| #define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor" | #define UBOOT_DM_CLK_IMX_FIXED_FACTOR "ccf_clk_fixed_factor" | ||||||
| 
 | 
 | ||||||
| static ulong clk_factor_recalc_rate(struct clk *clk) | static ulong clk_factor_recalc_rate(struct clk *clk) | ||||||
|  |  | ||||||
|  | @ -7,18 +7,23 @@ | ||||||
|  * Gated clock implementation |  * Gated clock implementation | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <asm/io.h> | #include <clk.h> | ||||||
| #include <malloc.h> | #include <log.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
|  | #include <malloc.h> | ||||||
|  | #include <asm/io.h> | ||||||
| #include <dm/device.h> | #include <dm/device.h> | ||||||
|  | #include <dm/device_compat.h> | ||||||
| #include <dm/devres.h> | #include <dm/devres.h> | ||||||
| #include <linux/bitops.h> | #include <linux/bitops.h> | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
| #include <clk.h> |  | ||||||
| #include "clk.h" |  | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
| 
 | 
 | ||||||
|  | #include "clk.h" | ||||||
|  | 
 | ||||||
| #define UBOOT_DM_CLK_GATE "clk_gate" | #define UBOOT_DM_CLK_GATE "clk_gate" | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -123,7 +128,7 @@ struct clk *clk_register_gate(struct device *dev, const char *name, | ||||||
| 
 | 
 | ||||||
| 	if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { | 	if (clk_gate_flags & CLK_GATE_HIWORD_MASK) { | ||||||
| 		if (bit_idx > 15) { | 		if (bit_idx > 15) { | ||||||
| 			pr_err("gate bit exceeds LOWORD field\n"); | 			dev_err(dev, "gate bit exceeds LOWORD field\n"); | ||||||
| 			return ERR_PTR(-EINVAL); | 			return ERR_PTR(-EINVAL); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -21,17 +21,22 @@ | ||||||
|  * clock. |  * clock. | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <clk.h> | #include <clk.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
|  | #include <log.h> | ||||||
|  | #include <malloc.h> | ||||||
|  | #include <asm/io.h> | ||||||
| #include <dm/device.h> | #include <dm/device.h> | ||||||
|  | #include <dm/device_compat.h> | ||||||
| #include <dm/devres.h> | #include <dm/devres.h> | ||||||
| #include <dm/uclass.h> | #include <dm/uclass.h> | ||||||
| #include <linux/bitops.h> | #include <linux/bitops.h> | ||||||
| #include <malloc.h> |  | ||||||
| #include <asm/io.h> |  | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
|  | 
 | ||||||
| #include "clk.h" | #include "clk.h" | ||||||
| 
 | 
 | ||||||
| #define UBOOT_DM_CLK_CCF_MUX "ccf_clk_mux" | #define UBOOT_DM_CLK_CCF_MUX "ccf_clk_mux" | ||||||
|  | @ -123,7 +128,7 @@ static int clk_mux_set_parent(struct clk *clk, struct clk *parent) | ||||||
| 
 | 
 | ||||||
| 	index = clk_fetch_parent_index(clk, parent); | 	index = clk_fetch_parent_index(clk, parent); | ||||||
| 	if (index < 0) { | 	if (index < 0) { | ||||||
| 		printf("Could not fetch index\n"); | 		log_err("Could not fetch index\n"); | ||||||
| 		return index; | 		return index; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -169,7 +174,7 @@ struct clk *clk_hw_register_mux_table(struct device *dev, const char *name, | ||||||
| 	if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { | 	if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { | ||||||
| 		width = fls(mask) - ffs(mask) + 1; | 		width = fls(mask) - ffs(mask) + 1; | ||||||
| 		if (width + shift > 16) { | 		if (width + shift > 16) { | ||||||
| 			pr_err("mux value exceeds LOWORD field\n"); | 			dev_err(dev, "mux value exceeds LOWORD field\n"); | ||||||
| 			return ERR_PTR(-EINVAL); | 			return ERR_PTR(-EINVAL); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #include <log.h> | #include <log.h> | ||||||
| #include <malloc.h> | #include <malloc.h> | ||||||
|  | #include <asm/global_data.h> | ||||||
| #include <dm/device_compat.h> | #include <dm/device_compat.h> | ||||||
| #include <dm/device-internal.h> | #include <dm/device-internal.h> | ||||||
| #include <dm/devres.h> | #include <dm/devres.h> | ||||||
|  | @ -23,7 +24,6 @@ | ||||||
| #include <linux/bug.h> | #include <linux/bug.h> | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
| #include <asm/global_data.h> |  | ||||||
| 
 | 
 | ||||||
| static inline const struct clk_ops *clk_dev_ops(struct udevice *dev) | static inline const struct clk_ops *clk_dev_ops(struct udevice *dev) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -4,14 +4,16 @@ | ||||||
|  * Lukasz Majewski, DENX Software Engineering, lukma@denx.de |  * Lukasz Majewski, DENX Software Engineering, lukma@denx.de | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
|  | #include <clk.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
| #include <log.h> | #include <log.h> | ||||||
| #include <dm/device.h> | #include <dm/device.h> | ||||||
| #include <dm/uclass.h> | #include <dm/uclass.h> | ||||||
| #include <dm/lists.h> | #include <dm/lists.h> | ||||||
| #include <dm/device-internal.h> | #include <dm/device-internal.h> | ||||||
| #include <clk.h> |  | ||||||
| 
 | 
 | ||||||
| int clk_register(struct clk *clk, const char *drv_name, | int clk_register(struct clk *clk, const char *drv_name, | ||||||
| 		 const char *name, const char *parent_name) | 		 const char *name, const char *parent_name) | ||||||
|  | @ -22,23 +24,23 @@ int clk_register(struct clk *clk, const char *drv_name, | ||||||
| 
 | 
 | ||||||
| 	ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent); | 	ret = uclass_get_device_by_name(UCLASS_CLK, parent_name, &parent); | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		printf("%s: failed to get %s device (parent of %s)\n", | 		log_err("%s: failed to get %s device (parent of %s)\n", | ||||||
| 			__func__, parent_name, name); | 			__func__, parent_name, name); | ||||||
| 	} else { | 	} else { | ||||||
| 		debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, | 		log_debug("%s: name: %s parent: %s [0x%p]\n", __func__, name, | ||||||
| 			  parent->name, parent); | 			  parent->name, parent); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	drv = lists_driver_lookup_name(drv_name); | 	drv = lists_driver_lookup_name(drv_name); | ||||||
| 	if (!drv) { | 	if (!drv) { | ||||||
| 		printf("%s: %s is not a valid driver name\n", | 		log_err("%s: %s is not a valid driver name\n", | ||||||
| 			__func__, drv_name); | 			__func__, drv_name); | ||||||
| 		return -ENOENT; | 		return -ENOENT; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret = device_bind(parent, drv, name, NULL, ofnode_null(), &clk->dev); | 	ret = device_bind(parent, drv, name, NULL, ofnode_null(), &clk->dev); | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		printf("%s: CLK: %s driver bind error [%d]!\n", __func__, name, | 		log_err("%s: CLK: %s driver bind error [%d]!\n", __func__, name, | ||||||
| 			ret); | 			ret); | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -5,10 +5,13 @@ | ||||||
|  * Author: Anup Patel <anup.patel@wdc.com> |  * Author: Anup Patel <anup.patel@wdc.com> | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
| #include <div64.h> | #include <div64.h> | ||||||
| #include <dm.h> | #include <dm.h> | ||||||
|  | #include <log.h> | ||||||
| #include <linux/err.h> | #include <linux/err.h> | ||||||
| 
 | 
 | ||||||
| struct clk_fixed_factor { | struct clk_fixed_factor { | ||||||
|  |  | ||||||
|  | @ -3,9 +3,12 @@ | ||||||
|  * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> |  * Copyright (C) 2016 Masahiro Yamada <yamada.masahiro@socionext.com> | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #define LOG_CATEGORY UCLASS_CLK | ||||||
|  | 
 | ||||||
| #include <common.h> | #include <common.h> | ||||||
| #include <clk-uclass.h> | #include <clk-uclass.h> | ||||||
| #include <dm.h> | #include <dm.h> | ||||||
|  | #include <log.h> | ||||||
| #include <dm/device-internal.h> | #include <dm/device-internal.h> | ||||||
| #include <linux/clk-provider.h> | #include <linux/clk-provider.h> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -604,7 +604,8 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, | ||||||
| 
 | 
 | ||||||
| 			if (strstr(uname, "fpga-periph") && | 			if (strstr(uname, "fpga-periph") && | ||||||
| 				(!is_fpgamgr_early_user_mode() || | 				(!is_fpgamgr_early_user_mode() || | ||||||
| 				is_fpgamgr_user_mode())) { | 				is_fpgamgr_user_mode() || | ||||||
|  | 				is_periph_program_force())) { | ||||||
| 				fpga_node_name = uname; | 				fpga_node_name = uname; | ||||||
| 				printf("FPGA: Start to program "); | 				printf("FPGA: Start to program "); | ||||||
| 				printf("peripheral/full bitstream ...\n"); | 				printf("peripheral/full bitstream ...\n"); | ||||||
|  |  | ||||||
|  | @ -250,6 +250,12 @@ config SYS_I2C_MESON | ||||||
| 	  internal buffer holding up to 8 bytes for transfers and supports | 	  internal buffer holding up to 8 bytes for transfers and supports | ||||||
| 	  both 7-bit and 10-bit addresses. | 	  both 7-bit and 10-bit addresses. | ||||||
| 
 | 
 | ||||||
|  | config SYS_I2C_MICROCHIP | ||||||
|  | 	bool "Microchip I2C driver" | ||||||
|  | 	help | ||||||
|  | 	  Add support for the Microchip I2C driver. This is operating on | ||||||
|  | 	  standard mode up to 100 kbits/s and fast mode up to 400 kbits/s. | ||||||
|  | 
 | ||||||
| config SYS_I2C_MXC | config SYS_I2C_MXC | ||||||
| 	bool "NXP MXC I2C driver" | 	bool "NXP MXC I2C driver" | ||||||
| 	help | 	help | ||||||
|  |  | ||||||
|  | @ -28,6 +28,7 @@ obj-$(CONFIG_SYS_I2C_IPROC) += iproc_i2c.o | ||||||
| obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o | obj-$(CONFIG_SYS_I2C_KONA) += kona_i2c.o | ||||||
| obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o | obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o | ||||||
| obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o | obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o | ||||||
|  | obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-microchip.o | ||||||
| obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o | obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o | ||||||
| obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o | obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o | ||||||
| obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o | obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o | ||||||
|  |  | ||||||
|  | @ -0,0 +1,482 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
|  | /*
 | ||||||
|  |  * Microchip I2C controller driver | ||||||
|  |  * | ||||||
|  |  * Copyright (C) 2021 Microchip Technology Inc. | ||||||
|  |  * Padmarao Begari <padmarao.begari@microchip.com> | ||||||
|  |  */ | ||||||
|  | #include <common.h> | ||||||
|  | #include <clk.h> | ||||||
|  | #include <dm.h> | ||||||
|  | #include <i2c.h> | ||||||
|  | #include <asm/io.h> | ||||||
|  | #include <dm/device_compat.h> | ||||||
|  | #include <linux/bitops.h> | ||||||
|  | #include <linux/delay.h> | ||||||
|  | #include <linux/err.h> | ||||||
|  | 
 | ||||||
|  | #define	MICROCHIP_I2C_TIMEOUT	(1000 * 60) | ||||||
|  | 
 | ||||||
|  | #define MPFS_I2C_CTRL	(0x00) | ||||||
|  | #define	CTRL_CR0		(0x00) | ||||||
|  | #define	CTRL_CR1		(0x01) | ||||||
|  | #define	CTRL_AA			BIT(2) | ||||||
|  | #define	CTRL_SI			BIT(3) | ||||||
|  | #define	CTRL_STO		BIT(4) | ||||||
|  | #define	CTRL_STA		BIT(5) | ||||||
|  | #define	CTRL_ENS1		BIT(6) | ||||||
|  | #define	CTRL_CR2		(0x07) | ||||||
|  | #define MPFS_I2C_STATUS							(0x04) | ||||||
|  | #define	STATUS_BUS_ERROR						(0x00) | ||||||
|  | #define	STATUS_M_START_SENT						(0x08) | ||||||
|  | #define	STATUS_M_REPEATED_START_SENT			(0x10) | ||||||
|  | #define	STATUS_M_SLAW_ACK						(0x18) | ||||||
|  | #define	STATUS_M_SLAW_NACK						(0x20) | ||||||
|  | #define	STATUS_M_TX_DATA_ACK					(0x28) | ||||||
|  | #define	STATUS_M_TX_DATA_NACK					(0x30) | ||||||
|  | #define	STATUS_M_ARB_LOST						(0x38) | ||||||
|  | #define	STATUS_M_SLAR_ACK						(0x40) | ||||||
|  | #define	STATUS_M_SLAR_NACK						(0x48) | ||||||
|  | #define	STATUS_M_RX_DATA_ACKED					(0x50) | ||||||
|  | #define	STATUS_M_RX_DATA_NACKED					(0x58) | ||||||
|  | #define	STATUS_S_SLAW_ACKED						(0x60) | ||||||
|  | #define	STATUS_S_ARB_LOST_SLAW_ACKED			(0x68) | ||||||
|  | #define	STATUS_S_GENERAL_CALL_ACKED				(0x70) | ||||||
|  | #define	STATUS_S_ARB_LOST_GENERAL_CALL_ACKED	(0x78) | ||||||
|  | #define	STATUS_S_RX_DATA_ACKED					(0x80) | ||||||
|  | #define	STATUS_S_RX_DATA_NACKED					(0x88) | ||||||
|  | #define	STATUS_S_GENERAL_CALL_RX_DATA_ACKED		(0x90) | ||||||
|  | #define	STATUS_S_GENERAL_CALL_RX_DATA_NACKED	(0x98) | ||||||
|  | #define	STATUS_S_RX_STOP						(0xA0) | ||||||
|  | #define	STATUS_S_SLAR_ACKED						(0xA8) | ||||||
|  | #define	STATUS_S_ARB_LOST_SLAR_ACKED			(0xB0) | ||||||
|  | #define	STATUS_S_TX_DATA_ACK					(0xb8) | ||||||
|  | #define	STATUS_S_TX_DATA_NACK					(0xC0) | ||||||
|  | #define	STATUS_LAST_DATA_ACK					(0xC8) | ||||||
|  | #define	STATUS_M_SMB_MASTER_RESET				(0xD0) | ||||||
|  | #define	STATUS_S_SCL_LOW_TIMEOUT				(0xD8) | ||||||
|  | #define	STATUS_NO_STATE_INFO					(0xF8) | ||||||
|  | #define MPFS_I2C_DATA			(0x08) | ||||||
|  | #define MPFS_I2C_SLAVE0_ADDR	(0x0c) | ||||||
|  | #define MPFS_I2C_SMBUS			(0x10) | ||||||
|  | #define MPFS_I2C_FREQ			(0x14) | ||||||
|  | #define MPFS_I2C_GLITCHREG		(0x18) | ||||||
|  | #define MPFS_I2C_SLAVE1_ADDR	(0x1c) | ||||||
|  | 
 | ||||||
|  | #define PCLK_DIV_256	((0 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2)) | ||||||
|  | #define PCLK_DIV_224	((1 << CTRL_CR0) | (0 << CTRL_CR1) | (0 << CTRL_CR2)) | ||||||
|  | #define PCLK_DIV_192	((0 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2)) | ||||||
|  | #define PCLK_DIV_160	((1 << CTRL_CR0) | (1 << CTRL_CR1) | (0 << CTRL_CR2)) | ||||||
|  | #define PCLK_DIV_960	((0 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2)) | ||||||
|  | #define PCLK_DIV_120	((1 << CTRL_CR0) | (0 << CTRL_CR1) | (1 << CTRL_CR2)) | ||||||
|  | #define PCLK_DIV_60		((0 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2)) | ||||||
|  | #define BCLK_DIV_8		((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2)) | ||||||
|  | #define CLK_MASK		((1 << CTRL_CR0) | (1 << CTRL_CR1) | (1 << CTRL_CR2)) | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * mpfs_i2c_bus - I2C bus context | ||||||
|  |  * @base: pointer to register struct | ||||||
|  |  * @msg_len: number of bytes transferred in msg | ||||||
|  |  * @msg_err: error code for completed message | ||||||
|  |  * @i2c_clk: clock reference for i2c input clock | ||||||
|  |  * @clk_rate: current i2c bus clock rate | ||||||
|  |  * @buf: ptr to msg buffer for easier use. | ||||||
|  |  * @addr: i2c address. | ||||||
|  |  * @isr_status: cached copy of local ISR status. | ||||||
|  |  */ | ||||||
|  | struct mpfs_i2c_bus { | ||||||
|  | 	void __iomem *base; | ||||||
|  | 	size_t msg_len; | ||||||
|  | 	int msg_err; | ||||||
|  | 	struct clk i2c_clk; | ||||||
|  | 	u32 clk_rate; | ||||||
|  | 	u8 *buf; | ||||||
|  | 	u8 addr; | ||||||
|  | 	u32 isr_status; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static inline u8 i2c_8bit_addr_from_msg(const struct i2c_msg *msg) | ||||||
|  | { | ||||||
|  | 	return (msg->addr << 1) | (msg->flags & I2C_M_RD ? 1 : 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void mpfs_i2c_int_clear(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	u8 ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl &= ~CTRL_SI; | ||||||
|  | 	writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void mpfs_i2c_core_disable(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	u8 ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl &= ~CTRL_ENS1; | ||||||
|  | 	writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void mpfs_i2c_core_enable(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	u8 ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl |= CTRL_ENS1; | ||||||
|  | 	writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void mpfs_i2c_reset(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	mpfs_i2c_core_disable(bus); | ||||||
|  | 	mpfs_i2c_core_enable(bus); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void mpfs_i2c_stop(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	u8 ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl |= CTRL_STO; | ||||||
|  | 	writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline int mpfs_generate_divisor(u32 rate, u8 *code) | ||||||
|  | { | ||||||
|  | 	int ret = 0; | ||||||
|  | 
 | ||||||
|  | 	if (rate >= 960) | ||||||
|  | 		*code = PCLK_DIV_960; | ||||||
|  | 	else if (rate >= 256) | ||||||
|  | 		*code = PCLK_DIV_256; | ||||||
|  | 	else if (rate >= 224) | ||||||
|  | 		*code = PCLK_DIV_224; | ||||||
|  | 	else if (rate >= 192) | ||||||
|  | 		*code = PCLK_DIV_192; | ||||||
|  | 	else if (rate >= 160) | ||||||
|  | 		*code = PCLK_DIV_160; | ||||||
|  | 	else if (rate >= 120) | ||||||
|  | 		*code = PCLK_DIV_120; | ||||||
|  | 	else if (rate >= 60) | ||||||
|  | 		*code = PCLK_DIV_60; | ||||||
|  | 	else if (rate >= 8) | ||||||
|  | 		*code = BCLK_DIV_8; | ||||||
|  | 	else | ||||||
|  | 		ret = -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_init(struct mpfs_i2c_bus *bus, struct udevice *dev) | ||||||
|  | { | ||||||
|  | 	u32 clk_rate, divisor; | ||||||
|  | 	u8 clkval, ctrl; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = clk_get_by_index(dev, 0, &bus->i2c_clk); | ||||||
|  | 	if (ret) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	ret = clk_enable(&bus->i2c_clk); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	clk_rate = clk_get_rate(&bus->i2c_clk); | ||||||
|  | 	if (!clk_rate) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	clk_free(&bus->i2c_clk); | ||||||
|  | 
 | ||||||
|  | 	divisor = clk_rate / bus->clk_rate; | ||||||
|  | 
 | ||||||
|  | 	ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl &= ~CLK_MASK; | ||||||
|  | 
 | ||||||
|  | 	ret = mpfs_generate_divisor(divisor, &clkval); | ||||||
|  | 	if (ret) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	ctrl |= clkval; | ||||||
|  | 
 | ||||||
|  | 	writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	/* Reset I2C core */ | ||||||
|  | 	mpfs_i2c_reset(bus); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void mpfs_i2c_transfer(struct mpfs_i2c_bus *bus, u32 data) | ||||||
|  | { | ||||||
|  | 	if (bus->msg_len > 0) | ||||||
|  | 		writel(data, bus->base + MPFS_I2C_DATA); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void mpfs_i2c_empty_rx(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	u8 ctrl; | ||||||
|  | 	u8 data_read; | ||||||
|  | 
 | ||||||
|  | 	if (bus->msg_len > 0) { | ||||||
|  | 		data_read = readl(bus->base + MPFS_I2C_DATA); | ||||||
|  | 		*bus->buf++ = data_read; | ||||||
|  | 		bus->msg_len--; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (bus->msg_len == 0) { | ||||||
|  | 		ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		ctrl &= ~CTRL_AA; | ||||||
|  | 		writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_fill_tx(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	mpfs_i2c_transfer(bus, *bus->buf++); | ||||||
|  | 	bus->msg_len--; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_service_handler(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	bool finish = false; | ||||||
|  | 	u32 status; | ||||||
|  | 	u8 ctrl; | ||||||
|  | 
 | ||||||
|  | 	status = bus->isr_status; | ||||||
|  | 
 | ||||||
|  | 	switch (status)	{ | ||||||
|  | 	case STATUS_M_START_SENT: | ||||||
|  | 	case STATUS_M_REPEATED_START_SENT: | ||||||
|  | 		ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		ctrl &= ~CTRL_STA; | ||||||
|  | 		writel(bus->addr, bus->base + MPFS_I2C_DATA); | ||||||
|  | 		writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		break; | ||||||
|  | 	case STATUS_M_SLAW_ACK: | ||||||
|  | 	case STATUS_M_TX_DATA_ACK: | ||||||
|  | 		if (bus->msg_len > 0) { | ||||||
|  | 			mpfs_i2c_fill_tx(bus); | ||||||
|  | 		} else { | ||||||
|  | 			/* On the last byte to be transmitted, send STOP */ | ||||||
|  | 			mpfs_i2c_stop(bus); | ||||||
|  | 			finish = true; | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	case STATUS_M_SLAR_ACK: | ||||||
|  | 		ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		ctrl |= CTRL_AA; | ||||||
|  | 		writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		if (bus->msg_len == 0) { | ||||||
|  | 			/* On the last byte to be transmitted, send STOP */ | ||||||
|  | 			mpfs_i2c_stop(bus); | ||||||
|  | 			finish = true; | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	case STATUS_M_RX_DATA_ACKED: | ||||||
|  | 		mpfs_i2c_empty_rx(bus); | ||||||
|  | 		if (bus->msg_len == 0) { | ||||||
|  | 			/* On the last byte to be transmitted, send STOP */ | ||||||
|  | 			mpfs_i2c_stop(bus); | ||||||
|  | 			finish = true; | ||||||
|  | 		} | ||||||
|  | 		break; | ||||||
|  | 	case STATUS_M_TX_DATA_NACK: | ||||||
|  | 	case STATUS_M_RX_DATA_NACKED: | ||||||
|  | 	case STATUS_M_SLAR_NACK: | ||||||
|  | 	case STATUS_M_SLAW_NACK: | ||||||
|  | 		bus->msg_err = -ENXIO; | ||||||
|  | 		mpfs_i2c_stop(bus); | ||||||
|  | 		finish = true; | ||||||
|  | 		break; | ||||||
|  | 
 | ||||||
|  | 	case STATUS_M_ARB_LOST: | ||||||
|  | 		/* Handle Lost Arbitration */ | ||||||
|  | 		bus->msg_err = -EAGAIN; | ||||||
|  | 		finish = true; | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		break; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (finish) { | ||||||
|  | 		ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		ctrl &= ~CTRL_AA; | ||||||
|  | 		writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_service(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	int ret = 0; | ||||||
|  | 	int si_bit; | ||||||
|  | 
 | ||||||
|  | 	si_bit = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 	if (si_bit & CTRL_SI) { | ||||||
|  | 		bus->isr_status = readl(bus->base + MPFS_I2C_STATUS); | ||||||
|  | 		ret = mpfs_i2c_service_handler(bus); | ||||||
|  | 	} | ||||||
|  | 	/* Clear the si flag */ | ||||||
|  | 	mpfs_i2c_int_clear(bus); | ||||||
|  | 	si_bit = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_check_service_change(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	u8 ctrl; | ||||||
|  | 	u32 count = 0; | ||||||
|  | 
 | ||||||
|  | 	while (1) { | ||||||
|  | 		ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 		if (ctrl & CTRL_SI) | ||||||
|  | 			break; | ||||||
|  | 		udelay(1); | ||||||
|  | 		count += 1; | ||||||
|  | 		if (count == MICROCHIP_I2C_TIMEOUT) | ||||||
|  | 			return -ETIMEDOUT; | ||||||
|  | 	} | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_poll_device(struct mpfs_i2c_bus *bus) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	while (1) { | ||||||
|  | 		ret = mpfs_i2c_check_service_change(bus); | ||||||
|  | 		if (ret) | ||||||
|  | 			return ret; | ||||||
|  | 
 | ||||||
|  | 		ret = mpfs_i2c_service(bus); | ||||||
|  | 		if (!ret) | ||||||
|  | 			/* all messages have been transferred */ | ||||||
|  | 			return ret; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_xfer_msg(struct mpfs_i2c_bus *bus, struct i2c_msg *msg) | ||||||
|  | { | ||||||
|  | 	u8 ctrl; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (!msg->len || !msg->buf) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	bus->addr = i2c_8bit_addr_from_msg(msg); | ||||||
|  | 	bus->msg_len = msg->len; | ||||||
|  | 	bus->buf = msg->buf; | ||||||
|  | 	bus->msg_err = 0; | ||||||
|  | 
 | ||||||
|  | 	mpfs_i2c_core_enable(bus); | ||||||
|  | 
 | ||||||
|  | 	ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl |= CTRL_STA; | ||||||
|  | 
 | ||||||
|  | 	writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ret = mpfs_i2c_poll_device(bus); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	return bus->msg_err; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_xfer(struct udevice *dev, struct i2c_msg *msgs, int num_msgs) | ||||||
|  | { | ||||||
|  | 	struct mpfs_i2c_bus *bus = dev_get_priv(dev); | ||||||
|  | 	int idx, ret; | ||||||
|  | 
 | ||||||
|  | 	if (!msgs || !num_msgs) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	for (idx = 0; idx < num_msgs; idx++) { | ||||||
|  | 		ret = mpfs_i2c_xfer_msg(bus, msgs++); | ||||||
|  | 		if (ret) | ||||||
|  | 			return ret; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_probe_chip(struct udevice *dev, uint addr, uint flags) | ||||||
|  | { | ||||||
|  | 	struct mpfs_i2c_bus *bus = dev_get_priv(dev); | ||||||
|  | 	int ret; | ||||||
|  | 	u8 ctrl, reg = 0; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Send the chip address and verify that the | ||||||
|  | 	 * address was <ACK>ed. | ||||||
|  | 	 */ | ||||||
|  | 	bus->addr = addr << 1 | I2C_M_RD; | ||||||
|  | 	bus->buf = ® | ||||||
|  | 	bus->msg_len = 0; | ||||||
|  | 	bus->msg_err = 0; | ||||||
|  | 
 | ||||||
|  | 	mpfs_i2c_core_enable(bus); | ||||||
|  | 
 | ||||||
|  | 	ctrl = readl(bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ctrl |= CTRL_STA; | ||||||
|  | 
 | ||||||
|  | 	writel(ctrl, bus->base + MPFS_I2C_CTRL); | ||||||
|  | 
 | ||||||
|  | 	ret = mpfs_i2c_poll_device(bus); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	return bus->msg_err; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int mpfs_i2c_probe(struct udevice *dev) | ||||||
|  | { | ||||||
|  | 	int ret; | ||||||
|  | 	u32 val; | ||||||
|  | 	struct mpfs_i2c_bus *bus = dev_get_priv(dev); | ||||||
|  | 
 | ||||||
|  | 	bus->base = dev_read_addr_ptr(dev); | ||||||
|  | 	if (!bus->base) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	val = dev_read_u32(dev, "clock-frequency", &bus->clk_rate); | ||||||
|  | 	if (val) { | ||||||
|  | 		printf("Default to 100kHz\n"); | ||||||
|  | 		/* default clock rate */ | ||||||
|  | 		bus->clk_rate = 100000; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (bus->clk_rate > 400000 || bus->clk_rate <= 0) { | ||||||
|  | 		printf("Invalid clock-frequency %d\n", bus->clk_rate); | ||||||
|  | 		return -EINVAL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = mpfs_i2c_init(bus, dev); | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const struct dm_i2c_ops mpfs_i2c_ops = { | ||||||
|  | 	.xfer = mpfs_i2c_xfer, | ||||||
|  | 	.probe_chip = mpfs_i2c_probe_chip, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct udevice_id mpfs_i2c_ids[] = { | ||||||
|  | 	{.compatible = "microchip,mpfs-i2c"}, | ||||||
|  | 	{} | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | U_BOOT_DRIVER(mpfs_i2c) = { | ||||||
|  | 	.name = "mpfs_i2c", | ||||||
|  | 	.id = UCLASS_I2C, | ||||||
|  | 	.of_match = mpfs_i2c_ids, | ||||||
|  | 	.ops = &mpfs_i2c_ops, | ||||||
|  | 	.probe = mpfs_i2c_probe, | ||||||
|  | 	.priv_auto = sizeof(struct mpfs_i2c_bus), | ||||||
|  | }; | ||||||
|  | @ -860,6 +860,9 @@ static int mvtwsi_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) | ||||||
| { | { | ||||||
| 	struct mvtwsi_i2c_dev *dev = dev_get_priv(bus); | 	struct mvtwsi_i2c_dev *dev = dev_get_priv(bus); | ||||||
| 	struct i2c_msg *dmsg, *omsg, dummy; | 	struct i2c_msg *dmsg, *omsg, dummy; | ||||||
|  | 	u8 *addr_buf_ptr; | ||||||
|  | 	u8 addr_buf[4]; | ||||||
|  | 	int i; | ||||||
| 
 | 
 | ||||||
| 	memset(&dummy, 0, sizeof(struct i2c_msg)); | 	memset(&dummy, 0, sizeof(struct i2c_msg)); | ||||||
| 
 | 
 | ||||||
|  | @ -873,12 +876,17 @@ static int mvtwsi_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) | ||||||
| 	omsg = nmsgs == 1 ? &dummy : msg; | 	omsg = nmsgs == 1 ? &dummy : msg; | ||||||
| 	dmsg = nmsgs == 1 ? msg : msg + 1; | 	dmsg = nmsgs == 1 ? msg : msg + 1; | ||||||
| 
 | 
 | ||||||
|  | 	/* We need to swap the register address if its size is > 1 */ | ||||||
|  | 	addr_buf_ptr = &addr_buf[0]; | ||||||
|  | 	for (i = omsg->len; i > 0; i--) | ||||||
|  | 		*addr_buf_ptr++ = omsg->buf[i - 1]; | ||||||
|  | 
 | ||||||
| 	if (dmsg->flags & I2C_M_RD) | 	if (dmsg->flags & I2C_M_RD) | ||||||
| 		return __twsi_i2c_read(dev->base, dmsg->addr, omsg->buf, | 		return __twsi_i2c_read(dev->base, dmsg->addr, addr_buf, | ||||||
| 				       omsg->len, dmsg->buf, dmsg->len, | 				       omsg->len, dmsg->buf, dmsg->len, | ||||||
| 				       dev->tick); | 				       dev->tick); | ||||||
| 	else | 	else | ||||||
| 		return __twsi_i2c_write(dev->base, dmsg->addr, omsg->buf, | 		return __twsi_i2c_write(dev->base, dmsg->addr, addr_buf, | ||||||
| 					omsg->len, dmsg->buf, dmsg->len, | 					omsg->len, dmsg->buf, dmsg->len, | ||||||
| 					dev->tick); | 					dev->tick); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1045,16 +1045,10 @@ static int eqos_start(struct udevice *dev) | ||||||
| 	eqos->tx_desc_idx = 0; | 	eqos->tx_desc_idx = 0; | ||||||
| 	eqos->rx_desc_idx = 0; | 	eqos->rx_desc_idx = 0; | ||||||
| 
 | 
 | ||||||
| 	ret = eqos->config->ops->eqos_start_clks(dev); |  | ||||||
| 	if (ret < 0) { |  | ||||||
| 		pr_err("eqos_start_clks() failed: %d", ret); |  | ||||||
| 		goto err; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	ret = eqos->config->ops->eqos_start_resets(dev); | 	ret = eqos->config->ops->eqos_start_resets(dev); | ||||||
| 	if (ret < 0) { | 	if (ret < 0) { | ||||||
| 		pr_err("eqos_start_resets() failed: %d", ret); | 		pr_err("eqos_start_resets() failed: %d", ret); | ||||||
| 		goto err_stop_clks; | 		goto err; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	udelay(10); | 	udelay(10); | ||||||
|  | @ -1360,8 +1354,6 @@ err_shutdown_phy: | ||||||
| 	phy_shutdown(eqos->phy); | 	phy_shutdown(eqos->phy); | ||||||
| err_stop_resets: | err_stop_resets: | ||||||
| 	eqos->config->ops->eqos_stop_resets(dev); | 	eqos->config->ops->eqos_stop_resets(dev); | ||||||
| err_stop_clks: |  | ||||||
| 	eqos->config->ops->eqos_stop_clks(dev); |  | ||||||
| err: | err: | ||||||
| 	pr_err("FAILED: %d", ret); | 	pr_err("FAILED: %d", ret); | ||||||
| 	return ret; | 	return ret; | ||||||
|  | @ -1416,7 +1408,6 @@ static void eqos_stop(struct udevice *dev) | ||||||
| 		phy_shutdown(eqos->phy); | 		phy_shutdown(eqos->phy); | ||||||
| 	} | 	} | ||||||
| 	eqos->config->ops->eqos_stop_resets(dev); | 	eqos->config->ops->eqos_stop_resets(dev); | ||||||
| 	eqos->config->ops->eqos_stop_clks(dev); |  | ||||||
| 
 | 
 | ||||||
| 	debug("%s: OK\n", __func__); | 	debug("%s: OK\n", __func__); | ||||||
| } | } | ||||||
|  | @ -1862,6 +1853,12 @@ static int eqos_probe(struct udevice *dev) | ||||||
| 		goto err_remove_resources_core; | 		goto err_remove_resources_core; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	ret = eqos->config->ops->eqos_start_clks(dev); | ||||||
|  | 	if (ret < 0) { | ||||||
|  | 		pr_err("eqos_start_clks() failed: %d", ret); | ||||||
|  | 		goto err_remove_resources_tegra; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| #ifdef CONFIG_DM_ETH_PHY | #ifdef CONFIG_DM_ETH_PHY | ||||||
| 	eqos->mii = eth_phy_get_mdio_bus(dev); | 	eqos->mii = eth_phy_get_mdio_bus(dev); | ||||||
| #endif | #endif | ||||||
|  | @ -1870,7 +1867,7 @@ static int eqos_probe(struct udevice *dev) | ||||||
| 		if (!eqos->mii) { | 		if (!eqos->mii) { | ||||||
| 			pr_err("mdio_alloc() failed"); | 			pr_err("mdio_alloc() failed"); | ||||||
| 			ret = -ENOMEM; | 			ret = -ENOMEM; | ||||||
| 			goto err_remove_resources_tegra; | 			goto err_stop_clks; | ||||||
| 		} | 		} | ||||||
| 		eqos->mii->read = eqos_mdio_read; | 		eqos->mii->read = eqos_mdio_read; | ||||||
| 		eqos->mii->write = eqos_mdio_write; | 		eqos->mii->write = eqos_mdio_write; | ||||||
|  | @ -1893,6 +1890,8 @@ static int eqos_probe(struct udevice *dev) | ||||||
| 
 | 
 | ||||||
| err_free_mdio: | err_free_mdio: | ||||||
| 	mdio_free(eqos->mii); | 	mdio_free(eqos->mii); | ||||||
|  | err_stop_clks: | ||||||
|  | 	eqos->config->ops->eqos_stop_clks(dev); | ||||||
| err_remove_resources_tegra: | err_remove_resources_tegra: | ||||||
| 	eqos->config->ops->eqos_remove_resources(dev); | 	eqos->config->ops->eqos_remove_resources(dev); | ||||||
| err_remove_resources_core: | err_remove_resources_core: | ||||||
|  | @ -1910,6 +1909,7 @@ static int eqos_remove(struct udevice *dev) | ||||||
| 
 | 
 | ||||||
| 	mdio_unregister(eqos->mii); | 	mdio_unregister(eqos->mii); | ||||||
| 	mdio_free(eqos->mii); | 	mdio_free(eqos->mii); | ||||||
|  | 	eqos->config->ops->eqos_stop_clks(dev); | ||||||
| 	eqos->config->ops->eqos_remove_resources(dev); | 	eqos->config->ops->eqos_remove_resources(dev); | ||||||
| 
 | 
 | ||||||
| 	eqos_probe_resources_core(dev); | 	eqos_probe_resources_core(dev); | ||||||
|  |  | ||||||
|  | @ -138,7 +138,7 @@ static int eth_phy_of_to_plat(struct udevice *dev) | ||||||
| 	ret = gpio_request_by_name(dev, "reset-gpios", 0, | 	ret = gpio_request_by_name(dev, "reset-gpios", 0, | ||||||
| 				   &uc_priv->reset_gpio, | 				   &uc_priv->reset_gpio, | ||||||
| 				   GPIOD_IS_OUT); | 				   GPIOD_IS_OUT); | ||||||
| 	if (ret != -ENOENT) | 	if (ret && ret != -ENOENT) | ||||||
| 		return ret; | 		return ret; | ||||||
| 
 | 
 | ||||||
| 	uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0); | 	uc_priv->reset_assert_delay = dev_read_u32_default(dev, "reset-assert-us", 0); | ||||||
|  |  | ||||||
|  | @ -1348,7 +1348,7 @@ static const struct macb_usrio_cfg macb_default_usrio = { | ||||||
| 	.clken = MACB_BIT(CLKEN), | 	.clken = MACB_BIT(CLKEN), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const struct macb_config default_gem_config = { | static struct macb_config default_gem_config = { | ||||||
| 	.dma_burst_length = 16, | 	.dma_burst_length = 16, | ||||||
| 	.hw_dma_cap = HW_DMA_CAP_32B, | 	.hw_dma_cap = HW_DMA_CAP_32B, | ||||||
| 	.clk_init = NULL, | 	.clk_init = NULL, | ||||||
|  | @ -1383,8 +1383,13 @@ static int macb_eth_probe(struct udevice *dev) | ||||||
| 	macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); | 	macb->is_big_endian = (cpu_to_be32(0x12345678) == 0x12345678); | ||||||
| 
 | 
 | ||||||
| 	macb->config = (struct macb_config *)dev_get_driver_data(dev); | 	macb->config = (struct macb_config *)dev_get_driver_data(dev); | ||||||
| 	if (!macb->config) | 	if (!macb->config) { | ||||||
|  | 		if (IS_ENABLED(CONFIG_DMA_ADDR_T_64BIT)) { | ||||||
|  | 			if (GEM_BFEXT(DAW64, gem_readl(macb, DCFG6))) | ||||||
|  | 				default_gem_config.hw_dma_cap = HW_DMA_CAP_64B; | ||||||
|  | 		} | ||||||
| 		macb->config = &default_gem_config; | 		macb->config = &default_gem_config; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| #ifdef CONFIG_CLK | #ifdef CONFIG_CLK | ||||||
| 	ret = macb_enable_clk(dev); | 	ret = macb_enable_clk(dev); | ||||||
|  | @ -1453,13 +1458,6 @@ static const struct macb_usrio_cfg sama7g5_usrio = { | ||||||
| 	.clken = BIT(2), | 	.clken = BIT(2), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const struct macb_config microchip_config = { |  | ||||||
| 	.dma_burst_length = 16, |  | ||||||
| 	.hw_dma_cap = HW_DMA_CAP_64B, |  | ||||||
| 	.clk_init = NULL, |  | ||||||
| 	.usrio = &macb_default_usrio, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static const struct macb_config sama5d4_config = { | static const struct macb_config sama5d4_config = { | ||||||
| 	.dma_burst_length = 4, | 	.dma_burst_length = 4, | ||||||
| 	.hw_dma_cap = HW_DMA_CAP_32B, | 	.hw_dma_cap = HW_DMA_CAP_32B, | ||||||
|  | @ -1502,8 +1500,6 @@ static const struct udevice_id macb_eth_ids[] = { | ||||||
| 	{ .compatible = "cdns,zynq-gem" }, | 	{ .compatible = "cdns,zynq-gem" }, | ||||||
| 	{ .compatible = "sifive,fu540-c000-gem", | 	{ .compatible = "sifive,fu540-c000-gem", | ||||||
| 	  .data = (ulong)&sifive_config }, | 	  .data = (ulong)&sifive_config }, | ||||||
| 	{ .compatible = "microchip,mpfs-mss-gem", |  | ||||||
| 	  .data = (ulong)µchip_config }, |  | ||||||
| 	{ } | 	{ } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -129,7 +129,7 @@ struct ravb_priv { | ||||||
| 	struct phy_device	*phydev; | 	struct phy_device	*phydev; | ||||||
| 	struct mii_dev		*bus; | 	struct mii_dev		*bus; | ||||||
| 	void __iomem		*iobase; | 	void __iomem		*iobase; | ||||||
| 	struct clk		clk; | 	struct clk_bulk		clks; | ||||||
| 	struct gpio_desc	reset_gpio; | 	struct gpio_desc	reset_gpio; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -485,7 +485,7 @@ static int ravb_probe(struct udevice *dev) | ||||||
| 	iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE); | 	iobase = map_physmem(pdata->iobase, 0x1000, MAP_NOCACHE); | ||||||
| 	eth->iobase = iobase; | 	eth->iobase = iobase; | ||||||
| 
 | 
 | ||||||
| 	ret = clk_get_by_index(dev, 0, ð->clk); | 	ret = clk_get_bulk(dev, ð->clks); | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 		goto err_mdio_alloc; | 		goto err_mdio_alloc; | ||||||
| 
 | 
 | ||||||
|  | @ -518,7 +518,7 @@ static int ravb_probe(struct udevice *dev) | ||||||
| 	eth->bus = miiphy_get_dev_by_name(dev->name); | 	eth->bus = miiphy_get_dev_by_name(dev->name); | ||||||
| 
 | 
 | ||||||
| 	/* Bring up PHY */ | 	/* Bring up PHY */ | ||||||
| 	ret = clk_enable(ð->clk); | 	ret = clk_enable_bulk(ð->clks); | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		goto err_mdio_register; | 		goto err_mdio_register; | ||||||
| 
 | 
 | ||||||
|  | @ -533,7 +533,7 @@ static int ravb_probe(struct udevice *dev) | ||||||
| 	return 0; | 	return 0; | ||||||
| 
 | 
 | ||||||
| err_mdio_reset: | err_mdio_reset: | ||||||
| 	clk_disable(ð->clk); | 	clk_release_bulk(ð->clks); | ||||||
| err_mdio_register: | err_mdio_register: | ||||||
| 	mdio_free(mdiodev); | 	mdio_free(mdiodev); | ||||||
| err_mdio_alloc: | err_mdio_alloc: | ||||||
|  | @ -545,7 +545,7 @@ static int ravb_remove(struct udevice *dev) | ||||||
| { | { | ||||||
| 	struct ravb_priv *eth = dev_get_priv(dev); | 	struct ravb_priv *eth = dev_get_priv(dev); | ||||||
| 
 | 
 | ||||||
| 	clk_disable(ð->clk); | 	clk_release_bulk(ð->clks); | ||||||
| 
 | 
 | ||||||
| 	free(eth->phydev); | 	free(eth->phydev); | ||||||
| 	mdio_unregister(eth->bus); | 	mdio_unregister(eth->bus); | ||||||
|  |  | ||||||
|  | @ -193,7 +193,7 @@ struct pcie_advk { | ||||||
| 	int			sec_busno; | 	int			sec_busno; | ||||||
| 	struct udevice		*dev; | 	struct udevice		*dev; | ||||||
| 	struct gpio_desc	reset_gpio; | 	struct gpio_desc	reset_gpio; | ||||||
| 	u32			cfgcache[0x34 - 0x10]; | 	u32			cfgcache[(0x3c - 0x10) / 4]; | ||||||
| 	bool			cfgcrssve; | 	bool			cfgcrssve; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | @ -380,20 +380,19 @@ static int pcie_advk_read_config(const struct udevice *bus, pci_dev_t bdf, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * The configuration space of the PCI Bridge on primary (local) bus is | 	 * The configuration space of the PCI Bridge on primary (first) bus is | ||||||
| 	 * not accessible via PIO transfers like all other PCIe devices. PCI | 	 * not accessible via PIO transfers like all other PCIe devices. PCI | ||||||
| 	 * Bridge config registers are available directly in Aardvark memory | 	 * Bridge config registers are available directly in Aardvark memory | ||||||
| 	 * space starting at offset zero. Moreover PCI Bridge registers in the | 	 * space starting at offset zero. The PCI Bridge config space is of | ||||||
| 	 * range 0x10 - 0x34 are not available and register 0x38 (Expansion ROM | 	 * Type 0, but the BAR registers (including ROM BAR) don't have the same | ||||||
| 	 * Base Address) is at offset 0x30. | 	 * meaning as in the PCIe specification. Therefore do not access BAR | ||||||
| 	 * We therefore read configuration space content of the primary PCI | 	 * registers and non-common registers (those which have different | ||||||
| 	 * Bridge from our virtual cache. | 	 * meaning for Type 0 and Type 1 config space) of the primary PCI Bridge | ||||||
|  | 	 * and instead read their content from driver virtual cfgcache[]. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (busno == pcie->first_busno) { | 	if (busno == pcie->first_busno) { | ||||||
| 		if (offset >= 0x10 && offset < 0x34) | 		if ((offset >= 0x10 && offset < 0x34) || (offset >= 0x38 && offset < 0x3c)) | ||||||
| 			data = pcie->cfgcache[(offset - 0x10) / 4]; | 			data = pcie->cfgcache[(offset - 0x10) / 4]; | ||||||
| 		else if ((offset & ~3) == PCI_ROM_ADDRESS1) |  | ||||||
| 			data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG); |  | ||||||
| 		else | 		else | ||||||
| 			data = advk_readl(pcie, offset & ~3); | 			data = advk_readl(pcie, offset & ~3); | ||||||
| 
 | 
 | ||||||
|  | @ -567,23 +566,22 @@ static int pcie_advk_write_config(struct udevice *bus, pci_dev_t bdf, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * As explained in pcie_advk_read_config(), for the configuration | 	 * As explained in pcie_advk_read_config(), PCI Bridge config registers | ||||||
| 	 * space of the primary PCI Bridge, we write the content into virtual | 	 * are available directly in Aardvark memory space starting at offset | ||||||
| 	 * cache. | 	 * zero. Type 1 specific registers are not available, so we write their | ||||||
|  | 	 * content only into driver virtual cfgcache[]. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (busno == pcie->first_busno) { | 	if (busno == pcie->first_busno) { | ||||||
| 		if (offset >= 0x10 && offset < 0x34) { | 		if ((offset >= 0x10 && offset < 0x34) || | ||||||
|  | 		    (offset >= 0x38 && offset < 0x3c)) { | ||||||
| 			data = pcie->cfgcache[(offset - 0x10) / 4]; | 			data = pcie->cfgcache[(offset - 0x10) / 4]; | ||||||
| 			data = pci_conv_size_to_32(data, value, offset, size); | 			data = pci_conv_size_to_32(data, value, offset, size); | ||||||
| 			/* This PCI bridge does not have configurable bars */ | 			/* This PCI bridge does not have configurable bars */ | ||||||
| 			if ((offset & ~3) == PCI_BASE_ADDRESS_0 || | 			if ((offset & ~3) == PCI_BASE_ADDRESS_0 || | ||||||
| 			    (offset & ~3) == PCI_BASE_ADDRESS_1) | 			    (offset & ~3) == PCI_BASE_ADDRESS_1 || | ||||||
|  | 			    (offset & ~3) == PCI_ROM_ADDRESS1) | ||||||
| 				data = 0x0; | 				data = 0x0; | ||||||
| 			pcie->cfgcache[(offset - 0x10) / 4] = data; | 			pcie->cfgcache[(offset - 0x10) / 4] = data; | ||||||
| 		} else if ((offset & ~3) == PCI_ROM_ADDRESS1) { |  | ||||||
| 			data = advk_readl(pcie, PCIE_CORE_EXP_ROM_BAR_REG); |  | ||||||
| 			data = pci_conv_size_to_32(data, value, offset, size); |  | ||||||
| 			advk_writel(pcie, data, PCIE_CORE_EXP_ROM_BAR_REG); |  | ||||||
| 		} else { | 		} else { | ||||||
| 			data = advk_readl(pcie, offset & ~3); | 			data = advk_readl(pcie, offset & ~3); | ||||||
| 			data = pci_conv_size_to_32(data, value, offset, size); | 			data = pci_conv_size_to_32(data, value, offset, size); | ||||||
|  | @ -821,12 +819,20 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie) | ||||||
| 	 * | 	 * | ||||||
| 	 * Note that this Aardvark PCI Bridge does not have a compliant Type 1 | 	 * Note that this Aardvark PCI Bridge does not have a compliant Type 1 | ||||||
| 	 * Configuration Space and it even cannot be accessed via Aardvark's | 	 * Configuration Space and it even cannot be accessed via Aardvark's | ||||||
| 	 * PCI config space access method. Something like config space is | 	 * PCI config space access method. Aardvark PCI Bridge Config space is | ||||||
| 	 * available in internal Aardvark registers starting at offset 0x0 | 	 * available in internal Aardvark registers starting at offset 0x0 | ||||||
| 	 * and is reported as Type 0. In range 0x10 - 0x34 it has totally | 	 * and has format of Type 0 config space. | ||||||
| 	 * different registers. So our driver reports Header Type as Type 1 and | 	 * | ||||||
| 	 * for the above mentioned range redirects access to the virtual | 	 * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34) | ||||||
| 	 * cfgcache[] buffer, which avoids changing internal Aardvark registers. | 	 * have the same format in Marvell's specification as in PCIe | ||||||
|  | 	 * specification, but their meaning is totally different (and not even | ||||||
|  | 	 * the same meaning as explained in the corresponding comment in the | ||||||
|  | 	 * pci_mvebu driver; aardvark is still different). | ||||||
|  | 	 * | ||||||
|  | 	 * So our driver converts Type 0 config space to Type 1 and reports | ||||||
|  | 	 * Header Type as Type 1. Access to BAR registers and to non-existent | ||||||
|  | 	 * Type 1 registers is redirected to the virtual cfgcache[] buffer, | ||||||
|  | 	 * which avoids changing unrelated registers. | ||||||
| 	 */ | 	 */ | ||||||
| 	reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG); | 	reg = advk_readl(pcie, PCIE_CORE_DEV_REV_REG); | ||||||
| 	reg &= ~0xffffff00; | 	reg &= ~0xffffff00; | ||||||
|  |  | ||||||
|  | @ -89,7 +89,7 @@ struct mvebu_pcie { | ||||||
| 	unsigned int mem_attr; | 	unsigned int mem_attr; | ||||||
| 	unsigned int io_target; | 	unsigned int io_target; | ||||||
| 	unsigned int io_attr; | 	unsigned int io_attr; | ||||||
| 	u32 cfgcache[0x34 - 0x10]; | 	u32 cfgcache[(0x3c - 0x10) / 4]; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -168,20 +168,20 @@ static int mvebu_pcie_read_config(const struct udevice *bus, pci_dev_t bdf, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * mvebu has different internal registers mapped into PCI config space | 	 * The configuration space of the PCI Bridge on primary (first) bus is | ||||||
| 	 * in range 0x10-0x34 for PCI bridge, so do not access PCI config space | 	 * of Type 0 but the BAR registers (including ROM BAR) don't have the | ||||||
| 	 * for this range and instead read content from driver virtual cfgcache | 	 * same meaning as in the PCIe specification. Therefore do not access | ||||||
|  | 	 * BAR registers and non-common registers (those which have different | ||||||
|  | 	 * meaning for Type 0 and Type 1 config space) of the PCI Bridge and | ||||||
|  | 	 * instead read their content from driver virtual cfgcache[]. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (busno == pcie->first_busno && offset >= 0x10 && offset < 0x34) { | 	if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) || | ||||||
|  | 					   (offset >= 0x38 && offset < 0x3c))) { | ||||||
| 		data = pcie->cfgcache[(offset - 0x10) / 4]; | 		data = pcie->cfgcache[(offset - 0x10) / 4]; | ||||||
| 		debug("(addr,size,val)=(0x%04x, %d, 0x%08x) from cfgcache\n", | 		debug("(addr,size,val)=(0x%04x, %d, 0x%08x) from cfgcache\n", | ||||||
| 		      offset, size, data); | 		      offset, size, data); | ||||||
| 		*valuep = pci_conv_32_to_size(data, offset, size); | 		*valuep = pci_conv_32_to_size(data, offset, size); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} else if (busno == pcie->first_busno && |  | ||||||
| 		   (offset & ~3) == PCI_ROM_ADDRESS1) { |  | ||||||
| 		/* mvebu has Expansion ROM Base Address (0x38) at offset 0x30 */ |  | ||||||
| 		offset -= PCI_ROM_ADDRESS1 - PCIE_EXP_ROM_BAR_OFF; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
|  | @ -248,17 +248,21 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * mvebu has different internal registers mapped into PCI config space | 	 * As explained in mvebu_pcie_read_config(), PCI Bridge Type 1 specific | ||||||
| 	 * in range 0x10-0x34 for PCI bridge, so do not access PCI config space | 	 * config registers are not available, so we write their content only | ||||||
| 	 * for this range and instead write content to driver virtual cfgcache | 	 * into driver virtual cfgcache[]. | ||||||
|  | 	 * And as explained in mvebu_pcie_probe(), mvebu has its own specific | ||||||
|  | 	 * way for configuring primary and secondary bus numbers. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (busno == pcie->first_busno && offset >= 0x10 && offset < 0x34) { | 	if (busno == pcie->first_busno && ((offset >= 0x10 && offset < 0x34) || | ||||||
|  | 					   (offset >= 0x38 && offset < 0x3c))) { | ||||||
| 		debug("Writing to cfgcache only\n"); | 		debug("Writing to cfgcache only\n"); | ||||||
| 		data = pcie->cfgcache[(offset - 0x10) / 4]; | 		data = pcie->cfgcache[(offset - 0x10) / 4]; | ||||||
| 		data = pci_conv_size_to_32(data, value, offset, size); | 		data = pci_conv_size_to_32(data, value, offset, size); | ||||||
| 		/* mvebu PCI bridge does not have configurable bars */ | 		/* mvebu PCI bridge does not have configurable bars */ | ||||||
| 		if ((offset & ~3) == PCI_BASE_ADDRESS_0 || | 		if ((offset & ~3) == PCI_BASE_ADDRESS_0 || | ||||||
| 		    (offset & ~3) == PCI_BASE_ADDRESS_1) | 		    (offset & ~3) == PCI_BASE_ADDRESS_1 || | ||||||
|  | 		    (offset & ~3) == PCI_ROM_ADDRESS1) | ||||||
| 			data = 0x0; | 			data = 0x0; | ||||||
| 		pcie->cfgcache[(offset - 0x10) / 4] = data; | 		pcie->cfgcache[(offset - 0x10) / 4] = data; | ||||||
| 		/* mvebu has its own way how to set PCI primary bus number */ | 		/* mvebu has its own way how to set PCI primary bus number */ | ||||||
|  | @ -276,10 +280,6 @@ static int mvebu_pcie_write_config(struct udevice *bus, pci_dev_t bdf, | ||||||
| 			      pcie->sec_busno); | 			      pcie->sec_busno); | ||||||
| 		} | 		} | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} else if (busno == pcie->first_busno && |  | ||||||
| 		   (offset & ~3) == PCI_ROM_ADDRESS1) { |  | ||||||
| 		/* mvebu has Expansion ROM Base Address (0x38) at offset 0x30 */ |  | ||||||
| 		offset -= PCI_ROM_ADDRESS1 - PCIE_EXP_ROM_BAR_OFF; |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
|  | @ -385,13 +385,20 @@ static int mvebu_pcie_probe(struct udevice *dev) | ||||||
| 	 * U-Boot cannot recognize as P2P Bridge. | 	 * U-Boot cannot recognize as P2P Bridge. | ||||||
| 	 * | 	 * | ||||||
| 	 * Note that this mvebu PCI Bridge does not have compliant Type 1 | 	 * Note that this mvebu PCI Bridge does not have compliant Type 1 | ||||||
| 	 * Configuration Space. Header Type is reported as Type 0 and in | 	 * Configuration Space. Header Type is reported as Type 0 and it | ||||||
| 	 * range 0x10-0x34 it has aliased internal mvebu registers 0x10-0x34 | 	 * has format of Type 0 config space. | ||||||
| 	 * (e.g. PCIE_BAR_LO_OFF) and register 0x38 is reserved. |  | ||||||
| 	 * | 	 * | ||||||
| 	 * Driver for this range redirects access to virtual cfgcache[] buffer | 	 * Moreover Type 0 BAR registers (ranges 0x10 - 0x28 and 0x30 - 0x34) | ||||||
| 	 * which avoids changing internal mvebu registers. And changes Header | 	 * have the same format in Marvell's specification as in PCIe | ||||||
| 	 * Type response value to Type 1. | 	 * specification, but their meaning is totally different and they do | ||||||
|  | 	 * different things: they are aliased into internal mvebu registers | ||||||
|  | 	 * (e.g. PCIE_BAR_LO_OFF) and these should not be changed or | ||||||
|  | 	 * reconfigured by pci device drivers. | ||||||
|  | 	 * | ||||||
|  | 	 * So our driver converts Type 0 config space to Type 1 and reports | ||||||
|  | 	 * Header Type as Type 1. Access to BAR registers and to non-existent | ||||||
|  | 	 * Type 1 registers is redirected to the virtual cfgcache[] buffer, | ||||||
|  | 	 * which avoids changing unrelated registers. | ||||||
| 	 */ | 	 */ | ||||||
| 	reg = readl(pcie->base + PCIE_DEV_REV_OFF); | 	reg = readl(pcie->base + PCIE_DEV_REV_OFF); | ||||||
| 	reg &= ~0xffffff00; | 	reg &= ~0xffffff00; | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ | ||||||
| #include <serial.h> | #include <serial.h> | ||||||
| #include <asm/io.h> | #include <asm/io.h> | ||||||
| #include <asm/arch/cpu.h> | #include <asm/arch/cpu.h> | ||||||
|  | #include <mach/soc.h> | ||||||
| 
 | 
 | ||||||
| struct mvebu_plat { | struct mvebu_plat { | ||||||
| 	void __iomem *base; | 	void __iomem *base; | ||||||
|  | @ -214,6 +215,7 @@ static int mvebu_serial_remove(struct udevice *dev) | ||||||
| 	u32 new_oversampling; | 	u32 new_oversampling; | ||||||
| 	u32 oversampling; | 	u32 oversampling; | ||||||
| 	u32 d1, d2; | 	u32 d1, d2; | ||||||
|  | 	u32 nb_rst; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Switch UART base clock back to XTAL because older Linux kernel | 	 * Switch UART base clock back to XTAL because older Linux kernel | ||||||
|  | @ -261,12 +263,22 @@ static int mvebu_serial_remove(struct udevice *dev) | ||||||
| 			return 0; | 			return 0; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/* wait until TX empty */ | ||||||
| 	while (!(readl(base + UART_STATUS_REG) & UART_STATUS_TX_EMPTY)) | 	while (!(readl(base + UART_STATUS_REG) & UART_STATUS_TX_EMPTY)) | ||||||
| 		; | 		; | ||||||
| 
 | 
 | ||||||
|  | 	/* external reset of UART via North Bridge Peripheral */ | ||||||
|  | 	nb_rst = readl(MVEBU_REGISTER(0x12400)); | ||||||
|  | 	writel(nb_rst & ~BIT(3), MVEBU_REGISTER(0x12400)); | ||||||
|  | 	writel(nb_rst | BIT(3), MVEBU_REGISTER(0x12400)); | ||||||
|  | 
 | ||||||
|  | 	/* set baudrate and oversampling */ | ||||||
| 	writel(new_divider, base + UART_BAUD_REG); | 	writel(new_divider, base + UART_BAUD_REG); | ||||||
| 	writel(new_oversampling, base + UART_POSSR_REG); | 	writel(new_oversampling, base + UART_POSSR_REG); | ||||||
| 
 | 
 | ||||||
|  | 	/* No Parity, 1 Stop */ | ||||||
|  | 	writel(0, base + UART_CTRL_REG); | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -306,7 +318,6 @@ U_BOOT_DRIVER(serial_mvebu) = { | ||||||
| #ifdef CONFIG_DEBUG_MVEBU_A3700_UART | #ifdef CONFIG_DEBUG_MVEBU_A3700_UART | ||||||
| 
 | 
 | ||||||
| #include <debug_uart.h> | #include <debug_uart.h> | ||||||
| #include <mach/soc.h> |  | ||||||
| 
 | 
 | ||||||
| static inline void _debug_uart_init(void) | static inline void _debug_uart_init(void) | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -378,8 +378,14 @@ out: | ||||||
| int tpm_tis_cleanup(struct udevice *dev) | int tpm_tis_cleanup(struct udevice *dev) | ||||||
| { | { | ||||||
| 	struct tpm_chip *chip = dev_get_priv(dev); | 	struct tpm_chip *chip = dev_get_priv(dev); | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = tpm_tis_request_locality(dev, 0); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
| 
 | 
 | ||||||
| 	tpm_tis_ready(dev); | 	tpm_tis_ready(dev); | ||||||
|  | 
 | ||||||
| 	tpm_tis_release_locality(dev, chip->locality); | 	tpm_tis_release_locality(dev, chip->locality); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -118,10 +118,13 @@ iounmap: | ||||||
| static int tpm_tis_remove(struct udevice *dev) | static int tpm_tis_remove(struct udevice *dev) | ||||||
| { | { | ||||||
| 	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); | 	struct tpm_tis_chip_data *drv_data = (void *)dev_get_driver_data(dev); | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = tpm_tis_cleanup(dev); | ||||||
| 
 | 
 | ||||||
| 	iounmap(drv_data->iobase); | 	iounmap(drv_data->iobase); | ||||||
| 
 | 
 | ||||||
| 	return tpm_tis_cleanup(dev); | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct tpm_ops tpm_tis_ops = { | static const struct tpm_ops tpm_tis_ops = { | ||||||
|  |  | ||||||
|  | @ -34,9 +34,10 @@ enum if_type { | ||||||
| 	IF_TYPE_SATA, | 	IF_TYPE_SATA, | ||||||
| 	IF_TYPE_HOST, | 	IF_TYPE_HOST, | ||||||
| 	IF_TYPE_NVME, | 	IF_TYPE_NVME, | ||||||
| 	IF_TYPE_EFI, | 	IF_TYPE_EFI_LOADER, | ||||||
| 	IF_TYPE_PVBLOCK, | 	IF_TYPE_PVBLOCK, | ||||||
| 	IF_TYPE_VIRTIO, | 	IF_TYPE_VIRTIO, | ||||||
|  | 	IF_TYPE_EFI_MEDIA, | ||||||
| 
 | 
 | ||||||
| 	IF_TYPE_COUNT,			/* Number of interface types */ | 	IF_TYPE_COUNT,			/* Number of interface types */ | ||||||
| }; | }; | ||||||
|  | @ -369,6 +370,18 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name, | ||||||
| 		       const char *name, int if_type, int devnum, int blksz, | 		       const char *name, int if_type, int devnum, int blksz, | ||||||
| 		       lbaint_t lba, struct udevice **devp); | 		       lbaint_t lba, struct udevice **devp); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * blk_probe_or_unbind() - Try to probe | ||||||
|  |  * | ||||||
|  |  * Try to probe the device, primarily for enumerating partitions. | ||||||
|  |  * If it fails, the device itself is unbound since it means that it won't | ||||||
|  |  * work any more. | ||||||
|  |  * | ||||||
|  |  * @dev:	The device to probe | ||||||
|  |  * Return:	0 if OK, -ve on error | ||||||
|  |  */ | ||||||
|  | int blk_probe_or_unbind(struct udevice *dev); | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * blk_unbind_all() - Unbind all device of the given interface type |  * blk_unbind_all() - Unbind all device of the given interface type | ||||||
|  * |  * | ||||||
|  |  | ||||||
|  | @ -389,7 +389,8 @@ int clk_free(struct clk *clk); | ||||||
|  * |  * | ||||||
|  * @clk:	A clock struct that was previously successfully requested by |  * @clk:	A clock struct that was previously successfully requested by | ||||||
|  *		clk_request/get_by_*(). |  *		clk_request/get_by_*(). | ||||||
|  * @return clock rate in Hz, or -ve error code. |  * @return clock rate in Hz on success, 0 for invalid clock, or -ve error code | ||||||
|  |  *	   for other errors. | ||||||
|  */ |  */ | ||||||
| ulong clk_get_rate(struct clk *clk); | ulong clk_get_rate(struct clk *clk); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -119,12 +119,23 @@ | ||||||
| /* Increase max gunzip size */ | /* Increase max gunzip size */ | ||||||
| #define CONFIG_SYS_BOOTM_LEN	(64 << 20) | #define CONFIG_SYS_BOOTM_LEN	(64 << 20) | ||||||
| 
 | 
 | ||||||
|  | /* Support autoboot from RAM (kernel image is loaded via debug port) */ | ||||||
|  | #define KERNEL_IMAGE_ADDR	"0x2000000 " | ||||||
|  | #define BOOTENV_DEV_NAME_RAM(devtypeu, devtypel, instance) \ | ||||||
|  | 	"ram " | ||||||
|  | #define BOOTENV_DEV_RAM(devtypeu, devtypel, instance) \ | ||||||
|  | 	"bootcmd_ram=" \ | ||||||
|  | 	"booti " \ | ||||||
|  | 	KERNEL_IMAGE_ADDR \ | ||||||
|  | 	"- $fdtcontroladdr\0" | ||||||
|  | 
 | ||||||
| /* When we use RAM as ENV */ | /* When we use RAM as ENV */ | ||||||
| 
 | 
 | ||||||
| /* Enable distro boot */ | /* Enable distro boot */ | ||||||
| #define BOOT_TARGET_DEVICES(func) \ | #define BOOT_TARGET_DEVICES(func) \ | ||||||
| 	func(MMC, mmc, 0) \ | 	func(MMC, mmc, 0) \ | ||||||
| 	func(DHCP, dhcp, na) | 	func(DHCP, dhcp, na) \ | ||||||
|  | 	func(RAM, ram, na) | ||||||
| #include <config_distro_bootcmd.h> | #include <config_distro_bootcmd.h> | ||||||
| 
 | 
 | ||||||
| #define CONFIG_EXTRA_ENV_SETTINGS	\ | #define CONFIG_EXTRA_ENV_SETTINGS	\ | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ | ||||||
| 	"boot_fdt=try\0" \ | 	"boot_fdt=try\0" \ | ||||||
| 	"fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \ | 	"fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \ | ||||||
| 	"initrd_addr=0x43800000\0"		\ | 	"initrd_addr=0x43800000\0"		\ | ||||||
| 	"mmcdev=0\0" \ | 	"mmcdev=1\0" \ | ||||||
| 	"mmcpart=1\0" \ | 	"mmcpart=1\0" \ | ||||||
| 	"mmcrootpart=2\0" \ | 	"mmcrootpart=2\0" \ | ||||||
| 	"finduuid=part uuid mmc ${mmcdev}:${mmcrootpart} uuid\0" \ | 	"finduuid=part uuid mmc ${mmcdev}:${mmcrootpart} uuid\0" \ | ||||||
|  |  | ||||||
|  | @ -136,7 +136,8 @@ | ||||||
| #if CONFIG_IS_ENABLED(CMD_MMC) | #if CONFIG_IS_ENABLED(CMD_MMC) | ||||||
| 	#define BOOT_TARGET_MMC(func) \ | 	#define BOOT_TARGET_MMC(func) \ | ||||||
| 		func(MMC, mmc, 0) \ | 		func(MMC, mmc, 0) \ | ||||||
| 		func(MMC, mmc, 1) | 		func(MMC, mmc, 1) \ | ||||||
|  | 		func(MMC, mmc, 2) | ||||||
| #else | #else | ||||||
| 	#define BOOT_TARGET_MMC(func) | 	#define BOOT_TARGET_MMC(func) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -971,8 +971,8 @@ static inline bool device_is_on_pci_bus(const struct udevice *dev) | ||||||
|  * @parent: parent device to scan |  * @parent: parent device to scan | ||||||
|  */ |  */ | ||||||
| #define device_foreach_child_of_to_plat(pos, parent)	\ | #define device_foreach_child_of_to_plat(pos, parent)	\ | ||||||
| 	for (int _ret = device_first_child_ofdata_err(parent, &dev); !_ret; \ | 	for (int _ret = device_first_child_ofdata_err(parent, &pos); !_ret; \ | ||||||
| 	     _ret = device_next_child_ofdata_err(&dev)) | 	     _ret = device_next_child_ofdata_err(&pos)) | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * device_foreach_child_probe() - iterate through children, probing them |  * device_foreach_child_probe() - iterate through children, probing them | ||||||
|  | @ -988,8 +988,8 @@ static inline bool device_is_on_pci_bus(const struct udevice *dev) | ||||||
|  * @parent: parent device to scan |  * @parent: parent device to scan | ||||||
|  */ |  */ | ||||||
| #define device_foreach_child_probe(pos, parent)	\ | #define device_foreach_child_probe(pos, parent)	\ | ||||||
| 	for (int _ret = device_first_child_err(parent, &dev); !_ret; \ | 	for (int _ret = device_first_child_err(parent, &pos); !_ret; \ | ||||||
| 	     _ret = device_next_child_err(&dev)) | 	     _ret = device_next_child_err(&pos)) | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * dm_scan_fdt_dev() - Bind child device in the device tree |  * dm_scan_fdt_dev() - Bind child device in the device tree | ||||||
|  |  | ||||||
|  | @ -48,7 +48,8 @@ enum uclass_id { | ||||||
| 	UCLASS_DMA,		/* Direct Memory Access */ | 	UCLASS_DMA,		/* Direct Memory Access */ | ||||||
| 	UCLASS_DSA,		/* Distributed (Ethernet) Switch Architecture */ | 	UCLASS_DSA,		/* Distributed (Ethernet) Switch Architecture */ | ||||||
| 	UCLASS_ECDSA,		/* Elliptic curve cryptographic device */ | 	UCLASS_ECDSA,		/* Elliptic curve cryptographic device */ | ||||||
| 	UCLASS_EFI,		/* EFI managed devices */ | 	UCLASS_EFI_LOADER,	/* Devices created by UEFI applications */ | ||||||
|  | 	UCLASS_EFI_MEDIA,	/* Devices provided by UEFI firmware */ | ||||||
| 	UCLASS_ETH,		/* Ethernet device */ | 	UCLASS_ETH,		/* Ethernet device */ | ||||||
| 	UCLASS_ETH_PHY,		/* Ethernet PHY device */ | 	UCLASS_ETH_PHY,		/* Ethernet PHY device */ | ||||||
| 	UCLASS_FIRMWARE,	/* Firmware */ | 	UCLASS_FIRMWARE,	/* Firmware */ | ||||||
|  |  | ||||||
|  | @ -0,0 +1,196 @@ | ||||||
|  | /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ | ||||||
|  | /* Copyright (c) 2020-2021 Microchip Technology Inc */ | ||||||
|  | 
 | ||||||
|  | #ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H | ||||||
|  | #define _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H | ||||||
|  | 
 | ||||||
|  | #define PLIC_INT_INVALID						0 | ||||||
|  | #define PLIC_INT_L2_METADATA_CORR				1 | ||||||
|  | #define PLIC_INT_L2_METADATA_UNCORR				2 | ||||||
|  | #define PLIC_INT_L2_DATA_CORR					3 | ||||||
|  | #define PLIC_INT_L2_DATA_UNCORR					4 | ||||||
|  | #define PLIC_INT_DMA_CH0_DONE					5 | ||||||
|  | #define PLIC_INT_DMA_CH0_ERR					6 | ||||||
|  | #define PLIC_INT_DMA_CH1_DONE					7 | ||||||
|  | #define PLIC_INT_DMA_CH1_ERR					8 | ||||||
|  | #define PLIC_INT_DMA_CH2_DONE					9 | ||||||
|  | #define PLIC_INT_DMA_CH2_ERR					10 | ||||||
|  | #define PLIC_INT_DMA_CH3_DONE					11 | ||||||
|  | #define PLIC_INT_DMA_CH3_ERR					12 | ||||||
|  | 
 | ||||||
|  | #define PLIC_INT_GPIO0_BIT0_OR_GPIO2_BIT0		13 | ||||||
|  | #define PLIC_INT_GPIO0_BIT1_OR_GPIO2_BIT1		14 | ||||||
|  | #define PLIC_INT_GPIO0_BIT2_OR_GPIO2_BIT2		15 | ||||||
|  | #define PLIC_INT_GPIO0_BIT3_OR_GPIO2_BIT3		16 | ||||||
|  | #define PLIC_INT_GPIO0_BIT4_OR_GPIO2_BIT4		17 | ||||||
|  | #define PLIC_INT_GPIO0_BIT5_OR_GPIO2_BIT5		18 | ||||||
|  | #define PLIC_INT_GPIO0_BIT6_OR_GPIO2_BIT6		19 | ||||||
|  | #define PLIC_INT_GPIO0_BIT7_OR_GPIO2_BIT7		20 | ||||||
|  | #define PLIC_INT_GPIO0_BIT8_OR_GPIO2_BIT8		21 | ||||||
|  | #define PLIC_INT_GPIO0_BIT9_OR_GPIO2_BIT9		22 | ||||||
|  | #define PLIC_INT_GPIO0_BIT10_OR_GPIO2_BIT10		23 | ||||||
|  | #define PLIC_INT_GPIO0_BIT11_OR_GPIO2_BIT11		24 | ||||||
|  | #define PLIC_INT_GPIO0_BIT12_OR_GPIO2_BIT12		25 | ||||||
|  | #define PLIC_INT_GPIO0_BIT13_OR_GPIO2_BIT13		26 | ||||||
|  | #define PLIC_INT_GPIO1_BIT0_OR_GPIO2_BIT14		27 | ||||||
|  | #define PLIC_INT_GPIO1_BIT1_OR_GPIO2_BIT15		28 | ||||||
|  | #define PLIC_INT_GPIO1_BIT2_OR_GPIO2_BIT16		29 | ||||||
|  | #define PLIC_INT_GPIO1_BIT3_OR_GPIO2_BIT17		30 | ||||||
|  | #define PLIC_INT_GPIO1_BIT4_OR_GPIO2_BIT18		31 | ||||||
|  | #define PLIC_INT_GPIO1_BIT5_OR_GPIO2_BIT19		32 | ||||||
|  | #define PLIC_INT_GPIO1_BIT6_OR_GPIO2_BIT20		33 | ||||||
|  | #define PLIC_INT_GPIO1_BIT7_OR_GPIO2_BIT21		34 | ||||||
|  | #define PLIC_INT_GPIO1_BIT8_OR_GPIO2_BIT22		35 | ||||||
|  | #define PLIC_INT_GPIO1_BIT9_OR_GPIO2_BIT23		36 | ||||||
|  | #define PLIC_INT_GPIO1_BIT10_OR_GPIO2_BIT24		37 | ||||||
|  | #define PLIC_INT_GPIO1_BIT11_OR_GPIO2_BIT25		38 | ||||||
|  | #define PLIC_INT_GPIO1_BIT12_OR_GPIO2_BIT26		39 | ||||||
|  | #define PLIC_INT_GPIO1_BIT13_OR_GPIO2_BIT27		40 | ||||||
|  | #define PLIC_INT_GPIO1_BIT14_OR_GPIO2_BIT28		41 | ||||||
|  | #define PLIC_INT_GPIO1_BIT15_OR_GPIO2_BIT29		42 | ||||||
|  | #define PLIC_INT_GPIO1_BIT16_OR_GPIO2_BIT30		43 | ||||||
|  | #define PLIC_INT_GPIO1_BIT17_OR_GPIO2_BIT31		44 | ||||||
|  | #define PLIC_INT_GPIO1_BIT18					45 | ||||||
|  | #define PLIC_INT_GPIO1_BIT19					46 | ||||||
|  | #define PLIC_INT_GPIO1_BIT20					47 | ||||||
|  | #define PLIC_INT_GPIO1_BIT21					48 | ||||||
|  | #define PLIC_INT_GPIO1_BIT22					49 | ||||||
|  | #define PLIC_INT_GPIO1_BIT23					50 | ||||||
|  | #define PLIC_INT_GPIO0_NON_DIRECT				51 | ||||||
|  | #define PLIC_INT_GPIO1_NON_DIRECT				52 | ||||||
|  | #define PLIC_INT_GPIO2_NON_DIRECT				53 | ||||||
|  | #define PLIC_INT_SPI0							54 | ||||||
|  | #define PLIC_INT_SPI1							55 | ||||||
|  | #define PLIC_INT_CAN0							56 | ||||||
|  | #define PLIC_INT_CAN1							57 | ||||||
|  | #define PLIC_INT_I2C0_MAIN						58 | ||||||
|  | #define PLIC_INT_I2C0_ALERT						59 | ||||||
|  | #define PLIC_INT_I2C0_SUS						60 | ||||||
|  | #define PLIC_INT_I2C1_MAIN						61 | ||||||
|  | #define PLIC_INT_I2C1_ALERT						62 | ||||||
|  | #define PLIC_INT_I2C1_SUS						63 | ||||||
|  | #define PLIC_INT_MAC0_INT						64 | ||||||
|  | #define PLIC_INT_MAC0_QUEUE1					65 | ||||||
|  | #define PLIC_INT_MAC0_QUEUE2					66 | ||||||
|  | #define PLIC_INT_MAC0_QUEUE3					67 | ||||||
|  | #define PLIC_INT_MAC0_EMAC						68 | ||||||
|  | #define PLIC_INT_MAC0_MMSL						69 | ||||||
|  | #define PLIC_INT_MAC1_INT						70 | ||||||
|  | #define PLIC_INT_MAC1_QUEUE1					71 | ||||||
|  | #define PLIC_INT_MAC1_QUEUE2					72 | ||||||
|  | #define PLIC_INT_MAC1_QUEUE3					73 | ||||||
|  | #define PLIC_INT_MAC1_EMAC						74 | ||||||
|  | #define PLIC_INT_MAC1_MMSL						75 | ||||||
|  | #define PLIC_INT_DDRC_TRAIN						76 | ||||||
|  | #define PLIC_INT_SCB_INTERRUPT					77 | ||||||
|  | #define PLIC_INT_ECC_ERROR						78 | ||||||
|  | #define PLIC_INT_ECC_CORRECT					79 | ||||||
|  | #define PLIC_INT_RTC_WAKEUP						80 | ||||||
|  | #define PLIC_INT_RTC_MATCH						81 | ||||||
|  | #define PLIC_INT_TIMER1							82 | ||||||
|  | #define PLIC_INT_TIMER2							83 | ||||||
|  | #define PLIC_INT_ENVM							84 | ||||||
|  | #define PLIC_INT_QSPI							85 | ||||||
|  | #define PLIC_INT_USB_DMA						86 | ||||||
|  | #define PLIC_INT_USB_MC							87 | ||||||
|  | #define PLIC_INT_MMC_MAIN						88 | ||||||
|  | #define PLIC_INT_MMC_WAKEUP						89 | ||||||
|  | #define PLIC_INT_MMUART0						90 | ||||||
|  | #define PLIC_INT_MMUART1						91 | ||||||
|  | #define PLIC_INT_MMUART2						92 | ||||||
|  | #define PLIC_INT_MMUART3						93 | ||||||
|  | #define PLIC_INT_MMUART4						94 | ||||||
|  | #define PLIC_INT_G5C_DEVRST						95 | ||||||
|  | #define PLIC_INT_G5C_MESSAGE					96 | ||||||
|  | #define PLIC_INT_USOC_VC_INTERRUPT				97 | ||||||
|  | #define PLIC_INT_USOC_SMB_INTERRUPT				98 | ||||||
|  | #define PLIC_INT_E51_0_MAINTENACE				99 | ||||||
|  | #define PLIC_INT_WDOG0_MRVP						100 | ||||||
|  | #define PLIC_INT_WDOG1_MRVP						101 | ||||||
|  | #define PLIC_INT_WDOG2_MRVP						102 | ||||||
|  | #define PLIC_INT_WDOG3_MRVP						103 | ||||||
|  | #define PLIC_INT_WDOG4_MRVP						104 | ||||||
|  | #define PLIC_INT_WDOG0_TOUT						105 | ||||||
|  | #define PLIC_INT_WDOG1_TOUT						106 | ||||||
|  | #define PLIC_INT_WDOG2_TOUT						107 | ||||||
|  | #define PLIC_INT_WDOG3_TOUT						108 | ||||||
|  | #define PLIC_INT_WDOG4_TOUT						109 | ||||||
|  | #define PLIC_INT_G5C_MSS_SPI					110 | ||||||
|  | #define PLIC_INT_VOLT_TEMP_ALARM				111 | ||||||
|  | #define PLIC_INT_ATHENA_COMPLETE				112 | ||||||
|  | #define PLIC_INT_ATHENA_ALARM					113 | ||||||
|  | #define PLIC_INT_ATHENA_BUS_ERROR				114 | ||||||
|  | #define PLIC_INT_USOC_AXIC_US					115 | ||||||
|  | #define PLIC_INT_USOC_AXIC_DS					116 | ||||||
|  | #define PLIC_INT_SPARE							117 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_0					118 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_1					119 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_2					120 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_3					121 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_4					122 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_5					123 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_6					124 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_7					125 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_8					126 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_9					127 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_10					128 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_11					129 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_12					130 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_13					131 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_14					132 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_15					133 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_16					134 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_17					135 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_18					136 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_19					137 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_20					138 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_21					139 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_22					140 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_23					141 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_24					142 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_25					143 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_26					144 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_27					145 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_28					146 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_29					147 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_30					148 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_31					149 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_32					150 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_33					151 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_34					152 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_35					153 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_36					154 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_37					155 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_38					156 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_39					157 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_40					158 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_41					159 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_42					160 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_43					161 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_44					162 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_45					163 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_46					164 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_47					165 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_48					166 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_49					167 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_50					168 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_51					169 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_52					170 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_53					171 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_54					172 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_55					173 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_56					174 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_57					175 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_58					176 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_59					177 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_60					178 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_61					179 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_62					180 | ||||||
|  | #define PLIC_INT_FABRIC_F2H_63					181 | ||||||
|  | #define PLIC_INT_BUS_ERROR_UNIT_HART_0			182 | ||||||
|  | #define PLIC_INT_BUS_ERROR_UNIT_HART_1			183 | ||||||
|  | #define PLIC_INT_BUS_ERROR_UNIT_HART_2			184 | ||||||
|  | #define PLIC_INT_BUS_ERROR_UNIT_HART_3			185 | ||||||
|  | #define PLIC_INT_BUS_ERROR_UNIT_HART_4			186 | ||||||
|  | 
 | ||||||
|  | #endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_MICROCHIP_MPFS_PLIC_H */ | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | /* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ | ||||||
|  | /* Copyright (c) 2020-2021 Microchip Technology Inc */ | ||||||
|  | 
 | ||||||
|  | #ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H | ||||||
|  | #define _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H | ||||||
|  | 
 | ||||||
|  | #define HART_INT_U_SOFT   0 | ||||||
|  | #define HART_INT_S_SOFT   1 | ||||||
|  | #define HART_INT_M_SOFT   3 | ||||||
|  | #define HART_INT_U_TIMER  4 | ||||||
|  | #define HART_INT_S_TIMER  5 | ||||||
|  | #define HART_INT_M_TIMER  7 | ||||||
|  | #define HART_INT_U_EXT    8 | ||||||
|  | #define HART_INT_S_EXT    9 | ||||||
|  | #define HART_INT_M_EXT    11 | ||||||
|  | 
 | ||||||
|  | #endif /* _DT_BINDINGS_INTERRUPT_CONTROLLER_RISCV_HART_H */ | ||||||
|  | @ -414,6 +414,17 @@ struct efi_priv { | ||||||
| 	void *next_hdr; | 	void *next_hdr; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * EFI attributes of the udevice handled by efi_media driver | ||||||
|  |  * | ||||||
|  |  * @handle: handle of the controller on which this driver is installed | ||||||
|  |  * @blkio: block io protocol proxied by this driver | ||||||
|  |  */ | ||||||
|  | struct efi_media_plat { | ||||||
|  | 	efi_handle_t		handle; | ||||||
|  | 	struct efi_block_io	*blkio; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /* Base address of the EFI image */ | /* Base address of the EFI image */ | ||||||
| extern char image_base[]; | extern char image_base[]; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -525,6 +525,8 @@ efi_status_t efi_disk_register(void); | ||||||
| efi_status_t efi_rng_register(void); | efi_status_t efi_rng_register(void); | ||||||
| /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ | /* Called by efi_init_obj_list() to install EFI_TCG2_PROTOCOL */ | ||||||
| efi_status_t efi_tcg2_register(void); | efi_status_t efi_tcg2_register(void); | ||||||
|  | /* Called by efi_init_obj_list() to do initial measurement */ | ||||||
|  | efi_status_t efi_tcg2_do_initial_measurement(void); | ||||||
| /* measure the pe-coff image, extend PCR and add Event Log */ | /* measure the pe-coff image, extend PCR and add Event Log */ | ||||||
| efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, | efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, | ||||||
| 				   struct efi_loaded_image_obj *handle, | 				   struct efi_loaded_image_obj *handle, | ||||||
|  | @ -988,4 +990,6 @@ efi_status_t efi_esrt_register(void); | ||||||
|  */ |  */ | ||||||
| efi_status_t efi_esrt_populate(void); | efi_status_t efi_esrt_populate(void); | ||||||
| efi_status_t efi_load_capsule_drivers(void); | efi_status_t efi_load_capsule_drivers(void); | ||||||
|  | 
 | ||||||
|  | efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz); | ||||||
| #endif /* _EFI_LOADER_H */ | #endif /* _EFI_LOADER_H */ | ||||||
|  |  | ||||||
|  | @ -512,13 +512,16 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, | ||||||
|  * @dev		TPM device |  * @dev		TPM device | ||||||
|  * @idx		Index of the PCR |  * @idx		Index of the PCR | ||||||
|  * @idx_min_sz	Minimum size in bytes of the pcrSelect array |  * @idx_min_sz	Minimum size in bytes of the pcrSelect array | ||||||
|  |  * @algorithm	Algorithm used, defined in 'enum tpm2_algorithms' | ||||||
|  * @data	Output buffer for contents of the named PCR |  * @data	Output buffer for contents of the named PCR | ||||||
|  |  * @digest_len  len of the data | ||||||
|  * @updates	Optional out parameter: number of updates for this PCR |  * @updates	Optional out parameter: number of updates for this PCR | ||||||
|  * |  * | ||||||
|  * @return code of the operation |  * @return code of the operation | ||||||
|  */ |  */ | ||||||
| u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, | u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, | ||||||
| 		  void *data, unsigned int *updates); | 		  u16 algorithm, void *data, u32 digest_len, | ||||||
|  | 		  unsigned int *updates); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Issue a TPM2_GetCapability command.  This implementation is limited |  * Issue a TPM2_GetCapability command.  This implementation is limited | ||||||
|  |  | ||||||
|  | @ -147,7 +147,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) | ||||||
| 	if (!obj) | 	if (!obj) | ||||||
| 		return -ENOENT; | 		return -ENOENT; | ||||||
| 
 | 
 | ||||||
| 	devnum = blk_find_max_devnum(IF_TYPE_EFI); | 	devnum = blk_find_max_devnum(IF_TYPE_EFI_LOADER); | ||||||
| 	if (devnum == -ENODEV) | 	if (devnum == -ENODEV) | ||||||
| 		devnum = 0; | 		devnum = 0; | ||||||
| 	else if (devnum < 0) | 	else if (devnum < 0) | ||||||
|  | @ -159,8 +159,8 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) | ||||||
| 	sprintf(name, "efiblk#%d", devnum); | 	sprintf(name, "efiblk#%d", devnum); | ||||||
| 
 | 
 | ||||||
| 	/* Create driver model udevice for the EFI block io device */ | 	/* Create driver model udevice for the EFI block io device */ | ||||||
| 	ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum, | 	ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI_LOADER, | ||||||
| 				io->media->block_size, | 				devnum, io->media->block_size, | ||||||
| 				(lbaint_t)io->media->last_block, &bdev); | 				(lbaint_t)io->media->last_block, &bdev); | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		return ret; | 		return ret; | ||||||
|  | @ -209,6 +209,6 @@ static const struct efi_driver_ops driver_ops = { | ||||||
| /* Identify as EFI driver */ | /* Identify as EFI driver */ | ||||||
| U_BOOT_DRIVER(efi_block) = { | U_BOOT_DRIVER(efi_block) = { | ||||||
| 	.name		= "EFI block driver", | 	.name		= "EFI block driver", | ||||||
| 	.id		= UCLASS_EFI, | 	.id		= UCLASS_EFI_LOADER, | ||||||
| 	.ops		= &driver_ops, | 	.ops		= &driver_ops, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -308,7 +308,7 @@ efi_status_t efi_driver_init(void) | ||||||
| 	log_debug("Initializing EFI driver framework\n"); | 	log_debug("Initializing EFI driver framework\n"); | ||||||
| 	for (drv = ll_entry_start(struct driver, driver); | 	for (drv = ll_entry_start(struct driver, driver); | ||||||
| 	     drv < ll_entry_end(struct driver, driver); ++drv) { | 	     drv < ll_entry_end(struct driver, driver); ++drv) { | ||||||
| 		if (drv->id == UCLASS_EFI) { | 		if (drv->id == UCLASS_EFI_LOADER) { | ||||||
| 			ret = efi_add_driver(drv); | 			ret = efi_add_driver(drv); | ||||||
| 			if (ret != EFI_SUCCESS) { | 			if (ret != EFI_SUCCESS) { | ||||||
| 				log_err("Failed to add EFI driver %s\n", | 				log_err("Failed to add EFI driver %s\n", | ||||||
|  | @ -328,7 +328,7 @@ efi_status_t efi_driver_init(void) | ||||||
|  */ |  */ | ||||||
| static int efi_uc_init(struct uclass *class) | static int efi_uc_init(struct uclass *class) | ||||||
| { | { | ||||||
| 	log_debug("Initializing UCLASS_EFI\n"); | 	log_debug("Initializing UCLASS_EFI_LOADER\n"); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -340,13 +340,13 @@ static int efi_uc_init(struct uclass *class) | ||||||
|  */ |  */ | ||||||
| static int efi_uc_destroy(struct uclass *class) | static int efi_uc_destroy(struct uclass *class) | ||||||
| { | { | ||||||
| 	log_debug("Destroying UCLASS_EFI\n"); | 	log_debug("Destroying UCLASS_EFI_LOADER\n"); | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| UCLASS_DRIVER(efi) = { | UCLASS_DRIVER(efi) = { | ||||||
| 	.name		= "efi", | 	.name		= "efi", | ||||||
| 	.id		= UCLASS_EFI, | 	.id		= UCLASS_EFI_LOADER, | ||||||
| 	.init		= efi_uc_init, | 	.init		= efi_uc_init, | ||||||
| 	.destroy	= efi_uc_destroy, | 	.destroy	= efi_uc_destroy, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -308,6 +308,8 @@ config EFI_TCG2_PROTOCOL | ||||||
| 	bool "EFI_TCG2_PROTOCOL support" | 	bool "EFI_TCG2_PROTOCOL support" | ||||||
| 	default y | 	default y | ||||||
| 	depends on TPM_V2 | 	depends on TPM_V2 | ||||||
|  | 	# Sandbox TPM currently fails on GetCapabilities needed for TCG2 | ||||||
|  | 	depends on !SANDBOX | ||||||
| 	select SHA1 | 	select SHA1 | ||||||
| 	select SHA256 | 	select SHA256 | ||||||
| 	select SHA384 | 	select SHA384 | ||||||
|  |  | ||||||
|  | @ -3016,9 +3016,12 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, | ||||||
| 	if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { | 	if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { | ||||||
| 		if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) { | 		if (image_obj->image_type == IMAGE_SUBSYSTEM_EFI_APPLICATION) { | ||||||
| 			ret = efi_tcg2_measure_efi_app_invocation(image_obj); | 			ret = efi_tcg2_measure_efi_app_invocation(image_obj); | ||||||
| 			if (ret != EFI_SUCCESS) { | 			if (ret == EFI_SECURITY_VIOLATION) { | ||||||
| 				log_warning("tcg2 measurement fails(0x%lx)\n", | 				/*
 | ||||||
| 					    ret); | 				 * TCG2 Protocol is installed but no TPM device found, | ||||||
|  | 				 * this is not expected. | ||||||
|  | 				 */ | ||||||
|  | 				return EFI_EXIT(EFI_SECURITY_VIOLATION); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -934,9 +934,16 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj *handle, | ||||||
| 
 | 
 | ||||||
| #if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL) | #if CONFIG_IS_ENABLED(EFI_TCG2_PROTOCOL) | ||||||
| 	/* Measure an PE/COFF image */ | 	/* Measure an PE/COFF image */ | ||||||
| 	if (tcg2_measure_pe_image(efi, efi_size, handle, | 	ret = tcg2_measure_pe_image(efi, efi_size, handle, loaded_image_info); | ||||||
| 				  loaded_image_info)) | 	if (ret == EFI_SECURITY_VIOLATION) { | ||||||
| 		log_err("PE image measurement failed\n"); | 		/*
 | ||||||
|  | 		 * TCG2 Protocol is installed but no TPM device found, | ||||||
|  | 		 * this is not expected. | ||||||
|  | 		 */ | ||||||
|  | 		log_err("PE image measurement failed, no tpm device found\n"); | ||||||
|  | 		goto err; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	/* Copy PE headers */ | 	/* Copy PE headers */ | ||||||
|  |  | ||||||
|  | @ -241,6 +241,10 @@ efi_status_t efi_init_obj_list(void) | ||||||
| 		ret = efi_tcg2_register(); | 		ret = efi_tcg2_register(); | ||||||
| 		if (ret != EFI_SUCCESS) | 		if (ret != EFI_SUCCESS) | ||||||
| 			goto out; | 			goto out; | ||||||
|  | 
 | ||||||
|  | 		ret = efi_tcg2_do_initial_measurement(); | ||||||
|  | 		if (ret == EFI_SECURITY_VIOLATION) | ||||||
|  | 			goto out; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Secure boot */ | 	/* Secure boot */ | ||||||
|  |  | ||||||
|  | @ -153,6 +153,15 @@ static u16 alg_to_len(u16 hash_alg) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static bool is_tcg2_protocol_installed(void) | ||||||
|  | { | ||||||
|  | 	struct efi_handler *handler; | ||||||
|  | 	efi_status_t ret; | ||||||
|  | 
 | ||||||
|  | 	ret = efi_search_protocol(efi_root, &efi_guid_tcg2_protocol, &handler); | ||||||
|  | 	return ret == EFI_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static u32 tcg_event_final_size(struct tpml_digest_values *digest_list) | static u32 tcg_event_final_size(struct tpml_digest_values *digest_list) | ||||||
| { | { | ||||||
| 	u32 len; | 	u32 len; | ||||||
|  | @ -199,6 +208,44 @@ static efi_status_t tcg2_pcr_extend(struct udevice *dev, u32 pcr_index, | ||||||
| 	return EFI_SUCCESS; | 	return EFI_SUCCESS; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* tcg2_pcr_read - Read PCRs for a TPM2 device for a given tpml_digest_values
 | ||||||
|  |  * | ||||||
|  |  * @dev:		device | ||||||
|  |  * @pcr_index:		PCR index | ||||||
|  |  * @digest_list:	list of digest algorithms to extend | ||||||
|  |  * | ||||||
|  |  * @Return: status code | ||||||
|  |  */ | ||||||
|  | static efi_status_t tcg2_pcr_read(struct udevice *dev, u32 pcr_index, | ||||||
|  | 				  struct tpml_digest_values *digest_list) | ||||||
|  | { | ||||||
|  | 	struct tpm_chip_priv *priv; | ||||||
|  | 	unsigned int updates, pcr_select_min; | ||||||
|  | 	u32 rc; | ||||||
|  | 	size_t i; | ||||||
|  | 
 | ||||||
|  | 	priv = dev_get_uclass_priv(dev); | ||||||
|  | 	if (!priv) | ||||||
|  | 		return EFI_DEVICE_ERROR; | ||||||
|  | 
 | ||||||
|  | 	pcr_select_min = priv->pcr_select_min; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < digest_list->count; i++) { | ||||||
|  | 		u16 hash_alg = digest_list->digests[i].hash_alg; | ||||||
|  | 		u8 *digest = (u8 *)&digest_list->digests[i].digest; | ||||||
|  | 
 | ||||||
|  | 		rc = tpm2_pcr_read(dev, pcr_index, pcr_select_min, | ||||||
|  | 				   hash_alg, digest, alg_to_len(hash_alg), | ||||||
|  | 				   &updates); | ||||||
|  | 		if (rc) { | ||||||
|  | 			EFI_PRINT("Failed to read PCR\n"); | ||||||
|  | 			return EFI_DEVICE_ERROR; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* put_event - Append an agile event to an eventlog
 | /* put_event - Append an agile event to an eventlog
 | ||||||
|  * |  * | ||||||
|  * @pcr_index:		PCR index |  * @pcr_index:		PCR index | ||||||
|  | @ -324,6 +371,45 @@ __weak efi_status_t platform_get_tpm2_device(struct udevice **dev) | ||||||
| 	return EFI_NOT_FOUND; | 	return EFI_NOT_FOUND; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * platform_get_eventlog() - retrieve the eventlog address and size | ||||||
|  |  * | ||||||
|  |  * This function retrieves the eventlog address and size if the underlying | ||||||
|  |  * firmware has done some measurements and passed them. | ||||||
|  |  * | ||||||
|  |  * This function may be overridden based on platform specific method of | ||||||
|  |  * passing the eventlog address and size. | ||||||
|  |  * | ||||||
|  |  * @dev:	udevice | ||||||
|  |  * @addr:	eventlog address | ||||||
|  |  * @sz:		eventlog size | ||||||
|  |  * Return:	status code | ||||||
|  |  */ | ||||||
|  | __weak efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, | ||||||
|  | 					  u32 *sz) | ||||||
|  | { | ||||||
|  | 	const u64 *basep; | ||||||
|  | 	const u32 *sizep; | ||||||
|  | 
 | ||||||
|  | 	basep = dev_read_prop(dev, "tpm_event_log_addr", NULL); | ||||||
|  | 	if (!basep) | ||||||
|  | 		return EFI_NOT_FOUND; | ||||||
|  | 
 | ||||||
|  | 	*addr = be64_to_cpup((__force __be64 *)basep); | ||||||
|  | 
 | ||||||
|  | 	sizep = dev_read_prop(dev, "tpm_event_log_size", NULL); | ||||||
|  | 	if (!sizep) | ||||||
|  | 		return EFI_NOT_FOUND; | ||||||
|  | 
 | ||||||
|  | 	*sz = be32_to_cpup((__force __be32 *)sizep); | ||||||
|  | 	if (*sz == 0) { | ||||||
|  | 		log_debug("event log empty\n"); | ||||||
|  | 		return EFI_NOT_FOUND; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * tpm2_get_max_command_size() - get the supported max command size |  * tpm2_get_max_command_size() - get the supported max command size | ||||||
|  * |  * | ||||||
|  | @ -886,9 +972,12 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, | ||||||
| 	IMAGE_NT_HEADERS32 *nt; | 	IMAGE_NT_HEADERS32 *nt; | ||||||
| 	struct efi_handler *handler; | 	struct efi_handler *handler; | ||||||
| 
 | 
 | ||||||
|  | 	if (!is_tcg2_protocol_installed()) | ||||||
|  | 		return EFI_SUCCESS; | ||||||
|  | 
 | ||||||
| 	ret = platform_get_tpm2_device(&dev); | 	ret = platform_get_tpm2_device(&dev); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| 		return ret; | 		return EFI_SECURITY_VIOLATION; | ||||||
| 
 | 
 | ||||||
| 	switch (handle->image_type) { | 	switch (handle->image_type) { | ||||||
| 	case IMAGE_SUBSYSTEM_EFI_APPLICATION: | 	case IMAGE_SUBSYSTEM_EFI_APPLICATION: | ||||||
|  | @ -1181,6 +1270,318 @@ static const struct efi_tcg2_protocol efi_tcg2_protocol = { | ||||||
| 	.get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks, | 	.get_result_of_set_active_pcr_banks = efi_tcg2_get_result_of_set_active_pcr_banks, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * parse_event_log_header() -  Parse and verify the event log header fields | ||||||
|  |  * | ||||||
|  |  * @buffer:			Pointer to the start of the eventlog | ||||||
|  |  * @size:			Size of the eventlog | ||||||
|  |  * @pos:			Return offset of the next event in buffer right | ||||||
|  |  *				after the event header i.e specID | ||||||
|  |  * | ||||||
|  |  * Return:	status code | ||||||
|  |  */ | ||||||
|  | static efi_status_t parse_event_log_header(void *buffer, u32 size, u32 *pos) | ||||||
|  | { | ||||||
|  | 	struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; | ||||||
|  | 	int i = 0; | ||||||
|  | 
 | ||||||
|  | 	if (size < sizeof(*event_header)) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	if (get_unaligned_le32(&event_header->pcr_index) != 0 || | ||||||
|  | 	    get_unaligned_le32(&event_header->event_type) != EV_NO_ACTION) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	for (i = 0; i < sizeof(event_header->digest); i++) { | ||||||
|  | 		if (event_header->digest[i]) | ||||||
|  | 			return EFI_COMPROMISED_DATA; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*pos += sizeof(*event_header); | ||||||
|  | 
 | ||||||
|  | 	return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * parse_specid_event() -  Parse and verify the specID Event in the eventlog | ||||||
|  |  * | ||||||
|  |  * @dev:		udevice | ||||||
|  |  * @buffer:		Pointer to the start of the eventlog | ||||||
|  |  * @log_size:		Size of the eventlog | ||||||
|  |  * @pos:		[in] Offset of specID event in the eventlog buffer | ||||||
|  |  *			[out] Return offset of the next event in the buffer | ||||||
|  |  *			after the specID | ||||||
|  |  * @digest_list:	list of digests in the event | ||||||
|  |  * | ||||||
|  |  * Return:		status code | ||||||
|  |  * @pos			Offset in the eventlog where the specID event ends | ||||||
|  |  * @digest_list:	list of digests in the event | ||||||
|  |  */ | ||||||
|  | static efi_status_t parse_specid_event(struct udevice *dev, void *buffer, | ||||||
|  | 				       u32 log_size, u32 *pos, | ||||||
|  | 				       struct tpml_digest_values *digest_list) | ||||||
|  | { | ||||||
|  | 	struct tcg_efi_spec_id_event *spec_event; | ||||||
|  | 	struct tcg_pcr_event *event_header = (struct tcg_pcr_event *)buffer; | ||||||
|  | 	size_t spec_event_size; | ||||||
|  | 	u32 active = 0, supported = 0, pcr_count = 0, alg_count = 0; | ||||||
|  | 	u32 spec_active = 0; | ||||||
|  | 	u16 hash_alg; | ||||||
|  | 	u8 vendor_sz; | ||||||
|  | 	int err, i; | ||||||
|  | 
 | ||||||
|  | 	if (*pos >= log_size || (*pos + sizeof(*spec_event)) > log_size) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	/* Check specID event data */ | ||||||
|  | 	spec_event = (struct tcg_efi_spec_id_event *)((uintptr_t)buffer + *pos); | ||||||
|  | 	/* Check for signature */ | ||||||
|  | 	if (memcmp(spec_event->signature, TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03, | ||||||
|  | 		   sizeof(TCG_EFI_SPEC_ID_EVENT_SIGNATURE_03))) { | ||||||
|  | 		log_err("specID Event: Signature mismatch\n"); | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (spec_event->spec_version_minor != | ||||||
|  | 			TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MINOR_TPM2 || | ||||||
|  | 	    spec_event->spec_version_major != | ||||||
|  | 			TCG_EFI_SPEC_ID_EVENT_SPEC_VERSION_MAJOR_TPM2) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	if (spec_event->number_of_algorithms > MAX_HASH_COUNT || | ||||||
|  | 	    spec_event->number_of_algorithms < 1) { | ||||||
|  | 		log_err("specID Event: Number of algorithms incorrect\n"); | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	alg_count = spec_event->number_of_algorithms; | ||||||
|  | 
 | ||||||
|  | 	err = tpm2_get_pcr_info(dev, &supported, &active, &pcr_count); | ||||||
|  | 	if (err) | ||||||
|  | 		return EFI_DEVICE_ERROR; | ||||||
|  | 
 | ||||||
|  | 	digest_list->count = 0; | ||||||
|  | 	/*
 | ||||||
|  | 	 * We have to take care that the sequence of algorithms that we record | ||||||
|  | 	 * in digest_list matches the sequence in eventlog. | ||||||
|  | 	 */ | ||||||
|  | 	for (i = 0; i < alg_count; i++) { | ||||||
|  | 		hash_alg = | ||||||
|  | 		  get_unaligned_le16(&spec_event->digest_sizes[i].algorithm_id); | ||||||
|  | 
 | ||||||
|  | 		if (!(supported & alg_to_mask(hash_alg))) { | ||||||
|  | 			log_err("specID Event: Unsupported algorithm\n"); | ||||||
|  | 			return EFI_COMPROMISED_DATA; | ||||||
|  | 		} | ||||||
|  | 		digest_list->digests[digest_list->count++].hash_alg = hash_alg; | ||||||
|  | 
 | ||||||
|  | 		spec_active |= alg_to_mask(hash_alg); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * TCG specification expects the event log to have hashes for all | ||||||
|  | 	 * active PCR's | ||||||
|  | 	 */ | ||||||
|  | 	if (spec_active != active) { | ||||||
|  | 		/*
 | ||||||
|  | 		 * Previous stage bootloader should know all the active PCR's | ||||||
|  | 		 * and use them in the Eventlog. | ||||||
|  | 		 */ | ||||||
|  | 		log_err("specID Event: All active hash alg not present\n"); | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * the size of the spec event and placement of vendor_info_size | ||||||
|  | 	 * depends on supported algoriths | ||||||
|  | 	 */ | ||||||
|  | 	spec_event_size = | ||||||
|  | 		offsetof(struct tcg_efi_spec_id_event, digest_sizes) + | ||||||
|  | 		alg_count * sizeof(spec_event->digest_sizes[0]); | ||||||
|  | 
 | ||||||
|  | 	if (*pos + spec_event_size >= log_size) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	vendor_sz = *(uint8_t *)((uintptr_t)buffer + *pos + spec_event_size); | ||||||
|  | 
 | ||||||
|  | 	spec_event_size += sizeof(vendor_sz) + vendor_sz; | ||||||
|  | 	*pos += spec_event_size; | ||||||
|  | 
 | ||||||
|  | 	if (get_unaligned_le32(&event_header->event_size) != spec_event_size) { | ||||||
|  | 		log_err("specID event: header event size mismatch\n"); | ||||||
|  | 		/* Right way to handle this can be to call SetActive PCR's */ | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * tcg2_parse_event() -  Parse the event in the eventlog | ||||||
|  |  * | ||||||
|  |  * @dev:		udevice | ||||||
|  |  * @buffer:		Pointer to the start of the eventlog | ||||||
|  |  * @log_size:		Size of the eventlog | ||||||
|  |  * @offset:		[in] Offset of the event in the eventlog buffer | ||||||
|  |  *			[out] Return offset of the next event in the buffer | ||||||
|  |  * @digest_list:	list of digests in the event | ||||||
|  |  * @pcr			Index of the PCR in the event | ||||||
|  |  * | ||||||
|  |  * Return:		status code | ||||||
|  |  */ | ||||||
|  | static efi_status_t tcg2_parse_event(struct udevice *dev, void *buffer, | ||||||
|  | 				     u32 log_size, u32 *offset, | ||||||
|  | 				     struct tpml_digest_values *digest_list, | ||||||
|  | 				     u32 *pcr) | ||||||
|  | { | ||||||
|  | 	struct tcg_pcr_event2 *event = NULL; | ||||||
|  | 	u32 count, size, event_size; | ||||||
|  | 	size_t pos; | ||||||
|  | 
 | ||||||
|  | 	event_size = tcg_event_final_size(digest_list); | ||||||
|  | 	if (*offset >= log_size || *offset + event_size > log_size) { | ||||||
|  | 		log_err("Event exceeds log size\n"); | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	event = (struct tcg_pcr_event2 *)((uintptr_t)buffer + *offset); | ||||||
|  | 	*pcr = get_unaligned_le32(&event->pcr_index); | ||||||
|  | 
 | ||||||
|  | 	/* get the count */ | ||||||
|  | 	count = get_unaligned_le32(&event->digests.count); | ||||||
|  | 	if (count != digest_list->count) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	pos = offsetof(struct tcg_pcr_event2, digests); | ||||||
|  | 	pos += offsetof(struct tpml_digest_values, digests); | ||||||
|  | 
 | ||||||
|  | 	for (int i = 0; i < digest_list->count; i++) { | ||||||
|  | 		u16 alg; | ||||||
|  | 		u16 hash_alg = digest_list->digests[i].hash_alg; | ||||||
|  | 		u8 *digest = (u8 *)&digest_list->digests[i].digest; | ||||||
|  | 
 | ||||||
|  | 		alg = get_unaligned_le16((void *)((uintptr_t)event + pos)); | ||||||
|  | 
 | ||||||
|  | 		if (alg != hash_alg) | ||||||
|  | 			return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 		pos += offsetof(struct tpmt_ha, digest); | ||||||
|  | 		memcpy(digest, (void *)((uintptr_t)event + pos), alg_to_len(hash_alg)); | ||||||
|  | 		pos += alg_to_len(hash_alg); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	size = get_unaligned_le32((void *)((uintptr_t)event + pos)); | ||||||
|  | 	event_size += size; | ||||||
|  | 	pos += sizeof(u32); /* tcg_pcr_event2 event_size*/ | ||||||
|  | 	pos += size; | ||||||
|  | 
 | ||||||
|  | 	/* make sure the calculated buffer is what we checked against */ | ||||||
|  | 	if (pos != event_size) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	if (pos > log_size) | ||||||
|  | 		return EFI_COMPROMISED_DATA; | ||||||
|  | 
 | ||||||
|  | 	*offset += pos; | ||||||
|  | 
 | ||||||
|  | 	return EFI_SUCCESS; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * tcg2_get_fw_eventlog() -  Get the eventlog address and size | ||||||
|  |  * | ||||||
|  |  * If the previous firmware has passed some eventlog, this function get it's | ||||||
|  |  * location and check for it's validity. | ||||||
|  |  * | ||||||
|  |  * @dev:		udevice | ||||||
|  |  * @log_buffer:		eventlog address | ||||||
|  |  * @log_sz:		eventlog size | ||||||
|  |  * | ||||||
|  |  * Return:	status code | ||||||
|  |  */ | ||||||
|  | static efi_status_t tcg2_get_fw_eventlog(struct udevice *dev, void *log_buffer, | ||||||
|  | 					 size_t *log_sz) | ||||||
|  | { | ||||||
|  | 	struct tpml_digest_values digest_list; | ||||||
|  | 	void *buffer; | ||||||
|  | 	efi_status_t ret; | ||||||
|  | 	u32 pcr, pos; | ||||||
|  | 	u64 base; | ||||||
|  | 	u32 sz; | ||||||
|  | 	bool extend_pcr = false; | ||||||
|  | 	int i; | ||||||
|  | 
 | ||||||
|  | 	ret = platform_get_eventlog(dev, &base, &sz); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	if (sz > TPM2_EVENT_LOG_SIZE) | ||||||
|  | 		return EFI_VOLUME_FULL; | ||||||
|  | 
 | ||||||
|  | 	buffer = (void *)(uintptr_t)base; | ||||||
|  | 	pos = 0; | ||||||
|  | 	/* Parse the eventlog to check for its validity */ | ||||||
|  | 	ret = parse_event_log_header(buffer, sz, &pos); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	ret = parse_specid_event(dev, buffer, sz, &pos, &digest_list); | ||||||
|  | 	if (ret) { | ||||||
|  | 		log_err("Error parsing SPEC ID Event\n"); | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ret = tcg2_pcr_read(dev, 0, &digest_list); | ||||||
|  | 	if (ret) { | ||||||
|  | 		log_err("Error reading PCR 0\n"); | ||||||
|  | 		return ret; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * If PCR0 is 0, previous firmware didn't have the capability | ||||||
|  | 	 * to extend the PCR. In this scenario, extend the PCR as | ||||||
|  | 	 * the eventlog is parsed. | ||||||
|  | 	 */ | ||||||
|  | 	for (i = 0; i < digest_list.count; i++) { | ||||||
|  | 		u8 hash_buf[TPM2_SHA512_DIGEST_SIZE] = { 0 }; | ||||||
|  | 		u16 hash_alg = digest_list.digests[i].hash_alg; | ||||||
|  | 
 | ||||||
|  | 		if (!memcmp((u8 *)&digest_list.digests[i].digest, hash_buf, | ||||||
|  | 			    alg_to_len(hash_alg))) | ||||||
|  | 			extend_pcr = true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	while (pos < sz) { | ||||||
|  | 		ret = tcg2_parse_event(dev, buffer, sz, &pos, &digest_list, | ||||||
|  | 				       &pcr); | ||||||
|  | 		if (ret) { | ||||||
|  | 			log_err("Error parsing event\n"); | ||||||
|  | 			return ret; | ||||||
|  | 		} | ||||||
|  | 		if (extend_pcr) { | ||||||
|  | 			ret = tcg2_pcr_extend(dev, pcr, &digest_list); | ||||||
|  | 			if (ret != EFI_SUCCESS) { | ||||||
|  | 				log_err("Error in extending PCR\n"); | ||||||
|  | 				return ret; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			/* Clear the digest for next event */ | ||||||
|  | 			for (i = 0; i < digest_list.count; i++) { | ||||||
|  | 				u16 hash_alg = digest_list.digests[i].hash_alg; | ||||||
|  | 				u8 *digest = | ||||||
|  | 				   (u8 *)&digest_list.digests[i].digest; | ||||||
|  | 
 | ||||||
|  | 				memset(digest, 0, alg_to_len(hash_alg)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	memcpy(log_buffer, buffer, sz); | ||||||
|  | 	*log_sz = sz; | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * create_specid_event() - Create the first event in the eventlog |  * create_specid_event() - Create the first event in the eventlog | ||||||
|  * |  * | ||||||
|  | @ -1275,6 +1676,14 @@ void tcg2_uninit(void) | ||||||
| 	event_log.buffer = NULL; | 	event_log.buffer = NULL; | ||||||
| 	efi_free_pool(event_log.final_buffer); | 	efi_free_pool(event_log.final_buffer); | ||||||
| 	event_log.final_buffer = NULL; | 	event_log.final_buffer = NULL; | ||||||
|  | 
 | ||||||
|  | 	if (!is_tcg2_protocol_installed()) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol, | ||||||
|  | 				  (void *)&efi_tcg2_protocol); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		log_err("Failed to remove EFI TCG2 protocol\n"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -1312,69 +1721,6 @@ out: | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 |  | ||||||
|  * efi_init_event_log() - initialize an eventlog |  | ||||||
|  */ |  | ||||||
| static efi_status_t efi_init_event_log(void) |  | ||||||
| { |  | ||||||
| 	/*
 |  | ||||||
| 	 * vendor_info_size is currently set to 0, we need to change the length |  | ||||||
| 	 * and allocate the flexible array member if this changes |  | ||||||
| 	 */ |  | ||||||
| 	struct tcg_pcr_event *event_header = NULL; |  | ||||||
| 	struct udevice *dev; |  | ||||||
| 	size_t spec_event_size; |  | ||||||
| 	efi_status_t ret; |  | ||||||
| 
 |  | ||||||
| 	ret = platform_get_tpm2_device(&dev); |  | ||||||
| 	if (ret != EFI_SUCCESS) |  | ||||||
| 		goto out; |  | ||||||
| 
 |  | ||||||
| 	ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE, |  | ||||||
| 				(void **)&event_log.buffer); |  | ||||||
| 	if (ret != EFI_SUCCESS) |  | ||||||
| 		goto out; |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * initialize log area as 0xff so the OS can easily figure out the |  | ||||||
| 	 * last log entry |  | ||||||
| 	 */ |  | ||||||
| 	memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE); |  | ||||||
| 	event_log.pos = 0; |  | ||||||
| 	event_log.last_event_size = 0; |  | ||||||
| 	event_log.get_event_called = false; |  | ||||||
| 	event_log.ebs_called = false; |  | ||||||
| 	event_log.truncated = false; |  | ||||||
| 
 |  | ||||||
| 	/*
 |  | ||||||
| 	 * The log header is defined to be in SHA1 event log entry format. |  | ||||||
| 	 * Setup event header |  | ||||||
| 	 */ |  | ||||||
| 	event_header =  (struct tcg_pcr_event *)event_log.buffer; |  | ||||||
| 	put_unaligned_le32(0, &event_header->pcr_index); |  | ||||||
| 	put_unaligned_le32(EV_NO_ACTION, &event_header->event_type); |  | ||||||
| 	memset(&event_header->digest, 0, sizeof(event_header->digest)); |  | ||||||
| 	ret = create_specid_event(dev, (void *)((uintptr_t)event_log.buffer + sizeof(*event_header)), |  | ||||||
| 				  &spec_event_size); |  | ||||||
| 	if (ret != EFI_SUCCESS) |  | ||||||
| 		goto free_pool; |  | ||||||
| 	put_unaligned_le32(spec_event_size, &event_header->event_size); |  | ||||||
| 	event_log.pos = spec_event_size + sizeof(*event_header); |  | ||||||
| 	event_log.last_event_size = event_log.pos; |  | ||||||
| 
 |  | ||||||
| 	ret = create_final_event(); |  | ||||||
| 	if (ret != EFI_SUCCESS) |  | ||||||
| 		goto free_pool; |  | ||||||
| 
 |  | ||||||
| out: |  | ||||||
| 	return ret; |  | ||||||
| 
 |  | ||||||
| free_pool: |  | ||||||
| 	efi_free_pool(event_log.buffer); |  | ||||||
| 	event_log.buffer = NULL; |  | ||||||
| 	return ret; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /**
 | /**
 | ||||||
|  * tcg2_measure_event() - common function to add event log and extend PCR |  * tcg2_measure_event() - common function to add event log and extend PCR | ||||||
|  * |  * | ||||||
|  | @ -1427,6 +1773,93 @@ static efi_status_t efi_append_scrtm_version(struct udevice *dev) | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * efi_init_event_log() - initialize an eventlog | ||||||
|  |  * | ||||||
|  |  * Return:		status code | ||||||
|  |  */ | ||||||
|  | static efi_status_t efi_init_event_log(void) | ||||||
|  | { | ||||||
|  | 	/*
 | ||||||
|  | 	 * vendor_info_size is currently set to 0, we need to change the length | ||||||
|  | 	 * and allocate the flexible array member if this changes | ||||||
|  | 	 */ | ||||||
|  | 	struct tcg_pcr_event *event_header = NULL; | ||||||
|  | 	struct udevice *dev; | ||||||
|  | 	size_t spec_event_size; | ||||||
|  | 	efi_status_t ret; | ||||||
|  | 
 | ||||||
|  | 	ret = platform_get_tpm2_device(&dev); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE, | ||||||
|  | 				(void **)&event_log.buffer); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * initialize log area as 0xff so the OS can easily figure out the | ||||||
|  | 	 * last log entry | ||||||
|  | 	 */ | ||||||
|  | 	memset(event_log.buffer, 0xff, TPM2_EVENT_LOG_SIZE); | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * The log header is defined to be in SHA1 event log entry format. | ||||||
|  | 	 * Setup event header | ||||||
|  | 	 */ | ||||||
|  | 	event_header =  (struct tcg_pcr_event *)event_log.buffer; | ||||||
|  | 	event_log.pos = 0; | ||||||
|  | 	event_log.last_event_size = 0; | ||||||
|  | 	event_log.get_event_called = false; | ||||||
|  | 	event_log.ebs_called = false; | ||||||
|  | 	event_log.truncated = false; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * Check if earlier firmware have passed any eventlog. Different | ||||||
|  | 	 * platforms can use different ways to do so. | ||||||
|  | 	 */ | ||||||
|  | 	ret = tcg2_get_fw_eventlog(dev, event_log.buffer, &event_log.pos); | ||||||
|  | 	/*
 | ||||||
|  | 	 * If earlier firmware hasn't passed any eventlog, go ahead and | ||||||
|  | 	 * create the eventlog header. | ||||||
|  | 	 */ | ||||||
|  | 	if (ret == EFI_NOT_FOUND) { | ||||||
|  | 		put_unaligned_le32(0, &event_header->pcr_index); | ||||||
|  | 		put_unaligned_le32(EV_NO_ACTION, &event_header->event_type); | ||||||
|  | 		memset(&event_header->digest, 0, sizeof(event_header->digest)); | ||||||
|  | 		ret = create_specid_event(dev, | ||||||
|  | 					  (void *)((uintptr_t)event_log.buffer + | ||||||
|  | 						   sizeof(*event_header)), | ||||||
|  | 					  &spec_event_size); | ||||||
|  | 		if (ret != EFI_SUCCESS) | ||||||
|  | 			goto free_pool; | ||||||
|  | 		put_unaligned_le32(spec_event_size, &event_header->event_size); | ||||||
|  | 		event_log.pos = spec_event_size + sizeof(*event_header); | ||||||
|  | 		event_log.last_event_size = event_log.pos; | ||||||
|  | 
 | ||||||
|  | 		/*
 | ||||||
|  | 		 * Add SCRTM version to the log if previous firmmware | ||||||
|  | 		 * doesn't pass an eventlog. | ||||||
|  | 		 */ | ||||||
|  | 		ret = efi_append_scrtm_version(dev); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		goto free_pool; | ||||||
|  | 
 | ||||||
|  | 	ret = create_final_event(); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		goto free_pool; | ||||||
|  | 
 | ||||||
|  | 	return ret; | ||||||
|  | 
 | ||||||
|  | free_pool: | ||||||
|  | 	efi_free_pool(event_log.buffer); | ||||||
|  | 	event_log.buffer = NULL; | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * tcg2_measure_variable() - add variable event log and extend PCR |  * tcg2_measure_variable() - add variable event log and extend PCR | ||||||
|  * |  * | ||||||
|  | @ -1759,12 +2192,15 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(struct efi_loaded_image_obj *ha | ||||||
| 	u32 event = 0; | 	u32 event = 0; | ||||||
| 	struct smbios_entry *entry; | 	struct smbios_entry *entry; | ||||||
| 
 | 
 | ||||||
|  | 	if (!is_tcg2_protocol_installed()) | ||||||
|  | 		return EFI_SUCCESS; | ||||||
|  | 
 | ||||||
| 	if (tcg2_efi_app_invoked) | 	if (tcg2_efi_app_invoked) | ||||||
| 		return EFI_SUCCESS; | 		return EFI_SUCCESS; | ||||||
| 
 | 
 | ||||||
| 	ret = platform_get_tpm2_device(&dev); | 	ret = platform_get_tpm2_device(&dev); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| 		return ret; | 		return EFI_SECURITY_VIOLATION; | ||||||
| 
 | 
 | ||||||
| 	ret = tcg2_measure_boot_variable(dev); | 	ret = tcg2_measure_boot_variable(dev); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
|  | @ -1809,6 +2245,9 @@ efi_status_t efi_tcg2_measure_efi_app_exit(void) | ||||||
| 	efi_status_t ret; | 	efi_status_t ret; | ||||||
| 	struct udevice *dev; | 	struct udevice *dev; | ||||||
| 
 | 
 | ||||||
|  | 	if (!is_tcg2_protocol_installed()) | ||||||
|  | 		return EFI_SUCCESS; | ||||||
|  | 
 | ||||||
| 	ret = platform_get_tpm2_device(&dev); | 	ret = platform_get_tpm2_device(&dev); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| 		return ret; | 		return ret; | ||||||
|  | @ -1834,6 +2273,12 @@ efi_tcg2_notify_exit_boot_services(struct efi_event *event, void *context) | ||||||
| 	EFI_ENTRY("%p, %p", event, context); | 	EFI_ENTRY("%p, %p", event, context); | ||||||
| 
 | 
 | ||||||
| 	event_log.ebs_called = true; | 	event_log.ebs_called = true; | ||||||
|  | 
 | ||||||
|  | 	if (!is_tcg2_protocol_installed()) { | ||||||
|  | 		ret = EFI_SUCCESS; | ||||||
|  | 		goto out; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	ret = platform_get_tpm2_device(&dev); | 	ret = platform_get_tpm2_device(&dev); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -1863,6 +2308,9 @@ efi_status_t efi_tcg2_notify_exit_boot_services_failed(void) | ||||||
| 	struct udevice *dev; | 	struct udevice *dev; | ||||||
| 	efi_status_t ret; | 	efi_status_t ret; | ||||||
| 
 | 
 | ||||||
|  | 	if (!is_tcg2_protocol_installed()) | ||||||
|  | 		return EFI_SUCCESS; | ||||||
|  | 
 | ||||||
| 	ret = platform_get_tpm2_device(&dev); | 	ret = platform_get_tpm2_device(&dev); | ||||||
| 	if (ret != EFI_SUCCESS) | 	if (ret != EFI_SUCCESS) | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -1932,12 +2380,37 @@ error: | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * efi_tcg2_do_initial_measurement() - do initial measurement | ||||||
|  |  * | ||||||
|  |  * Return:	status code | ||||||
|  |  */ | ||||||
|  | efi_status_t efi_tcg2_do_initial_measurement(void) | ||||||
|  | { | ||||||
|  | 	efi_status_t ret; | ||||||
|  | 	struct udevice *dev; | ||||||
|  | 
 | ||||||
|  | 	if (!is_tcg2_protocol_installed()) | ||||||
|  | 		return EFI_SUCCESS; | ||||||
|  | 
 | ||||||
|  | 	ret = platform_get_tpm2_device(&dev); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		return EFI_SECURITY_VIOLATION; | ||||||
|  | 
 | ||||||
|  | 	ret = tcg2_measure_secure_boot_variable(dev); | ||||||
|  | 	if (ret != EFI_SUCCESS) | ||||||
|  | 		goto out; | ||||||
|  | 
 | ||||||
|  | out: | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * efi_tcg2_register() - register EFI_TCG2_PROTOCOL |  * efi_tcg2_register() - register EFI_TCG2_PROTOCOL | ||||||
|  * |  * | ||||||
|  * If a TPM2 device is available, the TPM TCG2 Protocol is registered |  * If a TPM2 device is available, the TPM TCG2 Protocol is registered | ||||||
|  * |  * | ||||||
|  * Return:	An error status is only returned if adding the protocol fails. |  * Return:	status code | ||||||
|  */ |  */ | ||||||
| efi_status_t efi_tcg2_register(void) | efi_status_t efi_tcg2_register(void) | ||||||
| { | { | ||||||
|  | @ -1960,10 +2433,6 @@ efi_status_t efi_tcg2_register(void) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret = efi_init_event_log(); | 	ret = efi_init_event_log(); | ||||||
| 	if (ret != EFI_SUCCESS) |  | ||||||
| 		goto fail; |  | ||||||
| 
 |  | ||||||
| 	ret = efi_append_scrtm_version(dev); |  | ||||||
| 	if (ret != EFI_SUCCESS) { | 	if (ret != EFI_SUCCESS) { | ||||||
| 		tcg2_uninit(); | 		tcg2_uninit(); | ||||||
| 		goto fail; | 		goto fail; | ||||||
|  | @ -1984,24 +2453,9 @@ efi_status_t efi_tcg2_register(void) | ||||||
| 		goto fail; | 		goto fail; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret = tcg2_measure_secure_boot_variable(dev); |  | ||||||
| 	if (ret != EFI_SUCCESS) { |  | ||||||
| 		tcg2_uninit(); |  | ||||||
| 		goto fail; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return ret; | 	return ret; | ||||||
| 
 | 
 | ||||||
| fail: | fail: | ||||||
| 	log_err("Cannot install EFI_TCG2_PROTOCOL\n"); | 	log_err("Cannot install EFI_TCG2_PROTOCOL\n"); | ||||||
| 	/*
 | 	return ret; | ||||||
| 	 * Return EFI_SUCCESS and don't stop the EFI subsystem. |  | ||||||
| 	 * That's done for 2 reasons |  | ||||||
| 	 * - If the protocol is not installed the PCRs won't be extended.  So |  | ||||||
| 	 *   someone later in the boot flow will notice that and take the |  | ||||||
| 	 *   necessary actions. |  | ||||||
| 	 * - The TPM sandbox is limited and we won't be able to run any efi |  | ||||||
| 	 *   related tests with TCG2 enabled |  | ||||||
| 	 */ |  | ||||||
| 	return EFI_SUCCESS; |  | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								lib/tpm-v2.c
								
								
								
								
							
							
						
						
									
										12
									
								
								lib/tpm-v2.c
								
								
								
								
							|  | @ -254,7 +254,8 @@ u32 tpm2_nv_write_value(struct udevice *dev, u32 index, const void *data, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, | u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, | ||||||
| 		  void *data, unsigned int *updates) | 		  u16 algorithm, void *data, u32 digest_len, | ||||||
|  | 		  unsigned int *updates) | ||||||
| { | { | ||||||
| 	u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); | 	u8 idx_array_sz = max(idx_min_sz, DIV_ROUND_UP(idx, 8)); | ||||||
| 	u8 command_v2[COMMAND_BUFFER_SIZE] = { | 	u8 command_v2[COMMAND_BUFFER_SIZE] = { | ||||||
|  | @ -264,7 +265,7 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, | ||||||
| 
 | 
 | ||||||
| 		/* TPML_PCR_SELECTION */ | 		/* TPML_PCR_SELECTION */ | ||||||
| 		tpm_u32(1),			/* Number of selections */ | 		tpm_u32(1),			/* Number of selections */ | ||||||
| 		tpm_u16(TPM2_ALG_SHA256),	/* Algorithm of the hash */ | 		tpm_u16(algorithm),		/* Algorithm of the hash */ | ||||||
| 		idx_array_sz,			/* Array size for selection */ | 		idx_array_sz,			/* Array size for selection */ | ||||||
| 		/* bitmap(idx)			   Selected PCR bitmap */ | 		/* bitmap(idx)			   Selected PCR bitmap */ | ||||||
| 	}; | 	}; | ||||||
|  | @ -283,10 +284,13 @@ u32 tpm2_pcr_read(struct udevice *dev, u32 idx, unsigned int idx_min_sz, | ||||||
| 	if (ret) | 	if (ret) | ||||||
| 		return ret; | 		return ret; | ||||||
| 
 | 
 | ||||||
|  | 	if (digest_len > response_len) | ||||||
|  | 		return TPM_LIB_ERROR; | ||||||
|  | 
 | ||||||
| 	if (unpack_byte_string(response, response_len, "ds", | 	if (unpack_byte_string(response, response_len, "ds", | ||||||
| 			       10, &counter, | 			       10, &counter, | ||||||
| 			       response_len - TPM2_DIGEST_LEN, data, | 			       response_len - digest_len, data, | ||||||
| 			       TPM2_DIGEST_LEN)) | 			       digest_len)) | ||||||
| 		return TPM_LIB_ERROR; | 		return TPM_LIB_ERROR; | ||||||
| 
 | 
 | ||||||
| 	if (updates) | 	if (updates) | ||||||
|  |  | ||||||
|  | @ -37,6 +37,7 @@ obj-$(CONFIG_DMA) += dma.o | ||||||
| obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o | obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o | ||||||
| obj-$(CONFIG_DM_DSA) += dsa.o | obj-$(CONFIG_DM_DSA) += dsa.o | ||||||
| obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o | obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o | ||||||
|  | obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o | ||||||
| obj-$(CONFIG_DM_ETH) += eth.o | obj-$(CONFIG_DM_ETH) += eth.o | ||||||
| ifneq ($(CONFIG_EFI_PARTITION),) | ifneq ($(CONFIG_EFI_PARTITION),) | ||||||
| obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o | obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o | ||||||
|  |  | ||||||
|  | @ -0,0 +1,24 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
|  | /*
 | ||||||
|  |  * Test for EFI_MEDIA uclass | ||||||
|  |  * | ||||||
|  |  * Copyright 2021 Google LLC | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <dm.h> | ||||||
|  | #include <asm/test.h> | ||||||
|  | #include <dm/test.h> | ||||||
|  | #include <test/test.h> | ||||||
|  | #include <test/ut.h> | ||||||
|  | 
 | ||||||
|  | /* Test that we can use the EFI_MEDIA uclass */ | ||||||
|  | static int dm_test_efi_media(struct unit_test_state *uts) | ||||||
|  | { | ||||||
|  | 	struct udevice *dev; | ||||||
|  | 
 | ||||||
|  | 	ut_assertok(uclass_first_device_err(UCLASS_EFI_MEDIA, &dev)); | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | DM_TEST(dm_test_efi_media, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); | ||||||
|  | @ -210,3 +210,23 @@ def test_efi_selftest_text_input_ex(u_boot_console): | ||||||
|     if m != 0: |     if m != 0: | ||||||
|         raise Exception('Failures occurred during the EFI selftest') |         raise Exception('Failures occurred during the EFI selftest') | ||||||
|     u_boot_console.restart_uboot() |     u_boot_console.restart_uboot() | ||||||
|  | 
 | ||||||
|  | @pytest.mark.buildconfigspec('cmd_bootefi_selftest') | ||||||
|  | @pytest.mark.buildconfigspec('efi_tcg2_protocol') | ||||||
|  | def test_efi_selftest_tcg2(u_boot_console): | ||||||
|  |     """Test the EFI_TCG2 PROTOCOL | ||||||
|  | 
 | ||||||
|  |     :param u_boot_console: U-Boot console | ||||||
|  | 
 | ||||||
|  |     This function executes the 'tcg2' unit test. | ||||||
|  |     """ | ||||||
|  |     u_boot_console.restart_uboot() | ||||||
|  |     u_boot_console.run_command(cmd='setenv efi_selftest list') | ||||||
|  |     output = u_boot_console.run_command('bootefi selftest') | ||||||
|  |     assert '\'tcg2\'' in output | ||||||
|  |     u_boot_console.run_command(cmd='setenv efi_selftest tcg2') | ||||||
|  |     u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False) | ||||||
|  |     m = u_boot_console.p.expect(['Summary: 0 failures', 'Press any key']) | ||||||
|  |     if m != 0: | ||||||
|  |         raise Exception('Failures occurred during the EFI selftest') | ||||||
|  |     u_boot_console.restart_uboot() | ||||||
|  |  | ||||||
|  | @ -186,6 +186,7 @@ def test_tpm2_change_auth(u_boot_console): | ||||||
|     u_boot_console.run_command('tpm2 clear TPM2_RH_PLATFORM') |     u_boot_console.run_command('tpm2 clear TPM2_RH_PLATFORM') | ||||||
|     assert output.endswith('0') |     assert output.endswith('0') | ||||||
| 
 | 
 | ||||||
|  | @pytest.mark.buildconfigspec('sandbox') | ||||||
| @pytest.mark.buildconfigspec('cmd_tpm_v2') | @pytest.mark.buildconfigspec('cmd_tpm_v2') | ||||||
| def test_tpm2_get_capability(u_boot_console): | def test_tpm2_get_capability(u_boot_console): | ||||||
|     """Execute a TPM_GetCapability command. |     """Execute a TPM_GetCapability command. | ||||||
|  |  | ||||||
|  | @ -1083,12 +1083,6 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	erase.length = erasesize; | 	erase.length = erasesize; | ||||||
| 	if (DEVTYPE(dev) != MTD_ABSENT) { |  | ||||||
| 		was_locked = ioctl(fd, MEMISLOCKED, &erase); |  | ||||||
| 		/* treat any errors as unlocked flash */ |  | ||||||
| 		if (was_locked < 0) |  | ||||||
| 			was_locked = 0; |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	/* This only runs once on NOR flash and SPI-dataflash */ | 	/* This only runs once on NOR flash and SPI-dataflash */ | ||||||
| 	while (processed < write_total) { | 	while (processed < write_total) { | ||||||
|  | @ -1108,6 +1102,10 @@ static int flash_write_buf(int dev, int fd, void *buf, size_t count) | ||||||
| 
 | 
 | ||||||
| 		if (DEVTYPE(dev) != MTD_ABSENT) { | 		if (DEVTYPE(dev) != MTD_ABSENT) { | ||||||
| 			erase.start = blockstart; | 			erase.start = blockstart; | ||||||
|  | 			was_locked = ioctl(fd, MEMISLOCKED, &erase); | ||||||
|  | 			/* treat any errors as unlocked flash */ | ||||||
|  | 			if (was_locked < 0) | ||||||
|  | 					was_locked = 0; | ||||||
| 			if (was_locked) | 			if (was_locked) | ||||||
| 				ioctl(fd, MEMUNLOCK, &erase); | 				ioctl(fd, MEMUNLOCK, &erase); | ||||||
| 			/* These do not need an explicit erase cycle */ | 			/* These do not need an explicit erase cycle */ | ||||||
|  | @ -1163,7 +1161,6 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset) | ||||||
| 	char tmp = ENV_REDUND_OBSOLETE; | 	char tmp = ENV_REDUND_OBSOLETE; | ||||||
| 	int was_locked;	/* flash lock flag */ | 	int was_locked;	/* flash lock flag */ | ||||||
| 
 | 
 | ||||||
| 	was_locked = ioctl(fd, MEMISLOCKED, &erase); |  | ||||||
| 	erase.start = DEVOFFSET(dev); | 	erase.start = DEVOFFSET(dev); | ||||||
| 	erase.length = DEVESIZE(dev); | 	erase.length = DEVESIZE(dev); | ||||||
| 	/* This relies on the fact, that ENV_REDUND_OBSOLETE == 0 */ | 	/* This relies on the fact, that ENV_REDUND_OBSOLETE == 0 */ | ||||||
|  | @ -1173,6 +1170,10 @@ static int flash_flag_obsolete(int dev, int fd, off_t offset) | ||||||
| 			DEVNAME(dev)); | 			DEVNAME(dev)); | ||||||
| 		return rc; | 		return rc; | ||||||
| 	} | 	} | ||||||
|  | 	was_locked = ioctl(fd, MEMISLOCKED, &erase); | ||||||
|  | 	/* treat any errors as unlocked flash */ | ||||||
|  | 	if (was_locked < 0) | ||||||
|  | 		was_locked = 0; | ||||||
| 	if (was_locked) | 	if (was_locked) | ||||||
| 		ioctl(fd, MEMUNLOCK, &erase); | 		ioctl(fd, MEMUNLOCK, &erase); | ||||||
| 	rc = write(fd, &tmp, sizeof(tmp)); | 	rc = write(fd, &tmp, sizeof(tmp)); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue