1 2#include "ddk750_help.h" 3#include "ddk750_reg.h" 4#include "ddk750_mode.h" 5#include "ddk750_chip.h" 6 7/* 8 SM750LE only: 9 This function takes care extra registers and bit fields required to set 10 up a mode in SM750LE 11 12 Explanation about Display Control register: 13 HW only supports 7 predefined pixel clocks, and clock select is 14 in bit 29:27 of Display Control register. 15*/ 16static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam, unsigned long dispControl) 17{ 18 unsigned long x, y; 19 20 x = pModeParam->horizontal_display_end; 21 y = pModeParam->vertical_display_end; 22 23 /* SM750LE has to set up the top-left and bottom-right 24 registers as well. 25 Note that normal SM750/SM718 only use those two register for 26 auto-centering mode. 27 */ 28 POKE32(CRT_AUTO_CENTERING_TL, 29 FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, TOP, 0) 30 | FIELD_VALUE(0, CRT_AUTO_CENTERING_TL, LEFT, 0)); 31 32 POKE32(CRT_AUTO_CENTERING_BR, 33 FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, BOTTOM, y-1) 34 | FIELD_VALUE(0, CRT_AUTO_CENTERING_BR, RIGHT, x-1)); 35 36 /* Assume common fields in dispControl have been properly set before 37 calling this function. 38 This function only sets the extra fields in dispControl. 39 */ 40 41 /* Clear bit 29:27 of display control register */ 42 dispControl &= FIELD_CLEAR(CRT_DISPLAY_CTRL, CLK); 43 44 /* Set bit 29:27 of display control register for the right clock */ 45 /* Note that SM750LE only need to supported 7 resoluitons. */ 46 if ( x == 800 && y == 600 ) 47 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL41); 48 else if (x == 1024 && y == 768) 49 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL65); 50 else if (x == 1152 && y == 864) 51 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); 52 else if (x == 1280 && y == 768) 53 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL80); 54 else if (x == 1280 && y == 720) 55 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL74); 56 else if (x == 1280 && y == 960) 57 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); 58 else if (x == 1280 && y == 1024) 59 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL108); 60 else /* default to VGA clock */ 61 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLK, PLL25); 62 63 /* Set bit 25:24 of display controller */ 64 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CRTSELECT, CRT); 65 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, RGBBIT, 24BIT); 66 67 /* Set bit 14 of display controller */ 68 dispControl = FIELD_SET(dispControl, CRT_DISPLAY_CTRL, CLOCK_PHASE, ACTIVE_LOW); 69 70 POKE32(CRT_DISPLAY_CTRL, dispControl); 71 72 return dispControl; 73} 74 75 76 77/* only timing related registers will be programed */ 78static int programModeRegisters(mode_parameter_t * pModeParam,pll_value_t * pll) 79{ 80 int ret = 0; 81 int cnt = 0; 82 unsigned int ulTmpValue,ulReg; 83 if(pll->clockType == SECONDARY_PLL) 84 { 85 /* programe secondary pixel clock */ 86 POKE32(CRT_PLL_CTRL,formatPllReg(pll)); 87 POKE32(CRT_HORIZONTAL_TOTAL, 88 FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) 89 | FIELD_VALUE(0, CRT_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); 90 91 POKE32(CRT_HORIZONTAL_SYNC, 92 FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) 93 | FIELD_VALUE(0, CRT_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); 94 95 POKE32(CRT_VERTICAL_TOTAL, 96 FIELD_VALUE(0, CRT_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) 97 | FIELD_VALUE(0, CRT_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); 98 99 POKE32(CRT_VERTICAL_SYNC, 100 FIELD_VALUE(0, CRT_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) 101 | FIELD_VALUE(0, CRT_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); 102 103 104 ulTmpValue = FIELD_VALUE(0,CRT_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| 105 FIELD_VALUE(0,CRT_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| 106 FIELD_SET(0,CRT_DISPLAY_CTRL,TIMING,ENABLE)| 107 FIELD_SET(0,CRT_DISPLAY_CTRL,PLANE,ENABLE); 108 109 110 if(getChipType() == SM750LE){ 111 displayControlAdjust_SM750LE(pModeParam,ulTmpValue); 112 }else{ 113 ulReg = PEEK32(CRT_DISPLAY_CTRL) 114 & FIELD_CLEAR(CRT_DISPLAY_CTRL,VSYNC_PHASE) 115 & FIELD_CLEAR(CRT_DISPLAY_CTRL,HSYNC_PHASE) 116 & FIELD_CLEAR(CRT_DISPLAY_CTRL,TIMING) 117 & FIELD_CLEAR(CRT_DISPLAY_CTRL,PLANE); 118 119 POKE32(CRT_DISPLAY_CTRL,ulTmpValue|ulReg); 120 } 121 122 } 123 else if(pll->clockType == PRIMARY_PLL) 124 { 125 unsigned int ulReservedBits; 126 POKE32(PANEL_PLL_CTRL,formatPllReg(pll)); 127 128 POKE32(PANEL_HORIZONTAL_TOTAL, 129 FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, TOTAL, pModeParam->horizontal_total - 1) 130 | FIELD_VALUE(0, PANEL_HORIZONTAL_TOTAL, DISPLAY_END, pModeParam->horizontal_display_end - 1)); 131 132 POKE32(PANEL_HORIZONTAL_SYNC, 133 FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, WIDTH, pModeParam->horizontal_sync_width) 134 | FIELD_VALUE(0, PANEL_HORIZONTAL_SYNC, START, pModeParam->horizontal_sync_start - 1)); 135 136 POKE32(PANEL_VERTICAL_TOTAL, 137 FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, TOTAL, pModeParam->vertical_total - 1) 138 | FIELD_VALUE(0, PANEL_VERTICAL_TOTAL, DISPLAY_END, pModeParam->vertical_display_end - 1)); 139 140 POKE32(PANEL_VERTICAL_SYNC, 141 FIELD_VALUE(0, PANEL_VERTICAL_SYNC, HEIGHT, pModeParam->vertical_sync_height) 142 | FIELD_VALUE(0, PANEL_VERTICAL_SYNC, START, pModeParam->vertical_sync_start - 1)); 143 144 ulTmpValue = FIELD_VALUE(0,PANEL_DISPLAY_CTRL,VSYNC_PHASE,pModeParam->vertical_sync_polarity)| 145 FIELD_VALUE(0,PANEL_DISPLAY_CTRL,HSYNC_PHASE,pModeParam->horizontal_sync_polarity)| 146 FIELD_VALUE(0,PANEL_DISPLAY_CTRL,CLOCK_PHASE,pModeParam->clock_phase_polarity)| 147 FIELD_SET(0,PANEL_DISPLAY_CTRL,TIMING,ENABLE)| 148 FIELD_SET(0,PANEL_DISPLAY_CTRL,PLANE,ENABLE); 149 150 ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | 151 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | 152 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE)| 153 FIELD_SET(0,PANEL_DISPLAY_CTRL,VSYNC,ACTIVE_LOW); 154 155 ulReg = (PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) 156 & FIELD_CLEAR(PANEL_DISPLAY_CTRL, CLOCK_PHASE) 157 & FIELD_CLEAR(PANEL_DISPLAY_CTRL, VSYNC_PHASE) 158 & FIELD_CLEAR(PANEL_DISPLAY_CTRL, HSYNC_PHASE) 159 & FIELD_CLEAR(PANEL_DISPLAY_CTRL, TIMING) 160 & FIELD_CLEAR(PANEL_DISPLAY_CTRL, PLANE); 161 162 163 /* May a hardware bug or just my test chip (not confirmed). 164 * PANEL_DISPLAY_CTRL register seems requiring few writes 165 * before a value can be succesfully written in. 166 * Added some masks to mask out the reserved bits. 167 * Note: This problem happens by design. The hardware will wait for the 168 * next vertical sync to turn on/off the plane. 169 */ 170 171 POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); 172#if 1 173 while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != (ulTmpValue|ulReg)) 174 { 175 cnt++; 176 if(cnt > 1000) 177 break; 178 POKE32(PANEL_DISPLAY_CTRL,ulTmpValue|ulReg); 179 } 180#endif 181 } 182 else{ 183 ret = -1; 184 } 185 return ret; 186} 187 188int ddk750_setModeTiming(mode_parameter_t * parm,clock_type_t clock) 189{ 190 pll_value_t pll; 191 unsigned int uiActualPixelClk; 192 pll.inputFreq = DEFAULT_INPUT_CLOCK; 193 pll.clockType = clock; 194 195 uiActualPixelClk = calcPllValue(parm->pixel_clock,&pll); 196 if(getChipType() == SM750LE){ 197 /* set graphic mode via IO method */ 198 outb_p(0x88,0x3d4); 199 outb_p(0x06,0x3d5); 200 } 201 programModeRegisters(parm,&pll); 202 return 0; 203} 204 205 206