blob: b6443fe62746680ac41e1c67252e7d0369009692 [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
2-- Copyright (C) 2015-2016 secunet Security Networks AG
3--
4-- This program is free software; you can redistribute it and/or modify
5-- it under the terms of the GNU General Public License as published by
Nico Huber125a29e2016-10-18 00:23:54 +02006-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
Nico Huber83693c82016-10-08 22:17:55 +02008--
9-- This program is distributed in the hope that it will be useful,
10-- but WITHOUT ANY WARRANTY; without even the implied warranty of
11-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-- GNU General Public License for more details.
13--
14
15with HW.Time;
16with HW.GFX.DP_Training;
17with HW.GFX.GMA.DP_Info;
18with HW.GFX.GMA.DP_Aux_Ch;
19with HW.GFX.GMA.Registers;
20
21with HW.Debug;
22with GNAT.Source_Info;
23
24package body HW.GFX.GMA.Connectors.EDP
25is
26
27 DP_CTL_DISPLAYPORT_ENABLE : constant := 1 * 2 ** 31;
28 DP_CTL_PIPE_SELECT_MASK : constant := 3 * 2 ** 29;
29 DP_CTL_PIPE_SELECT_SHIFT : constant := 29;
30 DP_CTL_VSWING_EMPH_SET_MASK : constant := 63 * 2 ** 22;
31 DP_CTL_PORT_WIDTH_MASK : constant := 7 * 2 ** 19;
32 DP_CTL_PORT_WIDTH_1_LANE : constant := 0 * 2 ** 19;
33 DP_CTL_PORT_WIDTH_2_LANES : constant := 1 * 2 ** 19;
34 DP_CTL_PORT_WIDTH_4_LANES : constant := 3 * 2 ** 19;
35 DP_CTL_ENHANCED_FRAMING_ENABLE : constant := 1 * 2 ** 18;
36 DP_CTL_PLL_FREQUENCY_MASK : constant := 3 * 2 ** 16;
37 DP_CTL_PLL_FREQUENCY_270 : constant := 0 * 2 ** 16;
38 DP_CTL_PLL_FREQUENCY_162 : constant := 1 * 2 ** 16;
39 DP_CTL_PORT_REVERSAL : constant := 1 * 2 ** 15;
40 DP_CTL_PLL_ENABLE : constant := 1 * 2 ** 14;
41 DP_CTL_LINK_TRAIN_MASK : constant := 3 * 2 ** 8;
42 DP_CTL_LINK_TRAIN_PAT1 : constant := 0 * 2 ** 8;
43 DP_CTL_LINK_TRAIN_PAT2 : constant := 1 * 2 ** 8;
44 DP_CTL_LINK_TRAIN_IDLE : constant := 2 * 2 ** 8;
45 DP_CTL_LINK_TRAIN_NORMAL : constant := 3 * 2 ** 8;
46 DP_CTL_ALT_SCRAMBLER_RESET : constant := 1 * 2 ** 6;
47 DP_CTL_VSYNC_ACTIVE_HIGH : constant := 1 * 2 ** 4;
48 DP_CTL_HSYNC_ACTIVE_HIGH : constant := 1 * 2 ** 3;
49 DP_CTL_PORT_DETECT : constant := 1 * 2 ** 2;
50
51 -- TODO? Values are for Ivy Bridge only
52 DP_CTL_VSWING_0_EMPH_0 : constant := 1 * 2 ** 27 + 1 * 2 ** 24 + 0 * 2 ** 22;
53 DP_CTL_VSWING_0_EMPH_1 : constant := 1 * 2 ** 27 + 2 * 2 ** 24 + 2 * 2 ** 22;
54 DP_CTL_VSWING_0_EMPH_2 : constant := 1 * 2 ** 27 + 3 * 2 ** 24 + 3 * 2 ** 22;
55 DP_CTL_VSWING_1_EMPH_0 : constant := 1 * 2 ** 27 + 4 * 2 ** 24 + 0 * 2 ** 22;
56 DP_CTL_VSWING_1_EMPH_1 : constant := 1 * 2 ** 27 + 5 * 2 ** 24 + 2 * 2 ** 22;
57 DP_CTL_VSWING_2_EMPH_0 : constant := 1 * 2 ** 27 + 6 * 2 ** 24 + 0 * 2 ** 22;
58 DP_CTL_VSWING_2_EMPH_1 : constant := 1 * 2 ** 27 + 7 * 2 ** 24 + 2 * 2 ** 22;
59
60 type DP_CTL_PORT_WIDTH_T is array (DP_Lane_Count) of Word32;
61 DP_CTL_PORT_WIDTH : constant DP_CTL_PORT_WIDTH_T :=
62 DP_CTL_PORT_WIDTH_T'
63 (DP_Lane_Count_1 => DP_CTL_PORT_WIDTH_1_LANE,
64 DP_Lane_Count_2 => DP_CTL_PORT_WIDTH_2_LANES,
65 DP_Lane_Count_4 => DP_CTL_PORT_WIDTH_4_LANES);
66
67 type DP_CTL_LINK_TRAIN_Array is array (DP_Info.Training_Pattern) of Word32;
68 DP_CTL_LINK_TRAIN : constant DP_CTL_LINK_TRAIN_Array :=
69 DP_CTL_LINK_TRAIN_Array'
70 (DP_Info.TP_1 => DP_CTL_LINK_TRAIN_PAT1,
71 DP_Info.TP_2 => DP_CTL_LINK_TRAIN_PAT2,
72 DP_Info.TP_3 => DP_CTL_LINK_TRAIN_PAT2,
73 DP_Info.TP_Idle => DP_CTL_LINK_TRAIN_IDLE,
74 DP_Info.TP_None => DP_CTL_LINK_TRAIN_NORMAL);
75
76 ----------------------------------------------------------------------------
77
78 procedure Pre_Training is
79 begin
80 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
81
82 Registers.Unset_And_Set_Mask
83 (Register => Registers.DP_CTL_A,
84 Mask_Unset => DP_CTL_LINK_TRAIN_MASK,
85 Mask_Set => DP_CTL_LINK_TRAIN (DP_Info.TP_1) or
86 DP_CTL_DISPLAYPORT_ENABLE);
87 end Pre_Training;
88
89 ----------------------------------------------------------------------------
90
91 pragma Warnings (GNATprove, Off, "unused variable ""Port""",
92 Reason => "Needed for a common interface");
93 function Max_V_Swing
94 (Port : Digital_Port)
95 return DP_Info.DP_Voltage_Swing
96 is
97 begin
98 return DP_Info.VS_Level_2;
99 end Max_V_Swing;
100
101 function Max_Pre_Emph
102 (Port : Digital_Port;
103 Train_Set : DP_Info.Train_Set)
104 return DP_Info.DP_Pre_Emph
105 is
106 begin
107 return
108 (case Train_Set.Voltage_Swing is
109 when DP_Info.VS_Level_0 => DP_Info.Emph_Level_2,
110 when DP_Info.VS_Level_1 |
111 DP_Info.VS_Level_2 => DP_Info.Emph_Level_1,
112 when others => DP_Info.Emph_Level_0);
113 end Max_Pre_Emph;
114
115 ----------------------------------------------------------------------------
116
117 pragma Warnings (GNATprove, Off, "unused variable ""Link""",
118 Reason => "Needed for a common interface");
119 procedure Set_Training_Pattern
120 (Port : Digital_Port;
121 Link : DP_Link;
122 Pattern : DP_Info.Training_Pattern)
123 is
124 use type DP_Info.Training_Pattern;
125 begin
126 if Pattern < DP_Info.TP_Idle then
127 Registers.Unset_And_Set_Mask
128 (Register => Registers.DP_CTL_A,
129 Mask_Unset => DP_CTL_LINK_TRAIN_MASK,
130 Mask_Set => DP_CTL_LINK_TRAIN (Pattern));
131 else
132 -- send at least 5 idle patterns
133 Registers.Unset_And_Set_Mask
134 (Register => Registers.DP_CTL_A,
135 Mask_Unset => DP_CTL_LINK_TRAIN_MASK,
136 Mask_Set => DP_CTL_LINK_TRAIN (DP_Info.TP_Idle));
137
138 -- we switch to normal frame delivery later in Post_On procedure
139 end if;
140 end Set_Training_Pattern;
141
142 procedure Set_Signal_Levels
143 (Port : Digital_Port;
144 Link : DP_Link;
145 Train_Set : DP_Info.Train_Set)
146 is
147 VSwing_Emph : Word32;
148 begin
149 VSwing_Emph :=
150 (case Train_Set.Voltage_Swing is
151 when DP_Info.VS_Level_0 =>
152 (case Train_Set.Pre_Emph is
153 when DP_Info.Emph_Level_0 => DP_CTL_VSWING_0_EMPH_0,
154 when DP_Info.Emph_Level_1 => DP_CTL_VSWING_0_EMPH_1,
155 when DP_Info.Emph_Level_2 => DP_CTL_VSWING_0_EMPH_2,
156 when others => DP_CTL_VSWING_0_EMPH_0),
157 when DP_Info.VS_Level_1 =>
158 (case Train_Set.Pre_Emph is
159 when DP_Info.Emph_Level_0 => DP_CTL_VSWING_1_EMPH_0,
160 when DP_Info.Emph_Level_1 => DP_CTL_VSWING_1_EMPH_1,
161 when others => DP_CTL_VSWING_1_EMPH_0),
162 when DP_Info.VS_Level_2 =>
163 (case Train_Set.Pre_Emph is
164 when DP_Info.Emph_Level_0 => DP_CTL_VSWING_2_EMPH_0,
165 when DP_Info.Emph_Level_1 => DP_CTL_VSWING_2_EMPH_1,
166 when others => DP_CTL_VSWING_2_EMPH_0),
167 when others => DP_CTL_VSWING_0_EMPH_0);
168
169 Registers.Unset_And_Set_Mask
170 (Register => Registers.DP_CTL_A,
171 Mask_Unset => DP_CTL_VSWING_EMPH_SET_MASK,
172 Mask_Set => VSwing_Emph);
173 end Set_Signal_Levels;
174 pragma Warnings (GNATprove, On, "unused variable ""Port""");
175 pragma Warnings (GNATprove, On, "unused variable ""Link""");
176
177 ----------------------------------------------------------------------------
178
179 procedure Pre_On
180 (Port_Cfg : Port_Config;
181 Pipe_Hint : Word32)
182 is
183 DP_CTL_Set : Word32;
184 begin
185 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
186
187 DP_CTL_Set :=
188 Shift_Left (Pipe_Hint, DP_CTL_PIPE_SELECT_SHIFT) or
189 DP_CTL_PORT_WIDTH (Port_Cfg.DP.Lane_Count);
190
191 if Port_Cfg.DP.Enhanced_Framing then
192 DP_CTL_Set := DP_CTL_Set or DP_CTL_ENHANCED_FRAMING_ENABLE;
193 end if;
194
195 case Port_Cfg.DP.Bandwidth is
196 when DP_Bandwidth_1_62 =>
197 DP_CTL_Set := DP_CTL_Set or DP_CTL_PLL_FREQUENCY_162;
198 when DP_Bandwidth_2_7 =>
199 DP_CTL_Set := DP_CTL_Set or DP_CTL_PLL_FREQUENCY_270;
200 when others =>
201 null;
202 end case;
203
204 if Port_Cfg.Mode.V_Sync_Active_High then
205 DP_CTL_Set := DP_CTL_Set or DP_CTL_VSYNC_ACTIVE_HIGH;
206 end if;
207 if Port_Cfg.Mode.H_Sync_Active_High then
208 DP_CTL_Set := DP_CTL_Set or DP_CTL_HSYNC_ACTIVE_HIGH;
209 end if;
210
211 Registers.Write
212 (Register => Registers.DP_CTL_A,
213 Value => DP_CTL_Set);
214
215 Registers.Write
216 (Register => Registers.DP_CTL_A,
217 Value => DP_CTL_PLL_ENABLE or DP_CTL_Set);
218 Registers.Posting_Read (Registers.DP_CTL_A);
219 Time.U_Delay (20);
220 end Pre_On;
221
222 ----------------------------------------------------------------------------
223
224 procedure Post_On
225 (Link : in DP_Link;
226 Success : out Boolean)
227 is
228 pragma Warnings (GNATprove, Off, "unused variable ""Port""",
229 Reason => "Needed for a common interface");
230 function To_DP (Port : Digital_Port) return DP_Port
231 is
232 begin
233 return DP_A;
234 end To_DP;
235 pragma Warnings (GNATprove, On, "unused variable ""Port""");
236 package Training is new DP_Training
237 (TPS3_Supported => False,
238 T => Digital_Port,
239 Aux_T => DP_Port,
240 Aux_Ch => DP_Aux_Ch,
241 DP_Info => DP_Info,
242 To_Aux => To_DP,
243 Max_V_Swing => Max_V_Swing,
244 Max_Pre_Emph => Max_Pre_Emph,
245 Set_Pattern => Set_Training_Pattern,
246 Set_Signal_Levels => Set_Signal_Levels,
247 Off => Off);
248 begin
249 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
250
251 Training.Train_DP
252 (Port => DIGI_A,
253 Link => Link,
254 Success => Success);
255
256 if Success then
257 Registers.Unset_And_Set_Mask
258 (Register => Registers.DP_CTL_A,
259 Mask_Unset => DP_CTL_LINK_TRAIN_MASK,
260 Mask_Set => DP_CTL_LINK_TRAIN_NORMAL);
261 end if;
262 end Post_On;
263
264 ----------------------------------------------------------------------------
265
266 procedure Off (Port : Digital_Port)
267 is
268 Enabled : Boolean;
269 begin
270 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
271
272 Registers.Unset_And_Set_Mask
273 (Register => Registers.DP_CTL_A,
274 Mask_Unset => DP_CTL_LINK_TRAIN_MASK,
275 Mask_Set => DP_CTL_LINK_TRAIN_IDLE);
276 Registers.Posting_Read (Registers.DP_CTL_A);
277
278 Registers.Unset_Mask
279 (Register => Registers.DP_CTL_A,
280 Mask => DP_CTL_DISPLAYPORT_ENABLE);
281 -- implicit Posting_Read below
282
283 Registers.Is_Set_Mask
284 (Register => Registers.DP_CTL_A,
285 Mask => DP_CTL_PLL_ENABLE,
286 Result => Enabled);
287
288 Registers.Write
289 (Register => Registers.DP_CTL_A,
290 Value => 16#0000_0000#);
291 Registers.Posting_Read (Registers.DP_CTL_A);
292
293 if Enabled then
294 Time.U_Delay (20);
295 end if;
296 end Off;
297
298end HW.GFX.GMA.Connectors.EDP;