blob: 7efadeb9e4f47e2193e1e807a386668b6d4bcd94 [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
Nico Huber3be61d42017-01-09 13:58:18 +01002-- Copyright (C) 2016-2017 secunet Security Networks AG
Nico Huber83693c82016-10-08 22:17:55 +02003--
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.GFX.GMA.Config;
16with HW.GFX.GMA.Registers;
Nico Huber3be61d42017-01-09 13:58:18 +010017with HW.GFX.GMA.Config_Helpers;
Nico Huber83693c82016-10-08 22:17:55 +020018
19package body HW.GFX.GMA.Port_Detect
20is
21
Nico Huber83693c82016-10-08 22:17:55 +020022 DP_PORT_DETECTED : constant := 1 * 2 ** 2;
23 PCH_DIGI_PORT_DETECTED : constant := 1 * 2 ** 2;
24 PCH_LVDS_PORT_DETECTED : constant := 1 * 2 ** 1;
25
26 SHOTPLUG_CTL_DETECT_MASK : constant := 16#0003_0303#;
27
28 type PCH_Digital_Port_Value is array (PCH_HDMI_Port) of Word32;
29 SHOTPLUG_CTL_HPD_INPUT_ENABLE : constant PCH_Digital_Port_Value :=
30 (PCH_HDMI_B => 1 * 2 ** 4,
31 PCH_HDMI_C => 1 * 2 ** 12,
32 PCH_HDMI_D => 1 * 2 ** 20);
33 SHOTPLUG_CTL_SHORT_PULSE_MASK : constant PCH_Digital_Port_Value :=
34 (PCH_HDMI_B => 3 * 2 ** 2,
35 PCH_HDMI_C => 3 * 2 ** 10,
36 PCH_HDMI_D => 3 * 2 ** 18);
37 SHOTPLUG_CTL_HPD_STATUS : constant PCH_Digital_Port_Value :=
38 (PCH_HDMI_B => 3 * 2 ** 0,
39 PCH_HDMI_C => 3 * 2 ** 8,
40 PCH_HDMI_D => 3 * 2 ** 16);
41 SHOTPLUG_CTL_LONG_DETECT : constant PCH_Digital_Port_Value :=
42 (PCH_HDMI_B => 1 * 2 ** 1,
43 PCH_HDMI_C => 1 * 2 ** 9,
44 PCH_HDMI_D => 1 * 2 ** 17);
45
46 type PCH_Digital_Regs is array (PCH_HDMI_Port) of Registers.Registers_Index;
47 PCH_HDMI : constant PCH_Digital_Regs :=
48 (PCH_HDMI_B => Registers.PCH_HDMIB,
49 PCH_HDMI_C => Registers.PCH_HDMIC,
50 PCH_HDMI_D => Registers.PCH_HDMID);
51 PCH_DP : constant PCH_Digital_Regs :=
52 (PCH_HDMI_B => Registers.PCH_DP_B,
53 PCH_HDMI_C => Registers.PCH_DP_C,
54 PCH_HDMI_D => Registers.PCH_DP_D);
55
56 procedure Initialize
57 is
Nico Huber8beafd72020-01-07 14:59:44 +010058 LVDS_Detected,
59 eDP_Detected,
Nico Huber83693c82016-10-08 22:17:55 +020060 HDMI_Detected,
61 DP_Detected : Boolean;
62
63 type PCH_Port_To_GMA_Port is array (PCH_HDMI_Port) of Port_Type;
64 To_Digital_Port : constant PCH_Port_To_GMA_Port :=
Nico Huber0d454cd2016-11-21 13:33:43 +010065 (PCH_HDMI_B => HDMI1,
66 PCH_HDMI_C => HDMI2,
67 PCH_HDMI_D => HDMI3);
Nico Huber83693c82016-10-08 22:17:55 +020068 To_DP_Port : constant PCH_Port_To_GMA_Port :=
69 (PCH_HDMI_B => DP1,
70 PCH_HDMI_C => DP2,
71 PCH_HDMI_D => DP3);
72 begin
Nico Huber318bca12018-06-09 19:22:52 +020073 Config.Valid_Port (Analog) := True;
74
Nico Huber8beafd72020-01-07 14:59:44 +010075 -- PCH_LVDS
76 Registers.Is_Set_Mask
77 (Register => Registers.PCH_LVDS,
78 Mask => PCH_LVDS_PORT_DETECTED,
79 Result => LVDS_Detected);
80 Config.Valid_Port (LVDS) := LVDS_Detected;
81
82 -- eDP
83 Registers.Is_Set_Mask
84 (Register => Registers.DP_CTL_A,
85 Mask => DP_PORT_DETECTED,
86 Result => eDP_Detected);
87 Config.Valid_Port (eDP) := eDP_Detected;
Nico Huber83693c82016-10-08 22:17:55 +020088
89 -- PCH_HDMI_[BCD], PCH_DP_[BCD] share hotplug registers
90 for PCH_Port in PCH_HDMI_Port loop
91 Registers.Is_Set_Mask
92 (Register => PCH_HDMI (PCH_Port),
93 Mask => PCH_DIGI_PORT_DETECTED,
94 Result => HDMI_Detected);
95 Config.Valid_Port (To_Digital_Port (PCH_Port)) := HDMI_Detected;
96
97 Registers.Is_Set_Mask
98 (Register => PCH_DP (PCH_Port),
99 Mask => PCH_DIGI_PORT_DETECTED,
100 Result => DP_Detected);
101 Config.Valid_Port (To_DP_Port (PCH_Port)) := DP_Detected;
102
103 if HDMI_Detected or DP_Detected then
104 Registers.Unset_And_Set_Mask
105 (Register => Registers.SHOTPLUG_CTL,
106 Mask_Unset => SHOTPLUG_CTL_DETECT_MASK or
107 SHOTPLUG_CTL_SHORT_PULSE_MASK (PCH_Port),
108 Mask_Set => SHOTPLUG_CTL_HPD_INPUT_ENABLE (PCH_Port) or
109 SHOTPLUG_CTL_HPD_STATUS (PCH_Port)); -- clear
110 else
111 Registers.Unset_Mask
112 (Register => Registers.SHOTPLUG_CTL,
113 Mask => SHOTPLUG_CTL_DETECT_MASK or
114 SHOTPLUG_CTL_HPD_INPUT_ENABLE (PCH_Port));
115 end if;
116 end loop;
117 end Initialize;
118
Nico Huber3be61d42017-01-09 13:58:18 +0100119 procedure Hotplug_Detect (Port : in Active_Port_Type; Detected : out Boolean)
Nico Huber83693c82016-10-08 22:17:55 +0200120 is
121 Ctl32 : Word32;
122 PCH_Port : constant GMA.PCH_Port :=
Nico Huber3be61d42017-01-09 13:58:18 +0100123 (case Port is
124 when DP1 => PCH_HDMI_B,
125 when DP2 => PCH_HDMI_C,
126 when DP3 => PCH_HDMI_D,
127 when others => Config_Helpers.To_PCH_Port (Port));
Nico Huber83693c82016-10-08 22:17:55 +0200128 begin
Nico Huber8fb0f312017-01-18 14:35:45 +0100129 if PCH_Port in PCH_HDMI_B .. PCH_HDMI_D then
130 Registers.Read (Registers.SHOTPLUG_CTL, Ctl32, Verbose => False);
131 Detected := (Ctl32 and SHOTPLUG_CTL_LONG_DETECT (PCH_Port)) /= 0;
Nico Huber83693c82016-10-08 22:17:55 +0200132
Nico Huber8fb0f312017-01-18 14:35:45 +0100133 if (Ctl32 and SHOTPLUG_CTL_HPD_STATUS (PCH_Port)) /= 0 then
134 Registers.Unset_And_Set_Mask
135 (Register => Registers.SHOTPLUG_CTL,
136 Mask_Unset => SHOTPLUG_CTL_DETECT_MASK,
137 Mask_Set => SHOTPLUG_CTL_HPD_STATUS (PCH_Port));
138 end if;
139 else
140 Detected := False;
141 end if;
Nico Huber83693c82016-10-08 22:17:55 +0200142 end Hotplug_Detect;
143
Nico Huber4798c662017-01-11 12:44:48 +0100144 procedure Clear_Hotplug_Detect (Port : Active_Port_Type)
145 is
146 Ignored_HPD : Boolean;
147 begin
148 pragma Warnings (GNATprove, Off, "unused assignment to ""Ignored_HPD""",
149 Reason => "We want to clear pending events only");
150 Port_Detect.Hotplug_Detect (Port, Ignored_HPD);
151 pragma Warnings (GNATprove, On, "unused assignment to ""Ignored_HPD""");
152 end Clear_Hotplug_Detect;
153
Nico Huber83693c82016-10-08 22:17:55 +0200154end HW.GFX.GMA.Port_Detect;