Merge branch 'master' of git://git.denx.de/u-boot-socfpga
- Various stratix10, gen5 updates
This commit is contained in:
		
						commit
						b4fde1633e
					
				|  | @ -0,0 +1,19 @@ | |||
| // SPDX-License-Identifier: GPL-2.0+ | ||||
| /* | ||||
|  * U-Boot additions | ||||
|  * | ||||
|  * Copyright (c) 2019 Simon Goldschmidt | ||||
|  */ | ||||
| /{ | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &rst { | ||||
| 	u-boot,dm-pre-reloc; | ||||
| }; | ||||
| 
 | ||||
| &sdr { | ||||
| 	u-boot,dm-pre-reloc; | ||||
| }; | ||||
|  | @ -84,6 +84,7 @@ | |||
| 				#dma-requests = <32>; | ||||
| 				clocks = <&l4_main_clk>; | ||||
| 				clock-names = "apb_pclk"; | ||||
| 				resets = <&rst DMA_RESET>; | ||||
| 			}; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -100,6 +101,7 @@ | |||
| 			reg = <0xffc00000 0x1000>; | ||||
| 			interrupts = <0 131 4>, <0 132 4>, <0 133 4>, <0 134 4>; | ||||
| 			clocks = <&can0_clk>; | ||||
| 			resets = <&rst CAN0_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -108,6 +110,7 @@ | |||
| 			reg = <0xffc01000 0x1000>; | ||||
| 			interrupts = <0 135 4>, <0 136 4>, <0 137 4>, <0 138 4>; | ||||
| 			clocks = <&can1_clk>; | ||||
| 			resets = <&rst CAN1_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -585,6 +588,7 @@ | |||
| 			compatible = "snps,dw-apb-gpio"; | ||||
| 			reg = <0xff708000 0x1000>; | ||||
| 			clocks = <&l4_mp_clk>; | ||||
| 			resets = <&rst GPIO0_RESET>; | ||||
| 			status = "disabled"; | ||||
| 
 | ||||
