~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: 77d7915b2b56c4021a6d5835a634806e60cdc5fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* 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