mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 10:26:10 +01:00 
			
		
		
		
	Driver for Cadence EDAC DDR controller, as found in the Renesas RZ/N1. Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org> Reviewed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
		
			
				
	
	
		
			176 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* SPDX-License-Identifier: BSD-2-Clause */
 | |
| /*
 | |
|  * Cadence DDR Controller
 | |
|  *
 | |
|  * Copyright (C) 2015 Renesas Electronics Europe Ltd
 | |
|  */
 | |
| 
 | |
| #ifndef CADENCE_DDR_CTRL_H
 | |
| #define CADENCE_DDR_CTRL_H
 | |
| 
 | |
| enum cdns_ddr_range_prot {
 | |
| 	CDNS_DDR_RANGE_PROT_BITS_PRIV_SECURE = 0,
 | |
| 	CDNS_DDR_RANGE_PROT_BITS_SECURE = 1,
 | |
| 	CDNS_DDR_RANGE_PROT_BITS_PRIV = 2,
 | |
| 	CDNS_DDR_RANGE_PROT_BITS_FULL = 3,
 | |
| };
 | |
| 
 | |
| /**
 | |
|  * Initialise the Cadence DDR Controller, but doesn't start it.
 | |
|  *
 | |
|  * It sets up the controller so that all 4 AXI slave ports allow access to all
 | |
|  * of the DDR with the same settings. This means that:
 | |
|  *  - Full access permisions.
 | |
|  *  - All read/write priorities are set to 2.
 | |
|  *  - Bandwidth is set to 50%, overflow is allowed, i.e. it's a soft limit.
 | |
|  * If you want different properties for different ports and/or addr ranges, call
 | |
|  * the other functions before calling cdns_ddr_ctrl_start().
 | |
|  *
 | |
|  * @ddr_ctrl_base  Physical address of the DDR Controller.
 | |
|  * @async          0 if DDR clock is synchronous with the controller clock
 | |
|  *                 otherwise 1.
 | |
|  * @reg0           Pointer to array of 32-bit values to be written to registers
 | |
|  *                 0 to 87. The values are generated by Cadence TCL scripts.
 | |
|  * @reg350         Pointer to array of 32-bit values to be written to registers
 | |
|  *                 350 to 374. The values are generated by Cadence TCL scripts.
 | |
|  * @ddr_start_addr Physical address of the start of DDR.
 | |
|  * @ddr_size       Size of the DDR in bytes. The controller will set the port
 | |
|  *                 protection range to match this size.
 | |
|  * @enable_ecc     0 to disable ECC, 1 to enable it.
 | |
|  * @enable_8bit    0 to use 16-bit bus width, 1 to use 8-bit bus width.
 | |
|  */
 | |
| void cdns_ddr_ctrl_init(void *ddr_ctrl_base, int async,
 | |
| 			const u32 *reg0, const u32 *reg350,
 | |
| 			u32 ddr_start_addr, u32 ddr_size,
 | |
| 			int enable_ecc, int enable_8bit);
 | |
| 
 | |
| /**
 | |
|  * Start the Cadence DDR Controller.
 | |
|  *
 | |
|  * @ddr_ctrl_base  Physical address of the DDR Controller.
 | |
|  */
 | |
| void cdns_ddr_ctrl_start(void *ddr_ctrl_base);
 | |
| 
 | |
| /**
 | |
|  * Set the priority for read and write operations for a specific AXI slave port.
 | |
|  *
 | |
|  * @base      Physical address of the DDR Controller.
 | |
|  * @port      Port number. Range is 0 to 3.
 | |
|  * @read_pri  Priority for reads.  Range is 0 to 3, where 0 is highest priority.
 | |
|  * @write_pri Priority for writes. Range is 0 to 3, where 0 is highest priority.
 | |
|  */
 | |
| void cdns_ddr_set_port_rw_priority(void *base, int port,
 | |
| 				   u8 read_pri, u8 write_pri);
 | |
| 
 | |
| /**
 | |
|  * Specify address range for a protection entry, for a specific AXI slave port.
 | |
|  *
 | |
|  * @base       Physical address of the DDR Controller.
 | |
|  * @port       Port number. Range is 0 to 3.
 | |
|  * @entry      The protection entry. Range is 0 to 15.
 | |
|  * @start_addr Physical of the address range, must be aligned to 16KB.
 | |
|  * @size       Size of the address range, must be multiple of 16KB.
 | |
|  */
 | |
| void cdns_ddr_enable_port_addr_range(void *base, int port, int entry,
 | |
| 				     u32 addr_start, u32 size);
 | |
| 
 | |
| /**
 | |
|  * Specify address range for a protection entry, for all AXI slave ports.
 | |
|  *
 | |
|  * @base       Physical address of the DDR Controller.
 | |
|  * @entry      The protection entry. Range is 0 to 15.
 | |
|  * @start_addr Physical of the address range, must be aligned to 16KB.
 | |
|  * @size       Size of the address range, must be multiple of 16KB.
 | |
|  */
 | |
| void cdns_ddr_enable_addr_range(void *base, int entry,
 | |
| 				u32 addr_start, u32 size);
 | |
| 
 | |
