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 break; 746 case DRM_MODE_DPMS_OFF: 747 if (ast->tx_chip_type == AST_TX_DP501) 748 ast_set_dp501_video_output(crtc->dev, 0); 749 break; 750 } 751 } 752 753 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, 754 struct drm_crtc_state *state) 755 { 756 struct drm_device *dev = crtc->dev; 757 struct ast_crtc_state *ast_state; 758 const struct drm_format_info *format; 759 bool succ; 760 761 if (!state->enable) 762 return 0; /* no mode checks if CRTC is being disabled */ 763 764 ast_state = to_ast_crtc_state(state); 765 766 format = ast_state->format; 767 if (drm_WARN_ON_ONCE(dev, !format)) 768 return -EINVAL; /* BUG: We didn't set format in primary check(). */ 769 770 succ = ast_get_vbios_mode_info(format, &state->mode, 771 &state->adjusted_mode, 772 &ast_state->vbios_mode_info); 773 if (!succ) 774 return -EINVAL; 775 776 return 0; 777 } 778 779 static void 780 ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) 781 { 782 struct ast_private *ast = to_ast_private(crtc->dev); 783 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc->state); 784 struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state); 785 786 /* 787 * The gamma LUT has to be reloaded after changing the primary 788 * plane's color format. 789 */ 790 if (old_ast_crtc_state->format != ast_crtc_state->format) 791 ast_crtc_load_lut(ast, crtc); 792 } 793 794 static void 795 ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, 796 struct drm_crtc_state *old_crtc_state) 797 { 798 struct drm_device *dev = crtc->dev; 799 struct ast_private *ast = to_ast_private(dev); 800 struct drm_crtc_state *crtc_state = crtc->state; 801 struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc_state); 802 struct ast_vbios_mode_info *vbios_mode_info = 803 &ast_crtc_state->vbios_mode_info; 804 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 805 806 ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); 807 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); 808 ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); 809 ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); 810 ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); 811 ast_set_crtthd_reg(ast); 812 ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info); 813 814 ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 815 } 816 817 static void 818 ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, 819 struct drm_crtc_state *old_crtc_state) 820 { 821 struct drm_device *dev = crtc->dev; 822 struct ast_private *ast = to_ast_private(dev); 823 824 ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 825 826 /* 827 * HW cursors require the underlying primary plane and CRTC to 828 * display a valid mode and image. This is not the case during 829 * full modeset operations. So we temporarily disable any active 830 * plane, including the HW cursor. Each plane's atomic_update() 831 * helper will re-enable it if necessary. 832 * 833 * We only do this during *full* modesets. It does not affect 834 * simple pageflips on the planes. 835 */ 836 drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); 837 838 /* 839 * Ensure that no scanout takes place before reprogramming mode 840 * and format registers. 841 */ 842 ast_wait_for_vretrace(ast); 843 } 844 845 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { 846 .atomic_check = ast_crtc_helper_atomic_check, 847 .atomic_flush = ast_crtc_helper_atomic_flush, 848 .atomic_enable = ast_crtc_helper_atomic_enable, 849 .atomic_disable = ast_crtc_helper_atomic_disable, 850 }; 851 852 static void ast_crtc_reset(struct drm_crtc *crtc) 853 { 854 struct ast_crtc_state *ast_state = 855 kzalloc(sizeof(*ast_state), GFP_KERNEL); 856 857 if (crtc->state) 858 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 859 860 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); 861 } 862 863 static struct drm_crtc_state * 864 ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) 865 { 866 struct ast_crtc_state *new_ast_state, *ast_state; 867 struct drm_device *dev = crtc->dev; 868 869 if (drm_WARN_ON(dev, !crtc->state)) 870 return NULL; 871 872 new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); 873 if (!new_ast_state) 874 return NULL; 875 __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base); 876 877 ast_state = to_ast_crtc_state(crtc->state); 878 879 new_ast_state->format = ast_state->format; 880 memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info, 881 sizeof(new_ast_state->vbios_mode_info)); 882 883 return &new_ast_state->base; 884 } 885 886 static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, 887 struct drm_crtc_state *state) 888 { 889 struct ast_crtc_state *ast_state = to_ast_crtc_state(state); 890 891 __drm_atomic_helper_crtc_destroy_state(&ast_state->base); 892 kfree(ast_state); 893 } 894 895 static const struct drm_crtc_funcs ast_crtc_funcs = { 896 .reset = ast_crtc_reset, 897 .gamma_set = drm_atomic_helper_legacy_gamma_set, 898 .destroy = drm_crtc_cleanup, 899 .set_config = drm_atomic_helper_set_config, 900 .page_flip = drm_atomic_helper_page_flip, 901 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state, 902 .atomic_destroy_state = ast_crtc_atomic_destroy_state, 903 }; 904 905 static int ast_crtc_init(struct drm_device *dev) 906 { 907 struct ast_private *ast = to_ast_private(dev); 908 struct drm_crtc *crtc = &ast->crtc; 909 int ret; 910 911 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane, 912 &ast->cursor_plane, &ast_crtc_funcs, 913 NULL); 914 if (ret) 915 return ret; 916 917 drm_mode_crtc_set_gamma_size(crtc, 256); 918 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs); 919 920 return 0; 921 } 922 923 /* 924 * Encoder 925 */ 926 927 static int ast_encoder_init(struct drm_device *dev) 928 { 929 struct ast_private *ast = to_ast_private(dev); 930 struct drm_encoder *encoder = &ast->encoder; 931 int ret; 932 933 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); 934 if (ret) 935 return ret; 936 937 encoder->possible_crtcs = 1; 938 939 return 0; 940 } 941 942 /* 943 * Connector 944 */ 945 946 static int ast_get_modes(struct drm_connector *connector) 947 { 948 struct ast_connector *ast_connector = to_ast_connector(connector); 949 struct ast_private *ast = to_ast_private(connector->dev); 950 struct edid *edid; 951 int ret; 952 bool flags = false; 953 if (ast->tx_chip_type == AST_TX_DP501) { 954 ast->dp501_maxclk = 0xff; 955 edid = kmalloc(128, GFP_KERNEL); 956 if (!edid) 957 return -ENOMEM; 958 959 flags = ast_dp501_read_edid(connector->dev, (u8 *)edid); 960 if (flags) 961 ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev); 962 else 963 kfree(edid); 964 } 965 if (!flags) 966 edid = drm_get_edid(connector, &ast_connector->i2c->adapter); 967 if (edid) { 968 drm_connector_update_edid_property(&ast_connector->base, edid); 969 ret = drm_add_edid_modes(connector, edid); 970 kfree(edid); 971 return ret; 972 } else 973 drm_connector_update_edid_property(&ast_connector->base, NULL); 974 return 0; 975 } 976 977 static enum drm_mode_status ast_mode_valid(struct drm_connector *connector, 978 struct drm_display_mode *mode) 979 { 980 struct ast_private *ast = to_ast_private(connector->dev); 981 int flags = MODE_NOMODE; 982 uint32_t jtemp; 983 984 if (ast->support_wide_screen) { 985 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050)) 986 return MODE_OK; 987 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800)) 988 return MODE_OK; 989 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900)) 990 return MODE_OK; 991 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768)) 992 return MODE_OK; 993 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900)) 994 return MODE_OK; 995 996 if ((ast->chip == AST2100) || (ast->chip == AST2200) || 997 (ast->chip == AST2300) || (ast->chip == AST2400) || 998 (ast->chip == AST2500)) { 999 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) 1000 return MODE_OK; 1001 1002 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { 1003 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); 1004 if (jtemp & 0x01) 1005 return MODE_NOMODE; 1006 else 1007 return MODE_OK; 1008 } 1009 } 1010 } 1011 switch (mode->hdisplay) { 1012 case 640: 1013 if (mode->vdisplay == 480) flags = MODE_OK; 1014 break; 1015 case 800: 1016 if (mode->vdisplay == 600) flags = MODE_OK; 1017 break; 1018 case 1024: 1019 if (mode->vdisplay == 768) flags = MODE_OK; 1020 break; 1021 case 1280: 1022 if (mode->vdisplay == 1024) flags = MODE_OK; 1023 break; 1024 case 1600: 1025 if (mode->vdisplay == 1200) flags = MODE_OK; 1026 break; 1027 default: 1028 return flags; 1029 } 1030 1031 return flags; 1032 } 1033 1034 static void ast_connector_destroy(struct drm_connector *connector) 1035 { 1036 struct ast_connector *ast_connector = to_ast_connector(connector); 1037 ast_i2c_destroy(ast_connector->i2c); 1038 drm_connector_cleanup(connector); 1039 } 1040 1041 static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { 1042 .get_modes = ast_get_modes, 1043 .mode_valid = ast_mode_valid, 1044 }; 1045 1046 static const struct drm_connector_funcs ast_connector_funcs = { 1047 .reset = drm_atomic_helper_connector_reset, 1048 .fill_modes = drm_helper_probe_single_connector_modes, 1049 .destroy = ast_connector_destroy, 1050 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1051 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1052 }; 1053 1054 static int ast_connector_init(struct drm_device *dev) 1055 { 1056 struct ast_private *ast = to_ast_private(dev); 1057 struct ast_connector *ast_connector = &ast->connector; 1058 struct drm_connector *connector = &ast_connector->base; 1059 struct drm_encoder *encoder = &ast->encoder; 1060 1061 ast_connector->i2c = ast_i2c_create(dev); 1062 if (!ast_connector->i2c) 1063 drm_err(dev, "failed to add ddc bus for connector\n"); 1064 1065 drm_connector_init_with_ddc(dev, connector, 1066 &ast_connector_funcs, 1067 DRM_MODE_CONNECTOR_VGA, 1068 &ast_connector->i2c->adapter); 1069 1070 drm_connector_helper_add(connector, &ast_connector_helper_funcs); 1071 1072 connector->interlace_allowed = 0; 1073 connector->doublescan_allowed = 0; 1074 1075 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1076 1077 drm_connector_attach_encoder(connector, encoder); 1078 1079 return 0; 1080 } 1081 1082 /* 1083 * Mode config 1084 */ 1085 1086 static const struct drm_mode_config_helper_funcs 1087 ast_mode_config_helper_funcs = { 1088 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, 1089 }; 1090 1091 static const struct drm_mode_config_funcs ast_mode_config_funcs = { 1092 .fb_create = drm_gem_fb_create, 1093 .mode_valid = drm_vram_helper_mode_valid, 1094 .atomic_check = drm_atomic_helper_check, 1095 .atomic_commit = drm_atomic_helper_commit, 1096 }; 1097 1098 int ast_mode_config_init(struct ast_private *ast) 1099 { 1100 struct drm_device *dev = &ast->base; 1101 int ret; 1102 1103 ret = ast_cursor_init(ast); 1104 if (ret) 1105 return ret; 1106 1107 ret = drmm_mode_config_init(dev); 1108 if (ret) 1109 return ret; 1110 1111 dev->mode_config.funcs = &ast_mode_config_funcs; 1112 dev->mode_config.min_width = 0; 1113 dev->mode_config.min_height = 0; 1114 dev->mode_config.preferred_depth = 24; 1115 dev->mode_config.prefer_shadow = 1; 1116 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0); 1117 1118 if (ast->chip == AST2100 || 1119 ast->chip == AST2200 || 1120 ast->chip == AST2300 || 1121 ast->chip == AST2400 || 1122 ast->chip == AST2500) { 1123 dev->mode_config.max_width = 1920; 1124 dev->mode_config.max_height = 2048; 1125 } else { 1126 dev->mode_config.max_width = 1600; 1127 dev->mode_config.max_height = 1200; 1128 } 1129 1130 dev->mode_config.helper_private = &ast_mode_config_helper_funcs; 1131 1132 memset(&ast->primary_plane, 0, sizeof(ast->primary_plane)); 1133 ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01, 1134 &ast_primary_plane_funcs, 1135 ast_primary_plane_formats, 1136 ARRAY_SIZE(ast_primary_plane_formats), 1137 NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 1138 if (ret) { 1139 drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret); 1140 return ret; 1141 } 1142 drm_plane_helper_add(&ast->primary_plane, 1143 &ast_primary_plane_helper_funcs); 1144 1145 ret = drm_universal_plane_init(dev, &ast->cursor_plane, 0x01, 1146 &ast_cursor_plane_funcs, 1147 ast_cursor_plane_formats, 1148 ARRAY_SIZE(ast_cursor_plane_formats), 1149 NULL, DRM_PLANE_TYPE_CURSOR, NULL); 1150 if (ret) { 1151 drm_err(dev, "drm_universal_plane_failed(): %d\n", ret); 1152 return ret; 1153 } 1154 drm_plane_helper_add(&ast->cursor_plane, 1155 &ast_cursor_plane_helper_funcs); 1156 1157 ast_crtc_init(dev); 1158 ast_encoder_init(dev); 1159 ast_connector_init(dev); 1160 1161 drm_mode_config_reset(dev); 1162 1163 return 0; 1164 } 1165 1166 static int get_clock(void *i2c_priv) 1167 { 1168 struct ast_i2c_chan *i2c = i2c_priv; 1169 struct ast_private *ast = to_ast_private(i2c->dev); 1170 uint32_t val, val2, count, pass; 1171 1172 count = 0; 1173 pass = 0; 1174 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1175 do { 1176 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1177 if (val == val2) { 1178 pass++; 1179 } else { 1180 pass = 0; 1181 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1182 } 1183 } while ((pass < 5) && (count++ < 0x10000)); 1184 1185 return val & 1 ? 1 : 0; 1186 } 1187 1188 static int get_data(void *i2c_priv) 1189 { 1190 struct ast_i2c_chan *i2c = i2c_priv; 1191 struct ast_private *ast = to_ast_private(i2c->dev); 1192 uint32_t val, val2, count, pass; 1193 1194 count = 0; 1195 pass = 0; 1196 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1197 do { 1198 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1199 if (val == val2) { 1200 pass++; 1201 } else { 1202 pass = 0; 1203 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1204 } 1205 } while ((pass < 5) && (count++ < 0x10000)); 1206 1207 return val & 1 ? 1 : 0; 1208 } 1209 1210 static void set_clock(void *i2c_priv, int clock) 1211 { 1212 struct ast_i2c_chan *i2c = i2c_priv; 1213 struct ast_private *ast = to_ast_private(i2c->dev); 1214 int i; 1215 u8 ujcrb7, jtemp; 1216 1217 for (i = 0; i < 0x10000; i++) { 1218 ujcrb7 = ((clock & 0x01) ? 0 : 1); 1219 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); 1220 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); 1221 if (ujcrb7 == jtemp) 1222 break; 1223 } 1224 } 1225 1226 static void set_data(void *i2c_priv, int data) 1227 { 1228 struct ast_i2c_chan *i2c = i2c_priv; 1229 struct ast_private *ast = to_ast_private(i2c->dev); 1230 int i; 1231 u8 ujcrb7, jtemp; 1232 1233 for (i = 0; i < 0x10000; i++) { 1234 ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; 1235 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); 1236 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); 1237 if (ujcrb7 == jtemp) 1238 break; 1239 } 1240 } 1241 1242 static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev) 1243 { 1244 struct ast_i2c_chan *i2c; 1245 int ret; 1246 1247 i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL); 1248 if (!i2c) 1249 return NULL; 1250 1251 i2c->adapter.owner = THIS_MODULE; 1252 i2c->adapter.class = I2C_CLASS_DDC; 1253 i2c->adapter.dev.parent = &dev->pdev->dev; 1254 i2c->dev = dev; 1255 i2c_set_adapdata(&i2c->adapter, i2c); 1256 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), 1257 "AST i2c bit bus"); 1258 i2c->adapter.algo_data = &i2c->bit; 1259 1260 i2c->bit.udelay = 20; 1261 i2c->bit.timeout = 2; 1262 i2c->bit.data = i2c; 1263 i2c->bit.setsda = set_data; 1264 i2c->bit.setscl = set_clock; 1265 i2c->bit.getsda = get_data; 1266 i2c->bit.getscl = get_clock; 1267 ret = i2c_bit_add_bus(&i2c->adapter); 1268 if (ret) { 1269 drm_err(dev, "Failed to register bit i2c\n"); 1270 goto out_free; 1271 } 1272 1273 return i2c; 1274 out_free: 1275 kfree(i2c); 1276 return NULL; 1277 } 1278 1279 static void ast_i2c_destroy(struct ast_i2c_chan *i2c) 1280 { 1281 if (!i2c) 1282 return; 1283 i2c_del_adapter(&i2c->adapter); 1284 kfree(i2c); 1285 } 1286