packaging: update the changelog
[profile/ivi/intel-emgd-kmod.git] / emgd / core / init / tnc / micro_init_tnc.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: micro_init_tnc.c
4  * $Revision: 1.26 $
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
38 #include <igd.h>
39 #include <igd_errno.h>
40 #include <igd_init.h>
41
42 #include <context.h>
43 #include <intelpci.h>
44 #include <general.h>
45 #include <utils.h>
46
47 #include <igd_debug.h>
48 #include <drmP.h>
49 #include <memory.h>
50 #include <asm/cacheflush.h>
51
52 #include <tnc/regs.h>
53 #include <tnc/context.h>
54 #include <linux/pci_ids.h>
55
56 #include "../cmn/init_dispatch.h"
57
58 #define PFX "EMGD: "
59
60 #define SCR1    0x71410 /* scratch register set by vbios indicating status*/
61 #define SCR2    0x71418 /* scratch register set by vbios indicating amount of stolen memory */
62 #define FW_ID   0xE1DF0000 /* firmware identifier */
63 #define ST_BIT  0x00000004 /* bit2- stolen memory bit */
64 #define PSB_GMCH_CTRL       0x52
65 #define PSB_GMCH_ENABLED    0x04
66 #define PSB_PGETBL_CTL      0x00002020
67 #define PSB_GATT_RESOURCE   2
68 #define PSB_GTT_RESOURCE    3
69 #define PSB_BSM             0x5c
70 #define PSB_PTE_VALID       0x0001
71
72
73
74 /*!
75  * @addtogroup core_group
76  * @{
77  */
78
79 #ifdef CONFIG_TNC
80
81 extern unsigned char io_mapped;
82 extern unsigned short io_base;
83
84 /* For dev2 [0:2:0] */
85 extern unsigned char io_mapped_lvds;
86 extern unsigned short io_base_lvds;
87
88 /* For dev3 [0:3:0] */
89 extern unsigned char io_mapped_sdvo;
90 extern unsigned short io_base_sdvo;
91
92 /* For dev31 [0:31:0] */
93 extern unsigned char io_mapped_lpc;
94 extern unsigned short io_base_lpc;
95
96 /* For STMicro SDVO [6:0:1] */
97 extern unsigned char io_mapped_sdvo_st;
98 extern unsigned short io_base_sdvo_st;
99 extern unsigned char io_mapped_sdvo_st_gpio;
100 extern unsigned short io_base_sdvo_st_gpio;
101
102 extern int full_config_tnc(igd_context_t *context,
103         init_dispatch_t *dispatch);
104 extern int get_revision_id_tnc(igd_context_t *context, os_pci_dev_t vga_dev, os_pci_dev_t sdvo_dev);
105 extern int full_get_param_tnc(igd_context_t *context, unsigned long id,
106         unsigned long *value);
107 extern void full_shutdown_tnc(igd_context_t *context);
108
109 extern int query_2d_caps_hwhint_tnc(
110                  igd_context_t *context,
111                  unsigned long caps_val,
112                  unsigned long *status);
113
114 static int query_tnc(igd_context_t *context,init_dispatch_t *dispatch,
115         os_pci_dev_t vga_dev, unsigned int *bus, unsigned int *slot,
116         unsigned int *func);
117 static int config_tnc(igd_context_t *context,
118         init_dispatch_t *dispatch);
119 static int set_param_tnc(igd_context_t *context, unsigned long id,
120         unsigned long value);
121 static int get_param_tnc(igd_context_t *context, unsigned long id,
122         unsigned long *value);
123 static void shutdown_tnc(igd_context_t *context);
124
125 static void gtt_shutdown_tnc(igd_context_t *context);
126 static void gtt_init_tnc(igd_context_t *context);
127
128 /* Helper Functions */
129 static int query_sch_message(unsigned long reg, unsigned long* value);
130 static int dump_fuse_values(void);
131
132 static platform_context_tnc_t platform_context_tnc;
133
134 os_pci_dev_t bridge_dev;
135
136 init_dispatch_t init_dispatch_tnc = {
137         "Intel Atom E6xx Processor",
138         "Atom_E6xx",
139         "lvds",
140         query_tnc,
141         config_tnc,
142         set_param_tnc,
143         get_param_tnc,
144         shutdown_tnc,
145         query_2d_caps_hwhint_tnc
146 };
147
148 /* Array to keep the Bridge ID. Atom E6xx ULP uses a different bridge ID */
149 static unsigned short bridge_id[] =
150 {
151         PCI_DEVICE_ID_BRIDGE_TNC,
152         PCI_DEVICE_ID_BRIDGE_TNC_ULP,
153         0
154 };
155
156 #define SKU_NO 3
157 #define RATIO_NO 8
158 /*
159  * Atom E6xx GFX frequencies
160  * The gfx clock frequencies depends on the board SKU and ratio
161  * The table of frequencies can be found in Atom E6xx EAS
162  * Chapter: Clocks and Reset Unit
163  */
164 static unsigned short tnc_gfx_freq_list[RATIO_NO][SKU_NO] =
165 {
166         /* rows represent the gfx clock ratio,
167          * columns the sku */
168
169         /* sku_100 sku_100L sku_83 */
170         {200,   100,    166}, /*1:1*/
171         {266,   133,    222}, /*4:3*/
172         {320,   160,    266}, /*8:5*/
173         {400,   200,    333}, /*2:1 DEFAULT*/
174         {0,             0,              0 }, /*16:7 RSVD*/
175         {533,   266,    444}, /*8:3*/
176         {640,   320,    553}, /*16:5*/
177         {800,   400,    666}     /*4:1 RSVD*/
178 };
179
180 static unsigned short tnc_core_freq_list[SKU_NO] =
181 {
182 /* sku_100 sku_100L sku_83 */
183         200,    100,    166
184 };
185
186 /* MCR define */
187 #define READ_FUS_EFF0                   0xD08106F0
188 #define READ_FUS_EFF1                   0xD08107F0
189 #define READ_FUS_EFF2                   0xD08108F0
190 #define READ_FUS_EFF3                   0xD08109F0
191 #define READ_FUS_EFF4                   0xD0810AF0
192 #define READ_FUS_EFF5                   0xD0810BF0
193
194
195
196 /*
197  * GTT shutdown.
198  *
199  * Unmap the GTT mapping that was done during init time.
200  */
201 static void gtt_shutdown_tnc(igd_context_t *context)
202 {
203         if (context->device_context.virt_gttadr) {
204                 iounmap(context->device_context.virt_gttadr);
205
206                 context->device_context.virt_gttadr = NULL;
207         }
208         if(context->device_context.scratch_page){
209                 __free_page(context->device_context.scratch_page);
210                 context->device_context.scratch_page = NULL;
211         }
212 }
213
214
215 /*
216  * Initialize the GTT.
217  *   - Find the size of stolen memory
218  *   - Add stolen memory to the GTT
219  *   - Map the GTT and video memory
220  */
221
222 static void gtt_init_tnc(igd_context_t *context)
223 {
224         struct drm_device *dev;
225         unsigned char *mmio = context->device_context.virt_mmadr;
226         unsigned long dvmt_mode = 0;
227         unsigned long gtt_pages = 0;
228         unsigned long stolen_mem_size = 0;
229         unsigned long scratch;
230         unsigned long base;
231         unsigned long pte;
232         unsigned short gmch_ctl;
233         unsigned long pge_ctl;
234         unsigned long gtt_phys_start;
235         unsigned long gatt_start;
236         unsigned long gatt_pages;
237         unsigned long gtt_start;
238         unsigned long gtt_order;
239         unsigned long stolen_mem_base;
240         unsigned long *gtt_table;
241         struct page *gtt_table_page;
242         int i;
243
244         dev = (struct drm_device *)context->drm_dev;
245
246         /* Enable the GMCH */
247         OS_PCI_READ_CONFIG_16((os_pci_dev_t)dev->pdev, PSB_GMCH_CTRL,
248                         &gmch_ctl);
249         OS_PCI_WRITE_CONFIG_16((os_pci_dev_t)dev->pdev, PSB_GMCH_CTRL,
250                         (gmch_ctl | PSB_GMCH_ENABLED));
251         context->device_context.gmch_ctl = gmch_ctl;
252
253         /* Get the page table control register */
254         pge_ctl = readl(mmio + PSB_PGETBL_CTL);
255         gtt_phys_start = pge_ctl & PAGE_MASK;
256
257         /* Create a scratch page to initialize empty GTT entries */
258         if(NULL == context->device_context.scratch_page){
259                 context->device_context.scratch_page = alloc_page(GFP_DMA32 | __GFP_ZERO);
260         }
261
262         /*
263         * Is pci_resource_start(dev->pdev, PSB_GATT_RESOURCE); the same
264         * as pci_read_config_dword(dev->pdev, 0x1C, &value)?
265         *
266         * PSB_GATT_RESOURCE length is the amount of memory addressable
267         * by the GTT table.
268         */
269         gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
270         gatt_pages = (pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) >> PAGE_SHIFT);
271         context->device_context.gatt_pages = gatt_pages;
272
273         /*
274          * The GTT wasn't set up by the vBios
275          */
276         if (!pge_ctl) {
277                 context->device_context.stolen_pages = 0;
278
279                 gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
280                 gtt_order = get_order(gtt_pages << PAGE_SHIFT);
281                 gtt_table = (unsigned long *)__get_free_pages(GFP_KERNEL, gtt_order);
282                 /* Make sure allocation was successful */
283                 if (NULL == gtt_table) {
284                         EMGD_ERROR("Failed to allocate kernel pages for GTT");
285                         return;
286                 }
287                 context->device_context.virt_gttadr = gtt_table;
288
289                 for (i=0; i < (1 << gtt_order); i++) {
290                         gtt_table_page = virt_to_page(gtt_table + (PAGE_SIZE * i));
291                         EMGD_DEBUG("Setting reserved bit on %p", gtt_table_page);
292                         set_bit(PG_reserved, &gtt_table_page->flags);
293                 }
294
295                 gtt_phys_start = virt_to_phys(gtt_table);
296
297                 for (i = 0; i < gtt_pages; i++) {
298                         gtt_table[i] = (unsigned long)context->device_context.scratch_page;
299                 }
300
301                 printk(KERN_INFO "Detected GTT was not enabled by firmware");
302                 printk(KERN_INFO "GMMADR(region 0) start: 0x%08lx (%ldM).\n",
303                         gatt_start, (gatt_pages / 256));
304                 printk(KERN_INFO "GTTADR(region 3) start: 0x%08lx (can map %ldM RAM), and "
305                         "actual RAM base 0x%08lx.\n",
306                         (unsigned long)gtt_table, (gtt_pages * 4), gtt_phys_start);
307
308                 /* Enable the newly created GTT */
309                 EMGD_DEBUG("Enabling new GTT");
310                 writel(gtt_phys_start, mmio + PSB_PGETBL_CTL);
311                 pge_ctl = readl(mmio + PSB_PGETBL_CTL);
312
313         } else {
314
315                 /*
316                  * Get the start address of the GTT page table
317                  *
318                  * In full_config_vga, this is done differently.  The address is read
319                  * from pcidev0's pci config space, at TNC_PCI_GTTADR and the size comes
320                  * from TNC_OFFSET_VGA_MSAC. The value read for size is a size id
321                  *    1 = 128, 2 = 256, 3 = 512
322                  * emgd_gtt->gtt_start = OS_PCI_READ_CONFIG_32(
323                  *            context->platform_context->pcidev0, TNC_PCI_GTTADDR)
324                  * gtt_pages = OS_PCI_READ_CONFIG_8(context->platform_context->pcidev0,
325                  *            TNC_OFFSET_VGA_MSAC) * 1024;
326                  *
327                  * PSB_GTT_RESOURCE length is the size of the GTT table. Thus,
328                  * gtt_pages is the number of pages that make up the table.
329                  */
330                 gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
331                 gtt_pages = (pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT);
332
333                 /* Get stolen memory configuration. */
334                 pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *)&stolen_mem_base);
335                 stolen_mem_size = gtt_phys_start - stolen_mem_base - PAGE_SIZE;
336
337                 /* Display useful information in the kernel log */
338                 printk(KERN_INFO "GMMADR(region 0) start: 0x%08lx (%ldM).\n",
339                                 gatt_start, (gatt_pages / 256));
340                 printk(KERN_INFO "GTTADR(region 3) start: 0x%08lx (can map %ldM RAM), and "
341                                 "actual RAM base 0x%08lx.\n",
342                                 gtt_start, (gtt_pages * 4), gtt_phys_start);
343                 printk(KERN_INFO "Stolen memory information \n");
344                 printk(KERN_INFO "       base in RAM: 0x%lx \n", stolen_mem_base);
345                 printk(KERN_INFO "       size: %luK, calculated by (GTT RAM base) - "
346                                 "(Stolen base)\n", (stolen_mem_size / 1024));
347                 dvmt_mode = (gmch_ctl >> 4) & 0x7;
348                 printk(KERN_INFO "       size: %dM (dvmt mode=%ld)\n",
349                                 (dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
350
351                 context->device_context.virt_gttadr =
352                 ioremap_nocache(gtt_start, gtt_pages << PAGE_SHIFT);
353
354                 if (!context->device_context.virt_gttadr) {
355                         printk(KERN_ERR "Failed to map the GTT.\n");
356                         /* TODO: Clean up somelthing here */
357                         return;
358                 }
359
360                 /* Insert stolen memory pages into the beginning of GTT */
361                 base = stolen_mem_base >> PAGE_SHIFT;
362                 context->device_context.stolen_pages = stolen_mem_size >> PAGE_SHIFT;
363
364                 printk(KERN_INFO "Set up %ld stolen pages starting at 0x%08lx, "
365                         "GTT offset %dK\n", context->device_context.stolen_pages, base, 0);
366
367                 for (i = 0; i < context->device_context.stolen_pages; i++) {
368                         pte = ((base + i) << PAGE_SHIFT) | PSB_PTE_VALID;
369                         writel(pte, context->device_context.virt_gttadr + i);
370                 }
371
372         }
373
374         /* Update the scratch registers to say we have no stolen memory */
375         scratch = readl(mmio + SCR1);
376         if ((scratch & FW_ID) == FW_ID) {
377                 /* if an EMGD vBios modify only the stolen memory bit */
378                 scratch |= ST_BIT;
379                 writel(scratch, mmio + SCR1);
380         } else {
381                 /* Not an EMGD vBios so just set the entire register to a known value */
382                 writel((FW_ID|ST_BIT), mmio + SCR1);
383         }
384
385         /*
386          * Report back that there is 0MB of stolen memory regardless of
387          * what was really in there.  Fresh pages will be inserted over
388          * the top of the existing stolen memory.
389          */
390         writel(0, mmio + SCR2);
391
392         /*
393          * FIXME: Shouldn't this fill in all the GTT page table entries with
394          * the scratch page?
395          */
396
397         return;
398 }
399
400
401 /*!
402  * Helper function to query MCR registers
403  * @param reg
404  * @param value
405  *
406  * @return -IGD_ERROR_INVAL on error
407  * @return 0 on success
408  */
409 static int query_sch_message(unsigned long reg, unsigned long* value){
410
411         platform_context_tnc_t *platform_context = &platform_context_tnc;
412
413         /* Send the opcode into the MCR */
414         if(OS_PCI_WRITE_CONFIG_32(platform_context->bridgedev,
415                 0xD0, reg)){
416                 EMGD_ERROR_EXIT("Writing into the MCR Failed");
417                 return -IGD_ERROR_INVAL;
418         }
419
420         if(OS_PCI_READ_CONFIG_32(platform_context->bridgedev,
421                 0xD4, value)) {
422
423                 EMGD_ERROR_EXIT("Writing to MDR Failed");
424                 return -IGD_ERROR_INVAL;
425         }
426
427         return 0;
428 }
429
430 /*!
431  *
432  * @param context
433  * @param dispatch
434  * @param vga_dev
435  * @param bus
436  * @param slot
437  * @param func
438  *
439  * @return -IGD_ERROR_NODEV on failure
440  * @return 0 on success
441  */
442 static int query_tnc(
443         igd_context_t *context,
444         init_dispatch_t *dispatch,
445         os_pci_dev_t vga_dev,
446         unsigned int *bus,
447         unsigned int *slot,
448         unsigned int *func)
449 {
450         platform_context_tnc_t *platform_context = &platform_context_tnc;
451
452         int i = 0;
453
454         EMGD_TRACE_ENTER;
455
456
457
458         /* So we don't have to pollute our function tables with multiple
459          * entries for every variant of TNC, update the device ID if one
460          * of the other SKUs is found
461          */
462         context->device_context.did = PCI_DEVICE_ID_VGA_TNC;
463
464         platform_context->did = context->device_context.did;
465         context->platform_context = (void *)&platform_context_tnc;
466
467         OS_PTHREAD_MUTEX_INIT(&platform_context_tnc.flip_mutex, NULL);
468
469         /* find and store the bridge dev since we will be using it a lot
470          * in the init modules */
471         while(bridge_id[i] != 0){
472         platform_context->bridgedev = OS_PCI_FIND_DEVICE(
473                                 PCI_VENDOR_ID_INTEL,
474                                 bridge_id[i],
475                                 0xFFFF, /* Scan the whole PCI bus */
476                                 0,
477                                 0,
478                                 (os_pci_dev_t)0);
479                 if(platform_context->bridgedev){
480                         bridge_dev = platform_context->bridgedev;
481                 context->device_context.bid = bridge_id[i];
482                 break;
483                 }
484                 i++;
485          }
486         /*
487          * Current specs indicate that Atom E6xx has only one PCI function.
488          * If this changes then we need to make sure we have func 0
489          * here as in previous chips.
490          */
491         platform_context->pcidev0 = vga_dev;
492
493         /* find device 3 */
494         platform_context->pcidev1 = OS_PCI_FIND_DEVICE(PCI_VENDOR_ID_INTEL,
495                         PCI_DEVICE_ID_SDVO_TNC,
496                         0,
497                         3,
498                         0,
499                         (os_pci_dev_t)0);
500
501         platform_context->stbridgedev = OS_PCI_FIND_DEVICE(PCI_VENDOR_ID_STMICRO,
502                         PCI_DEVICE_ID_SDVO_TNC_ST,
503                         6,
504                         0,
505                         1,
506                         (os_pci_dev_t)0);
507
508         if (platform_context->stbridgedev) {
509                 platform_context->stgpiodev = OS_PCI_FIND_DEVICE(PCI_VENDOR_ID_STMICRO,
510                         PCI_DEVICE_ID_SDVO_TNC_ST_GPIO,
511                         3,
512                         0,
513                         0,
514                         (os_pci_dev_t)0);
515
516                 if (!platform_context->stgpiodev) {
517                         platform_context->stgpiodev = OS_PCI_FIND_DEVICE(PCI_VENDOR_ID_STMICRO,
518                                 PCI_DEVICE_ID_SDVO_TNC_ST_GPIO,
519                                 4,
520                                 0,
521                                 5,
522                                 (os_pci_dev_t)0);
523                         if (!platform_context->stgpiodev) {
524                                 printk("Using STM device, but is not CUT1 or CUT2\n");
525                                 EMGD_ERROR_EXIT("Using STM device, but is not Cut1 or Cut2");
526                                 return -IGD_ERROR_NODEV;
527                         }
528                 }
529         }
530
531         /* Set to NULL, so full_shutdown_tnc() knows whether it was initialized: */
532         platform_context->lpc_dev = NULL;
533
534         /*
535          * finds the bus, device, func to be returned. Do this for D2:F0 only.
536          * the OS does not need to know the existence of D3:F0
537          */
538         OS_PCI_GET_SLOT_ADDRESS(vga_dev, bus, slot, func);
539
540         get_revision_id_tnc(context, vga_dev, platform_context->pcidev1);
541
542         /*
543          * Read BSM.
544          * This must be in query so it is available early for the vBIOS.
545          */
546         if(OS_PCI_READ_CONFIG_32(vga_dev,
547                         TNC_PCI_BSM, &context->device_context.fb_adr)) {
548                 EMGD_ERROR_EXIT("Reading BSM");
549                 return -IGD_ERROR_NODEV;
550         }
551         context->device_context.fb_adr &= 0xFFFFF000;
552
553         EMGD_DEBUG("BSM (High)@: 0x%lx, (Low) 0x%4lx",
554                 (context->device_context.fb_adr >> 16), context->device_context.fb_adr);
555
556         /*
557          * Read IO Base.
558          * This must be in query so it is available early for the vBIOS.
559          */
560         if(OS_PCI_READ_CONFIG_16(vga_dev, TNC_PCI_IOBAR, &io_base)) {
561                 EMGD_ERROR_EXIT("Reading IO Base");
562                 return -IGD_ERROR_NODEV;
563         }
564
565         /* Base Address is defined in Bits 15:3*/
566         io_base_lvds = io_base &= 0xfff8;
567         EMGD_DEBUG("io @: 0x%x", io_base);
568
569         /* Gen4 is always io_mapped */
570         io_mapped_lvds = io_mapped = 1;
571
572         /* Set dev3 iobase.  */
573         if(OS_PCI_READ_CONFIG_16((os_pci_dev_t)platform_context->pcidev1,
574                 TNC_PCI_IOBAR, &io_base_sdvo)) {
575
576                 EMGD_ERROR_EXIT("Reading SDVO IO Base");
577                 return -IGD_ERROR_NODEV;
578         }
579
580         /* Base Address is defined in Bits 15:3*/
581         io_base_sdvo &= 0xfff8;
582
583         io_mapped_sdvo = 1;
584         EMGD_DEBUG("sdvo io @: 0x%x", io_base_sdvo);
585
586         /* Set stmicro sdvo iobase.  */
587         if(OS_PCI_READ_CONFIG_16((os_pci_dev_t)platform_context->stbridgedev,
588                 TNC_PCI_IOBAR, &io_base_sdvo_st)) {
589
590                 EMGD_ERROR_EXIT("Reading SDVO IO Base");
591                 return -IGD_ERROR_NODEV;
592         }
593
594         /* Base Address is defined in Bits 15:3*/
595         io_base_sdvo_st &= 0xfff8;
596
597         io_mapped_sdvo_st = 1;
598         EMGD_DEBUG("STMicro's sdvo io @: 0x%x", io_base_sdvo_st);
599
600         /* Set stmicro gpio sdvo iobase.  */
601         if(OS_PCI_READ_CONFIG_16((os_pci_dev_t)platform_context->stgpiodev,
602                 TNC_PCI_IOBAR, &io_base_sdvo_st_gpio)) {
603
604                 EMGD_ERROR_EXIT("Reading SDVO IO Base");
605                 return -IGD_ERROR_NODEV;
606         }
607
608         /* Base Address is defined in Bits 15:3*/
609         io_base_sdvo_st_gpio &= 0xfff8;
610
611         io_mapped_sdvo_st_gpio = 1;
612         EMGD_DEBUG("STMicro's gpio io @: 0x%x", io_base_sdvo_st_gpio);
613
614         /* ---------------------------------------------------
615          * Initialize Device 31 : LPC Interface
616          * --------------------------------------------------*/
617         /*
618          * Map the LPC Interface Configuration [D31:F0]GPIO_BAR.
619          * The Atom E6xx LVDS pins are connected to GPIO pins,
620          * accessible using LPC Interface GPIO_BAR. These registers
621          * will later be used to "bit bash" the LVDS DDC signals
622          * SDVO does not need these registers.
623          * VBIOS may need access to these registers
624          */
625
626         platform_context->lpc_dev = OS_PCI_FIND_DEVICE(PCI_VENDOR_ID_INTEL,
627                         PCI_DEVICE_ID_LPC_TNC,
628                         0,
629                         31, /* LPC[D31:F0] */
630                         0,
631                         (os_pci_dev_t)0);
632
633         if(!platform_context->lpc_dev){
634                 /*
635                  * We could not detect the LPC interface in the PCI Bus. This will
636                  * be a problem. Sound the alarm, return with NO ERROR so that we do
637                  * not go and map the GPIO_BAR
638                  */
639                 EMGD_ERROR_EXIT("Reading GPIO BAR");
640                 return 0;
641         }
642
643         /* Set dev31 iobase */
644
645         /* Do not enable LPC device as System BIOS owns and does this */
646
647         /* read the GPIO BAR (OFFSET 44:47) */
648         if(OS_PCI_READ_CONFIG_16(platform_context->lpc_dev,
649                         TNC_PCI_GBA, &io_base_lpc)) {
650                 EMGD_ERROR_EXIT("Reading LPC GPIO BAR");
651                 /* We cannot read the GPIO BAR. It is a problem but we can go on with init
652                  * return with NO ERROR*/
653                 return 0;
654         }
655
656         io_base_lpc &= 0xffc0;
657
658         io_mapped_lpc = 1;
659         EMGD_DEBUG("lpc io @: 0x%x", io_base_lpc);
660
661         EMGD_TRACE_EXIT;
662         return 0;
663 }
664
665 /*!
666  *
667  * @param context
668  * @param dispatch
669  *
670  * @return -IGD_ERROR_NODEV on failure
671  * @return 0 on success
672  */
673 static int config_tnc(igd_context_t *context,
674         init_dispatch_t *dispatch)
675 {
676         unsigned long freq[2];
677         platform_context_tnc_t *platform_context = &platform_context_tnc;
678         unsigned long lbb;
679 #ifndef CONFIG_MICRO
680         unsigned int lp_ctrl_reg;
681         unsigned int hp_ctrl_reg;
682         unsigned int ved_cg_dis_reg;
683 #endif
684
685         EMGD_TRACE_ENTER;
686
687         OPT_MICRO_CALL(full_config_tnc(context, dispatch));
688
689         /* Get graphics and core frequency param if it exists */
690         if(!get_param_tnc(context, IGD_PARAM_GFX_FREQ,
691                         freq)) {
692                 context->device_context.gfx_freq = (unsigned short)freq[0];
693                 context->device_context.core_freq = (unsigned short)freq[1];
694         }
695
696         /*
697          * FIXME:
698          *  Coreclk register above is used to determine some clocking information
699          *  there is also a fuse to limit the dclk. More research needed.
700          */
701         /* From KT: Atom E6xx LVDS min and max dot clocks are 19.75 MHz to 79.5 MHz,
702          *          Atom E6xx SDVO min and max dot clocks are 25 MHz to 165 MHz */
703         context->device_context.max_dclk = 79500;   /* in KHz */
704
705 #ifndef CONFIG_MICRO
706         /* This breaks VBIOS LVDS display.  If this is truly a workaround for
707          * system BIOS then we need to understand what the system BIOS is going
708          * to do and make sure it doesn't re-break VBIOS. The hp_ctrl_reg write
709          * is the write that actually breaks LVDS display.  Tested with BIOS34
710          * which has the P-Unit workaround and LVDS still works.
711      */
712
713         /* This is just a workaround.
714          * GVD.G_LP_Control register is set to default mode for BIT0~BIT3.
715          * GVD.H_HP Control register's BIT1 is set 1.
716          * TODO: Removed this after this is fix in system BIOS.
717          */
718         lp_ctrl_reg = EMGD_READ32(EMGD_MMIO(context->device_context.virt_mmadr) + 0x20f4);
719         lp_ctrl_reg |= BIT1;
720         lp_ctrl_reg &= ~(BIT2 | BIT3);
721     EMGD_WRITE32(lp_ctrl_reg, EMGD_MMIO(context->device_context.virt_mmadr) + 0x20f4);
722
723         hp_ctrl_reg = EMGD_READ32(EMGD_MMIO(context->device_context.virt_mmadr) + 0x20f8);
724         hp_ctrl_reg |= BIT1;
725     EMGD_WRITE32(hp_ctrl_reg, EMGD_MMIO(context->device_context.virt_mmadr) + 0x20f8);
726
727         /* This is just a workaround.
728          * GVD.VED_CG_DIS register is set to disable clock gating for BIT16, BIT0~BIT8.
729          * Tested with Punit B0_500309_CFG2 and Punit C0_060510_CFG2 in BIOS39 and
730          * BIOS41 or above.
731          */
732         ved_cg_dis_reg = EMGD_READ32(EMGD_MMIO(context->device_context.virt_mmadr) + 0x2064);
733         ved_cg_dis_reg |= (BIT16 | BIT8 | 0xFF);
734     EMGD_WRITE32(ved_cg_dis_reg, EMGD_MMIO(context->device_context.virt_mmadr) + 0x2064);
735
736         /* read out the fuse values */
737         dump_fuse_values( );
738 #endif
739
740         gtt_init_tnc(context);
741
742        /*
743          * Setting the LBB to 0xFF if it is 0.
744          * This register is used to dynamic LVDS backlight control. By default,
745          * the register will reset to 0x0, this will cause the LVDS to be "off" when
746          * PD_ATTR_ID_BLM_LEGACY_MODE attribute is set. Customers could write
747          * application to set this register.
748          *
749          * TODO: The right way to fix this is to check for the attribute in lvds.c
750          * then set the register through pd. But this will add more code to VBIOS
751          * (as we need to add dispatch functions in pd)
752          */
753
754         if(OS_PCI_READ_CONFIG_32(platform_context->pcidev0, 0xF4, &lbb)) {
755                 EMGD_DEBUG("Reading Legacy Backlight Brightness");
756                 return -IGD_ERROR_NODEV;
757         }
758         if(!(lbb & 0xFF)){
759                 if(OS_PCI_WRITE_CONFIG_32(platform_context->pcidev0,
760                         0xF4, (lbb | 0xFF))){
761                         EMGD_DEBUG("Writing into Legacy Backlight Brightness");
762                         return -IGD_ERROR_INVAL;
763                 }
764         }
765
766
767         EMGD_TRACE_EXIT;
768         return 0;
769 }
770
771 /*!
772  *
773  * @param context
774  * @param id
775  * @param value
776  *
777  * @return -IGD_ERROR_INVAL on failure
778  * @return 0 on success
779  */
780 static int get_param_tnc(igd_context_t *context, unsigned long id,
781         unsigned long *value)
782 {
783 #define FB_SKU_MASK  (BIT12|BIT13|BIT14)
784 #define FB_SKU_SHIFT 12
785 #define FB_GFX_CLOCK_DIVIDE_MASK  (BIT20|BIT21|BIT22)
786 #define FB_GFX_CLOCK_DIVIDE_SHIFT 20
787
788         int ret = 0;
789         unsigned long control_reg;
790         unsigned short sku;
791         unsigned short ratio;
792
793         EMGD_TRACE_ENTER;
794
795         EMGD_DEBUG("ID: 0x%lx", id);
796
797         /* Scratch registers used as below:
798          *
799          * 0x71410:
800          * --------
801          *   Bits 31-16 - EID Firmware identifier 0xE1DF
802          *   Bits 15-00 - Tell what data is present.
803          * Here are bits for what we are using know:
804          *   Bit 0 - Panel id
805          *   Bit 1 - List of ports for which displays are attached
806          *   Bit 2 - Memory reservation
807          * If any of the above bits is set that mean data is followed
808          * in the next registers.
809          *
810          * 0x71414:
811          * --------
812          *   Bits 07-00 - Panel Id
813          *   Bits 11-08 - Port list
814          * Information for Port list: If any of the bit is set means,
815          *   a display is attached to that port as follows:
816          *    Bit 08 - CRT
817          *    Bit 09 - DVOA/Internal LVDS
818          *    Bit 10 - DVOB/RGBA
819          *    Bit 11 - DVOC
820          *
821          * 0x71418:
822          * --------
823          * Bits 15-00 - Reserved Memory value in number of 4k size pages
824          */
825         *value = 0;
826
827         switch(id) {
828         case IGD_PARAM_PORT_LIST:
829
830                 control_reg = EMGD_READ32(EMGD_MMIO(context->device_context.virt_mmadr) +
831                         0x71410);
832
833                 /*
834                  * Verify that the Embedded Firware is present.
835                  */
836                 if ((control_reg>>16) != 0xE1DF) {
837                         EMGD_DEBUG("Exit No Embedded vBIOS found");
838                         EMGD_TRACE_EXIT;
839                         return -IGD_ERROR_INVAL;
840                 }
841
842                 /*
843                  * If the port list bit is set in control register,
844                  * read the port list
845                  */
846                 if (control_reg & 0x2) {
847                         unsigned char temp;
848                         int i = 0;
849
850                         temp = (unsigned char)((EMGD_READ32(EMGD_MMIO(context->device_context.virt_mmadr) + 0x71414)>>8) & 0xFF);
851                         EMGD_DEBUG("Connected Port Bits: 0x%x", temp);
852
853                         /*
854                          * The meanings of bits in temp were dictated by VBIOS
855                          * and should not change due to backward compatibility
856                          * with Legacy VBIOS
857                          */
858                         if (temp & 0x02) {
859                                 /* Internal LVDS port */
860                                 value[i++] = 4;
861                         }
862                         if (temp & 0x04) {
863                                 /* DVOB Port */
864                                 value[i++] = 2;
865                         }
866                 } else {
867                         EMGD_DEBUG("Port List read failed: Incorrect Operation");
868                         ret = -IGD_ERROR_INVAL;
869                 }
870                 break;
871         case IGD_PARAM_GFX_FREQ:
872
873                 /* Read the fuse value */
874                 if(query_sch_message(READ_FUS_EFF3, &control_reg)){
875                         EMGD_ERROR("Cannot read GFX clock");
876                 }
877                 EMGD_DEBUG("SKU [reg 0x%x] value = 0x%lx", READ_FUS_EFF3, control_reg);
878
879                 /*
880                  * Sku and Ratio bits determine the gfx clock speed
881                  * sku - 0:sku_100 1:sku_100L 2:sku_83
882                  * ratio - 0-1:1 1-4:3 2-8:5 3-2:1 4-16:7(rsvd) 5-8:3 6-16:5 7:4:1(rsvd)
883                  */
884                 sku = (unsigned short)((control_reg & FB_SKU_MASK) >> FB_SKU_SHIFT) & 0x3;
885                 ratio = (unsigned short)((control_reg & FB_GFX_CLOCK_DIVIDE_MASK) >> FB_GFX_CLOCK_DIVIDE_SHIFT) & 0x7;
886
887                 EMGD_DEBUG("sku = 0x%x Ratio = 0x%x", sku, ratio);
888
889                 if(sku < SKU_NO && ratio < RATIO_NO){
890                         /* get the graphics clock speed from the sku-ratio array */
891                         value[0] = tnc_gfx_freq_list[ratio][sku];
892                         value[1] = tnc_core_freq_list[sku];
893                 } else {
894                         EMGD_ERROR("tnc_gfx_freq_list ARRAY OUT OF RANGE");
895                         /* set to the lowest default value */
896                         value[0] = 333;
897                         value[1] = 166;
898                 }
899
900                 EMGD_DEBUG("TNC GFX core frequency = %lu MHz", value[0]);
901                 EMGD_DEBUG("TNC Core clock frequency = %lu MHz", value[1]);
902
903                 break;
904
905         default:
906                 /* If the param is not found here then it may only be in the
907                  * full version.
908                  */
909                 OPT_MICRO_CALL_RET(ret, full_get_param_tnc(context, id, value));
910                 break;
911         }
912
913         EMGD_TRACE_EXIT;
914         return ret;
915 }
916
917 /*!
918  *
919  * @param context
920  * @param id
921  * @param value
922  *
923  * @return -IGD_ERROR_INVAL
924  */
925 static int set_param_tnc(igd_context_t *context, unsigned long id,
926         unsigned long value)
927 {
928         return 0;
929 }
930
931 /*!
932  * Functions reads all the fuse values and dumps out the value
933  * @return -IGD_ERROR_INVAL
934  */
935 #ifndef CONFIG_MICRO
936 static int dump_fuse_values(void)
937 {
938         unsigned long value = 0;
939
940         if(query_sch_message(READ_FUS_EFF0, &value)){
941                 EMGD_ERROR_EXIT("Reading Fuse Value Failed");
942         }
943         EMGD_DEBUG("READ_FUS_EFF0 [%lx]", value);
944
945         if(query_sch_message(READ_FUS_EFF1, &value)){
946                 EMGD_ERROR_EXIT("Reading Fuse Value Failed");
947         }
948         EMGD_DEBUG("READ_FUS_EFF1 [%lx]", value);
949
950         if(query_sch_message(READ_FUS_EFF2, &value)){
951                 EMGD_ERROR_EXIT("Reading Fuse Value Failed");
952         }
953         EMGD_DEBUG("READ_FUS_EFF2 [%lx]", value);
954
955         if(query_sch_message(READ_FUS_EFF3, &value)){
956                 EMGD_ERROR_EXIT("Reading Fuse Value Failed");
957         }
958         EMGD_DEBUG("READ_FUS_EFF3 [%lx]", value);
959
960         if(query_sch_message(READ_FUS_EFF4, &value)){
961                 EMGD_ERROR_EXIT("Reading Fuse Value Failed");
962         }
963         EMGD_DEBUG("READ_FUS_EFF4 [%lx]", value);
964
965         if(query_sch_message(READ_FUS_EFF5, &value)){
966                 EMGD_ERROR_EXIT("Reading Fuse Value Failed");
967         }
968         EMGD_DEBUG("READ_FUS_EFF5 [%lx]", value);
969
970         return 0;
971 }
972 #endif
973 /*!
974  *
975  * @param context
976  *
977  * @return void
978  */
979 static void shutdown_tnc(igd_context_t *context)
980 {
981         gtt_shutdown_tnc(context);
982
983         OPT_MICRO_VOID_CALL(full_shutdown_tnc(context));
984 }
985
986
987 /*!
988  *
989  * @param context
990  * @param dispatch
991  * @param vga_dev
992  *
993  * @return -IGD_ERROR_NODEV on failure
994  * @return 0 on success
995  */
996 int get_revision_id_tnc(igd_context_t *context,
997         os_pci_dev_t vga_dev,
998         os_pci_dev_t sdvo_dev)
999 {
1000         platform_context_tnc_t *platform_context;
1001
1002         EMGD_TRACE_ENTER;
1003          
1004         platform_context = (platform_context_tnc_t *)context->platform_context;
1005
1006         /* Read RID */
1007         if(OS_PCI_READ_CONFIG_8(vga_dev, PCI_RID,
1008                 (unsigned char *)&context->device_context.rid)) {
1009                 EMGD_ERROR_EXIT("Error occured reading RID");
1010                 return -IGD_ERROR_NODEV;
1011         }
1012          
1013         if(OS_PCI_READ_CONFIG_8(sdvo_dev, PCI_RID,
1014                 &platform_context->tnc_dev3_rid)) {
1015                 EMGD_ERROR_EXIT("Error occured reading TNC SDVO RID");
1016                 return -IGD_ERROR_NODEV;
1017         }
1018          
1019         EMGD_DEBUG(" rid = 0x%lx", context->device_context.rid);
1020         
1021         EMGD_TRACE_EXIT;
1022         return 0;
1023 }
1024
1025 #endif