1 /* 2 * Copyright 2012 Red Hat Inc. 3 * Parts based on xf86-video-ast 4 * Copyright (c) 2005 ASPEED Technology Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 * 26 */ 27 /* 28 * Authors: Dave Airlie <airlied@redhat.com> 29 */ 30 31 #include <linux/export.h> 32 #include <linux/pci.h> 33 34 #include <drm/drm_atomic.h> 35 #include <drm/drm_atomic_helper.h> 36 #include <drm/drm_atomic_state_helper.h> 37 #include <drm/drm_crtc.h> 38 #include <drm/drm_crtc_helper.h> 39 #include <drm/drm_fourcc.h> 40 #include <drm/drm_gem_framebuffer_helper.h> 41 #include <drm/drm_gem_vram_helper.h> 42 #include <drm/drm_plane_helper.h> 43 #include <drm/drm_probe_helper.h> 44 #include <drm/drm_simple_kms_helper.h> 45 46 #include "ast_drv.h" 47 #include "ast_tables.h" 48 49 static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev); 50 static void ast_i2c_destroy(struct ast_i2c_chan *i2c); 51 52 static inline void ast_load_palette_index(struct ast_private *ast, 53 u8 index, u8 red, u8 green, 54 u8 blue) 55 { 56 ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); 57 ast_io_read8(ast, AST_IO_SEQ_PORT); 58 ast_io_write8(ast, AST_IO_DAC_DATA, red); 59 ast_io_read8(ast, AST_IO_SEQ_PORT); 60 ast_io_write8(ast, AST_IO_DAC_DATA, green); 61 ast_io_read8(ast, AST_IO_SEQ_PORT); 62 ast_io_write8(ast, AST_IO_DAC_DATA, blue); 63 ast_io_read8(ast, AST_IO_SEQ_PORT); 64 } 65 66 static void ast_crtc_load_lut(struct ast_private *ast, struct drm_crtc *crtc) 67 { 68 u16 *r, *g, *b; 69 int i; 70 71 if (!crtc->enabled) 72 return; 73 74 r = crtc->gamma_store; 75 g = r + crtc->gamma_size; 76 b = g + crtc->gamma_size; 77 78 for (i = 0; i < 256; i++) 79 ast_load_palette_index(ast, i, *r++ >> 8, *g++ >> 8, *b++ >> 8); 80 } 81 82 static bool ast_get_vbios_mode_info(const struct drm_format_info *format, 83 const struct drm_display_mode *mode, 84 struct drm_display_mode *adjusted_mode, 85 struct ast_vbios_mode_info *vbios_mode) 86 { 87 u32 refresh_rate_index = 0, refresh_rate; 88 const struct ast_vbios_enhtable *best = NULL; 89 u32 hborder, vborder; 90 bool check_sync; 91 92 switch (format->cpp[0] * 8) { 93 case 8: 94 vbios_mode->std_table = &vbios_stdtable[VGAModeIndex]; 95 break; 96 case 16: 97 vbios_mode->std_table = &vbios_stdtable[HiCModeIndex]; 98 break; 99 case 24: 100 case 32: 101 vbios_mode->std_table = &vbios_stdtable[TrueCModeIndex]; 102 break; 103 default: 104 return false; 105 } 106 107 switch (mode->crtc_hdisplay) { 108 case 640: 109 vbios_mode->enh_table = &res_640x480[refresh_rate_index]; 110 break; 111 case 800: 112 vbios_mode->enh_table = &res_800x600[refresh_rate_index]; 113 break; 114 case 1024: 115 vbios_mode->enh_table = &res_1024x768[refresh_rate_index]; 116 break; 117 case 1280: 118 if (mode->crtc_vdisplay == 800) 119 vbios_mode->enh_table = &res_1280x800[refresh_rate_index]; 120 else 121 vbios_mode->enh_table = &res_1280x1024[refresh_rate_index]; 122 break; 123 case 1360: 124 vbios_mode->enh_table = &res_1360x768[refresh_rate_index]; 125 break; 126 case 1440: 127 vbios_mode->enh_table = &res_1440x900[refresh_rate_index]; 128 break; 129 case 1600: 130 if (mode->crtc_vdisplay == 900) 131 vbios_mode->enh_table = &res_1600x900[refresh_rate_index]; 132 else 133 vbios_mode->enh_table = &res_1600x1200[refresh_rate_index]; 134 break; 135 case 1680: 136 vbios_mode->enh_table = &res_1680x1050[refresh_rate_index]; 137 break; 138 case 1920: 139 if (mode->crtc_vdisplay == 1080) 140 vbios_mode->enh_table = &res_1920x1080[refresh_rate_index]; 141 else 142 vbios_mode->enh_table = &res_1920x1200[refresh_rate_index]; 143 break; 144 default: 145 return false; 146 } 147 148 refresh_rate = drm_mode_vrefresh(mode); 149 check_sync = vbios_mode->enh_table->flags & WideScreenMode; 150 151 while (1) { 152 const struct ast_vbios_enhtable *loop = vbios_mode->enh_table; 153 154 while (loop->refresh_rate != 0xff) { 155 if ((check_sync) && 156 (((mode->flags & DRM_MODE_FLAG_NVSYNC) && 157 (loop->flags & PVSync)) || 158 ((mode->flags & DRM_MODE_FLAG_PVSYNC) && 159 (loop->flags & NVSync)) || 160 ((mode->flags & DRM_MODE_FLAG_NHSYNC) && 161 (loop->flags & PHSync)) || 162 ((mode->flags & DRM_MODE_FLAG_PHSYNC) && 163 (loop->flags & NHSync)))) { 164 loop++; 165 continue; 166 } 167 if (loop->refresh_rate <= refresh_rate 168 && (!best || loop->refresh_rate > best->refresh_rate)) 169 best = loop; 170 loop++; 171 } 172 if (best || !check_sync) 173 break; 174 check_sync = 0; 175 } 176 177 if (best) 178 vbios_mode->enh_table = best; 179 180 hborder = (vbios_mode->enh_table->flags & HBorder) ? 8 : 0; 181 vborder = (vbios_mode->enh_table->flags & VBorder) ? 8 : 0; 182 183 adjusted_mode->crtc_htotal = vbios_mode->enh_table->ht; 184 adjusted_mode->crtc_hblank_start = vbios_mode->enh_table->hde + hborder; 185 adjusted_mode->crtc_hblank_end = vbios_mode->enh_table->ht - hborder; 186 adjusted_mode->crtc_hsync_start = vbios_mode->enh_table->hde + hborder + 187 vbios_mode->enh_table->hfp; 188 adjusted_mode->crtc_hsync_end = (vbios_mode->enh_table->hde + hborder + 189 vbios_mode->enh_table->hfp + 190 vbios_mode->enh_table->hsync); 191 192 adjusted_mode->crtc_vtotal = vbios_mode->enh_table->vt; 193 adjusted_mode->crtc_vblank_start = vbios_mode->enh_table->vde + vborder; 194 adjusted_mode->crtc_vblank_end = vbios_mode->enh_table->vt - vborder; 195 adjusted_mode->crtc_vsync_start = vbios_mode->enh_table->vde + vborder + 196 vbios_mode->enh_table->vfp; 197 adjusted_mode->crtc_vsync_end = (vbios_mode->enh_table->vde + vborder + 198 vbios_mode->enh_table->vfp + 199 vbios_mode->enh_table->vsync); 200 201 return true; 202 } 203 204 static void ast_set_vbios_color_reg(struct ast_private *ast, 205 const struct drm_format_info *format, 206 const struct ast_vbios_mode_info *vbios_mode) 207 { 208 u32 color_index; 209 210 switch (format->cpp[0]) { 211 case 1: 212 color_index = VGAModeIndex - 1; 213 break; 214 case 2: 215 color_index = HiCModeIndex; 216 break; 217 case 3: 218 case 4: 219 color_index = TrueCModeIndex; 220 break; 221 default: 222 return; 223 } 224 225 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4)); 226 227 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); 228 229 if (vbios_mode->enh_table->flags & NewModeInfo) { 230 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); 231 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8); 232 } 233 } 234 235 static void ast_set_vbios_mode_reg(struct ast_private *ast, 236 const struct drm_display_mode *adjusted_mode, 237 const struct ast_vbios_mode_info *vbios_mode) 238 { 239 u32 refresh_rate_index, mode_id; 240 241 refresh_rate_index = vbios_mode->enh_table->refresh_rate_index; 242 mode_id = vbios_mode->enh_table->mode_id; 243 244 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); 245 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); 246 247 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); 248 249 if (vbios_mode->enh_table->flags & NewModeInfo) { 250 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); 251 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); 252 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); 253 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); 254 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay); 255 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8); 256 } 257 } 258 259 static void ast_set_std_reg(struct ast_private *ast, 260 struct drm_display_mode *mode, 261 struct ast_vbios_mode_info *vbios_mode) 262 { 263 const struct ast_vbios_stdtable *stdtable; 264 u32 i; 265 u8 jreg; 266 267 stdtable = vbios_mode->std_table; 268 269 jreg = stdtable->misc; 270 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); 271 272 /* Set SEQ; except Screen Disable field */ 273 ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); 274 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]); 275 for (i = 1; i < 4; i++) { 276 jreg = stdtable->seq[i]; 277 ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1) , jreg); 278 } 279 280 /* Set CRTC; except base address and offset */ 281 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); 282 for (i = 0; i < 12; i++) 283 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); 284 for (i = 14; i < 19; i++) 285 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); 286 for (i = 20; i < 25; i++) 287 ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); 288 289 /* set AR */ 290 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 291 for (i = 0; i < 20; i++) { 292 jreg = stdtable->ar[i]; 293 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i); 294 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg); 295 } 296 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14); 297 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00); 298 299 jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 300 ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20); 301 302 /* Set GR */ 303 for (i = 0; i < 9; i++) 304 ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]); 305 } 306 307 static void ast_set_crtc_reg(struct ast_private *ast, 308 struct drm_display_mode *mode, 309 struct ast_vbios_mode_info *vbios_mode) 310 { 311 u8 jreg05 = 0, jreg07 = 0, jreg09 = 0, jregAC = 0, jregAD = 0, jregAE = 0; 312 u16 temp, precache = 0; 313 314 if ((ast->chip == AST2500) && 315 (vbios_mode->enh_table->flags & AST2500PreCatchCRT)) 316 precache = 40; 317 318 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); 319 320 temp = (mode->crtc_htotal >> 3) - 5; 321 if (temp & 0x100) 322 jregAC |= 0x01; /* HT D[8] */ 323 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp); 324 325 temp = (mode->crtc_hdisplay >> 3) - 1; 326 if (temp & 0x100) 327 jregAC |= 0x04; /* HDE D[8] */ 328 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp); 329 330 temp = (mode->crtc_hblank_start >> 3) - 1; 331 if (temp & 0x100) 332 jregAC |= 0x10; /* HBS D[8] */ 333 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp); 334 335 temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f; 336 if (temp & 0x20) 337 jreg05 |= 0x80; /* HBE D[5] */ 338 if (temp & 0x40) 339 jregAD |= 0x01; /* HBE D[5] */ 340 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f)); 341 342 temp = ((mode->crtc_hsync_start-precache) >> 3) - 1; 343 if (temp & 0x100) 344 jregAC |= 0x40; /* HRS D[5] */ 345 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp); 346 347 temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f; 348 if (temp & 0x20) 349 jregAD |= 0x04; /* HRE D[5] */ 350 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); 351 352 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC); 353 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD); 354 355 /* vert timings */ 356 temp = (mode->crtc_vtotal) - 2; 357 if (temp & 0x100) 358 jreg07 |= 0x01; 359 if (temp & 0x200) 360 jreg07 |= 0x20; 361 if (temp & 0x400) 362 jregAE |= 0x01; 363 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp); 364 365 temp = (mode->crtc_vsync_start) - 1; 366 if (temp & 0x100) 367 jreg07 |= 0x04; 368 if (temp & 0x200) 369 jreg07 |= 0x80; 370 if (temp & 0x400) 371 jregAE |= 0x08; 372 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp); 373 374 temp = (mode->crtc_vsync_end - 1) & 0x3f; 375 if (temp & 0x10) 376 jregAE |= 0x20; 377 if (temp & 0x20) 378 jregAE |= 0x40; 379 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf); 380 381 temp = mode->crtc_vdisplay - 1; 382 if (temp & 0x100) 383 jreg07 |= 0x02; 384 if (temp & 0x200) 385 jreg07 |= 0x40; 386 if (temp & 0x400) 387 jregAE |= 0x02; 388 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp); 389 390 temp = mode->crtc_vblank_start - 1; 391 if (temp & 0x100) 392 jreg07 |= 0x08; 393 if (temp & 0x200) 394 jreg09 |= 0x20; 395 if (temp & 0x400) 396 jregAE |= 0x04; 397 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp); 398 399 temp = mode->crtc_vblank_end - 1; 400 if (temp & 0x100) 401 jregAE |= 0x10; 402 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp); 403 404 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07); 405 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09); 406 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80)); 407 408 if (precache) 409 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80); 410 else 411 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00); 412 413 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80); 414 } 415 416 static void ast_set_offset_reg(struct ast_private *ast, 417 struct drm_framebuffer *fb) 418 { 419 u16 offset; 420 421 offset = fb->pitches[0] >> 3; 422 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); 423 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); 424 } 425 426 static void ast_set_dclk_reg(struct ast_private *ast, 427 struct drm_display_mode *mode, 428 struct ast_vbios_mode_info *vbios_mode) 429 { 430 const struct ast_vbios_dclk_info *clk_info; 431 432 if (ast->chip == AST2500) 433 clk_info = &dclk_table_ast2500[vbios_mode->enh_table->dclk_index]; 434 else 435 clk_info = &dclk_table[vbios_mode->enh_table->dclk_index]; 436 437 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1); 438 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2); 439 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f, 440 (clk_info->param3 & 0xc0) | 441 ((clk_info->param3 & 0x3) << 4)); 442 } 443 444 static void ast_set_color_reg(struct ast_private *ast, 445 const struct drm_format_info *format) 446 { 447 u8 jregA0 = 0, jregA3 = 0, jregA8 = 0; 448 449 switch (format->cpp[0] * 8) { 450 case 8: 451 jregA0 = 0x70; 452 jregA3 = 0x01; 453 jregA8 = 0x00; 454 break; 455 case 15: 456 case 16: 457 jregA0 = 0x70; 458 jregA3 = 0x04; 459 jregA8 = 0x02; 460 break; 461 case 32: 462 jregA0 = 0x70; 463 jregA3 = 0x08; 464 jregA8 = 0x02; 465 break; 466 } 467 468 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0); 469 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3); 470 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8); 471 } 472 473 static void ast_set_crtthd_reg(struct ast_private *ast) 474 { 475 /* Set Threshold */ 476 if (ast->chip == AST2300 || ast->chip == AST2400 || 477 ast->chip == AST2500) { 478 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); 479 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); 480 } else if (ast->chip == AST2100 || 481 ast->chip == AST1100 || 482 ast->chip == AST2200 || 483 ast->chip == AST2150) { 484 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f); 485 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f); 486 } else { 487 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f); 488 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f); 489 } 490 } 491 492 static void ast_set_sync_reg(struct ast_private *ast, 493 struct drm_display_mode *mode, 494 struct ast_vbios_mode_info *vbios_mode) 495 { 496 u8 jreg; 497 498 jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); 499 jreg &= ~0xC0; 500 if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80; 501 if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40; 502 ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); 503 } 504 505 static void ast_set_start_address_crt1(struct ast_private *ast, 506 unsigned offset) 507 { 508 u32 addr; 509 510 addr = offset >> 2; 511 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff)); 512 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff)); 513 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff)); 514 515 } 516 517 static void ast_wait_for_vretrace(struct ast_private *ast) 518 { 519 unsigned long timeout = jiffies + HZ; 520 u8 vgair1; 521 522 do { 523 vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); 524 } while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout)); 525 } 526 527 /* 528 * Primary plane 529 */ 530 531 static const uint32_t ast_primary_plane_formats[] = { 532 DRM_FORMAT_XRGB8888, 533 DRM_FORMAT_RGB565, 534 DRM_FORMAT_C8, 535 }; 536 537 static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane, 538 struct drm_plane_state *state) 539 { 540 struct drm_crtc_state *crtc_state; 541 struct ast_crtc_state *ast_crtc_state; 542 int ret; 543 544 if (!state->crtc) 545 return 0; 546 547 crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); 548 549 ret = drm_atomic_helper_check_plane_state(state, crtc_state, 550 DRM_PLANE_HELPER_NO_SCALING, 551 DRM_PLANE_HELPER_NO_SCALING, 552 false, true); 553 if (ret) 554 return ret; 555 556 if (!state->visible) 557 return 0; 558 559 ast_crtc_state = to_ast_crtc_state(crtc_state); 560 561 ast_crtc_state->format = state->fb->format; 562 563 return 0; 564 } 565 566 static void 567 ast_primary_plane_helper_atomic_update(struct drm_plane *plane, 568 struct drm_plane_state *old_state) 569 { 570 struct drm_device *dev = plane->dev; 571 struct ast_private *ast = to_ast_private(dev); 572 struct drm_plane_state *state = plane->state; 573 struct drm_gem_vram_object *gbo; 574 s64 gpu_addr; 575 struct drm_framebuffer *fb = state->fb; 576 struct drm_framebuffer *old_fb = old_state->fb; 577 578 if (!old_fb || (fb->format != old_fb->format)) { 579 struct drm_crtc_state *crtc_state = state->crtc->state; 580 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 581 struct ast_vbios_mode_info *vbios_mode_info = &ast_crtc_state->vbios_mode_info; 582 583 ast_set_color_reg(ast, fb->format); 584 ast_set_vbios_color_reg(ast, fb->format, vbios_mode_info); 585 } 586 587 gbo = drm_gem_vram_of_gem(fb->obj[0]); 588 gpu_addr = drm_gem_vram_offset(gbo); 589 if (drm_WARN_ON_ONCE(dev, gpu_addr < 0)) 590 return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */ 591 592 ast_set_offset_reg(ast, fb); 593 ast_set_start_address_crt1(ast, (u32)gpu_addr); 594 595 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00); 596 } 597 598 static void 599 ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, 600 struct drm_plane_state *old_state) 601 { 602 struct ast_private *ast = to_ast_private(plane->dev); 603 604 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); 605 } 606 607 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { 608 .prepare_fb = drm_gem_vram_plane_helper_prepare_fb, 609 .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb, 610 .atomic_check = ast_primary_plane_helper_atomic_check, 611 .atomic_update = ast_primary_plane_helper_atomic_update, 612 .atomic_disable = ast_primary_plane_helper_atomic_disable, 613 }; 614 615 static const struct drm_plane_funcs ast_primary_plane_funcs = { 616 .update_plane = drm_atomic_helper_update_plane, 617 .disable_plane = drm_atomic_helper_disable_plane, 618 .destroy = drm_plane_cleanup, 619 .reset = drm_atomic_helper_plane_reset, 620 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 621 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 622 }; 623 624 /* 625 * Cursor plane 626 */ 627 628 static const uint32_t ast_cursor_plane_formats[] = { 629 DRM_FORMAT_ARGB8888, 630 }; 631 632 static int 633 ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, 634 struct drm_plane_state *new_state) 635 { 636 struct drm_framebuffer *fb = new_state->fb; 637 struct drm_crtc *crtc = new_state->crtc; 638 struct ast_private *ast; 639 int ret; 640 641 if (!crtc || !fb) 642 return 0; 643 644 ast = to_ast_private(plane->dev); 645 646 ret = ast_cursor_blit(ast, fb); 647 if (ret) 648 return ret; 649 650 return 0; 651 } 652 653 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, 654 struct drm_plane_state *state) 655 { 656 struct drm_framebuffer *fb = state->fb; 657 struct drm_crtc_state *crtc_state; 658 int ret; 659 660 if (!state->crtc) 661 return 0; 662 663 crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); 664 665 ret = drm_atomic_helper_check_plane_state(state, crtc_state, 666 DRM_PLANE_HELPER_NO_SCALING, 667 DRM_PLANE_HELPER_NO_SCALING, 668 true, true); 669 if (ret) 670 return ret; 671 672 if (!state->visible) 673 return 0; 674 675 if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT) 676 return -EINVAL; 677 678 return 0; 679 } 680 681 static void 682 ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, 683 struct drm_plane_state *old_state) 684 { 685 struct drm_plane_state *state = plane->state; 686 struct drm_framebuffer *fb = state->fb; 687 struct ast_private *ast = to_ast_private(plane->dev); 688 unsigned int offset_x, offset_y; 689 690 offset_x = AST_MAX_HWC_WIDTH - fb->width; 691 offset_y = AST_MAX_HWC_WIDTH - fb->height; 692 693 if (state->fb != old_state->fb) { 694 /* A new cursor image was installed. */ 695 ast_cursor_page_flip(ast); 696 } 697 698 ast_cursor_show(ast, state->crtc_x, state->crtc_y, 699 offset_x, offset_y); 700 } 701 702 static void 703 ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane, 704 struct drm_plane_state *old_state) 705 { 706 struct ast_private *ast = to_ast_private(plane->dev); 707 708 ast_cursor_hide(ast); 709 } 710 711 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = { 712 .prepare_fb = ast_cursor_plane_helper_prepare_fb, 713 .cleanup_fb = NULL, /* not required for cursor plane */ 714 .atomic_check = ast_cursor_plane_helper_atomic_check, 715 .atomic_update = ast_cursor_plane_helper_atomic_update, 716 .atomic_disable = ast_cursor_plane_helper_atomic_disable, 717 }; 718 719 static const struct drm_plane_funcs ast_cursor_plane_funcs = { 720 .update_plane = drm_atomic_helper_update_plane, 721 .disable_plane = drm_atomic_helper_disable_plane, 722 .destroy = drm_plane_cleanup, 723 .reset = drm_atomic_helper_plane_reset, 724 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 725 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 726 }; 727 728 /* 729 * CRTC 730 */ 731 732 static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) 733 { 734 struct ast_private *ast = to_ast_private(crtc->dev); 735 736 /* TODO: Maybe control display signal generation with 737 * Sync Enable (bit CR17.7). 738 */ 739 switch (mode) { 740 case DRM_MODE_DPMS_ON: 741 case DRM_MODE_DPMS_STANDBY: 742 case DRM_MODE_DPMS_SUSPEND: 743 if (ast->tx_chip_type == AST_TX_DP501) 744 ast_set_dp501_video_output(crtc->dev, 1); 745 ast_crtc_load_lut(ast, crtc); 746 break; 747 case DRM_MODE_DPMS_OFF: 748 if (ast->tx_chip_type == AST_TX_DP501) 749 ast_set_dp501_video_output(crtc->dev, 0); 750 break; 751 } 752 } 753 754 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, 755 struct drm_crtc_state *state) 756 { 757 struct drm_device *dev = crtc->dev; 758 struct ast_crtc_state *ast_state; 759 const struct drm_format_info *format; 760 bool succ; 761 762 if (!state->enable) 763 return 0; /* no mode checks if CRTC is being disabled */ 764 765 ast_state = to_ast_crtc_state(state); 766 767 format = ast_state->format; 768 if (drm_WARN_ON_ONCE(dev, !format)) 769 return -EINVAL; /* BUG: We didn't set format in primary check(). */ 770 771 succ = ast_get_vbios_mode_info(format, &state->mode, 772 &state->adjusted_mode, 773 &ast_state->vbios_mode_info); 774 if (!succ) 775 return -EINVAL; 776 777 return 0; 778 } 779 780 static void 781 ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, 782 struct drm_crtc_state *old_crtc_state) 783 { 784 struct drm_device *dev = crtc->dev; 785 struct ast_private *ast = to_ast_private(dev); 786 struct drm_crtc_state *crtc_state = crtc->state; 787 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 788 struct ast_vbios_mode_info *vbios_mode_info = 789 &ast_crtc_state->vbios_mode_info; 790 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 791 792 ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); 793 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); 794 ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); 795 ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); 796 ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); 797 ast_set_crtthd_reg(ast); 798 ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info); 799 800 ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 801 } 802 803 static void 804 ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, 805 struct drm_crtc_state *old_crtc_state) 806 { 807 struct drm_device *dev = crtc->dev; 808 struct ast_private *ast = to_ast_private(dev); 809 810 ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 811 812 /* 813 * HW cursors require the underlying primary plane and CRTC to 814 * display a valid mode and image. This is not the case during 815 * full modeset operations. So we temporarily disable any active 816 * plane, including the HW cursor. Each plane's atomic_update() 817 * helper will re-enable it if necessary. 818 * 819 * We only do this during *full* modesets. It does not affect 820 * simple pageflips on the planes. 821 */ 822 drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); 823 824 /* 825 * Ensure that no scanout takes place before reprogramming mode 826 * and format registers. 827 */ 828 ast_wait_for_vretrace(ast); 829 } 830 831 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { 832 .atomic_check = ast_crtc_helper_atomic_check, 833 .atomic_enable = ast_crtc_helper_atomic_enable, 834 .atomic_disable = ast_crtc_helper_atomic_disable, 835 }; 836 837 static void ast_crtc_reset(struct drm_crtc *crtc) 838 { 839 struct ast_crtc_state *ast_state = 840 kzalloc(sizeof(*ast_state), GFP_KERNEL); 841 842 if (crtc->state) 843 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 844 845 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); 846 } 847 848 static struct drm_crtc_state * 849 ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) 850 { 851 struct ast_crtc_state *new_ast_state, *ast_state; 852 struct drm_device *dev = crtc->dev; 853 854 if (drm_WARN_ON(dev, !crtc->state)) 855 return NULL; 856 857 new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); 858 if (!new_ast_state) 859 return NULL; 860 __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base); 861 862 ast_state = to_ast_crtc_state(crtc->state); 863 864 new_ast_state->format = ast_state->format; 865 memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info, 866 sizeof(new_ast_state->vbios_mode_info)); 867 868 return &new_ast_state->base; 869 } 870 871 static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, 872 struct drm_crtc_state *state) 873 { 874 struct ast_crtc_state *ast_state = to_ast_crtc_state(state); 875 876 __drm_atomic_helper_crtc_destroy_state(&ast_state->base); 877 kfree(ast_state); 878 } 879 880 static const struct drm_crtc_funcs ast_crtc_funcs = { 881 .reset = ast_crtc_reset, 882 .gamma_set = drm_atomic_helper_legacy_gamma_set, 883 .destroy = drm_crtc_cleanup, 884 .set_config = drm_atomic_helper_set_config, 885 .page_flip = drm_atomic_helper_page_flip, 886 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state, 887 .atomic_destroy_state = ast_crtc_atomic_destroy_state, 888 }; 889 890 static int ast_crtc_init(struct drm_device *dev) 891 { 892 struct ast_private *ast = to_ast_private(dev); 893 struct drm_crtc *crtc = &ast->crtc; 894 int ret; 895 896 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane, 897 &ast->cursor_plane, &ast_crtc_funcs, 898 NULL); 899 if (ret) 900 return ret; 901 902 drm_mode_crtc_set_gamma_size(crtc, 256); 903 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs); 904 905 return 0; 906 } 907 908 /* 909 * Encoder 910 */ 911 912 static int ast_encoder_init(struct drm_device *dev) 913 { 914 struct ast_private *ast = to_ast_private(dev); 915 struct drm_encoder *encoder = &ast->encoder; 916 int ret; 917 918 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); 919 if (ret) 920 return ret; 921 922 encoder->possible_crtcs = 1; 923 924 return 0; 925 } 926 927 /* 928 * Connector 929 */ 930 931 static int ast_get_modes(struct drm_connector *connector) 932 { 933 struct ast_connector *ast_connector = to_ast_connector(connector); 934 struct ast_private *ast = to_ast_private(connector->dev); 935 struct edid *edid; 936 int ret; 937 bool flags = false; 938 if (ast->tx_chip_type == AST_TX_DP501) { 939 ast->dp501_maxclk = 0xff; 940 edid = kmalloc(128, GFP_KERNEL); 941 if (!edid) 942 return -ENOMEM; 943 944 flags = ast_dp501_read_edid(connector->dev, (u8 *)edid); 945 if (flags) 946 ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev); 947 else 948 kfree(edid); 949 } 950 if (!flags) 951 edid = drm_get_edid(connector, &ast_connector->i2c->adapter); 952 if (edid) { 953 drm_connector_update_edid_property(&ast_connector->base, edid); 954 ret = drm_add_edid_modes(connector, edid); 955 kfree(edid); 956 return ret; 957 } else 958 drm_connector_update_edid_property(&ast_connector->base, NULL); 959 return 0; 960 } 961 962 static enum drm_mode_status ast_mode_valid(struct drm_connector *connector, 963 struct drm_display_mode *mode) 964 { 965 struct ast_private *ast = to_ast_private(connector->dev); 966 int flags = MODE_NOMODE; 967 uint32_t jtemp; 968 969 if (ast->support_wide_screen) { 970 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050)) 971 return MODE_OK; 972 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800)) 973 return MODE_OK; 974 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900)) 975 return MODE_OK; 976 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768)) 977 return MODE_OK; 978 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900)) 979 return MODE_OK; 980 981 if ((ast->chip == AST2100) || (ast->chip == AST2200) || 982 (ast->chip == AST2300) || (ast->chip == AST2400) || 983 (ast->chip == AST2500)) { 984 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) 985 return MODE_OK; 986 987 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { 988 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); 989 if (jtemp & 0x01) 990 return MODE_NOMODE; 991 else 992 return MODE_OK; 993 } 994 } 995 } 996 switch (mode->hdisplay) { 997 case 640: 998 if (mode->vdisplay == 480) flags = MODE_OK; 999 break; 1000 case 800: 1001 if (mode->vdisplay == 600) flags = MODE_OK; 1002 break; 1003 case 1024: 1004 if (mode->vdisplay == 768) flags = MODE_OK; 1005 break; 1006 case 1280: 1007 if (mode->vdisplay == 1024) flags = MODE_OK; 1008 break; 1009 case 1600: 1010 if (mode->vdisplay == 1200) flags = MODE_OK; 1011 break; 1012 default: 1013 return flags; 1014 } 1015 1016 return flags; 1017 } 1018 1019 static void ast_connector_destroy(struct drm_connector *connector) 1020 { 1021 struct ast_connector *ast_connector = to_ast_connector(connector); 1022 ast_i2c_destroy(ast_connector->i2c); 1023 drm_connector_cleanup(connector); 1024 } 1025 1026 static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { 1027 .get_modes = ast_get_modes, 1028 .mode_valid = ast_mode_valid, 1029 }; 1030 1031 static const struct drm_connector_funcs ast_connector_funcs = { 1032 .reset = drm_atomic_helper_connector_reset, 1033 .fill_modes = drm_helper_probe_single_connector_modes, 1034 .destroy = ast_connector_destroy, 1035 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1036 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1037 }; 1038 1039 static int ast_connector_init(struct drm_device *dev) 1040 { 1041 struct ast_private *ast = to_ast_private(dev); 1042 struct ast_connector *ast_connector = &ast->connector; 1043 struct drm_connector *connector = &ast_connector->base; 1044 struct drm_encoder *encoder = &ast->encoder; 1045 1046 ast_connector->i2c = ast_i2c_create(dev); 1047 if (!ast_connector->i2c) 1048 drm_err(dev, "failed to add ddc bus for connector\n"); 1049 1050 drm_connector_init_with_ddc(dev, connector, 1051 &ast_connector_funcs, 1052 DRM_MODE_CONNECTOR_VGA, 1053 &ast_connector->i2c->adapter); 1054 1055 drm_connector_helper_add(connector, &ast_connector_helper_funcs); 1056 1057 connector->interlace_allowed = 0; 1058 connector->doublescan_allowed = 0; 1059 1060 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1061 1062 drm_connector_attach_encoder(connector, encoder); 1063 1064 return 0; 1065 } 1066 1067 /* 1068 * Mode config 1069 */ 1070 1071 static const struct drm_mode_config_helper_funcs 1072 ast_mode_config_helper_funcs = { 1073 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, 1074 }; 1075 1076 static const struct drm_mode_config_funcs ast_mode_config_funcs = { 1077 .fb_create = drm_gem_fb_create, 1078 .mode_valid = drm_vram_helper_mode_valid, 1079 .atomic_check = drm_atomic_helper_check, 1080 .atomic_commit = drm_atomic_helper_commit, 1081 }; 1082 1083 int ast_mode_config_init(struct ast_private *ast) 1084 { 1085 struct drm_device *dev = &ast->base; 1086 int ret; 1087 1088 ret = ast_cursor_init(ast); 1089 if (ret) 1090 return ret; 1091 1092 ret = drmm_mode_config_init(dev); 1093 if (ret) 1094 return ret; 1095 1096 dev->mode_config.funcs = &ast_mode_config_funcs; 1097 dev->mode_config.min_width = 0; 1098 dev->mode_config.min_height = 0; 1099 dev->mode_config.preferred_depth = 24; 1100 dev->mode_config.prefer_shadow = 1; 1101 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0); 1102 1103 if (ast->chip == AST2100 || 1104 ast->chip == AST2200 || 1105 ast->chip == AST2300 || 1106 ast->chip == AST2400 || 1107 ast->chip == AST2500) { 1108 dev->mode_config.max_width = 1920; 1109 dev->mode_config.max_height = 2048; 1110 } else { 1111 dev->mode_config.max_width = 1600; 1112 dev->mode_config.max_height = 1200; 1113 } 1114 1115 dev->mode_config.helper_private = &ast_mode_config_helper_funcs; 1116 1117 memset(&ast->primary_plane, 0, sizeof(ast->primary_plane)); 1118 ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01, 1119 &ast_primary_plane_funcs, 1120 ast_primary_plane_formats, 1121 ARRAY_SIZE(ast_primary_plane_formats), 1122 NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 1123 if (ret) { 1124 drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret); 1125 return ret; 1126 } 1127 drm_plane_helper_add(&ast->primary_plane, 1128 &ast_primary_plane_helper_funcs); 1129 1130 ret = drm_universal_plane_init(dev, &ast->cursor_plane, 0x01, 1131 &ast_cursor_plane_funcs, 1132 ast_cursor_plane_formats, 1133 ARRAY_SIZE(ast_cursor_plane_formats), 1134 NULL, DRM_PLANE_TYPE_CURSOR, NULL); 1135 if (ret) { 1136 drm_err(dev, "drm_universal_plane_failed(): %d\n", ret); 1137 return ret; 1138 } 1139 drm_plane_helper_add(&ast->cursor_plane, 1140 &ast_cursor_plane_helper_funcs); 1141 1142 ast_crtc_init(dev); 1143 ast_encoder_init(dev); 1144 ast_connector_init(dev); 1145 1146 drm_mode_config_reset(dev); 1147 1148 return 0; 1149 } 1150 1151 static int get_clock(void *i2c_priv) 1152 { 1153 struct ast_i2c_chan *i2c = i2c_priv; 1154 struct ast_private *ast = to_ast_private(i2c->dev); 1155 uint32_t val, val2, count, pass; 1156 1157 count = 0; 1158 pass = 0; 1159 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1160 do { 1161 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1162 if (val == val2) { 1163 pass++; 1164 } else { 1165 pass = 0; 1166 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1167 } 1168 } while ((pass < 5) && (count++ < 0x10000)); 1169 1170 return val & 1 ? 1 : 0; 1171 } 1172 1173 static int get_data(void *i2c_priv) 1174 { 1175 struct ast_i2c_chan *i2c = i2c_priv; 1176 struct ast_private *ast = to_ast_private(i2c->dev); 1177 uint32_t val, val2, count, pass; 1178 1179 count = 0; 1180 pass = 0; 1181 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1182 do { 1183 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1184 if (val == val2) { 1185 pass++; 1186 } else { 1187 pass = 0; 1188 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1189 } 1190 } while ((pass < 5) && (count++ < 0x10000)); 1191 1192 return val & 1 ? 1 : 0; 1193 } 1194 1195 static void set_clock(void *i2c_priv, int clock) 1196 { 1197 struct ast_i2c_chan *i2c = i2c_priv; 1198 struct ast_private *ast = to_ast_private(i2c->dev); 1199 int i; 1200 u8 ujcrb7, jtemp; 1201 1202 for (i = 0; i < 0x10000; i++) { 1203 ujcrb7 = ((clock & 0x01) ? 0 : 1); 1204 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); 1205 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); 1206 if (ujcrb7 == jtemp) 1207 break; 1208 } 1209 } 1210 1211 static void set_data(void *i2c_priv, int data) 1212 { 1213 struct ast_i2c_chan *i2c = i2c_priv; 1214 struct ast_private *ast = to_ast_private(i2c->dev); 1215 int i; 1216 u8 ujcrb7, jtemp; 1217 1218 for (i = 0; i < 0x10000; i++) { 1219 ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; 1220 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); 1221 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); 1222 if (ujcrb7 == jtemp) 1223 break; 1224 } 1225 } 1226 1227 static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev) 1228 { 1229 struct ast_i2c_chan *i2c; 1230 int ret; 1231 1232 i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL); 1233 if (!i2c) 1234 return NULL; 1235 1236 i2c->adapter.owner = THIS_MODULE; 1237 i2c->adapter.class = I2C_CLASS_DDC; 1238 i2c->adapter.dev.parent = &dev->pdev->dev; 1239 i2c->dev = dev; 1240 i2c_set_adapdata(&i2c->adapter, i2c); 1241 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), 1242 "AST i2c bit bus"); 1243 i2c->adapter.algo_data = &i2c->bit; 1244 1245 i2c->bit.udelay = 20; 1246 i2c->bit.timeout = 2; 1247 i2c->bit.data = i2c; 1248 i2c->bit.setsda = set_data; 1249 i2c->bit.setscl = set_clock; 1250 i2c->bit.getsda = get_data; 1251 i2c->bit.getscl = get_clock; 1252 ret = i2c_bit_add_bus(&i2c->adapter); 1253 if (ret) { 1254 drm_err(dev, "Failed to register bit i2c\n"); 1255 goto out_free; 1256 } 1257 1258 return i2c; 1259 out_free: 1260 kfree(i2c); 1261 return NULL; 1262 } 1263 1264 static void ast_i2c_destroy(struct ast_i2c_chan *i2c) 1265 { 1266 if (!i2c) 1267 return; 1268 i2c_del_adapter(&i2c->adapter); 1269 kfree(i2c); 1270 } 1271