blob: 4d57041d4a0795c9d30ef998d372b31fe23974e5 [file] [log] [blame]
Arthur Heymans960e2392026-03-03 19:45:24 +01001--
2-- Copyright (C) 2026 Arthur Heymans <arthur@aheymans.xyz>
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
6-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
8--
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;
17
18with HW.Debug;
19with GNAT.Source_Info;
20
21package body HW.GFX.GMA.GMCH.LVDS is
22
23 LVDS_ENABLE : constant := 1 * 2 ** 31;
24 LVDS_DITHER_EN : constant := 1 * 2 ** 25;
25 LVDS_VSYNC_POLARITY_INVERT : constant := 1 * 2 ** 21;
26 LVDS_HSYNC_POLARITY_INVERT : constant := 1 * 2 ** 20;
27 LVDS_CLK_A_DATA_A0A2_POWER_MASK : constant := 3 * 2 ** 8;
28 LVDS_CLK_A_DATA_A0A2_POWER_DOWN : constant := 0 * 2 ** 8;
29 LVDS_CLK_A_DATA_A0A2_POWER_UP : constant := 3 * 2 ** 8;
30 LVDS_CLK_B_POWER_MASK : constant := 3 * 2 ** 4;
31 LVDS_CLK_B_POWER_DOWN : constant := 0 * 2 ** 4;
32 LVDS_CLK_B_POWER_UP : constant := 3 * 2 ** 4;
33 LVDS_DATA_B0B2_POWER_MASK : constant := 3 * 2 ** 2;
34 LVDS_DATA_B0B2_POWER_DOWN : constant := 0 * 2 ** 2;
35 LVDS_DATA_B0B2_POWER_UP : constant := 3 * 2 ** 2;
36
37 ----------------------------------------------------------------------------
38
39 procedure On (Port_Cfg : in Port_Config;
40 Pipe : in Pipe_Index)
41 is
42 -- Pre-i965: LVDS encoder can only source from Pipe B (Secondary).
43 LVDS_Pipe : constant Pipe_Index :=
44 (if Config.LVDS_Needs_Pipe_B then Secondary else Pipe);
45
46 Sync_Polarity : constant Word32 :=
47 (if Port_Cfg.Mode.H_Sync_Active_High then 0
48 else LVDS_HSYNC_POLARITY_INVERT) or
49 (if Port_Cfg.Mode.V_Sync_Active_High then 0
50 else LVDS_VSYNC_POLARITY_INVERT);
51
52 Two_Channel : constant Word32 :=
53 (if Port_Cfg.Mode.Dotclock >= Config.LVDS_Dual_Threshold then
54 LVDS_CLK_B_POWER_UP or LVDS_DATA_B0B2_POWER_UP else 0);
55 begin
56 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
57 pragma Debug (Port_Cfg.Mode.BPC /= 6, Debug.Put_Line
58 ("WARNING: Only 18bpp LVDS mode implemented."));
59 pragma Debug (Config.LVDS_Needs_Pipe_B and Pipe /= Secondary,
60 Debug.Put_Line ("WARNING: Forcing LVDS to Pipe B (pre-i965 requirement)."));
61
62 Registers.Write
63 (Register => Registers.GMCH_LVDS,
64 Value => LVDS_ENABLE or
65 GMCH_PORT_PIPE_SELECT (LVDS_Pipe) or
66 Sync_Polarity or
67 LVDS_CLK_A_DATA_A0A2_POWER_UP or
68 Two_Channel or
69 LVDS_DITHER_EN);
70 end On;
71
72 ----------------------------------------------------------------------------
73
74 procedure Off
75 is
76 begin
77 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
78
79 Registers.Write
80 (Register => Registers.GMCH_LVDS,
81 Value => LVDS_CLK_A_DATA_A0A2_POWER_DOWN or
82 LVDS_CLK_B_POWER_DOWN or
83 LVDS_DATA_B0B2_POWER_DOWN);
84 end Off;
85
86end HW.GFX.GMA.GMCH.LVDS;