xref: /openbsd/sys/dev/pci/drm/i915/intel_stolen.c (revision f005ef32)
1 /* Public domain. */
2 
3 #include <linux/types.h>
4 #include <linux/ioport.h>
5 #include <linux/pci.h>
6 #include <drm/i915_drm.h>
7 #include "i915_drv.h"
8 
9 struct resource intel_graphics_stolen_res = DEFINE_RES_MEM(0, 0);
10 
11 bus_addr_t
gen3_stolen_base(struct inteldrm_softc * dev_priv)12 gen3_stolen_base(struct inteldrm_softc *dev_priv)
13 {
14 	uint32_t bsm = pci_conf_read(dev_priv->pc, dev_priv->tag,
15 	    INTEL_BSM);
16 	return bsm & INTEL_BSM_MASK;
17 }
18 
19 bus_addr_t
gen11_stolen_base(struct inteldrm_softc * dev_priv)20 gen11_stolen_base(struct inteldrm_softc *dev_priv)
21 {
22 	uint64_t bsm = pci_conf_read(dev_priv->pc, dev_priv->tag,
23 	    INTEL_GEN11_BSM_DW0);
24 	bsm &= INTEL_BSM_MASK;
25 	bsm |= (uint64_t)pci_conf_read(dev_priv->pc, dev_priv->tag,
26 	    INTEL_GEN11_BSM_DW1) << 32;
27 	return bsm;
28 }
29 
30 bus_size_t
i830_stolen_size(struct inteldrm_softc * dev_priv)31 i830_stolen_size(struct inteldrm_softc *dev_priv)
32 {
33 	uint16_t gmch_ctl, gms;
34 
35 	pci_read_config_word(dev_priv->gmch.pdev, I830_GMCH_CTRL,
36 	    &gmch_ctl);
37 	gms = gmch_ctl & I830_GMCH_GMS_MASK;
38 
39 	switch (gms) {
40 	case I830_GMCH_GMS_STOLEN_512:
41 		return 512 * 1024;
42 	case I830_GMCH_GMS_STOLEN_1024:
43 		return 1 * 1024 * 1024;
44 	case I830_GMCH_GMS_STOLEN_8192:
45 		return 8 * 1024 * 1024;
46 	}
47 
48 	return 0;
49 }
50 
51 bus_size_t
gen3_stolen_size(struct inteldrm_softc * dev_priv)52 gen3_stolen_size(struct inteldrm_softc *dev_priv)
53 {
54 	uint16_t gmch_ctl, gms;
55 
56 	pci_read_config_word(dev_priv->gmch.pdev, I830_GMCH_CTRL,
57 	    &gmch_ctl);
58 	gms = gmch_ctl & I855_GMCH_GMS_MASK;
59 
60 	switch (gms) {
61 	case I855_GMCH_GMS_STOLEN_1M:
62 		return 1 * 1024 * 1024;
63 	case I855_GMCH_GMS_STOLEN_4M:
64 		return 4 * 1024 * 1024;
65 	case I855_GMCH_GMS_STOLEN_8M:
66 		return 8 * 1024 * 1024;
67 	case I855_GMCH_GMS_STOLEN_16M:
68 		return 16 * 1024 * 1024;
69 	case I855_GMCH_GMS_STOLEN_32M:
70 		return 32 * 1024 * 1024;
71 	case I915_GMCH_GMS_STOLEN_48M:
72 		return 48 * 1024 * 1024;
73 	case I915_GMCH_GMS_STOLEN_64M:
74 		return 64 * 1024 * 1024;
75 	case G33_GMCH_GMS_STOLEN_128M:
76 		return 128 * 1024 * 1024;
77 	case G33_GMCH_GMS_STOLEN_256M:
78 		return 256 * 1024 * 1024;
79 	case INTEL_GMCH_GMS_STOLEN_96M:
80 		return 96 * 1024 * 1024;
81 	case INTEL_GMCH_GMS_STOLEN_160M:
82 		return 160 * 1024 * 1024;
83 	case INTEL_GMCH_GMS_STOLEN_224M:
84 		return 224 * 1024 * 1024;
85 	case INTEL_GMCH_GMS_STOLEN_352M:
86 		return 352 * 1024 * 1024;
87 	}
88 
89 	return 0;
90 }
91 
92 bus_size_t
gen6_stolen_size(struct inteldrm_softc * dev_priv)93 gen6_stolen_size(struct inteldrm_softc *dev_priv)
94 {
95 	struct pci_dev *pdev = dev_priv->drm.pdev;
96 	uint16_t gmch_ctl, gms;
97 
98 	pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl);
99 	gms = (gmch_ctl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK;
100 
101 	return gms * (32 * 1024 * 1024);
102 }
103 
104 bus_size_t
chv_stolen_size(struct inteldrm_softc * dev_priv)105 chv_stolen_size(struct inteldrm_softc *dev_priv)
106 {
107 	struct pci_dev *pdev = dev_priv->drm.pdev;
108 	uint16_t gmch_ctl, gms;
109 
110 	pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl);
111 	gms = (gmch_ctl >> SNB_GMCH_GMS_SHIFT) & SNB_GMCH_GMS_MASK;
112 
113 	if (gms < 0x11)
114 		return gms * (32 * 1024 * 1024);
115 	else if (gms < 0x17)
116 		return (gms - 0x11) * (4 * 1024 * 1024) + (8 * 1024 * 1024);
117 	else
118 		return (gms - 0x17) + (4 * 1024 * 1024) + (36 * 1024 * 1024);
119 }
120 
121 bus_size_t
gen8_stolen_size(struct inteldrm_softc * dev_priv)122 gen8_stolen_size(struct inteldrm_softc *dev_priv)
123 {
124 	struct pci_dev *pdev = dev_priv->drm.pdev;
125 	uint16_t gmch_ctl, gms;
126 
127 	pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl);
128 	gms = (gmch_ctl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK;
129 
130 	return gms * (32 * 1024 * 1024);
131 }
132 
133 bus_size_t
gen9_stolen_size(struct inteldrm_softc * dev_priv)134 gen9_stolen_size(struct inteldrm_softc *dev_priv)
135 {
136 	struct pci_dev *pdev = dev_priv->drm.pdev;
137 	uint16_t gmch_ctl, gms;
138 
139 	pci_read_config_word(pdev, SNB_GMCH_CTRL, &gmch_ctl);
140 	gms = (gmch_ctl >> BDW_GMCH_GMS_SHIFT) & BDW_GMCH_GMS_MASK;
141 	if (gms < 0xf0)
142 		return gms * (32 * 1024 * 1024);
143 	else
144 		return (gms - 0xf0) * (4 * 1024 * 1024) + (4 * 1024 * 1024);
145 }
146 
147 void
intel_init_stolen_res(struct inteldrm_softc * dev_priv)148 intel_init_stolen_res(struct inteldrm_softc *dev_priv)
149 {
150 	bus_addr_t stolen_base = 0;
151 	bus_size_t stolen_size = 0;
152 
153 #ifdef notyet
154 	if (IS_I830(dev_priv))
155 		stolen_base  = i830_stolen_base(dev_priv);
156 	else if (IS_I845G(dev_priv))
157 		stolen_base  = i845_stolen_base(dev_priv);
158 	else if (IS_I85X(dev_priv))
159 		stolen_base  = i85x_stolen_base(dev_priv);
160 	else if (IS_I865G(dev_priv))
161 		stolen_base  = i865_stolen_base(dev_priv);
162 #endif
163 
164 	if (GRAPHICS_VER(dev_priv) >= 3 && GRAPHICS_VER(dev_priv) < 11)
165 		stolen_base  = gen3_stolen_base(dev_priv);
166 	else if (GRAPHICS_VER(dev_priv) == 11 || GRAPHICS_VER(dev_priv) == 12)
167 		stolen_base = gen11_stolen_base(dev_priv);
168 
169 	if (IS_I830(dev_priv) || IS_I845G(dev_priv))
170 		stolen_size = i830_stolen_size(dev_priv);
171 	else if (IS_I85X(dev_priv) || IS_I865G(dev_priv) ||
172 	    (GRAPHICS_VER(dev_priv) >= 3 && GRAPHICS_VER(dev_priv) <= 5))
173 		stolen_size = gen3_stolen_size(dev_priv);
174 	else if (IS_CHERRYVIEW(dev_priv))
175 		stolen_size = chv_stolen_size(dev_priv);
176 	else if (GRAPHICS_VER(dev_priv) >= 6 && GRAPHICS_VER(dev_priv) < 8)
177 		stolen_size = gen6_stolen_size(dev_priv);
178 	else if (GRAPHICS_VER(dev_priv) == 8)
179 		stolen_size = gen8_stolen_size(dev_priv);
180 	else if (GRAPHICS_VER(dev_priv) >= 9 && GRAPHICS_VER(dev_priv) <= 12)
181 		stolen_size = gen9_stolen_size(dev_priv);
182 
183 	if (stolen_base == 0 || stolen_size == 0)
184 		return;
185 
186 	intel_graphics_stolen_res.start = stolen_base;
187 	intel_graphics_stolen_res.end = stolen_base + stolen_size - 1;
188 }
189