| 			porta: gpio-controller@0 { | ||||
|  | @ -605,6 +609,7 @@ | |||
| 			compatible = "snps,dw-apb-gpio"; | ||||
| 			reg = <0xff709000 0x1000>; | ||||
| 			clocks = <&l4_mp_clk>; | ||||
| 			resets = <&rst GPIO1_RESET>; | ||||
| 			status = "disabled"; | ||||
| 
 | ||||
| 			portb: gpio-controller@0 { | ||||
|  | @ -625,6 +630,7 @@ | |||
| 			compatible = "snps,dw-apb-gpio"; | ||||
| 			reg = <0xff70a000 0x1000>; | ||||
| 			clocks = <&l4_mp_clk>; | ||||
| 			resets = <&rst GPIO2_RESET>; | ||||
| 			status = "disabled"; | ||||
| 
 | ||||
| 			portc: gpio-controller@0 { | ||||
|  | @ -735,6 +741,7 @@ | |||
| 			#size-cells = <0>; | ||||
| 			clocks = <&l4_mp_clk>, <&sdmmc_clk_divided>; | ||||
| 			clock-names = "biu", "ciu"; | ||||
| 			resets = <&rst SDMMC_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -746,9 +753,9 @@ | |||
| 			      <0xffb80000 0x10000>; | ||||
| 			reg-names = "nand_data", "denali_reg"; | ||||
| 			interrupts = <0x0 0x90 0x4>; | ||||
| 			dma-mask = <0xffffffff>; | ||||
| 			clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>; | ||||
| 			clock-names = "nand", "nand_x", "ecc"; | ||||
| 			resets = <&rst NAND_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -759,7 +766,7 @@ | |||
| 
 | ||||
| 		qspi: spi@ff705000 { | ||||
| 			compatible = "cdns,qspi-nor"; | ||||
|                         #address-cells = <1>; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			reg = <0xff705000 0x1000>, | ||||
| 			      <0xffa00000 0x1000>; | ||||
|  | @ -768,6 +775,7 @@ | |||
| 			cdns,fifo-width = <4>; | ||||
| 			cdns,trigger-address = <0x00000000>; | ||||
| 			clocks = <&qspi_clk>; | ||||
| 			resets = <&rst QSPI_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -783,9 +791,10 @@ | |||
| 			reg = <0xfffec000 0x100>; | ||||
| 		}; | ||||
| 
 | ||||
| 		sdr: sdr@ffc25000 { | ||||
| 		sdr: sdr@ffc20000 { | ||||
| 			compatible = "altr,sdr-ctl", "syscon"; | ||||
| 			reg = <0xffc25000 0x1000>; | ||||
| 			reg = <0xffc20000 0x6000>; | ||||
| 			resets = <&rst SDR_RESET>; | ||||
| 		}; | ||||
| 
 | ||||
| 		sdramedac { | ||||
|  | @ -802,6 +811,7 @@ | |||
| 			interrupts = <0 154 4>; | ||||
| 			num-cs = <4>; | ||||
| 			clocks = <&spi_m_clk>; | ||||
| 			resets = <&rst SPIM0_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -813,6 +823,7 @@ | |||
| 			interrupts = <0 155 4>; | ||||
| 			num-cs = <4>; | ||||
| 			clocks = <&spi_m_clk>; | ||||
| 			resets = <&rst SPIM1_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -879,6 +890,7 @@ | |||
| 			dmas = <&pdma 28>, | ||||
| 			       <&pdma 29>; | ||||
| 			dma-names = "tx", "rx"; | ||||
| 			resets = <&rst UART0_RESET>; | ||||
| 		}; | ||||
| 
 | ||||
| 		uart1: serial1@ffc03000 { | ||||
|  | @ -891,6 +903,7 @@ | |||
| 			dmas = <&pdma 30>, | ||||
| 			       <&pdma 31>; | ||||
| 			dma-names = "tx", "rx"; | ||||
| 			resets = <&rst UART1_RESET>; | ||||
| 		}; | ||||
| 
 | ||||
| 		usbphy0: usbphy { | ||||
|  | @ -930,6 +943,7 @@ | |||
| 			reg = <0xffd02000 0x1000>; | ||||
| 			interrupts = <0 171 4>; | ||||
| 			clocks = <&osc1>; | ||||
| 			resets = <&rst L4WD0_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
|  | @ -938,6 +952,7 @@ | |||
| 			reg = <0xffd03000 0x1000>; | ||||
| 			interrupts = <0 172 4>; | ||||
| 			clocks = <&osc1>; | ||||
| 			resets = <&rst L4WD1_RESET>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 	}; | ||||
|  |  | |||
|  | @ -6,15 +6,13 @@ | |||
|  * Copyright (c) 2018 Simon Goldschmidt | ||||
|  */ | ||||
| 
 | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| /{ | ||||
| 	aliases { | ||||
| 		spi0 = "/soc/spi@ff705000"; | ||||
| 		udc0 = &usb1; | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &watchdog0 { | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "socfpga_cyclone5.dtsi" | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| / { | ||||
| 	model = "Devboards.de DBM-SoC1"; | ||||
|  | @ -24,10 +25,6 @@ | |||
| 		device_type = "memory"; | ||||
| 		reg = <0x0 0x40000000>; /* 1GB */ | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &gmac1 { | ||||
|  |  | |||
|  | @ -6,14 +6,12 @@ | |||
|  * Copyright (c) 2018 Simon Goldschmidt | ||||
|  */ | ||||
| 
 | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| /{ | ||||
| 	aliases { | ||||
| 		udc0 = &usb1; | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &watchdog0 { | ||||
|  |  | |||
|  | @ -6,6 +6,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "socfpga_cyclone5.dtsi" | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| / { | ||||
| 	model = "Terasic DE10-Nano"; | ||||
|  | @ -26,10 +27,6 @@ | |||
| 		device_type = "memory"; | ||||
| 		reg = <0x0 0x40000000>; /* 1GB */ | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &gmac1 { | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "socfpga_cyclone5.dtsi" | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| / { | ||||
| 	model = "Terasic DE1-SoC"; | ||||
|  | @ -24,10 +25,6 @@ | |||
| 		device_type = "memory"; | ||||
| 		reg = <0x0 0x40000000>; /* 1GB */ | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &gmac1 { | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "socfpga_cyclone5.dtsi" | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| / { | ||||
| 	model = "SoCFPGA Cyclone V IS1"; | ||||
|  | @ -31,10 +32,6 @@ | |||
| 		regulator-min-microvolt = <3300000>; | ||||
| 		regulator-max-microvolt = <3300000>; | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &gmac1 { | ||||
|  |  | |||
|  | @ -6,15 +6,13 @@ | |||
|  * Copyright (c) 2018 Simon Goldschmidt | ||||
|  */ | ||||
| 
 | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| /{ | ||||
| 	aliases { | ||||
| 		spi0 = "/soc/spi@ff705000"; | ||||
| 		udc0 = &usb1; | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &can0 { | ||||
|  |  | |||
|  | @ -6,15 +6,13 @@ | |||
|  * Copyright (c) 2018 Simon Goldschmidt | ||||
|  */ | ||||
| 
 | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| /{ | ||||
| 	aliases { | ||||
| 		spi0 = "/soc/spi@ff705000"; | ||||
| 		udc0 = &usb1; | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &watchdog0 { | ||||
|  |  | |||
|  | @ -6,15 +6,13 @@ | |||
|  * Copyright (c) 2018 Simon Goldschmidt | ||||
|  */ | ||||
| 
 | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| /{ | ||||
| 	aliases { | ||||
| 		spi0 = "/soc/spi@ff705000"; | ||||
| 		udc0 = &usb1; | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &watchdog0 { | ||||
|  |  | |||
|  | @ -76,7 +76,6 @@ | |||
| 
 | ||||
| &qspi { | ||||
| 	status = "okay"; | ||||
| 	u-boot,dm-pre-reloc; | ||||
| 
 | ||||
| 	flash: flash@0 { | ||||
| 		#address-cells = <1>; | ||||
|  | @ -91,6 +90,5 @@ | |||
| 		cdns,tchsh-ns = <4>; | ||||
| 		cdns,tslch-ns = <4>; | ||||
| 		status = "okay"; | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
|  |  | |||
|  | @ -4,6 +4,7 @@ | |||
|  */ | ||||
| 
 | ||||
| #include "socfpga_cyclone5.dtsi" | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| / { | ||||
| 	model = "SoCFPGA Cyclone V SR1500"; | ||||
|  | @ -27,10 +28,6 @@ | |||
| 		device_type = "memory"; | ||||
| 		reg = <0x0 0x40000000>; /* 1GB */ | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &gmac1 { | ||||
|  |  | |||
|  | @ -6,15 +6,13 @@ | |||
|  * Copyright (c) 2018 Simon Goldschmidt | ||||
|  */ | ||||
| 
 | ||||
| #include "socfpga-common-u-boot.dtsi" | ||||
| 
 | ||||
| /{ | ||||
| 	aliases { | ||||
| 		spi0 = "/soc/spi@ff705000"; | ||||
| 		udc0 = &usb0; | ||||
| 	}; | ||||
| 
 | ||||
| 	soc { | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &watchdog0 { | ||||
|  |  | |||
|  | @ -237,6 +237,19 @@ | |||
| 			reg = <0xffe00000 0x100000>; | ||||
| 		}; | ||||
| 
 | ||||
| 		qspi: spi@ff8d2000 { | ||||
| 			compatible = "cdns,qspi-nor"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <0>; | ||||
| 			reg = <0xff8d2000 0x100>, | ||||
| 			      <0xff900000 0x100000>; | ||||
| 			interrupts = <0 3 4>; | ||||
| 			cdns,fifo-depth = <128>; | ||||
| 			cdns,fifo-width = <4>; | ||||
| 			cdns,trigger-address = <0x00000000>; | ||||
| 			status = "disabled"; | ||||
| 		}; | ||||
| 
 | ||||
| 		rst: rstmgr@ffd11000 { | ||||
| 			#reset-cells = <1>; | ||||
| 			compatible = "altr,rst-mgr"; | ||||
|  |  | |||
|  | @ -0,0 +1,25 @@ | |||
| // SPDX-License-Identifier: GPL-2.0+ | ||||
| /* | ||||
|  * U-Boot additions | ||||
|  * | ||||
|  * Copyright (C) 2019 Intel Corporation <www.intel.com> | ||||
|  */ | ||||
| 
 | ||||
| /{ | ||||
| 	aliases { | ||||
| 		spi0 = &qspi; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &qspi { | ||||
| 	status = "okay"; | ||||
| 	u-boot,dm-pre-reloc; | ||||
| }; | ||||
| 
 | ||||
| &flash0 { | ||||
| 	compatible = "jedec,spi-nor"; | ||||
| 	spi-max-frequency = <100000000>; | ||||
| 	spi-tx-bus-width = <4>; | ||||
| 	spi-rx-bus-width = <4>; | ||||
| 	u-boot,dm-pre-reloc; | ||||
| }; | ||||
|  | @ -36,7 +36,9 @@ | |||
| 
 | ||||
| 	memory { | ||||
| 		device_type = "memory"; | ||||
| 		reg = <0 0 0 0x80000000>; /* 2GB */ | ||||
| 		/* 4GB */ | ||||
| 		reg = <0 0x00000000 0 0x80000000>, | ||||
| 		      <1 0x80000000 0 0x80000000>; | ||||
| 		u-boot,dm-pre-reloc; | ||||
| 	}; | ||||
| }; | ||||
|  | @ -85,6 +87,41 @@ | |||
| 	smplsel = <0>; | ||||
| }; | ||||
| 
 | ||||
| &qspi { | ||||
| 	flash0: flash@0 { | ||||
| 		#address-cells = <1>; | ||||
| 		#size-cells = <1>; | ||||
| 		compatible = "n25q00a"; | ||||
| 		reg = <0>; | ||||
| 		spi-max-frequency = <50000000>; | ||||
| 
 | ||||
| 		m25p,fast-read; | ||||
| 		cdns,page-size = <256>; | ||||
| 		cdns,block-size = <16>; | ||||
| 		cdns,read-delay = <1>; | ||||
| 		cdns,tshsl-ns = <50>; | ||||
| 		cdns,tsd2d-ns = <50>; | ||||
| 		cdns,tchsh-ns = <4>; | ||||
| 		cdns,tslch-ns = <4>; | ||||
| 
 | ||||
| 		partitions { | ||||
| 			compatible = "fixed-partitions"; | ||||
| 			#address-cells = <1>; | ||||
| 			#size-cells = <1>; | ||||
| 
 | ||||
| 			qspi_boot: partition@0 { | ||||
| 				label = "Boot and fpga data"; | ||||
| 				reg = <0x0 0x4000000>; | ||||
| 			}; | ||||
| 
 | ||||
| 			qspi_rootfs: partition@4000000 { | ||||
| 				label = "Root Filesystem - JFFS2"; | ||||
| 				reg = <0x4000000 0x4000000>; | ||||
| 			}; | ||||
| 		}; | ||||
| 	}; | ||||
| }; | ||||
| 
 | ||||
| &uart0 { | ||||
| 	status = "okay"; | ||||
| }; | ||||
|  |  | |||
|  | @ -9,6 +9,7 @@ | |||
| 
 | ||||
| void reset_cpu(ulong addr); | ||||
| void reset_deassert_peripherals_handoff(void); | ||||
| int cpu_has_been_warmreset(void); | ||||
| 
 | ||||
| void socfpga_bridges_reset(int enable); | ||||
| 
 | ||||
|  | @ -47,6 +48,8 @@ struct socfpga_reset_manager { | |||
| #define RSTMGR_MPUMODRST_CORE0		0 | ||||
| #define RSTMGR_PER0MODRST_OCP_MASK	0x0020bf00 | ||||
| #define RSTMGR_BRGMODRST_DDRSCH_MASK	0X00000040 | ||||
| /* Watchdogs and MPU warm reset mask */ | ||||
| #define RSTMGR_L4WD_MPU_WARMRESET_MASK	0x000F0F00 | ||||
| 
 | ||||
| /*
 | ||||
|  * Define a reset identifier, from which a permodrst bank ID | ||||
|  |  | |||
|  | @ -7,10 +7,6 @@ | |||
| 
 | ||||
| #ifndef __ASSEMBLY__ | ||||
| 
 | ||||
| unsigned long sdram_calculate_size(void); | ||||
| int sdram_mmr_init_full(unsigned int sdr_phy_reg); | ||||
| int sdram_calibration_full(void); | ||||
| 
 | ||||
| const struct socfpga_sdram_config *socfpga_get_sdram_config(void); | ||||
| 
 | ||||
| void socfpga_get_seq_ac_init(const u32 **init, unsigned int *nelem); | ||||
|  |  | |||
|  | @ -22,6 +22,7 @@ int sdram_calibration_full(void); | |||
| #define ECCCTRL1			0x100 | ||||
| #define ECCCTRL2			0x104 | ||||
| #define ERRINTEN			0x110 | ||||
| #define ERRINTENS			0x114 | ||||
| #define INTMODE				0x11c | ||||
| #define INTSTAT				0x120 | ||||
| #define AUTOWB_CORRADDR			0x138 | ||||
|  | @ -52,6 +53,10 @@ int sdram_calibration_full(void); | |||
| #define DDR_HMC_SEQ2CORE_INT_RESP_MASK		BIT(3) | ||||
| #define DDR_HMC_HPSINTFCSEL_ENABLE_MASK		0x001f1f1f | ||||
| 
 | ||||
| #define	DDR_HMC_ERRINTEN_INTMASK				\ | ||||
| 		(DDR_HMC_ERRINTEN_SERRINTEN_EN_SET_MSK |	\ | ||||
| 		 DDR_HMC_ERRINTEN_DERRINTEN_EN_SET_MSK) | ||||
| 
 | ||||
| /* NOC DDR scheduler */ | ||||
| #define DDR_SCH_ID_COREID		0 | ||||
| #define DDR_SCH_ID_REVID		0x4 | ||||
|  | @ -180,4 +185,8 @@ int sdram_calibration_full(void); | |||
| #define CALTIMING9_CFG_4_ACT_TO_ACT(x)			\ | ||||
| 	(((x) >> 0) & 0xFF) | ||||
| 
 | ||||
| /* Firewall DDR scheduler MPFE */ | ||||
| #define FW_HMC_ADAPTOR_REG_ADDR			0xf8020004 | ||||
| #define FW_HMC_ADAPTOR_MPU_MASK			BIT(0) | ||||
| 
 | ||||
| #endif /* _SDRAM_S10_H_ */ | ||||
|  |  | |||
|  | @ -201,16 +201,6 @@ int arch_early_init_r(void) | |||
| 	/* Add device descriptor to FPGA device table */ | ||||
| 	socfpga_fpga_add(&altera_fpga[0]); | ||||
| 
 | ||||
| #ifdef CONFIG_DESIGNWARE_SPI | ||||
| 	/* Get Designware SPI controller out of reset */ | ||||
| 	socfpga_per_reset(SOCFPGA_RESET(SPIM0), 0); | ||||
| 	socfpga_per_reset(SOCFPGA_RESET(SPIM1), 0); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_NAND_DENALI | ||||
| 	socfpga_per_reset(SOCFPGA_RESET(NAND), 0); | ||||
| #endif | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -103,3 +103,12 @@ void reset_deassert_peripherals_handoff(void) | |||
| 	writel(~RSTMGR_PER0MODRST_OCP_MASK, &reset_manager_base->per0modrst); | ||||
| 	writel(0, &reset_manager_base->per0modrst); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Return non-zero if the CPU has been warm reset | ||||
|  */ | ||||
| int cpu_has_been_warmreset(void) | ||||
| { | ||||
| 	return readl(&reset_manager_base->status) & | ||||
| 		RSTMGR_L4WD_MPU_WARMRESET_MASK; | ||||
| } | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ | |||
| #include <debug_uart.h> | ||||
| #include <fdtdec.h> | ||||
| #include <watchdog.h> | ||||
| #include <dm/uclass.h> | ||||
| 
 | ||||
| DECLARE_GLOBAL_DATA_PTR; | ||||
| 
 | ||||
|  | @ -38,16 +39,12 @@ u32 spl_boot_device(void) | |||
| 		return BOOT_DEVICE_RAM; | ||||
| 	case 0x2:	/* NAND Flash (1.8V) */ | ||||
| 	case 0x3:	/* NAND Flash (3.0V) */ | ||||
| 		socfpga_per_reset(SOCFPGA_RESET(NAND), 0); | ||||
| 		return BOOT_DEVICE_NAND; | ||||
| 	case 0x4:	/* SD/MMC External Transceiver (1.8V) */ | ||||
| 	case 0x5:	/* SD/MMC Internal Transceiver (3.0V) */ | ||||
| 		socfpga_per_reset(SOCFPGA_RESET(SDMMC), 0); | ||||
| 		socfpga_per_reset(SOCFPGA_RESET(DMA), 0); | ||||
| 		return BOOT_DEVICE_MMC1; | ||||
| 	case 0x6:	/* QSPI Flash (1.8V) */ | ||||
| 	case 0x7:	/* QSPI Flash (3.0V) */ | ||||
| 		socfpga_per_reset(SOCFPGA_RESET(QSPI), 0); | ||||
| 		return BOOT_DEVICE_SPI; | ||||
| 	default: | ||||
| 		printf("Invalid boot device (bsel=%08x)!\n", bsel); | ||||
|  | @ -123,9 +120,9 @@ static void socfpga_pl310_clear(void) | |||
| void board_init_f(ulong dummy) | ||||
| { | ||||
| 	const struct cm_config *cm_default_cfg = cm_get_default_config(); | ||||
| 	unsigned long sdram_size; | ||||
| 	unsigned long reg; | ||||
| 	int ret; | ||||
| 	struct udevice *dev; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * First C code to run. Clear fake OCRAM ECC first as SBE | ||||
|  | @ -156,10 +153,7 @@ void board_init_f(ulong dummy) | |||
| 		socfpga_bridges_reset(1); | ||||
| 	} | ||||
| 
 | ||||
| 	socfpga_per_reset(SOCFPGA_RESET(SDR), 0); | ||||
| 	socfpga_per_reset(SOCFPGA_RESET(UART0), 0); | ||||
| 	socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0); | ||||
| 
 | ||||
| 	timer_init(); | ||||
| 
 | ||||
| 	debug("Reconfigure Clock Manager\n"); | ||||
|  | @ -181,8 +175,7 @@ void board_init_f(ulong dummy) | |||
| 	sysmgr_pinmux_init(); | ||||
| 	sysmgr_config_warmrstcfgio(0); | ||||
| 
 | ||||
| 	/* De-assert reset for peripherals and bridges based on handoff */ | ||||
| 	reset_deassert_peripherals_handoff(); | ||||
| 	/* De-assert reset for bridges based on handoff */ | ||||
| 	socfpga_bridges_reset(0); | ||||
| 
 | ||||
| 	debug("Unfreezing/Thaw all I/O banks\n"); | ||||
|  | @ -200,27 +193,16 @@ void board_init_f(ulong dummy) | |||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
| 	ret = uclass_get_device(UCLASS_RESET, 0, &dev); | ||||
| 	if (ret) | ||||
| 		debug("Reset init failed: %d\n", ret); | ||||
| 
 | ||||
| 	/* enable console uart printing */ | ||||
| 	preloader_console_init(); | ||||
| 
 | ||||
| 	if (sdram_mmr_init_full(0xffffffff) != 0) { | ||||
| 		puts("SDRAM init failed.\n"); | ||||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
| 	debug("SDRAM: Calibrating PHY\n"); | ||||
| 	/* SDRAM calibration */ | ||||
| 	if (sdram_calibration_full() == 0) { | ||||
| 		puts("SDRAM calibration failed.\n"); | ||||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
| 	sdram_size = sdram_calculate_size(); | ||||
| 	debug("SDRAM: %ld MiB\n", sdram_size >> 20); | ||||
| 
 | ||||
| 	/* Sanity check ensure correct SDRAM size specified */ | ||||
| 	if (get_ram_size(0, sdram_size) != sdram_size) { | ||||
| 		puts("SDRAM size check failed!\n"); | ||||
| 	ret = uclass_get_device(UCLASS_RAM, 0, &dev); | ||||
| 	if (ret) { | ||||
| 		debug("DRAM init failed: %d\n", ret); | ||||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -181,17 +181,6 @@ void board_init_f(ulong dummy) | |||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
| 	gd->ram_size = sdram_calculate_size(); | ||||
| 	printf("DDR: %d MiB\n", (int)(gd->ram_size >> 20)); | ||||
| 
 | ||||
| 	/* Sanity check ensure correct SDRAM size specified */ | ||||
| 	debug("DDR: Running SDRAM size sanity check\n"); | ||||
| 	if (get_ram_size(0, gd->ram_size) != gd->ram_size) { | ||||
| 		puts("DDR: SDRAM size check failed!\n"); | ||||
| 		hang(); | ||||
| 	} | ||||
| 	debug("DDR: SDRAM size check passed!\n"); | ||||
| 
 | ||||
| 	mbox_init(); | ||||
| 
 | ||||
| #ifdef CONFIG_CADENCE_QSPI | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ CONFIG_TARGET_SOCFPGA_STRATIX10_SOCDK=y | |||
| CONFIG_SPL=y | ||||
| CONFIG_IDENT_STRING="socfpga_stratix10" | ||||
| CONFIG_SPL_FS_FAT=y | ||||
| CONFIG_NR_DRAM_BANKS=1 | ||||
| CONFIG_NR_DRAM_BANKS=2 | ||||
| CONFIG_BOOTDELAY=5 | ||||
| CONFIG_SPL_SPI_LOAD=y | ||||
| CONFIG_HUSH_PARSER=y | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| config ALTERA_SDRAM | ||||
| 	bool "SoCFPGA DDR SDRAM driver" | ||||
| 	depends on TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 | ||||
| 	select RAM if TARGET_SOCFPGA_GEN5 | ||||
| 	select SPL_RAM if TARGET_SOCFPGA_GEN5 | ||||
| 	help | ||||
| 	  Enable DDR SDRAM controller for the SoCFPGA devices. | ||||
|  |  | |||
|  | @ -3,14 +3,30 @@ | |||
|  * Copyright Altera Corporation (C) 2014-2015 | ||||
|  */ | ||||
| #include <common.h> | ||||
| #include <dm.h> | ||||
| #include <errno.h> | ||||
| #include <div64.h> | ||||
| #include <ram.h> | ||||
| #include <reset.h> | ||||
| #include <watchdog.h> | ||||
| #include <asm/arch/fpga_manager.h> | ||||
| #include <asm/arch/reset_manager.h> | ||||
| #include <asm/arch/sdram.h> | ||||
| #include <asm/arch/system_manager.h> | ||||
| #include <asm/io.h> | ||||
| 
 | ||||
| #include "sequencer.h" | ||||
| 
 | ||||
| #ifdef CONFIG_SPL_BUILD | ||||
| 
 | ||||
| struct altera_gen5_sdram_priv { | ||||
| 	struct ram_info info; | ||||
| }; | ||||
| 
 | ||||
| struct altera_gen5_sdram_platdata { | ||||
| 	struct socfpga_sdr *sdr; | ||||
| }; | ||||
| 
 | ||||
| struct sdram_prot_rule { | ||||
| 	u32	sdram_start;	/* SDRAM start address */ | ||||
| 	u32	sdram_end;	/* SDRAM end address */ | ||||
|  | @ -26,8 +42,8 @@ struct sdram_prot_rule { | |||
| 
 | ||||
| static struct socfpga_system_manager *sysmgr_regs = | ||||
| 	(struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; | ||||
| static struct socfpga_sdr_ctrl *sdr_ctrl = | ||||
| 	(struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS; | ||||
| 
 | ||||
| static unsigned long sdram_calculate_size(struct socfpga_sdr_ctrl *sdr_ctrl); | ||||
| 
 | ||||
| /**
 | ||||
|  * get_errata_rows() - Up the number of DRAM rows to cover entire address space | ||||
|  | @ -104,7 +120,8 @@ static int get_errata_rows(const struct socfpga_sdram_config *cfg) | |||
| } | ||||
| 
 | ||||
| /* SDRAM protection rules vary from 0-19, a total of 20 rules. */ | ||||
| static void sdram_set_rule(struct sdram_prot_rule *prule) | ||||
| static void sdram_set_rule(struct socfpga_sdr_ctrl *sdr_ctrl, | ||||
| 			   struct sdram_prot_rule *prule) | ||||
| { | ||||
| 	u32 lo_addr_bits; | ||||
| 	u32 hi_addr_bits; | ||||
|  | @ -141,7 +158,8 @@ static void sdram_set_rule(struct sdram_prot_rule *prule) | |||
| 	writel(0, &sdr_ctrl->prot_rule_rdwr); | ||||
| } | ||||
| 
 | ||||
| static void sdram_get_rule(struct sdram_prot_rule *prule) | ||||
| static void sdram_get_rule(struct socfpga_sdr_ctrl *sdr_ctrl, | ||||
| 			   struct sdram_prot_rule *prule) | ||||
| { | ||||
| 	u32 addr; | ||||
| 	u32 id; | ||||
|  | @ -172,7 +190,8 @@ static void sdram_get_rule(struct sdram_prot_rule *prule) | |||
| } | ||||
| 
 | ||||
| static void | ||||
| sdram_set_protection_config(const u32 sdram_start, const u32 sdram_end) | ||||
| sdram_set_protection_config(struct socfpga_sdr_ctrl *sdr_ctrl, | ||||
| 			    const u32 sdram_start, const u32 sdram_end) | ||||
| { | ||||
| 	struct sdram_prot_rule rule; | ||||
| 	int rules; | ||||
|  | @ -185,7 +204,7 @@ sdram_set_protection_config(const u32 sdram_start, const u32 sdram_end) | |||
| 
 | ||||
| 	for (rules = 0; rules < 20; rules++) { | ||||
| 		rule.rule = rules; | ||||
| 		sdram_set_rule(&rule); | ||||
| 		sdram_set_rule(sdr_ctrl, &rule); | ||||
| 	} | ||||
| 
 | ||||
| 	/* new rule: accept SDRAM */ | ||||
|  | @ -200,13 +219,13 @@ sdram_set_protection_config(const u32 sdram_start, const u32 sdram_end) | |||
| 	rule.rule = 0; | ||||
| 
 | ||||
| 	/* set new rule */ | ||||
| 	sdram_set_rule(&rule); | ||||
| 	sdram_set_rule(sdr_ctrl, &rule); | ||||
| 
 | ||||
| 	/* default rule: reject everything */ | ||||
| 	writel(0x3ff, &sdr_ctrl->protport_default); | ||||
| } | ||||
| 
 | ||||
| static void sdram_dump_protection_config(void) | ||||
| static void sdram_dump_protection_config(struct socfpga_sdr_ctrl *sdr_ctrl) | ||||
| { | ||||
| 	struct sdram_prot_rule rule; | ||||
| 	int rules; | ||||
|  | @ -216,7 +235,7 @@ static void sdram_dump_protection_config(void) | |||
| 
 | ||||
| 	for (rules = 0; rules < 20; rules++) { | ||||
| 		rule.rule = rules; | ||||
| 		sdram_get_rule(&rule); | ||||
| 		sdram_get_rule(sdr_ctrl, &rule); | ||||
| 		debug("Rule %d, rules ...\n", rules); | ||||
| 		debug("    sdram start %x\n", rule.sdram_start); | ||||
| 		debug("    sdram end   %x\n", rule.sdram_end); | ||||
|  | @ -322,7 +341,8 @@ static u32 sdr_get_addr_rw(const struct socfpga_sdram_config *cfg) | |||
|  * | ||||
|  * This function loads the register values into the SDRAM controller block. | ||||
|  */ | ||||
| static void sdr_load_regs(const struct socfpga_sdram_config *cfg) | ||||
| static void sdr_load_regs(struct socfpga_sdr_ctrl *sdr_ctrl, | ||||
| 			  const struct socfpga_sdram_config *cfg) | ||||
| { | ||||
| 	const u32 ctrl_cfg = sdr_get_ctrlcfg(cfg); | ||||
| 	const u32 dram_addrw = sdr_get_addr_rw(cfg); | ||||
|  | @ -426,7 +446,8 @@ static void sdr_load_regs(const struct socfpga_sdram_config *cfg) | |||
|  * | ||||
|  * Initialize the SDRAM MMR. | ||||
|  */ | ||||
| int sdram_mmr_init_full(unsigned int sdr_phy_reg) | ||||
| int sdram_mmr_init_full(struct socfpga_sdr_ctrl *sdr_ctrl, | ||||
| 			unsigned int sdr_phy_reg) | ||||
| { | ||||
| 	const struct socfpga_sdram_config *cfg = socfpga_get_sdram_config(); | ||||
| 	const unsigned int rows = | ||||
|  | @ -436,7 +457,7 @@ int sdram_mmr_init_full(unsigned int sdr_phy_reg) | |||
| 
 | ||||
| 	writel(rows, &sysmgr_regs->iswgrp_handoff[4]); | ||||
| 
 | ||||
| 	sdr_load_regs(cfg); | ||||
| 	sdr_load_regs(sdr_ctrl, cfg); | ||||
| 
 | ||||
| 	/* saving this value to SYSMGR.ISWGRP.HANDOFF.FPGA2SDR */ | ||||
| 	writel(cfg->fpgaport_rst, &sysmgr_regs->iswgrp_handoff[3]); | ||||
|  | @ -459,9 +480,10 @@ int sdram_mmr_init_full(unsigned int sdr_phy_reg) | |||
| 			SDR_CTRLGRP_STATICCFG_APPLYCFG_MASK, | ||||
| 			1 << SDR_CTRLGRP_STATICCFG_APPLYCFG_LSB); | ||||
| 
 | ||||
| 	sdram_set_protection_config(0, sdram_calculate_size() - 1); | ||||
| 	sdram_set_protection_config(sdr_ctrl, 0, | ||||
| 				    sdram_calculate_size(sdr_ctrl) - 1); | ||||
| 
 | ||||
| 	sdram_dump_protection_config(); | ||||
| 	sdram_dump_protection_config(sdr_ctrl); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -472,7 +494,7 @@ int sdram_mmr_init_full(unsigned int sdr_phy_reg) | |||
|  * Calculate SDRAM device size based on SDRAM controller parameters. | ||||
|  * Size is specified in bytes. | ||||
|  */ | ||||
| unsigned long sdram_calculate_size(void) | ||||
| static unsigned long sdram_calculate_size(struct socfpga_sdr_ctrl *sdr_ctrl) | ||||
| { | ||||
| 	unsigned long temp; | ||||
| 	unsigned long row, bank, col, cs, width; | ||||
|  | @ -534,3 +556,94 @@ unsigned long sdram_calculate_size(void) | |||
| 
 | ||||
| 	return temp; | ||||
| } | ||||
| 
 | ||||
| static int altera_gen5_sdram_ofdata_to_platdata(struct udevice *dev) | ||||
| { | ||||
| 	struct altera_gen5_sdram_platdata *plat = dev->platdata; | ||||
| 
 | ||||
| 	plat->sdr = (struct socfpga_sdr *)devfdt_get_addr_index(dev, 0); | ||||
| 	if (!plat->sdr) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int altera_gen5_sdram_probe(struct udevice *dev) | ||||
| { | ||||
| 	int ret; | ||||
| 	unsigned long sdram_size; | ||||
| 	struct altera_gen5_sdram_platdata *plat = dev->platdata; | ||||
| 	struct altera_gen5_sdram_priv *priv = dev_get_priv(dev); | ||||
| 	struct socfpga_sdr_ctrl *sdr_ctrl = &plat->sdr->sdr_ctrl; | ||||
| 	struct reset_ctl_bulk resets; | ||||
| 
 | ||||
| 	ret = reset_get_bulk(dev, &resets); | ||||
| 	if (ret) { | ||||
| 		dev_err(dev, "Can't get reset: %d\n", ret); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 	reset_deassert_bulk(&resets); | ||||
| 
 | ||||
| 	if (sdram_mmr_init_full(sdr_ctrl, 0xffffffff) != 0) { | ||||
| 		puts("SDRAM init failed.\n"); | ||||
| 		goto failed; | ||||
| 	} | ||||
| 
 | ||||
| 	debug("SDRAM: Calibrating PHY\n"); | ||||
| 	/* SDRAM calibration */ | ||||
| 	if (sdram_calibration_full(plat->sdr) == 0) { | ||||
| 		puts("SDRAM calibration failed.\n"); | ||||
| 		goto failed; | ||||
| 	} | ||||
| 
 | ||||
| 	sdram_size = sdram_calculate_size(sdr_ctrl); | ||||
| 	debug("SDRAM: %ld MiB\n", sdram_size >> 20); | ||||
| 
 | ||||
| 	/* Sanity check ensure correct SDRAM size specified */ | ||||
| 	if (get_ram_size(0, sdram_size) != sdram_size) { | ||||
| 		puts("SDRAM size check failed!\n"); | ||||
| 		goto failed; | ||||
| 	} | ||||
| 
 | ||||
| 	priv->info.base = 0; | ||||
| 	priv->info.size = sdram_size; | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| failed: | ||||
| 	reset_release_bulk(&resets); | ||||
| 	return -ENODEV; | ||||
| } | ||||
| 
 | ||||
| static int altera_gen5_sdram_get_info(struct udevice *dev, | ||||
| 				      struct ram_info *info) | ||||
| { | ||||
| 	struct altera_gen5_sdram_priv *priv = dev_get_priv(dev); | ||||
| 
 | ||||
| 	info->base = priv->info.base; | ||||
| 	info->size = priv->info.size; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct ram_ops altera_gen5_sdram_ops = { | ||||
| 	.get_info = altera_gen5_sdram_get_info, | ||||
| }; | ||||
| 
 | ||||
| static const struct udevice_id altera_gen5_sdram_ids[] = { | ||||
| 	{ .compatible = "altr,sdr-ctl" }, | ||||
| 	{ /* sentinel */ } | ||||
| }; | ||||
| 
 | ||||
| U_BOOT_DRIVER(altera_gen5_sdram) = { | ||||
| 	.name = "altr_sdr_ctl", | ||||
| 	.id = UCLASS_RAM, | ||||
| 	.of_match = altera_gen5_sdram_ids, | ||||
| 	.ops = &altera_gen5_sdram_ops, | ||||
| 	.ofdata_to_platdata = altera_gen5_sdram_ofdata_to_platdata, | ||||
| 	.platdata_auto_alloc_size = sizeof(struct altera_gen5_sdram_platdata), | ||||
| 	.probe = altera_gen5_sdram_probe, | ||||
| 	.priv_auto_alloc_size = sizeof(struct altera_gen5_sdram_priv), | ||||
| }; | ||||
| 
 | ||||
| #endif /* CONFIG_SPL_BUILD */ | ||||
|  |  | |||
|  | @ -7,12 +7,14 @@ | |||
| #include <common.h> | ||||
| #include <errno.h> | ||||
| #include <div64.h> | ||||
| #include <fdtdec.h> | ||||
| #include <asm/io.h> | ||||
| #include <wait_bit.h> | ||||
| #include <asm/arch/firewall_s10.h> | ||||
| #include <asm/arch/sdram_s10.h> | ||||
| #include <asm/arch/system_manager.h> | ||||
| #include <asm/arch/reset_manager.h> | ||||
| #include <linux/sizes.h> | ||||
| 
 | ||||
| DECLARE_GLOBAL_DATA_PTR; | ||||
| 
 | ||||
|  | @ -21,6 +23,8 @@ static const struct socfpga_system_manager *sysmgr_regs = | |||
| 
 | ||||
| #define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R)) | ||||
| 
 | ||||
| #define PGTABLE_OFF	0x4000 | ||||
| 
 | ||||
| /* The followring are the supported configurations */ | ||||
| u32 ddr_config[] = { | ||||
| 	/* DDR_CONFIG(Address order,Bank,Column,Row) */ | ||||
|  | @ -134,6 +138,108 @@ static int poll_hmc_clock_status(void) | |||
| 				 SYSMGR_HMC_CLK_STATUS_MSK, true, 1000, false); | ||||
| } | ||||
| 
 | ||||
| static void sdram_clear_mem(phys_addr_t addr, phys_size_t size) | ||||
| { | ||||
| 	phys_size_t i; | ||||
| 
 | ||||
| 	if (addr % CONFIG_SYS_CACHELINE_SIZE) { | ||||
| 		printf("DDR: address 0x%llx is not cacheline size aligned.\n", | ||||
| 		       addr); | ||||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
| 	if (size % CONFIG_SYS_CACHELINE_SIZE) { | ||||
| 		printf("DDR: size 0x%llx is not multiple of cacheline size\n", | ||||
| 		       size); | ||||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Use DC ZVA instruction to clear memory to zeros by a cache line */ | ||||
| 	for (i = 0; i < size; i = i + CONFIG_SYS_CACHELINE_SIZE) { | ||||
| 		asm volatile("dc zva, %0" | ||||
| 		     : | ||||
| 		     : "r"(addr) | ||||
| 		     : "memory"); | ||||
| 		addr += CONFIG_SYS_CACHELINE_SIZE; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void sdram_init_ecc_bits(bd_t *bd) | ||||
| { | ||||
| 	phys_size_t size, size_init; | ||||
| 	phys_addr_t start_addr; | ||||
| 	int bank = 0; | ||||
| 	unsigned int start = get_timer(0); | ||||
| 
 | ||||
| 	icache_enable(); | ||||
| 
 | ||||
| 	start_addr = bd->bi_dram[0].start; | ||||
| 	size = bd->bi_dram[0].size; | ||||
| 
 | ||||
| 	/* Initialize small block for page table */ | ||||
| 	memset((void *)start_addr, 0, PGTABLE_SIZE + PGTABLE_OFF); | ||||
| 	gd->arch.tlb_addr = start_addr + PGTABLE_OFF; | ||||
| 	gd->arch.tlb_size = PGTABLE_SIZE; | ||||
| 	start_addr += PGTABLE_SIZE + PGTABLE_OFF; | ||||
| 	size -= (PGTABLE_OFF + PGTABLE_SIZE); | ||||
| 	dcache_enable(); | ||||
| 
 | ||||
| 	while (1) { | ||||
| 		while (size) { | ||||
| 			size_init = min((phys_addr_t)SZ_1G, (phys_addr_t)size); | ||||
| 			sdram_clear_mem(start_addr, size_init); | ||||
| 			size -= size_init; | ||||
| 			start_addr += size_init; | ||||
| 			WATCHDOG_RESET(); | ||||
| 		} | ||||
| 
 | ||||
| 		bank++; | ||||
| 		if (bank >= CONFIG_NR_DRAM_BANKS) | ||||
| 			break; | ||||
| 
 | ||||
| 		start_addr = bd->bi_dram[bank].start; | ||||
| 		size = bd->bi_dram[bank].size; | ||||
| 	} | ||||
| 
 | ||||
| 	dcache_disable(); | ||||
| 	icache_disable(); | ||||
| 
 | ||||
| 	printf("SDRAM-ECC: Initialized success with %d ms\n", | ||||
| 	       (unsigned int)get_timer(start)); | ||||
| } | ||||
| 
 | ||||
| static void sdram_size_check(bd_t *bd) | ||||
| { | ||||
| 	phys_size_t total_ram_check = 0; | ||||
| 	phys_size_t ram_check = 0; | ||||
| 	phys_addr_t start = 0; | ||||
| 	int bank; | ||||
| 
 | ||||
| 	/* Sanity check ensure correct SDRAM size specified */ | ||||
| 	debug("DDR: Running SDRAM size sanity check\n"); | ||||
| 
 | ||||
| 	for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { | ||||
| 		start = bd->bi_dram[bank].start; | ||||
| 		while (ram_check < bd->bi_dram[bank].size) { | ||||
| 			ram_check += get_ram_size((void *)(start + ram_check), | ||||
| 						 (phys_size_t)SZ_1G); | ||||
| 		} | ||||
| 		total_ram_check += ram_check; | ||||
| 		ram_check = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	/* If the ram_size is 2GB smaller, we can assume the IO space is
 | ||||
| 	 * not mapped in.  gd->ram_size is the actual size of the dram | ||||
| 	 * not the accessible size. | ||||
| 	 */ | ||||
| 	if (total_ram_check != gd->ram_size) { | ||||
| 		puts("DDR: SDRAM size check failed!\n"); | ||||
| 		hang(); | ||||
| 	} | ||||
| 
 | ||||
| 	debug("DDR: SDRAM size check passed!\n"); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * sdram_mmr_init_full() - Function to initialize SDRAM MMR | ||||
|  * | ||||
|  | @ -144,6 +250,8 @@ int sdram_mmr_init_full(unsigned int unused) | |||
| 	u32 update_value, io48_value, ddrioctl; | ||||
| 	u32 i; | ||||
| 	int ret; | ||||
| 	phys_size_t hw_size; | ||||
| 	bd_t bd = {0}; | ||||
| 
 | ||||
| 	/* Enable access to DDR from CPU master */ | ||||
| 	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_DDRREG), | ||||
|  | @ -335,9 +443,22 @@ int sdram_mmr_init_full(unsigned int unused) | |||
| 	unsigned long long size = sdram_calculate_size(); | ||||
| 	/* If the size is invalid, use default Config size */ | ||||
| 	if (size <= 0) | ||||
| 		gd->ram_size = PHYS_SDRAM_1_SIZE; | ||||
| 		hw_size = PHYS_SDRAM_1_SIZE; | ||||
| 	else | ||||
| 		gd->ram_size = size; | ||||
| 		hw_size = size; | ||||
| 
 | ||||
| 	/* Get bank configuration from devicetree */ | ||||
| 	ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL, | ||||
| 				     (phys_size_t *)&gd->ram_size, &bd); | ||||
| 	if (ret) { | ||||
| 		puts("DDR: Failed to decode memory node\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	if (gd->ram_size != hw_size) | ||||
| 		printf("DDR: Warning: DRAM size from device tree mismatch with hardware.\n"); | ||||
| 
 | ||||
| 	printf("DDR: %lld MiB\n", gd->ram_size >> 20); | ||||
| 
 | ||||
| 	/* Enable or disable the SDRAM ECC */ | ||||
| 	if (CTRLCFG1_CFG_CTRL_EN_ECC(ctrlcfg1)) { | ||||
|  | @ -351,6 +472,15 @@ int sdram_mmr_init_full(unsigned int unused) | |||
| 		setbits_le32(SOCFPGA_SDR_ADDRESS + ECCCTRL2, | ||||
| 			     (DDR_HMC_ECCCTL2_RMW_EN_SET_MSK | | ||||
| 			      DDR_HMC_ECCCTL2_AWB_EN_SET_MSK)); | ||||
| 		writel(DDR_HMC_ERRINTEN_INTMASK, | ||||
| 		       SOCFPGA_SDR_ADDRESS + ERRINTENS); | ||||
| 
 | ||||
| 		/* Enable non-secure writes to HMC Adapter for SDRAM ECC */ | ||||
| 		writel(FW_HMC_ADAPTOR_MPU_MASK, FW_HMC_ADAPTOR_REG_ADDR); | ||||
| 
 | ||||
| 		/* Initialize memory content if not from warm reset */ | ||||
| 		if (!cpu_has_been_warmreset()) | ||||
| 			sdram_init_ecc_bits(&bd); | ||||
| 	} else { | ||||
| 		clrbits_le32(SOCFPGA_SDR_ADDRESS + ECCCTRL1, | ||||
| 			     (DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK | | ||||
|  | @ -361,6 +491,8 @@ int sdram_mmr_init_full(unsigned int unused) | |||
| 			      DDR_HMC_ECCCTL2_AWB_EN_SET_MSK)); | ||||
| 	} | ||||
| 
 | ||||
| 	sdram_size_check(&bd); | ||||
| 
 | ||||
| 	debug("DDR: HMC init success\n"); | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -3705,12 +3705,19 @@ static void initialize_tracking(void) | |||
| 	       &sdr_reg_file->trk_rfsh); | ||||
| } | ||||
| 
 | ||||
| int sdram_calibration_full(void) | ||||
| int sdram_calibration_full(struct socfpga_sdr *sdr) | ||||
| { | ||||
| 	struct param_type my_param; | ||||
| 	struct gbl_type my_gbl; | ||||
| 	u32 pass; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * For size reasons, this file uses hard coded addresses. | ||||
| 	 * Check if we are called with the correct address. | ||||
| 	 */ | ||||
| 	if (sdr != (struct socfpga_sdr *)SOCFPGA_SDR_ADDRESS) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	memset(&my_param, 0, sizeof(my_param)); | ||||
| 	memset(&my_gbl, 0, sizeof(my_gbl)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -223,4 +223,39 @@ struct socfpga_data_mgr { | |||
| 	u32	mem_t_add; | ||||
| 	u32	t_rl_add; | ||||
| }; | ||||
| 
 | ||||
| /* This struct describes the controller @ SOCFPGA_SDR_ADDRESS */ | ||||
| struct socfpga_sdr { | ||||
| 	/* SDR_PHYGRP_SCCGRP_ADDRESS */ | ||||
| 	u8 _align1[0xe00]; | ||||
| 	/* SDR_PHYGRP_SCCGRP_ADDRESS | 0xe00 */ | ||||
| 	struct socfpga_sdr_scc_mgr sdr_scc_mgr; | ||||
| 	u8 _align2[0x1bc]; | ||||
| 	/* SDR_PHYGRP_PHYMGRGRP_ADDRESS */ | ||||
| 	struct socfpga_phy_mgr_cmd phy_mgr_cmd; | ||||
| 	u8 _align3[0x2c]; | ||||
| 	/* SDR_PHYGRP_PHYMGRGRP_ADDRESS | 0x40 */ | ||||
| 	struct socfpga_phy_mgr_cfg phy_mgr_cfg; | ||||
| 	u8 _align4[0xfa0]; | ||||
| 	/* SDR_PHYGRP_RWMGRGRP_ADDRESS */ | ||||
| 	u8 rwmgr_grp[0x800]; | ||||
| 	/* SDR_PHYGRP_RWMGRGRP_ADDRESS | 0x800 */ | ||||
| 	struct socfpga_sdr_rw_load_manager sdr_rw_load_mgr_regs; | ||||
| 	u8 _align5[0x3f0]; | ||||
| 	/* SDR_PHYGRP_RWMGRGRP_ADDRESS | 0xC00 */ | ||||
| 	struct socfpga_sdr_rw_load_jump_manager sdr_rw_load_jump_mgr_regs; | ||||
| 	u8 _align6[0x13f0]; | ||||
| 	/* SDR_PHYGRP_DATAMGRGRP_ADDRESS */ | ||||
| 	struct socfpga_data_mgr data_mgr; | ||||
| 	u8 _align7[0x7f0]; | ||||
| 	/* SDR_PHYGRP_REGFILEGRP_ADDRESS */ | ||||
| 	struct socfpga_sdr_reg_file sdr_reg_file; | ||||
| 	u8 _align8[0x7c8]; | ||||
| 	/* SDR_CTRLGRP_ADDRESS */ | ||||
| 	struct socfpga_sdr_ctrl sdr_ctrl; | ||||
| 	u8 _align9[0xea4]; | ||||
| }; | ||||
| 
 | ||||
| int sdram_calibration_full(struct socfpga_sdr *sdr); | ||||
| 
 | ||||
| #endif /* _SEQUENCER_H_ */ | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ | |||
| #include <linux/bitops.h> | ||||
| #include <linux/mtd/rawnand.h> | ||||
| #include <linux/types.h> | ||||
| #include <reset.h> | ||||
| 
 | ||||
| #define DEVICE_RESET				0x0 | ||||
| #define     DEVICE_RESET__BANK(bank)			BIT(bank) | ||||
|  | @ -315,6 +316,7 @@ struct denali_nand_info { | |||
| 	void (*host_write)(struct denali_nand_info *denali, u32 addr, u32 data); | ||||
| 	void (*setup_dma)(struct denali_nand_info *denali, dma_addr_t dma_addr, | ||||
| 			  int page, int write); | ||||
| 	struct reset_ctl_bulk resets; | ||||
| }; | ||||
| 
 | ||||
| #define DENALI_CAP_HW_ECC_FIXUP			BIT(0) | ||||
|  |  | |||
|  | @ -131,15 +131,30 @@ static int denali_dt_probe(struct udevice *dev) | |||
| 		denali->clk_x_rate = 200000000; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = reset_get_bulk(dev, &denali->resets); | ||||
| 	if (ret) | ||||
| 		dev_warn(dev, "Can't get reset: %d\n", ret); | ||||
| 	else | ||||
| 		reset_deassert_bulk(&denali->resets); | ||||
| 
 | ||||
| 	return denali_init(denali); | ||||
| } | ||||
| 
 | ||||
| static int denali_dt_remove(struct udevice *dev) | ||||
| { | ||||
| 	struct denali_nand_info *denali = dev_get_priv(dev); | ||||
| 
 | ||||
| 	return reset_release_bulk(&denali->resets); | ||||
| } | ||||
| 
 | ||||
| U_BOOT_DRIVER(denali_nand_dt) = { | ||||
| 	.name = "denali-nand-dt", | ||||
| 	.id = UCLASS_MISC, | ||||
| 	.of_match = denali_nand_dt_ids, | ||||
| 	.probe = denali_dt_probe, | ||||
| 	.priv_auto_alloc_size = sizeof(struct denali_nand_info), | ||||
| 	.remove = denali_dt_remove, | ||||
| 	.flags = DM_FLAG_OS_PREPARE, | ||||
| }; | ||||
| 
 | ||||
| void board_nand_init(void) | ||||
|  |  | |||
|  | @ -24,9 +24,39 @@ | |||
| #define NR_BANKS		8 | ||||
| 
 | ||||
| struct socfpga_reset_data { | ||||
| 	void __iomem *membase; | ||||
| 	void __iomem *modrst_base; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * For compatibility with Kernels that don't support peripheral reset, this | ||||
|  * driver can keep the old behaviour of not asserting peripheral reset before | ||||
|  * starting the OS and deasserting all peripheral resets (enabling all | ||||
|  * peripherals). | ||||
|  * | ||||
|  * For that, the reset driver checks the environment variable | ||||
|  * "socfpga_legacy_reset_compat". If this variable is '1', perihperals are not | ||||
|  * reset again once taken out of reset and all peripherals in 'permodrst' are | ||||
|  * taken out of reset before booting into the OS. | ||||
|  * Note that this should be required for gen5 systems only that are running | ||||
|  * Linux kernels without proper peripheral reset support for all drivers used. | ||||
|  */ | ||||
| static bool socfpga_reset_keep_enabled(void) | ||||
| { | ||||
| #if !defined(CONFIG_SPL_BUILD) || CONFIG_IS_ENABLED(ENV_SUPPORT) | ||||
| 	const char *env_str; | ||||
| 	long val; | ||||
| 
 | ||||
| 	env_str = env_get("socfpga_legacy_reset_compat"); | ||||
| 	if (env_str) { | ||||
| 		val = simple_strtol(env_str, NULL, 0); | ||||
| 		if (val == 1) | ||||
| 			return true; | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static int socfpga_reset_assert(struct reset_ctl *reset_ctl) | ||||
| { | ||||
| 	struct socfpga_reset_data *data = dev_get_priv(reset_ctl->dev); | ||||
|  | @ -35,7 +65,7 @@ static int socfpga_reset_assert(struct reset_ctl *reset_ctl) | |||
| 	int bank = id / (reg_width * BITS_PER_BYTE); | ||||
| 	int offset = id % (reg_width * BITS_PER_BYTE); | ||||
| 
 | ||||
| 	setbits_le32(data->membase + (bank * BANK_INCREMENT), BIT(offset)); | ||||
| 	setbits_le32(data->modrst_base + (bank * BANK_INCREMENT), BIT(offset)); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -47,7 +77,7 @@ static int socfpga_reset_deassert(struct reset_ctl *reset_ctl) | |||
| 	int bank = id / (reg_width * BITS_PER_BYTE); | ||||
| 	int offset = id % (reg_width * BITS_PER_BYTE); | ||||
| 
 | ||||
| 	clrbits_le32(data->membase + (bank * BANK_INCREMENT), BIT(offset)); | ||||
| 	clrbits_le32(data->modrst_base + (bank * BANK_INCREMENT), BIT(offset)); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -80,11 +110,24 @@ static int socfpga_reset_probe(struct udevice *dev) | |||
| 	const void *blob = gd->fdt_blob; | ||||
| 	int node = dev_of_offset(dev); | ||||
| 	u32 modrst_offset; | ||||
| 	void __iomem *membase; | ||||
| 
 | ||||
| 	data->membase = devfdt_get_addr_ptr(dev); | ||||
| 	membase = devfdt_get_addr_ptr(dev); | ||||
| 
 | ||||
| 	modrst_offset = fdtdec_get_int(blob, node, "altr,modrst-offset", 0x10); | ||||
| 	data->membase += modrst_offset; | ||||
| 	data->modrst_base = membase + modrst_offset; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int socfpga_reset_remove(struct udevice *dev) | ||||
| { | ||||
| 	struct socfpga_reset_data *data = dev_get_priv(dev); | ||||
| 
 | ||||
| 	if (socfpga_reset_keep_enabled()) { | ||||
| 		puts("Deasserting all peripheral resets\n"); | ||||
| 		writel(0, data->modrst_base + 4); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -101,4 +144,6 @@ U_BOOT_DRIVER(socfpga_reset) = { | |||
| 	.probe = socfpga_reset_probe, | ||||
| 	.priv_auto_alloc_size = sizeof(struct socfpga_reset_data), | ||||
| 	.ops = &socfpga_reset_ops, | ||||
| 	.remove = socfpga_reset_remove, | ||||
| 	.flags	= DM_FLAG_OS_PREPARE, | ||||
| }; | ||||
|  |  | |||
|  | @ -8,6 +8,7 @@ | |||
| #include <dm.h> | ||||
| #include <fdtdec.h> | ||||
| #include <malloc.h> | ||||
| #include <reset.h> | ||||
| #include <spi.h> | ||||
| #include <linux/errno.h> | ||||
| #include "cadence_qspi.h" | ||||
|  | @ -154,10 +155,17 @@ static int cadence_spi_probe(struct udevice *bus) | |||
| { | ||||
| 	struct cadence_spi_platdata *plat = bus->platdata; | ||||
| 	struct cadence_spi_priv *priv = dev_get_priv(bus); | ||||
| 	int ret; | ||||
| 
 | ||||
| 	priv->regbase = plat->regbase; | ||||
| 	priv->ahbbase = plat->ahbbase; | ||||
| 
 | ||||
| 	ret = reset_get_bulk(bus, &priv->resets); | ||||
| 	if (ret) | ||||
| 		dev_warn(bus, "Can't get reset: %d\n", ret); | ||||
| 	else | ||||
| 		reset_deassert_bulk(&priv->resets); | ||||
| 
 | ||||
| 	if (!priv->qspi_is_init) { | ||||
| 		cadence_qspi_apb_controller_init(plat); | ||||
| 		priv->qspi_is_init = 1; | ||||
|  | @ -166,6 +174,13 @@ static int cadence_spi_probe(struct udevice *bus) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int cadence_spi_remove(struct udevice *dev) | ||||
| { | ||||
| 	struct cadence_spi_priv *priv = dev_get_priv(dev); | ||||
| 
 | ||||
| 	return reset_release_bulk(&priv->resets); | ||||
| } | ||||
| 
 | ||||
| static int cadence_spi_set_mode(struct udevice *bus, uint mode) | ||||
| { | ||||
| 	struct cadence_spi_priv *priv = dev_get_priv(bus); | ||||
|  | @ -342,4 +357,6 @@ U_BOOT_DRIVER(cadence_spi) = { | |||
| 	.platdata_auto_alloc_size = sizeof(struct cadence_spi_platdata), | ||||
| 	.priv_auto_alloc_size = sizeof(struct cadence_spi_priv), | ||||
| 	.probe = cadence_spi_probe, | ||||
| 	.remove = cadence_spi_remove, | ||||
| 	.flags = DM_FLAG_OS_PREPARE, | ||||
| }; | ||||
|  |  | |||
|  | @ -7,6 +7,8 @@ | |||
| #ifndef __CADENCE_QSPI_H__ | ||||
| #define __CADENCE_QSPI_H__ | ||||
| 
 | ||||
| #include <reset.h> | ||||
| 
 | ||||
| #define CQSPI_IS_ADDR(cmd_len)		(cmd_len > 1 ? 1 : 0) | ||||
| 
 | ||||
| #define CQSPI_NO_DECODER_MAX_CS		4 | ||||
|  | @ -42,6 +44,8 @@ struct cadence_spi_priv { | |||
| 	unsigned int	qspi_calibrated_hz; | ||||
| 	unsigned int	qspi_calibrated_cs; | ||||
| 	unsigned int	previous_hz; | ||||
| 
 | ||||
| 	struct reset_ctl_bulk resets; | ||||
| }; | ||||
| 
 | ||||
| /* Functions call declaration */ | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ static int dw_apb_timer_get_count(struct udevice *dev, u64 *count) | |||
| 	 * requires the count to be incrementing. Invert the | ||||
| 	 * result. | ||||
| 	 */ | ||||
| 	*count = ~readl(priv->regs + DW_APB_CURR_VAL); | ||||
| 	*count = timer_conv_64(~readl(priv->regs + DW_APB_CURR_VAL)); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -338,6 +338,7 @@ unsigned int cm_get_qspi_controller_clk_hz(void); | |||
| 	"scriptaddr=0x02100000\0" \ | ||||
| 	"pxefile_addr_r=0x02200000\0" \ | ||||
| 	"ramdisk_addr_r=0x02300000\0" \ | ||||
| 	"socfpga_legacy_reset_compat=1\0" \ | ||||
| 	BOOTENV | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue