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