1#include "ddk750_reg.h" 2#include "ddk750_help.h" 3#include "ddk750_display.h" 4#include "ddk750_power.h" 5#include "ddk750_dvi.h" 6 7#define primaryWaitVerticalSync(delay) waitNextVerticalSync(0,delay) 8 9static void setDisplayControl(int ctrl,int dispState) 10{ 11 /* state != 0 means turn on both timing & plane en_bit */ 12 unsigned long ulDisplayCtrlReg, ulReservedBits; 13 int cnt; 14 15 cnt = 0; 16 17 /* Set the primary display control */ 18 if (!ctrl) 19 { 20 ulDisplayCtrlReg = PEEK32(PANEL_DISPLAY_CTRL); 21 /* Turn on/off the Panel display control */ 22 if (dispState) 23 { 24 /* Timing should be enabled first before enabling the plane 25 * because changing at the same time does not guarantee that 26 * the plane will also enabled or disabled. 27 */ 28 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 29 PANEL_DISPLAY_CTRL, TIMING, ENABLE); 30 POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); 31 32 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 33 PANEL_DISPLAY_CTRL, PLANE, ENABLE); 34 35 /* Added some masks to mask out the reserved bits. 36 * Sometimes, the reserved bits are set/reset randomly when 37 * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register 38 * reserved bits are needed to be masked out. 39 */ 40 ulReservedBits = FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | 41 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | 42 FIELD_SET(0, PANEL_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE); 43 44 /* Somehow the register value on the plane is not set 45 * until a few delay. Need to write 46 * and read it a couple times 47 */ 48 do 49 { 50 cnt++; 51 POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); 52 } while((PEEK32(PANEL_DISPLAY_CTRL) & ~ulReservedBits) != 53 (ulDisplayCtrlReg & ~ulReservedBits)); 54 printk("Set Panel Plane enbit:after tried %d times\n",cnt); 55 } 56 else 57 { 58 /* When turning off, there is no rule on the programming 59 * sequence since whenever the clock is off, then it does not 60 * matter whether the plane is enabled or disabled. 61 * Note: Modifying the plane bit will take effect on the 62 * next vertical sync. Need to find out if it is necessary to 63 * wait for 1 vsync before modifying the timing enable bit. 64 * */ 65 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 66 PANEL_DISPLAY_CTRL, PLANE, DISABLE); 67 POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); 68 69 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 70 PANEL_DISPLAY_CTRL, TIMING, DISABLE); 71 POKE32(PANEL_DISPLAY_CTRL, ulDisplayCtrlReg); 72 } 73 74 } 75 /* Set the secondary display control */ 76 else 77 { 78 ulDisplayCtrlReg = PEEK32(CRT_DISPLAY_CTRL); 79 80 if (dispState) 81 { 82 /* Timing should be enabled first before enabling the plane because changing at the 83 same time does not guarantee that the plane will also enabled or disabled. 84 */ 85 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 86 CRT_DISPLAY_CTRL, TIMING, ENABLE); 87 POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); 88 89 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 90 CRT_DISPLAY_CTRL, PLANE, ENABLE); 91 92 /* Added some masks to mask out the reserved bits. 93 * Sometimes, the reserved bits are set/reset randomly when 94 * writing to the PRIMARY_DISPLAY_CTRL, therefore, the register 95 * reserved bits are needed to be masked out. 96 */ 97 98 ulReservedBits = FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_1_MASK, ENABLE) | 99 FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_2_MASK, ENABLE) | 100 FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_3_MASK, ENABLE) | 101 FIELD_SET(0, CRT_DISPLAY_CTRL, RESERVED_4_MASK, ENABLE); 102 103 do 104 { 105 cnt++; 106 POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); 107 } while((PEEK32(CRT_DISPLAY_CTRL) & ~ulReservedBits) != 108 (ulDisplayCtrlReg & ~ulReservedBits)); 109 printk("Set Crt Plane enbit:after tried %d times\n",cnt); 110 } 111 else 112 { 113 /* When turning off, there is no rule on the programming 114 * sequence since whenever the clock is off, then it does not 115 * matter whether the plane is enabled or disabled. 116 * Note: Modifying the plane bit will take effect on the next 117 * vertical sync. Need to find out if it is necessary to 118 * wait for 1 vsync before modifying the timing enable bit. 119 */ 120 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 121 CRT_DISPLAY_CTRL, PLANE, DISABLE); 122 POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); 123 124 ulDisplayCtrlReg = FIELD_SET(ulDisplayCtrlReg, 125 CRT_DISPLAY_CTRL, TIMING, DISABLE); 126 POKE32(CRT_DISPLAY_CTRL, ulDisplayCtrlReg); 127 } 128 } 129} 130 131 132static void waitNextVerticalSync(int ctrl,int delay) 133{ 134 unsigned int status; 135 if(!ctrl){ 136 /* primary controller */ 137 138 /* Do not wait when the Primary PLL is off or display control is already off. 139 This will prevent the software to wait forever. */ 140 if ((FIELD_GET(PEEK32(PANEL_PLL_CTRL), PANEL_PLL_CTRL, POWER) == 141 PANEL_PLL_CTRL_POWER_OFF) || 142 (FIELD_GET(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, TIMING) == 143 PANEL_DISPLAY_CTRL_TIMING_DISABLE)) 144 { 145 return; 146 } 147 148 while (delay-- > 0) 149 { 150 /* Wait for end of vsync. */ 151 do 152 { 153 status = FIELD_GET(PEEK32(SYSTEM_CTRL), 154 SYSTEM_CTRL, 155 PANEL_VSYNC); 156 } 157 while (status == SYSTEM_CTRL_PANEL_VSYNC_ACTIVE); 158 159 /* Wait for start of vsync. */ 160 do 161 { 162 status = FIELD_GET(PEEK32(SYSTEM_CTRL), 163 SYSTEM_CTRL, 164 PANEL_VSYNC); 165 } 166 while (status == SYSTEM_CTRL_PANEL_VSYNC_INACTIVE); 167 } 168 169 }else{ 170 171 /* Do not wait when the Primary PLL is off or display control is already off. 172 This will prevent the software to wait forever. */ 173 if ((FIELD_GET(PEEK32(CRT_PLL_CTRL), CRT_PLL_CTRL, POWER) == 174 CRT_PLL_CTRL_POWER_OFF) || 175 (FIELD_GET(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, TIMING) == 176 CRT_DISPLAY_CTRL_TIMING_DISABLE)) 177 { 178 return; 179 } 180 181 while (delay-- > 0) 182 { 183 /* Wait for end of vsync. */ 184 do 185 { 186 status = FIELD_GET(PEEK32(SYSTEM_CTRL), 187 SYSTEM_CTRL, 188 CRT_VSYNC); 189 } 190 while (status == SYSTEM_CTRL_CRT_VSYNC_ACTIVE); 191 192 /* Wait for start of vsync. */ 193 do 194 { 195 status = FIELD_GET(PEEK32(SYSTEM_CTRL), 196 SYSTEM_CTRL, 197 CRT_VSYNC); 198 } 199 while (status == SYSTEM_CTRL_CRT_VSYNC_INACTIVE); 200 } 201 } 202} 203 204static void swPanelPowerSequence(int disp,int delay) 205{ 206 unsigned int reg; 207 208 /* disp should be 1 to open sequence */ 209 reg = PEEK32(PANEL_DISPLAY_CTRL); 210 reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); 211 POKE32(PANEL_DISPLAY_CTRL,reg); 212 primaryWaitVerticalSync(delay); 213 214 215 reg = PEEK32(PANEL_DISPLAY_CTRL); 216 reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,DATA,disp); 217 POKE32(PANEL_DISPLAY_CTRL,reg); 218 primaryWaitVerticalSync(delay); 219 220 reg = PEEK32(PANEL_DISPLAY_CTRL); 221 reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,VBIASEN,disp); 222 POKE32(PANEL_DISPLAY_CTRL,reg); 223 primaryWaitVerticalSync(delay); 224 225 226 reg = PEEK32(PANEL_DISPLAY_CTRL); 227 reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,FPEN,disp); 228 POKE32(PANEL_DISPLAY_CTRL,reg); 229 primaryWaitVerticalSync(delay); 230 231} 232 233void ddk750_setLogicalDispOut(disp_output_t output) 234{ 235 unsigned int reg; 236 if(output & PNL_2_USAGE){ 237 /* set panel path controller select */ 238 reg = PEEK32(PANEL_DISPLAY_CTRL); 239 reg = FIELD_VALUE(reg,PANEL_DISPLAY_CTRL,SELECT,(output & PNL_2_MASK)>>PNL_2_OFFSET); 240 POKE32(PANEL_DISPLAY_CTRL,reg); 241 } 242 243 if(output & CRT_2_USAGE){ 244 /* set crt path controller select */ 245 reg = PEEK32(CRT_DISPLAY_CTRL); 246 reg = FIELD_VALUE(reg,CRT_DISPLAY_CTRL,SELECT,(output & CRT_2_MASK)>>CRT_2_OFFSET); 247 /*se blank off */ 248 reg = FIELD_SET(reg,CRT_DISPLAY_CTRL,BLANK,OFF); 249 POKE32(CRT_DISPLAY_CTRL,reg); 250 251 } 252 253 if(output & PRI_TP_USAGE){ 254 /* set primary timing and plane en_bit */ 255 setDisplayControl(0,(output&PRI_TP_MASK)>>PRI_TP_OFFSET); 256 } 257 258 if(output & SEC_TP_USAGE){ 259 /* set secondary timing and plane en_bit*/ 260 setDisplayControl(1,(output&SEC_TP_MASK)>>SEC_TP_OFFSET); 261 } 262 263 if(output & PNL_SEQ_USAGE){ 264 /* set panel sequence */ 265 swPanelPowerSequence((output&PNL_SEQ_MASK)>>PNL_SEQ_OFFSET,4); 266 } 267 268 if(output & DAC_USAGE) 269 setDAC((output & DAC_MASK)>>DAC_OFFSET); 270 271 if(output & DPMS_USAGE) 272 ddk750_setDPMS((output & DPMS_MASK) >> DPMS_OFFSET); 273} 274 275 276int ddk750_initDVIDisp(void) 277{ 278 /* Initialize DVI. If the dviInit fail and the VendorID or the DeviceID are 279 not zeroed, then set the failure flag. If it is zeroe, it might mean 280 that the system is in Dual CRT Monitor configuration. */ 281 282 /* De-skew enabled with default 111b value. 283 This will fix some artifacts problem in some mode on board 2.2. 284 Somehow this fix does not affect board 2.1. 285 */ 286 if ((dviInit(1, /* Select Rising Edge */ 287 1, /* Select 24-bit bus */ 288 0, /* Select Single Edge clock */ 289 1, /* Enable HSync as is */ 290 1, /* Enable VSync as is */ 291 1, /* Enable De-skew */ 292 7, /* Set the de-skew setting to maximum setup */ 293 1, /* Enable continuous Sync */ 294 1, /* Enable PLL Filter */ 295 4 /* Use the recommended value for PLL Filter value */ 296 ) != 0) && (dviGetVendorID() != 0x0000) && (dviGetDeviceID() != 0x0000)) 297 { 298 return (-1); 299 } 300 301 /* TODO: Initialize other display component */ 302 303 /* Success */ 304 return 0; 305 306} 307 308