blob: 5af2e8429591b18bd722c5648f8693af5936bbe2 [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
58 Internal_Detected,
59 HDMI_Detected,
60 DP_Detected : Boolean;
61
62 type PCH_Port_To_GMA_Port is array (PCH_HDMI_Port) of Port_Type;
63 To_Digital_Port : constant PCH_Port_To_GMA_Port :=
Nico Huber0d454cd2016-11-21 13:33:43 +010064 (PCH_HDMI_B => HDMI1,
65 PCH_HDMI_C => HDMI2,
66 PCH_HDMI_D => HDMI3);
Nico Huber83693c82016-10-08 22:17:55 +020067 To_DP_Port : constant PCH_Port_To_GMA_Port :=
68 (PCH_HDMI_B => DP1,
69 PCH_HDMI_C => DP2,
70 PCH_HDMI_D => DP3);
71 begin
Nico Huber318bca12018-06-09 19:22:52 +020072 Config.Valid_Port (Analog) := True;
73
Nico Huber83693c82016-10-08 22:17:55 +020074 case Config.Internal_Display is
75 when LVDS =>
76 -- PCH_LVDS
77 Registers.Is_Set_Mask
78 (Register => Registers.PCH_LVDS,
79 Mask => PCH_LVDS_PORT_DETECTED,
80 Result => Internal_Detected);
81 when DP =>
82 -- eDP
83 Registers.Is_Set_Mask
84 (Register => Registers.DP_CTL_A,
85 Mask => DP_PORT_DETECTED,
86 Result => Internal_Detected);
87 when None =>
88 Internal_Detected := False;
89 end case;
90 Config.Valid_Port (Internal) := Internal_Detected;
91
92 -- PCH_HDMI_[BCD], PCH_DP_[BCD] share hotplug registers
93 for PCH_Port in PCH_HDMI_Port loop
94 Registers.Is_Set_Mask
95 (Register => PCH_HDMI (PCH_Port),
96 Mask => PCH_DIGI_PORT_DETECTED,
97 Result => HDMI_Detected);
98 Config.Valid_Port (To_Digital_Port (PCH_Port)) := HDMI_Detected;
99
100 Registers.Is_Set_Mask
101 (Register => PCH_DP (PCH_Port),
102 Mask => PCH_DIGI_PORT_DETECTED,
103 Result => DP_Detected);
104 Config.Valid_Port (To_DP_Port (PCH_Port)) := DP_Detected;
105
106 if HDMI_Detected or DP_Detected then
107 Registers.Unset_And_Set_Mask
108 (Register => Registers.SHOTPLUG_CTL,
109 Mask_Unset => SHOTPLUG_CTL_DETECT_MASK or
110 SHOTPLUG_CTL_SHORT_PULSE_MASK (PCH_Port),
111 Mask_Set => SHOTPLUG_CTL_HPD_INPUT_ENABLE (PCH_Port) or
112 SHOTPLUG_CTL_HPD_STATUS (PCH_Port)); -- clear
113 else
114 Registers.Unset_Mask
115 (Register => Registers.SHOTPLUG_CTL,
116 Mask => SHOTPLUG_CTL_DETECT_MASK or
117 SHOTPLUG_CTL_HPD_INPUT_ENABLE (PCH_Port));
118 end if;
119 end loop;
120 end Initialize;
121
Nico Huber3be61d42017-01-09 13:58:18 +0100122 procedure Hotplug_Detect (Port : in Active_Port_Type; Detected : out Boolean)
Nico Huber83693c82016-10-08 22:17:55 +0200123 is
124 Ctl32 : Word32;
125 PCH_Port : constant GMA.PCH_Port :=
Nico Huber3be61d42017-01-09 13:58:18 +0100126 (case Port is
127 when DP1 => PCH_HDMI_B,
128 when DP2 => PCH_HDMI_C,
129 when DP3 => PCH_HDMI_D,
130 when others => Config_Helpers.To_PCH_Port (Port));
Nico Huber83693c82016-10-08 22:17:55 +0200131 begin
Nico Huber8fb0f312017-01-18 14:35:45 +0100132 if PCH_Port in PCH_HDMI_B .. PCH_HDMI_D then
133 Registers.Read (Registers.SHOTPLUG_CTL, Ctl32, Verbose => False);
134 Detected := (Ctl32 and SHOTPLUG_CTL_LONG_DETECT (PCH_Port)) /= 0;
Nico Huber83693c82016-10-08 22:17:55 +0200135
Nico Huber8fb0f312017-01-18 14:35:45 +0100136 if (Ctl32 and SHOTPLUG_CTL_HPD_STATUS (PCH_Port)) /= 0 then
137 Registers.Unset_And_Set_Mask
138 (Register => Registers.SHOTPLUG_CTL,
139 Mask_Unset => SHOTPLUG_CTL_DETECT_MASK,
140 Mask_Set => SHOTPLUG_CTL_HPD_STATUS (PCH_Port));
141 end if;
142 else
143 Detected := False;
144 end if;
Nico Huber83693c82016-10-08 22:17:55 +0200145 end Hotplug_Detect;
146
Nico Huber4798c662017-01-11 12:44:48 +0100147 procedure Clear_Hotplug_Detect (Port : Active_Port_Type)
148 is
149 Ignored_HPD : Boolean;
150 begin
151 pragma Warnings (GNATprove, Off, "unused assignment to ""Ignored_HPD""",
152 Reason => "We want to clear pending events only");
153 Port_Detect.Hotplug_Detect (Port, Ignored_HPD);
154 pragma Warnings (GNATprove, On, "unused assignment to ""Ignored_HPD""");
155 end Clear_Hotplug_Detect;
156
Nico Huber83693c82016-10-08 22:17:55 +0200157end HW.GFX.GMA.Port_Detect;