cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

i810_gtf.c (9148B)


      1/*-*- linux-c -*-
      2 *  linux/drivers/video/i810_main.h -- Intel 810 Non-discrete Video Timings 
      3 *                                     (VESA GTF)
      4 *
      5 *      Copyright (C) 2001 Antonino Daplas<adaplas@pol.net>
      6 *      All Rights Reserved      
      7 *
      8 *
      9 *  This file is subject to the terms and conditions of the GNU General Public
     10 *  License. See the file COPYING in the main directory of this archive for
     11 *  more details.
     12 */
     13#include <linux/kernel.h>
     14
     15#include "i810_regs.h"
     16#include "i810.h"
     17#include "i810_main.h"
     18
     19/*
     20 * FIFO and Watermark tables - based almost wholly on i810_wmark.c in 
     21 * XFree86 v4.03 by Precision Insight.  Slightly modified for integer 
     22 * operation, instead of float
     23 */
     24
     25struct wm_info {
     26   u32 freq;
     27   u32  wm;
     28};
     29
     30static struct wm_info i810_wm_8_100[] = {
     31	{ 15, 0x0070c000 },  { 19, 0x0070c000 },  { 25, 0x22003000 },
     32	{ 28, 0x22003000 },  { 31, 0x22003000 },  { 36, 0x22007000 },
     33	{ 40, 0x22007000 },  { 45, 0x22007000 },  { 49, 0x22008000 },
     34	{ 50, 0x22008000 },  { 56, 0x22008000 },  { 65, 0x22008000 },
     35	{ 75, 0x22008000 },  { 78, 0x22008000 },  { 80, 0x22008000 },
     36	{ 94, 0x22008000 },  { 96, 0x22107000 },  { 99, 0x22107000 },
     37	{ 108, 0x22107000 }, { 121, 0x22107000 }, { 128, 0x22107000 },
     38	{ 132, 0x22109000 }, { 135, 0x22109000 }, { 157, 0x2210b000 },
     39	{ 162, 0x2210b000 }, { 175, 0x2210b000 }, { 189, 0x2220e000 },
     40	{ 195, 0x2220e000 }, { 202, 0x2220e000 }, { 204, 0x2220e000 },
     41	{ 218, 0x2220f000 }, { 229, 0x22210000 }, { 234, 0x22210000 }, 
     42};
     43
     44static struct wm_info i810_wm_16_100[] = {
     45	{ 15, 0x0070c000 },  { 19, 0x0020c000 },  { 25, 0x22006000 },
     46	{ 28, 0x22006000 },  { 31, 0x22007000 },  { 36, 0x22007000 },
     47	{ 40, 0x22007000 },  { 45, 0x22007000 },  { 49, 0x22009000 },
     48	{ 50, 0x22009000 },  { 56, 0x22108000 },  { 65, 0x2210e000 },
     49	{ 75, 0x2210e000 },  { 78, 0x2210e000 },  { 80, 0x22210000 },
     50	{ 94, 0x22210000 },  { 96, 0x22210000 },  { 99, 0x22210000 },
     51	{ 108, 0x22210000 }, { 121, 0x22210000 }, { 128, 0x22210000 },
     52	{ 132, 0x22314000 }, { 135, 0x22314000 }, { 157, 0x22415000 },
     53	{ 162, 0x22416000 }, { 175, 0x22416000 }, { 189, 0x22416000 },
     54	{ 195, 0x22416000 }, { 202, 0x22416000 }, { 204, 0x22416000 },
     55	{ 218, 0x22416000 }, { 229, 0x22416000 },
     56};
     57
     58static struct wm_info i810_wm_24_100[] = {
     59	{ 15, 0x0020c000 },  { 19, 0x0040c000 },  { 25, 0x22009000 },
     60	{ 28, 0x22009000 },  { 31, 0x2200a000 },  { 36, 0x2210c000 },
     61	{ 40, 0x2210c000 },  { 45, 0x2210c000 },  { 49, 0x22111000 },
     62	{ 50, 0x22111000 },  { 56, 0x22111000 },  { 65, 0x22214000 },
     63	{ 75, 0x22214000 },  { 78, 0x22215000 },  { 80, 0x22216000 },
     64	{ 94, 0x22218000 },  { 96, 0x22418000 },  { 99, 0x22418000 },
     65	{ 108, 0x22418000 }, { 121, 0x22418000 }, { 128, 0x22419000 },
     66	{ 132, 0x22519000 }, { 135, 0x4441d000 }, { 157, 0x44419000 },
     67	{ 162, 0x44419000 }, { 175, 0x44419000 }, { 189, 0x44419000 },
     68	{ 195, 0x44419000 }, { 202, 0x44419000 }, { 204, 0x44419000 },
     69};
     70
     71static struct wm_info i810_wm_8_133[] = {
     72	{ 15, 0x0070c000 },  { 19, 0x0070c000 },  { 25, 0x22003000 },
     73	{ 28, 0x22003000 },  { 31, 0x22003000 },  { 36, 0x22007000 },
     74	{ 40, 0x22007000 },  { 45, 0x22007000 },  { 49, 0x22008000 },
     75	{ 50, 0x22008000 },  { 56, 0x22008000 },  { 65, 0x22008000 },
     76	{ 75, 0x22008000 },  { 78, 0x22008000 },  { 80, 0x22008000 },
     77	{ 94, 0x22008000 },  { 96, 0x22107000 },  { 99, 0x22107000 },
     78	{ 108, 0x22107000 }, { 121, 0x22107000 }, { 128, 0x22107000 },
     79	{ 132, 0x22109000 }, { 135, 0x22109000 }, { 157, 0x2210b000 },
     80	{ 162, 0x2210b000 }, { 175, 0x2210b000 }, { 189, 0x2220e000 },
     81	{ 195, 0x2220e000 }, { 202, 0x2220e000 }, { 204, 0x2220e000 },
     82	{ 218, 0x2220f000 }, { 229, 0x22210000 }, { 234, 0x22210000 }, 
     83};
     84
     85static struct wm_info i810_wm_16_133[] = {
     86	{ 15, 0x0020c000 },  { 19, 0x0020c000 },  { 25, 0x22006000 },
     87	{ 28, 0x22006000 },  { 31, 0x22007000 },  { 36, 0x22007000 },
     88	{ 40, 0x22007000 },  { 45, 0x22007000 },  { 49, 0x22009000 },
     89	{ 50, 0x22009000 },  { 56, 0x22108000 },  { 65, 0x2210e000 },
     90	{ 75, 0x2210e000 },  { 78, 0x2210e000 },  { 80, 0x22210000 },
     91	{ 94, 0x22210000 },  { 96, 0x22210000 },  { 99, 0x22210000 },
     92	{ 108, 0x22210000 }, { 121, 0x22210000 }, { 128, 0x22210000 },
     93	{ 132, 0x22314000 }, { 135, 0x22314000 }, { 157, 0x22415000 },
     94	{ 162, 0x22416000 }, { 175, 0x22416000 }, { 189, 0x22416000 },
     95	{ 195, 0x22416000 }, { 202, 0x22416000 }, { 204, 0x22416000 },
     96	{ 218, 0x22416000 }, { 229, 0x22416000 },
     97};
     98
     99static struct wm_info i810_wm_24_133[] = {
    100	{ 15, 0x0020c000 },  { 19, 0x00408000 },  { 25, 0x22009000 },
    101	{ 28, 0x22009000 },  { 31, 0x2200a000 },  { 36, 0x2210c000 },
    102	{ 40, 0x2210c000 },  { 45, 0x2210c000 },  { 49, 0x22111000 },
    103	{ 50, 0x22111000 },  { 56, 0x22111000 },  { 65, 0x22214000 },
    104	{ 75, 0x22214000 },  { 78, 0x22215000 },  { 80, 0x22216000 },
    105	{ 94, 0x22218000 },  { 96, 0x22418000 },  { 99, 0x22418000 },
    106	{ 108, 0x22418000 }, { 121, 0x22418000 }, { 128, 0x22419000 },
    107	{ 132, 0x22519000 }, { 135, 0x4441d000 }, { 157, 0x44419000 },
    108	{ 162, 0x44419000 }, { 175, 0x44419000 }, { 189, 0x44419000 },
    109	{ 195, 0x44419000 }, { 202, 0x44419000 }, { 204, 0x44419000 },
    110};
    111
    112void round_off_xres(u32 *xres) { }
    113void round_off_yres(u32 *xres, u32 *yres) { }
    114
    115/**
    116 * i810fb_encode_registers - encode @var to hardware register values
    117 * @var: pointer to var structure
    118 * @par: pointer to hardware par structure
    119 * 
    120 * DESCRIPTION: 
    121 * Timing values in @var will be converted to appropriate
    122 * register values of @par.  
    123 */
    124void i810fb_encode_registers(const struct fb_var_screeninfo *var,
    125			     struct i810fb_par *par, u32 xres, u32 yres)
    126{
    127	int n, blank_s, blank_e;
    128	u8 __iomem *mmio = par->mmio_start_virtual;
    129	u8 msr = 0;
    130
    131	/* Horizontal */
    132	/* htotal */
    133	n = ((xres + var->right_margin + var->hsync_len + 
    134	      var->left_margin) >> 3) - 5;
    135	par->regs.cr00 =  (u8) n;
    136	par->regs.cr35 = (u8) ((n >> 8) & 1);
    137	
    138	/* xres */
    139	par->regs.cr01 = (u8) ((xres >> 3) - 1);
    140
    141	/* hblank */
    142	blank_e = (xres + var->right_margin + var->hsync_len + 
    143		   var->left_margin) >> 3;
    144	blank_e--;
    145	blank_s = blank_e - 127;
    146	if (blank_s < (xres >> 3))
    147		blank_s = xres >> 3;
    148	par->regs.cr02 = (u8) blank_s;
    149	par->regs.cr03 = (u8) (blank_e & 0x1F);
    150	par->regs.cr05 = (u8) ((blank_e & (1 << 5)) << 2);
    151	par->regs.cr39 = (u8) ((blank_e >> 6) & 1);
    152
    153	/* hsync */
    154	par->regs.cr04 = (u8) ((xres + var->right_margin) >> 3);
    155	par->regs.cr05 |= (u8) (((xres + var->right_margin + 
    156				  var->hsync_len) >> 3) & 0x1F);
    157	
    158       	/* Vertical */
    159	/* vtotal */
    160	n = yres + var->lower_margin + var->vsync_len + var->upper_margin - 2;
    161	par->regs.cr06 = (u8) (n & 0xFF);
    162	par->regs.cr30 = (u8) ((n >> 8) & 0x0F);
    163
    164	/* vsync */ 
    165	n = yres + var->lower_margin;
    166	par->regs.cr10 = (u8) (n & 0xFF);
    167	par->regs.cr32 = (u8) ((n >> 8) & 0x0F);
    168	par->regs.cr11 = i810_readb(CR11, mmio) & ~0x0F;
    169	par->regs.cr11 |= (u8) ((yres + var->lower_margin + 
    170				 var->vsync_len) & 0x0F);
    171
    172	/* yres */
    173	n = yres - 1;
    174	par->regs.cr12 = (u8) (n & 0xFF);
    175	par->regs.cr31 = (u8) ((n >> 8) & 0x0F);
    176	
    177	/* vblank */
    178	blank_e = yres + var->lower_margin + var->vsync_len + 
    179		var->upper_margin;
    180	blank_e--;
    181	blank_s = blank_e - 127;
    182	if (blank_s < yres)
    183		blank_s = yres;
    184	par->regs.cr15 = (u8) (blank_s & 0xFF);
    185	par->regs.cr33 = (u8) ((blank_s >> 8) & 0x0F);
    186	par->regs.cr16 = (u8) (blank_e & 0xFF);
    187	par->regs.cr09 = 0;	
    188
    189	/* sync polarity */
    190	if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
    191		msr |= 1 << 6;
    192	if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
    193		msr |= 1 << 7;
    194	par->regs.msr = msr;
    195
    196	/* interlace */
    197	if (var->vmode & FB_VMODE_INTERLACED) 
    198		par->interlace = (1 << 7) | ((u8) (var->yres >> 4));
    199	else 
    200		par->interlace = 0;
    201
    202	if (var->vmode & FB_VMODE_DOUBLE)
    203		par->regs.cr09 |= 1 << 7;
    204
    205	/* overlay */
    206	par->ovract = ((var->xres + var->right_margin + var->hsync_len + 
    207			var->left_margin - 32) | ((var->xres - 32) << 16));
    208}	
    209
    210void i810fb_fill_var_timings(struct fb_var_screeninfo *var) { }
    211
    212/**
    213 * i810_get_watermark - gets watermark
    214 * @var: pointer to fb_var_screeninfo
    215 * @par: pointer to i810fb_par structure
    216 *
    217 * DESCRIPTION:
    218 * Gets the required watermark based on 
    219 * pixelclock and RAMBUS frequency.
    220 * 
    221 * RETURNS:
    222 * watermark
    223 */
    224u32 i810_get_watermark(const struct fb_var_screeninfo *var,
    225		       struct i810fb_par *par)
    226{
    227	struct wm_info *wmark = NULL;
    228	u32 i, size = 0, pixclock, wm_best = 0, min, diff;
    229
    230	if (par->mem_freq == 100) {
    231		switch (var->bits_per_pixel) { 
    232		case 8:
    233			wmark = i810_wm_8_100;
    234			size = ARRAY_SIZE(i810_wm_8_100);
    235			break;
    236		case 16:
    237			wmark = i810_wm_16_100;
    238			size = ARRAY_SIZE(i810_wm_16_100);
    239			break;
    240		case 24:
    241		case 32:
    242			wmark = i810_wm_24_100;
    243			size = ARRAY_SIZE(i810_wm_24_100);
    244		}
    245	} else {
    246		switch(var->bits_per_pixel) {
    247		case 8:
    248			wmark = i810_wm_8_133;
    249			size = ARRAY_SIZE(i810_wm_8_133);
    250			break;
    251		case 16:
    252			wmark = i810_wm_16_133;
    253			size = ARRAY_SIZE(i810_wm_16_133);
    254			break;
    255		case 24:
    256		case 32:
    257			wmark = i810_wm_24_133;
    258			size = ARRAY_SIZE(i810_wm_24_133);
    259		}
    260	}
    261
    262	pixclock = 1000000/var->pixclock;
    263	min = ~0;
    264	for (i = 0; i < size; i++) {
    265		if (pixclock <= wmark[i].freq) 
    266			diff = wmark[i].freq - pixclock;
    267		else 
    268			diff = pixclock - wmark[i].freq;
    269		if (diff < min) {
    270			wm_best = wmark[i].wm;
    271			min = diff;
    272		}
    273	}
    274	return wm_best;		
    275}	
    276