| /**
 | |
|  * Specify protection entry details, for a specific AXI slave port.
 | |
|  *
 | |
|  * See the hardware manual for details of the range check bits.
 | |
|  *
 | |
|  * @base       Physical address of the DDR Controller.
 | |
|  * @port       Port number. Range is 0 to 3.
 | |
|  * @entry      The protection entry. Range is 0 to 15.
 | |
|  */
 | |
| void cdns_ddr_enable_port_prot(void *base, int port, int entry,
 | |
| 			       enum cdns_ddr_range_prot range_protection_bits,
 | |
| 			       u16 range_RID_check_bits,
 | |
| 			       u16 range_WID_check_bits,
 | |
| 			       u8 range_RID_check_bits_ID_lookup,
 | |
| 			       u8 range_WID_check_bits_ID_lookup);
 | |
| 
 | |
| /**
 | |
|  * Specify protection entry details, for all AXI slave ports.
 | |
|  *
 | |
|  * See the hardware manual for details of the range check bits.
 | |
|  *
 | |
|  * @base       Physical address of the DDR Controller.
 | |
|  * @entry      The protection entry. Range is 0 to 15.
 | |
|  */
 | |
| void cdns_ddr_enable_prot(void *base, int entry,
 | |
| 			  enum cdns_ddr_range_prot range_protection_bits,
 | |
| 			  u16 range_RID_check_bits,
 | |
| 			  u16 range_WID_check_bits,
 | |
| 			  u8 range_RID_check_bits_ID_lookup,
 | |
| 			  u8 range_WID_check_bits_ID_lookup);
 | |
| 
 | |
| /**
 | |
|  * Specify bandwidth for each AXI port.
 | |
|  *
 | |
|  * See the hardware manual for details of the range check bits.
 | |
|  *
 | |
|  * @base       Physical address of the DDR Controller.
 | |
|  * @port       Port number. Range is 0 to 3.
 | |
|  * @max_percent     0 to 100.
 | |
|  */
 | |
| void cdns_ddr_set_port_bandwidth(void *base, int port,
 | |
| 				 u8 max_percent, u8 overflow_ok);
 | |
| 
 | |
| /* Standard JEDEC registers */
 | |
| #define MODE_REGISTER_MASK		(3 << 14)
 | |
| #define MODE_REGISTER_MR0		(0 << 14)
 | |
| #define MODE_REGISTER_MR1		(1 << 14)
 | |
| #define MODE_REGISTER_MR2		(2 << 14)
 | |
| #define MODE_REGISTER_MR3		(3 << 14)
 | |
| #define MR1_DRIVE_STRENGTH_MASK		((1 << 5) | (1 << 1))
 | |
| #define MR1_DRIVE_STRENGTH_34_OHMS	((0 << 5) | (1 << 1))
 | |
| #define MR1_DRIVE_STRENGTH_40_OHMS	((0 << 5) | (0 << 1))
 | |
| #define MR1_ODT_IMPEDANCE_MASK		((1 << 9) | (1 << 6) | (1 << 2))
 | |
| #define MR1_ODT_IMPEDANCE_60_OHMS	((0 << 9) | (0 << 6) | (1 << 2))
 | |
| #define MR1_ODT_IMPEDANCE_120_OHMS	((0 << 9) | (1 << 6) | (0 << 2))
 | |
| #define MR1_ODT_IMPEDANCE_40_OHMS	((0 << 9) | (1 << 6) | (1 << 2))
 | |
| #define MR1_ODT_IMPEDANCE_20_OHMS	((1 << 9) | (0 << 6) | (0 << 2))
 | |
| #define MR1_ODT_IMPEDANCE_30_OHMS	((1 << 9) | (0 << 6) | (1 << 2))
 | |
| #define MR2_DYNAMIC_ODT_MASK		(3 << 9)
 | |
| #define MR2_DYNAMIC_ODT_OFF		(0 << 9)
 | |
| #define MR2_SELF_REFRESH_TEMP_MASK	(1 << 7)
 | |
| #define MR2_SELF_REFRESH_TEMP_EXT	(1 << 7)
 | |
| 
 | |
| /**
 | |
|  * Set certain fields of the JEDEC MR1 register.
 | |
|  */
 | |
| void cdns_ddr_set_mr1(void *base, int cs, u16 odt_impedance, u16 drive_strength);
 | |
| 
 | |
| /**
 | |
|  * Set certain fields of the JEDEC MR2 register.
 | |
|  */
 | |
| void cdns_ddr_set_mr2(void *base, int cs, u16 dynamic_odt, u16 self_refresh_temp);
 | |
| 
 | |
| /**
 | |
|  * Set ODT map of the DDR Controller.
 | |
|  */
 | |
| void cdns_ddr_set_odt_map(void *base, int cs, u16 odt_map);
 | |
| 
 | |
| /**
 | |
|  * Set ODT settings in the DDR Controller.
 | |
|  */
 | |
| void cdns_ddr_set_odt_times(void *base, u8 TODTL_2CMD, u8 TODTH_WR, u8 TODTH_RD,
 | |
| 			    u8 WR_TO_ODTH, u8 RD_TO_ODTH);
 | |
| 
 | |
| void cdns_ddr_set_same_cs_delays(void *base, u8 r2r, u8 r2w, u8 w2r, u8 w2w);
 | |
| void cdns_ddr_set_diff_cs_delays(void *base, u8 r2r, u8 r2w, u8 w2r, u8 w2w);
 | |
| 
 | |
| #endif
 |