blob: a0b4dec1790f71d63ddd94ab7e1e754734f9fb36 [file] [log] [blame]
Stefan Reinauer564e90f2012-05-04 15:37:18 -07001/*
2 * This file is part of i915tool
3 *
4 * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include "video.h"
21
22int verbose = 1;
23static unsigned short addrport, dataport;
24struct drm_device *i915;
25unsigned short vendor=0x8086, device=0x0116;
26struct pci_dev fake = {.vendor_id=0x8086, .device_id = 0x0116};
27int dofake = 0;
28u8 *bios_image = NULL;
29u8 *mmiobase;
30u32 mmiophys;
31int mmiosize;
32size_t bios_image_size;
33/* temporary */
34unsigned int i915_lvds_downclock = 0;
35int i915_vbt_sdvo_panel_type = -1;
36
37/* */
38
39/* not sure how we want to do this so let's guess */
40/* to make it easy, we start at zero and assume 250 hz. */
41unsigned long msecs(void)
42{
43 struct timeval start, now;
44 static int first = 0;
45 unsigned long j;
46 if (! first++)
47 gettimeofday(&start, NULL);
48 gettimeofday(&now, NULL);
49 j = (now.tv_sec - start.tv_sec)*1000 + (now.tv_usec-start.tv_usec)/1000;
50 return j;
51}
52
53void
54mdelay(unsigned long ms)
55{
56 unsigned long start;
57 start = msecs();
58 while (msecs() < (start + ms))
59 ;
60}
61
62void
63hexdump(u8 *base, int size)
64{
65 int i, j;
66 for(i = 0; i < size/sizeof(u32); i += 8) {
67 printf("%#x: ", i);
68 for(j = 0; j < 8; j++)
69 printf("%08x", base[i+j]);
70 printf("\n");
71 }
72}
73void udelay(int i)
74{
75 printf("UDELAY!\n");
76}
77
78unsigned long io_I915_READ(unsigned long addr)
79{
80 unsigned long val;
81 if (dofake)
82 return 0xcafebabe;
83 outl(addr, addrport);
84 val = inl(dataport);
85 if (verbose)
86 fprintf(stderr, "%s: %x <- %x\n", __func__, val, addr);
87 return val;
88}
89
90void io_I915_WRITE(unsigned long addr, unsigned long val)
91{
92 if (dofake)
93 return;
94 outl(addr, addrport);
95 outl(val, dataport);
96 if (verbose)
97 fprintf(stderr, "%s: %x -> %x\n", __func__, val, addr);
98}
99
100unsigned long I915_READ(unsigned long addr)
101{
102 volatile u32 *ptr = (u32 *)(mmiobase + addr);
103 unsigned long val;
104 if (dofake)
105 return 0xcafebabe;
106 val = *ptr;
107 if (verbose)
108 fprintf(stderr, "%s: %x <- %x\n", __func__, val, addr);
109 return val;
110}
111
112void I915_WRITE(unsigned long addr, unsigned long val)
113{
114 volatile u32 *ptr = (u32 *)(mmiobase + addr);
115 if (dofake)
116 return;
117 *ptr = val;
118 if (verbose)
119 fprintf(stderr, "%s: %x -> %x\n", __func__, val, addr);
120}
121
122u16 I915_READ16(unsigned long addr)
123{
124 volatile u16 *ptr = (u16 *)(mmiobase + addr);
125 unsigned long val;
126 if (dofake)
127 return 0xbabe;
128 val = *ptr;
129 if (verbose)
130 fprintf(stderr, "%s: %x <- %x\n", __func__, val, addr);
131 return val;
132}
133
134void I915_WRITE16(unsigned long addr, u16 val)
135{
136 volatile u16 *ptr = (u16 *)(mmiobase + addr);
137 if (dofake)
138 return;
139 *ptr = val;
140 if (verbose)
141 fprintf(stderr, "%s: %x -> %x\n", __func__, val, addr);
142}
143
144#define GTT_RETRY 1000
145static int gtt_poll(u32 reg, u32 mask, u32 value)
146{
147 unsigned try = GTT_RETRY;
148 u32 data;
149
150 while (try--) {
151 data = I915_READ(reg);
152 if ((data & mask) == value){
153 printf("succeeds after %d tries\n", GTT_RETRY-try);
154 return 1;
155 }
156 udelay(10);
157 }
158
159 fprintf(stderr, "GT init timeout\n");
160 return 0;
161}
162void *pci_map_rom(struct pci_dev *dev, size_t *size)
163{
164 *size = bios_image_size;
165 return bios_image;
166}
167
168void *pci_unmap_rom(struct pci_dev *dev, void *bios)
169{
170 return NULL;
171}
172
173void *dmi_check_system(unsigned long ignore)
174{
175 return NULL;
176}
177
178void
179mapit(void)
180{
181 int kfd;
182 kfd = open("/dev/mem", O_RDWR);
183 if (kfd < 0)
184 errx(1, "/dev/kmem");
185 mmiobase = mmap(NULL, mmiosize, PROT_WRITE|PROT_READ, MAP_SHARED, kfd,
186 mmiophys);
187 if ((void *)-1 == mmiobase)
188 errx(1, "mmap");
189}
190
191void
192devinit()
193{
194 u32 val;
195 /* force wake. */
196 I915_WRITE(0xa18c, 1);
197 gtt_poll(0x130090, 1, 1);
198}
199int main(int argc, char *argv[])
200{
201 struct pci_dev *pci_dev_find(struct drm_device *dev);
202
203 for(argc--, argv++; argc; argc--, argv++) {
204 if (argv[0][0] != '-')
205 break;
206 if (!strcmp(argv[0], "-f"))
207 dofake++;
208 }
209 i915 = calloc(1, sizeof(*i915));
210 i915->dev_private = calloc(1, sizeof(*i915->dev_private));
211 /* until we do a bit more w/ coccinelle */
212 i915->dev_private->dev = i915;
213
214 if (dofake) {
215 i915->pdev = &fake;
216 if (! find_idlist(i915, vendor, device))
217 errx(1, "can't find fake device in pciidlist");
218 } else {
219 if (! pci_dev_find(i915))
220 errx(1, "No VGA device of any kind found\n");
221 }
222
223 if (argc) {
224 FILE *fd;
225 int amt;
226 /* size it later */
227 bios_image = malloc(8*1048576);
228 fd = fopen(argv[0], "r");
229 amt = fread(bios_image, 65536, 128, fd);
Daniele Forsi201093e2014-07-27 18:45:30 +0200230 fclose(fd);
Stefan Reinauer564e90f2012-05-04 15:37:18 -0700231 if (amt < 1) {
232 free(bios_image);
233 } else {
234 i915->bios_bin = bios_image;
235 i915->dev_private->opregion.vbt = bios_image;
236 bios_image_size = amt * 65536;
Stefan Reinauer564e90f2012-05-04 15:37:18 -0700237 }
238 }
239 /* get the base address for the mmio indirection registers -- BAR 2 */
240 addrport = i915->pdev->base_addr[4] & ~3;
241 dataport = addrport + 4;
242 printf("Addrport is at %x, dataport at %x\n", addrport, dataport);
243 /* get the base of the mmio space */
244 mmiophys = i915->pdev->base_addr[0] & ~0xf;
245 mmiosize = i915->pdev->size[0];
246 printf("phys base is %#x, size %d\n", mmiophys, mmiosize);
247 mapit();
248 devinit();
249 //hexdump(mmiobase, mmiosize);
250 /* we should use ioperm but hey ... it's had troubles */
251 iopl(3);
252 intel_setup_bios(i915);
253 if (i915->bios_bin)
254 intel_parse_bios(i915);
255}