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