Move the drivers to a separate sub-directory
[profile/ivi/intel-emgd-kmod.git] / drivers / emgd / core / init / plb / init_plb.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: init_plb.c
4  * $Revision: 1.19 $
5  *-----------------------------------------------------------------------------
6  * Copyright (c) 2002-2010, Intel Corporation.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24  * THE SOFTWARE.
25  *
26  *-----------------------------------------------------------------------------
27  * Description:
28  *
29  *-----------------------------------------------------------------------------
30  */
31
32 #define MODULE_NAME hal.init
33
34 #include <io.h>
35 #include <pci.h>
36 #include <memmap.h>
37 #include <gart.h>
38
39 #include <memory.h>
40 #include <igd.h>
41 #include <igd_errno.h>
42 #include <igd_init.h>
43 #include <igd_gart.h>
44
45 #include <context.h>
46 #include <intelpci.h>
47 #include <general.h>
48
49 #include <plb/regs.h>
50 #include <plb/context.h>
51
52 #include "../cmn/init_dispatch.h"
53 #include "linux/pci_regs.h"
54 /*!
55  * @addtogroup core_group
56  * @{
57  */
58
59 static int bus_master_enable_plb(platform_context_plb_t *platform_context);
60 static int full_config_vga_plb(igd_context_t *context,
61         init_dispatch_t *dispatch);
62 static int get_stolen_mem_plb(igd_context_t *context, unsigned long *pages);
63
64 int full_get_param_plb(igd_context_t *context,
65         unsigned long id,
66         unsigned long *value);
67
68 /*!
69  *
70  * @param context
71  * @param dispatch
72  * @param vga_dev
73  *
74  * @return -IGD_ERROR_NODEV on failure
75  * @return 0 on success
76  */
77 int get_revision_id_plb(igd_context_t *context,
78         os_pci_dev_t vga_dev)
79 {
80         EMGD_TRACE_ENTER;
81
82         /* Read RID */
83         if(OS_PCI_READ_CONFIG_8(vga_dev, PCI_RID,
84                         (unsigned char *)&context->device_context.rid)) {
85                 EMGD_ERROR_EXIT("Error occured reading RID");
86                 return -IGD_ERROR_NODEV;
87         }
88
89         EMGD_DEBUG(" rid = 0x%lx", context->device_context.rid);
90
91         EMGD_TRACE_EXIT;
92         return 0;
93 }
94
95 /*!
96  *
97  * @param context
98  * @param dispatch
99  *
100  * @return 1 on failure
101  * @return 0 on success
102  */
103 int full_config_plb(igd_context_t *context,
104         init_dispatch_t *dispatch)
105 {
106         unsigned long /* FIXME - reserved_mem, */ graphics_frequency ;
107         platform_context_plb_t *platform_context;
108         int ret;
109
110         EMGD_TRACE_ENTER;
111
112         platform_context = (platform_context_plb_t *)context->platform_context;
113
114         _sgx_base = 0x40000;
115         _msvdx_base = 0x50000;
116
117         /*
118          * Enable bus mastering for platforms whose BIOS did not perform this
119          * task for us.
120          */
121         ret = bus_master_enable_plb(platform_context);
122         if(ret) {
123                 EMGD_ERROR("Error: Enabling bus master");
124         }
125
126         /* Config VGA */
127         ret = full_config_vga_plb(context, dispatch);
128         if(ret) {
129                 EMGD_ERROR_EXIT("Config VGA Failed");
130                 return ret;
131         }
132
133         get_stolen_mem_plb(context, &context->device_context.reserved_mem);
134
135 #if 0 /* FIXME - WHY IS THIS RETURNING 0 AND SETTING reserved_mem TO 0 ALSO? */
136         /* Get mem reservation param if it exists */
137         if(!full_get_param_plb(context, IGD_PARAM_MEM_RESERVATION,
138                         &reserved_mem)) {
139                 context->device_context.reserved_mem = reserved_mem;
140         }
141 #endif
142
143         /* Get graphics frequency param if it exists */
144         if(!full_get_param_plb(context, IGD_PARAM_GFX_FREQ,
145                         &graphics_frequency)) {
146                 context->device_context.gfx_freq = (unsigned short)graphics_frequency;
147         }
148
149         EMGD_TRACE_EXIT;
150         return 0;
151 }
152
153 /*!
154  *
155  * @param platform_context
156  *
157  * @return -1 on failure
158  * @return 0 on success
159  */
160 static int bus_master_enable_plb(platform_context_plb_t *platform_context){
161         int ret;
162         unsigned char tmp;
163
164         EMGD_TRACE_ENTER;
165
166         ret = OS_PCI_READ_CONFIG_8(platform_context->pcidev0, PCI_COMMAND_MASTER, &tmp);
167         if(ret) {
168                 EMGD_ERROR_EXIT("PCI read of bus master");
169                 return -1;
170         }
171
172         /*
173          * Get Bit 2, 1, and 0 and see if it is == 1
174          * all 3 bits has to be enabled. This is to enable register read/write
175          * in the case of a PCI card being added
176          */
177         if((tmp & 0x7) != 0x7 ) {
178
179                 tmp |= 0x7;
180                 ret = OS_PCI_WRITE_CONFIG_8(platform_context->pcidev0, PCI_COMMAND_MASTER, tmp);
181                 if(ret) {
182                         EMGD_ERROR_EXIT("PCI write of bus master");
183                         return -1;
184                 }
185         }
186
187         EMGD_TRACE_EXIT;
188         return 0;
189 }
190
191 /*!
192  *
193  * @param context
194  * @param dispatch
195  *
196  * @return -IGD_ERROR_NODEV on failure
197  * @return 0 on success
198  */
199 static int full_config_vga_plb(igd_context_t *context,
200         init_dispatch_t *dispatch)
201 {
202         platform_context_plb_t *platform_context =
203                 (platform_context_plb_t *)context->platform_context;
204
205         EMGD_TRACE_ENTER;
206
207         if(OS_PCI_READ_CONFIG_32(platform_context->pcidev0,
208                         PLB_PCI_MMADR, (void*)&context->device_context.mmadr)) {
209                 EMGD_ERROR_EXIT("Reading MMADR");
210                 return -IGD_ERROR_NODEV;
211         }
212
213         context->device_context.mmadr &= 0xfffffff9;
214         context->device_context.virt_mmadr =
215                 OS_MAP_IO_TO_MEM_NOCACHE(context->device_context.mmadr, PLB_MMIO_SIZE);
216
217         if (!context->device_context.virt_mmadr) {
218                 EMGD_ERROR_EXIT("Failed to map MMADR");
219                 return -IGD_ERROR_NODEV;
220         }
221
222         EMGD_DEBUG("mmadr mapped %dKB @           (phys):0x%lx (virt):%p",
223                 PLB_MMIO_SIZE/1024,
224                 context->device_context.mmadr,
225                 context->device_context.virt_mmadr);
226
227         /* PCI Interrupt Line */
228         if(OS_PCI_READ_CONFIG_8(platform_context->pcidev0,
229                         PCI_INTERRUPT_LINE, (void*)&platform_context->irq)) {
230                 platform_context->irq = 0;
231         }
232
233         EMGD_TRACE_EXIT;
234         return 0;
235 }
236
237 /*!
238  * Get the # of pages used for video memory. This does not use information from
239  * the scratch register, since this is done later if it exists.
240  *
241  * @param context
242  * @param pages
243  *
244  * @return -IGD_ERROR_INVAL on failure
245  * @return 0 on success
246  */
247 static int get_stolen_mem_plb(igd_context_t *context, unsigned long *pages)
248 {
249         platform_context_plb_t *platform_context;
250         os_pci_dev_t           vga_dev;
251         unsigned short         gmch_ctl;
252         unsigned long          stolen_mem; /* in bytes */
253         int ret;
254
255         EMGD_TRACE_ENTER;
256
257         platform_context = (platform_context_plb_t *)context->platform_context;
258         vga_dev = platform_context->pcidev0;
259
260         ret = OS_PCI_READ_CONFIG_16(vga_dev, PLB_PCI_GC, &gmch_ctl);
261         if (ret) {
262                 EMGD_ERROR_EXIT("Unable to read PLB_PCI_GC");
263                 return -IGD_ERROR_INVAL;
264         }
265
266         switch (gmch_ctl & 0x70) {
267         case 0x00:
268                 stolen_mem = 0;
269                 break;
270         case 0x10:
271                 /* 1M */
272                 stolen_mem = 1*1024*1024;
273                 break;
274         case 0x20:
275                 /* 4M */
276                 stolen_mem = 4*1024*1024;
277                 break;
278         case 0x30:
279                 /* 8M */
280                 stolen_mem = 8*1024*1024;
281                 break;
282         case 0x40:
283                 /* 16M */
284                 stolen_mem = 16*1024*1024;
285                 break;
286         case 0x50:
287                 /* 32M */
288                 stolen_mem = 32*1024*1024;
289                 break;
290         case 0x60:
291                 /* 48M */
292                 stolen_mem = 48*1024*1024;
293         case 0x70:
294                 /* 64M */
295                 stolen_mem = 64*1024*1024;
296                 break;
297         default:
298                 EMGD_ERROR_EXIT("Unknown Stolen Memory Size");
299                 return -IGD_ERROR_INVAL;
300         }
301
302         if (stolen_mem) {
303                 /*
304                  * Subtract off the size of the GTT which is
305                  * (number of entries in DWORDS) * 4 to get it into bytes
306                  */
307                 stolen_mem -= context->device_context.gatt_pages*4;
308                 /* Subtract off 1 page for the scratch page */
309                 stolen_mem -= 4*1024;
310         }
311
312         /* Convert to the # of pages available for stolen memory */
313         *pages = stolen_mem / 4096;
314
315         EMGD_DEBUG("Stolen memory: 0x%lx pages", *pages);
316
317         EMGD_TRACE_EXIT;
318         return 0;
319 }
320
321 /*!
322  *
323  * @param context
324  * @param id
325  * @param value
326  *
327  * @return -IGD_ERROR_INVAL on failure
328  * @return 0 on success
329  */
330 int full_get_param_plb(igd_context_t *context,
331         unsigned long id,
332         unsigned long *value)
333 {
334         int ret = 0;
335         unsigned char *mmio;
336         unsigned long control_reg;
337
338         EMGD_TRACE_ENTER;
339
340         EMGD_DEBUG("ID: 0x%lx", id);
341
342         /* Scratch registers used as below:
343          *
344          * 0x71410:
345          * --------
346          *   Bits 31-16 - EID Firmware identifier 0xE1DF
347          *   Bits 15-00 - Tell what data is present.
348          * Here are bits for what we are using know:
349          *   Bit 0 - Panel id
350          *   Bit 1 - List of ports for which displays are attached
351          *   Bit 2 - Memory reservation
352          * If any of the above bits is set that mean data is followed
353          * in the next registers.
354          *
355          * 0x71414:
356          * --------
357          *   Bits 07-00 - Panel Id
358          *   Bits 11-08 - Port list
359          * Information for Port list: If any of the bit is set means,
360          *   a display is attached to that port as follows:
361          *    Bit 08 - CRT
362          *    Bit 09 - DVOA/Internal LVDS
363          *    Bit 10 - DVOB/RGBA
364          *    Bit 11 - DVOC
365          *
366          * 0x71418:
367          * --------
368          *       Bits 15-00 - Reserved Memory value in number of 4k size pages
369          */
370         mmio = context->device_context.virt_mmadr;
371         control_reg = EMGD_READ32(EMGD_MMIO(mmio) + 0x71410);
372         *value = 0;
373
374         switch(id) {
375         case IGD_PARAM_PANEL_ID:
376                 /*
377                  * Check for Embedded firmware
378                  */
379                 if ((control_reg>>16) != 0xE1DF) {
380                         EMGD_DEBUG("No Embedded vBIOS found");
381                         EMGD_TRACE_EXIT;
382                         return -IGD_ERROR_INVAL;
383                 }
384
385                 /*
386                  * The panel id bit must be set in the control register
387                  * to indicate valid panel (config) ID value.
388                  */
389                 if (control_reg & 0x1) {
390                         *value = EMGD_READ32(EMGD_MMIO(mmio) + 0x71414) & 0xFF;
391                         if(!(*value)) {
392                                 /* we cannot allow for config id = 0 */
393                                 ret = -IGD_ERROR_INVAL;
394                         }
395                 } else {
396                         EMGD_DEBUG("Panel ID read failed: Incorrect Operation");
397                         ret = -IGD_ERROR_INVAL;
398                 }
399                 break;
400         case IGD_PARAM_MEM_RESERVATION:
401                 /*
402                  * Check for Embedded firmware
403                  */
404                 if ((control_reg>>16) != 0xE1DF) {
405                         EMGD_DEBUG("No Embedded vBIOS found");
406                         EMGD_TRACE_EXIT;
407                         return -IGD_ERROR_INVAL;
408                 }
409
410                 /*
411                  * The mem reservation bit must be set in the control register
412                  * to indicate valid mem reservation value.
413                  */
414                 if (control_reg & 0x4) {
415                         *value = (EMGD_READ32(EMGD_MMIO(mmio) + 0x71418) & 0xFFFF);
416                 } else {
417                         EMGD_DEBUG("Mem Reservation read failed: Incorrect Operation");
418                         ret = -IGD_ERROR_INVAL;
419                 }
420                 break;
421         default:
422                 ret = -IGD_ERROR_INVAL;
423                 break;
424         }
425
426         EMGD_TRACE_EXIT;
427         return ret;
428 }
429
430 /*!
431  *
432  * @param context
433  *
434  * @return void
435  */
436 void full_shutdown_plb(igd_context_t *context)
437 {
438         platform_context_plb_t *platform_context =
439                 (platform_context_plb_t *)context->platform_context;
440
441         EMGD_TRACE_ENTER;
442
443         /* unmap registers */
444         if(context->device_context.virt_mmadr) {
445                 EMGD_DEBUG("Unmapping Gfx registers and GTT Table...");
446                 OS_UNMAP_IO_FROM_MEM((void *) context->device_context.virt_mmadr,
447                         PLB_MMIO_SIZE);
448                 OS_UNMAP_IO_FROM_MEM((void *)context->device_context.virt_gttadr,
449                         context->device_context.gatt_pages * 4);
450         } else {
451                 printk(KERN_ERR "Unmapping MMIO space failed.\n");
452         }
453
454         if (platform_context) {
455                 OS_PCI_FREE_DEVICE(platform_context->pcidev0);
456         }
457         EMGD_TRACE_EXIT;
458 }