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 /* 518 * Primary plane 519 */ 520 521 static const uint32_t ast_primary_plane_formats[] = { 522 DRM_FORMAT_XRGB8888, 523 DRM_FORMAT_RGB565, 524 DRM_FORMAT_C8, 525 }; 526 527 static int ast_primary_plane_helper_atomic_check(struct drm_plane *plane, 528 struct drm_plane_state *state) 529 { 530 struct drm_crtc_state *crtc_state; 531 struct ast_crtc_state *ast_crtc_state; 532 int ret; 533 534 if (!state->crtc) 535 return 0; 536 537 crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); 538 539 ret = drm_atomic_helper_check_plane_state(state, crtc_state, 540 DRM_PLANE_HELPER_NO_SCALING, 541 DRM_PLANE_HELPER_NO_SCALING, 542 false, true); 543 if (ret) 544 return ret; 545 546 if (!state->visible) 547 return 0; 548 549 ast_crtc_state = to_ast_crtc_state(crtc_state); 550 551 ast_crtc_state->format = state->fb->format; 552 553 return 0; 554 } 555 556 static void 557 ast_primary_plane_helper_atomic_update(struct drm_plane *plane, 558 struct drm_plane_state *old_state) 559 { 560 struct drm_device *dev = plane->dev; 561 struct ast_private *ast = to_ast_private(dev); 562 struct drm_plane_state *state = plane->state; 563 struct drm_gem_vram_object *gbo; 564 s64 gpu_addr; 565 566 gbo = drm_gem_vram_of_gem(state->fb->obj[0]); 567 gpu_addr = drm_gem_vram_offset(gbo); 568 if (drm_WARN_ON_ONCE(dev, gpu_addr < 0)) 569 return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */ 570 571 ast_set_offset_reg(ast, state->fb); 572 ast_set_start_address_crt1(ast, (u32)gpu_addr); 573 574 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00); 575 } 576 577 static void 578 ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, 579 struct drm_plane_state *old_state) 580 { 581 struct ast_private *ast = to_ast_private(plane->dev); 582 583 ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); 584 } 585 586 static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { 587 .prepare_fb = drm_gem_vram_plane_helper_prepare_fb, 588 .cleanup_fb = drm_gem_vram_plane_helper_cleanup_fb, 589 .atomic_check = ast_primary_plane_helper_atomic_check, 590 .atomic_update = ast_primary_plane_helper_atomic_update, 591 .atomic_disable = ast_primary_plane_helper_atomic_disable, 592 }; 593 594 static const struct drm_plane_funcs ast_primary_plane_funcs = { 595 .update_plane = drm_atomic_helper_update_plane, 596 .disable_plane = drm_atomic_helper_disable_plane, 597 .destroy = drm_plane_cleanup, 598 .reset = drm_atomic_helper_plane_reset, 599 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 600 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 601 }; 602 603 /* 604 * Cursor plane 605 */ 606 607 static const uint32_t ast_cursor_plane_formats[] = { 608 DRM_FORMAT_ARGB8888, 609 }; 610 611 static int 612 ast_cursor_plane_helper_prepare_fb(struct drm_plane *plane, 613 struct drm_plane_state *new_state) 614 { 615 struct drm_framebuffer *fb = new_state->fb; 616 struct drm_crtc *crtc = new_state->crtc; 617 struct ast_private *ast; 618 int ret; 619 620 if (!crtc || !fb) 621 return 0; 622 623 ast = to_ast_private(plane->dev); 624 625 ret = ast_cursor_blit(ast, fb); 626 if (ret) 627 return ret; 628 629 return 0; 630 } 631 632 static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, 633 struct drm_plane_state *state) 634 { 635 struct drm_framebuffer *fb = state->fb; 636 struct drm_crtc_state *crtc_state; 637 int ret; 638 639 if (!state->crtc) 640 return 0; 641 642 crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc); 643 644 ret = drm_atomic_helper_check_plane_state(state, crtc_state, 645 DRM_PLANE_HELPER_NO_SCALING, 646 DRM_PLANE_HELPER_NO_SCALING, 647 true, true); 648 if (ret) 649 return ret; 650 651 if (!state->visible) 652 return 0; 653 654 if (fb->width > AST_MAX_HWC_WIDTH || fb->height > AST_MAX_HWC_HEIGHT) 655 return -EINVAL; 656 657 return 0; 658 } 659 660 static void 661 ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, 662 struct drm_plane_state *old_state) 663 { 664 struct drm_plane_state *state = plane->state; 665 struct drm_framebuffer *fb = state->fb; 666 struct ast_private *ast = plane->dev->dev_private; 667 unsigned int offset_x, offset_y; 668 669 offset_x = AST_MAX_HWC_WIDTH - fb->width; 670 offset_y = AST_MAX_HWC_WIDTH - fb->height; 671 672 if (state->fb != old_state->fb) { 673 /* A new cursor image was installed. */ 674 ast_cursor_page_flip(ast); 675 } 676 677 ast_cursor_show(ast, state->crtc_x, state->crtc_y, 678 offset_x, offset_y); 679 } 680 681 static void 682 ast_cursor_plane_helper_atomic_disable(struct drm_plane *plane, 683 struct drm_plane_state *old_state) 684 { 685 struct ast_private *ast = to_ast_private(plane->dev); 686 687 ast_cursor_hide(ast); 688 } 689 690 static const struct drm_plane_helper_funcs ast_cursor_plane_helper_funcs = { 691 .prepare_fb = ast_cursor_plane_helper_prepare_fb, 692 .cleanup_fb = NULL, /* not required for cursor plane */ 693 .atomic_check = ast_cursor_plane_helper_atomic_check, 694 .atomic_update = ast_cursor_plane_helper_atomic_update, 695 .atomic_disable = ast_cursor_plane_helper_atomic_disable, 696 }; 697 698 static const struct drm_plane_funcs ast_cursor_plane_funcs = { 699 .update_plane = drm_atomic_helper_update_plane, 700 .disable_plane = drm_atomic_helper_disable_plane, 701 .destroy = drm_plane_cleanup, 702 .reset = drm_atomic_helper_plane_reset, 703 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, 704 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, 705 }; 706 707 /* 708 * CRTC 709 */ 710 711 static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) 712 { 713 struct ast_private *ast = to_ast_private(crtc->dev); 714 715 /* TODO: Maybe control display signal generation with 716 * Sync Enable (bit CR17.7). 717 */ 718 switch (mode) { 719 case DRM_MODE_DPMS_ON: 720 case DRM_MODE_DPMS_STANDBY: 721 case DRM_MODE_DPMS_SUSPEND: 722 if (ast->tx_chip_type == AST_TX_DP501) 723 ast_set_dp501_video_output(crtc->dev, 1); 724 ast_crtc_load_lut(ast, crtc); 725 break; 726 case DRM_MODE_DPMS_OFF: 727 if (ast->tx_chip_type == AST_TX_DP501) 728 ast_set_dp501_video_output(crtc->dev, 0); 729 break; 730 } 731 } 732 733 static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc, 734 struct drm_crtc_state *state) 735 { 736 struct ast_crtc_state *ast_state; 737 const struct drm_format_info *format; 738 bool succ; 739 740 if (!state->enable) 741 return 0; /* no mode checks if CRTC is being disabled */ 742 743 ast_state = to_ast_crtc_state(state); 744 745 format = ast_state->format; 746 if (!format) 747 return 0; 748 749 succ = ast_get_vbios_mode_info(format, &state->mode, 750 &state->adjusted_mode, 751 &ast_state->vbios_mode_info); 752 if (!succ) 753 return -EINVAL; 754 755 return 0; 756 } 757 758 static void ast_crtc_helper_atomic_begin(struct drm_crtc *crtc, 759 struct drm_crtc_state *old_crtc_state) 760 { 761 struct ast_private *ast = to_ast_private(crtc->dev); 762 763 ast_open_key(ast); 764 } 765 766 static void ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, 767 struct drm_crtc_state *old_crtc_state) 768 { 769 struct drm_device *dev = crtc->dev; 770 struct ast_private *ast = to_ast_private(dev); 771 struct ast_crtc_state *ast_state; 772 const struct drm_format_info *format; 773 struct ast_vbios_mode_info *vbios_mode_info; 774 struct drm_display_mode *adjusted_mode; 775 776 ast_state = to_ast_crtc_state(crtc->state); 777 778 format = ast_state->format; 779 if (!format) 780 return; 781 782 vbios_mode_info = &ast_state->vbios_mode_info; 783 784 ast_set_color_reg(ast, format); 785 ast_set_vbios_color_reg(ast, format, vbios_mode_info); 786 787 if (!crtc->state->mode_changed) 788 return; 789 790 adjusted_mode = &crtc->state->adjusted_mode; 791 792 ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); 793 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); 794 ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); 795 ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); 796 ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); 797 ast_set_crtthd_reg(ast); 798 ast_set_sync_reg(ast, adjusted_mode, vbios_mode_info); 799 } 800 801 static void 802 ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, 803 struct drm_crtc_state *old_crtc_state) 804 { 805 ast_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 806 } 807 808 static void 809 ast_crtc_helper_atomic_disable(struct drm_crtc *crtc, 810 struct drm_crtc_state *old_crtc_state) 811 { 812 ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 813 } 814 815 static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { 816 .atomic_check = ast_crtc_helper_atomic_check, 817 .atomic_begin = ast_crtc_helper_atomic_begin, 818 .atomic_flush = ast_crtc_helper_atomic_flush, 819 .atomic_enable = ast_crtc_helper_atomic_enable, 820 .atomic_disable = ast_crtc_helper_atomic_disable, 821 }; 822 823 static void ast_crtc_reset(struct drm_crtc *crtc) 824 { 825 struct ast_crtc_state *ast_state = 826 kzalloc(sizeof(*ast_state), GFP_KERNEL); 827 828 if (crtc->state) 829 crtc->funcs->atomic_destroy_state(crtc, crtc->state); 830 831 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base); 832 } 833 834 static void ast_crtc_destroy(struct drm_crtc *crtc) 835 { 836 drm_crtc_cleanup(crtc); 837 kfree(crtc); 838 } 839 840 static struct drm_crtc_state * 841 ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) 842 { 843 struct ast_crtc_state *new_ast_state, *ast_state; 844 struct drm_device *dev = crtc->dev; 845 846 if (drm_WARN_ON(dev, !crtc->state)) 847 return NULL; 848 849 new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); 850 if (!new_ast_state) 851 return NULL; 852 __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base); 853 854 ast_state = to_ast_crtc_state(crtc->state); 855 856 new_ast_state->format = ast_state->format; 857 memcpy(&new_ast_state->vbios_mode_info, &ast_state->vbios_mode_info, 858 sizeof(new_ast_state->vbios_mode_info)); 859 860 return &new_ast_state->base; 861 } 862 863 static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, 864 struct drm_crtc_state *state) 865 { 866 struct ast_crtc_state *ast_state = to_ast_crtc_state(state); 867 868 __drm_atomic_helper_crtc_destroy_state(&ast_state->base); 869 kfree(ast_state); 870 } 871 872 static const struct drm_crtc_funcs ast_crtc_funcs = { 873 .reset = ast_crtc_reset, 874 .gamma_set = drm_atomic_helper_legacy_gamma_set, 875 .destroy = ast_crtc_destroy, 876 .set_config = drm_atomic_helper_set_config, 877 .page_flip = drm_atomic_helper_page_flip, 878 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state, 879 .atomic_destroy_state = ast_crtc_atomic_destroy_state, 880 }; 881 882 static int ast_crtc_init(struct drm_device *dev) 883 { 884 struct ast_private *ast = to_ast_private(dev); 885 struct drm_crtc *crtc; 886 int ret; 887 888 crtc = kzalloc(sizeof(*crtc), GFP_KERNEL); 889 if (!crtc) 890 return -ENOMEM; 891 892 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane, 893 &ast->cursor_plane, &ast_crtc_funcs, 894 NULL); 895 if (ret) 896 goto err_kfree; 897 898 drm_mode_crtc_set_gamma_size(crtc, 256); 899 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs); 900 901 return 0; 902 903 err_kfree: 904 kfree(crtc); 905 return ret; 906 } 907 908 /* 909 * Encoder 910 */ 911 912 static int ast_encoder_init(struct drm_device *dev) 913 { 914 struct ast_private *ast = to_ast_private(dev); 915 struct drm_encoder *encoder = &ast->encoder; 916 int ret; 917 918 ret = drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); 919 if (ret) 920 return ret; 921 922 encoder->possible_crtcs = 1; 923 924 return 0; 925 } 926 927 /* 928 * Connector 929 */ 930 931 static int ast_get_modes(struct drm_connector *connector) 932 { 933 struct ast_connector *ast_connector = to_ast_connector(connector); 934 struct ast_private *ast = to_ast_private(connector->dev); 935 struct edid *edid; 936 int ret; 937 bool flags = false; 938 if (ast->tx_chip_type == AST_TX_DP501) { 939 ast->dp501_maxclk = 0xff; 940 edid = kmalloc(128, GFP_KERNEL); 941 if (!edid) 942 return -ENOMEM; 943 944 flags = ast_dp501_read_edid(connector->dev, (u8 *)edid); 945 if (flags) 946 ast->dp501_maxclk = ast_get_dp501_max_clk(connector->dev); 947 else 948 kfree(edid); 949 } 950 if (!flags) 951 edid = drm_get_edid(connector, &ast_connector->i2c->adapter); 952 if (edid) { 953 drm_connector_update_edid_property(&ast_connector->base, edid); 954 ret = drm_add_edid_modes(connector, edid); 955 kfree(edid); 956 return ret; 957 } else 958 drm_connector_update_edid_property(&ast_connector->base, NULL); 959 return 0; 960 } 961 962 static enum drm_mode_status ast_mode_valid(struct drm_connector *connector, 963 struct drm_display_mode *mode) 964 { 965 struct ast_private *ast = to_ast_private(connector->dev); 966 int flags = MODE_NOMODE; 967 uint32_t jtemp; 968 969 if (ast->support_wide_screen) { 970 if ((mode->hdisplay == 1680) && (mode->vdisplay == 1050)) 971 return MODE_OK; 972 if ((mode->hdisplay == 1280) && (mode->vdisplay == 800)) 973 return MODE_OK; 974 if ((mode->hdisplay == 1440) && (mode->vdisplay == 900)) 975 return MODE_OK; 976 if ((mode->hdisplay == 1360) && (mode->vdisplay == 768)) 977 return MODE_OK; 978 if ((mode->hdisplay == 1600) && (mode->vdisplay == 900)) 979 return MODE_OK; 980 981 if ((ast->chip == AST2100) || (ast->chip == AST2200) || 982 (ast->chip == AST2300) || (ast->chip == AST2400) || 983 (ast->chip == AST2500)) { 984 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1080)) 985 return MODE_OK; 986 987 if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { 988 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); 989 if (jtemp & 0x01) 990 return MODE_NOMODE; 991 else 992 return MODE_OK; 993 } 994 } 995 } 996 switch (mode->hdisplay) { 997 case 640: 998 if (mode->vdisplay == 480) flags = MODE_OK; 999 break; 1000 case 800: 1001 if (mode->vdisplay == 600) flags = MODE_OK; 1002 break; 1003 case 1024: 1004 if (mode->vdisplay == 768) flags = MODE_OK; 1005 break; 1006 case 1280: 1007 if (mode->vdisplay == 1024) flags = MODE_OK; 1008 break; 1009 case 1600: 1010 if (mode->vdisplay == 1200) flags = MODE_OK; 1011 break; 1012 default: 1013 return flags; 1014 } 1015 1016 return flags; 1017 } 1018 1019 static void ast_connector_destroy(struct drm_connector *connector) 1020 { 1021 struct ast_connector *ast_connector = to_ast_connector(connector); 1022 ast_i2c_destroy(ast_connector->i2c); 1023 drm_connector_cleanup(connector); 1024 kfree(connector); 1025 } 1026 1027 static const struct drm_connector_helper_funcs ast_connector_helper_funcs = { 1028 .get_modes = ast_get_modes, 1029 .mode_valid = ast_mode_valid, 1030 }; 1031 1032 static const struct drm_connector_funcs ast_connector_funcs = { 1033 .reset = drm_atomic_helper_connector_reset, 1034 .fill_modes = drm_helper_probe_single_connector_modes, 1035 .destroy = ast_connector_destroy, 1036 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1037 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1038 }; 1039 1040 static int ast_connector_init(struct drm_device *dev) 1041 { 1042 struct ast_connector *ast_connector; 1043 struct drm_connector *connector; 1044 struct drm_encoder *encoder; 1045 1046 ast_connector = kzalloc(sizeof(struct ast_connector), GFP_KERNEL); 1047 if (!ast_connector) 1048 return -ENOMEM; 1049 1050 connector = &ast_connector->base; 1051 ast_connector->i2c = ast_i2c_create(dev); 1052 if (!ast_connector->i2c) 1053 drm_err(dev, "failed to add ddc bus for connector\n"); 1054 1055 drm_connector_init_with_ddc(dev, connector, 1056 &ast_connector_funcs, 1057 DRM_MODE_CONNECTOR_VGA, 1058 &ast_connector->i2c->adapter); 1059 1060 drm_connector_helper_add(connector, &ast_connector_helper_funcs); 1061 1062 connector->interlace_allowed = 0; 1063 connector->doublescan_allowed = 0; 1064 1065 connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1066 1067 encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head); 1068 drm_connector_attach_encoder(connector, encoder); 1069 1070 return 0; 1071 } 1072 1073 /* 1074 * Mode config 1075 */ 1076 1077 static const struct drm_mode_config_funcs ast_mode_config_funcs = { 1078 .fb_create = drm_gem_fb_create, 1079 .mode_valid = drm_vram_helper_mode_valid, 1080 .atomic_check = drm_atomic_helper_check, 1081 .atomic_commit = drm_atomic_helper_commit, 1082 }; 1083 1084 int ast_mode_config_init(struct ast_private *ast) 1085 { 1086 struct drm_device *dev = ast->dev; 1087 int ret; 1088 1089 ret = ast_cursor_init(ast); 1090 if (ret) 1091 return ret; 1092 1093 ret = drmm_mode_config_init(dev); 1094 if (ret) 1095 return ret; 1096 1097 dev->mode_config.funcs = &ast_mode_config_funcs; 1098 dev->mode_config.min_width = 0; 1099 dev->mode_config.min_height = 0; 1100 dev->mode_config.preferred_depth = 24; 1101 dev->mode_config.prefer_shadow = 1; 1102 dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0); 1103 1104 if (ast->chip == AST2100 || 1105 ast->chip == AST2200 || 1106 ast->chip == AST2300 || 1107 ast->chip == AST2400 || 1108 ast->chip == AST2500) { 1109 dev->mode_config.max_width = 1920; 1110 dev->mode_config.max_height = 2048; 1111 } else { 1112 dev->mode_config.max_width = 1600; 1113 dev->mode_config.max_height = 1200; 1114 } 1115 1116 memset(&ast->primary_plane, 0, sizeof(ast->primary_plane)); 1117 ret = drm_universal_plane_init(dev, &ast->primary_plane, 0x01, 1118 &ast_primary_plane_funcs, 1119 ast_primary_plane_formats, 1120 ARRAY_SIZE(ast_primary_plane_formats), 1121 NULL, DRM_PLANE_TYPE_PRIMARY, NULL); 1122 if (ret) { 1123 drm_err(dev, "ast: drm_universal_plane_init() failed: %d\n", ret); 1124 return ret; 1125 } 1126 drm_plane_helper_add(&ast->primary_plane, 1127 &ast_primary_plane_helper_funcs); 1128 1129 ret = drm_universal_plane_init(dev, &ast->cursor_plane, 0x01, 1130 &ast_cursor_plane_funcs, 1131 ast_cursor_plane_formats, 1132 ARRAY_SIZE(ast_cursor_plane_formats), 1133 NULL, DRM_PLANE_TYPE_CURSOR, NULL); 1134 if (ret) { 1135 drm_err(dev, "drm_universal_plane_failed(): %d\n", ret); 1136 return ret; 1137 } 1138 drm_plane_helper_add(&ast->cursor_plane, 1139 &ast_cursor_plane_helper_funcs); 1140 1141 ast_crtc_init(dev); 1142 ast_encoder_init(dev); 1143 ast_connector_init(dev); 1144 1145 drm_mode_config_reset(dev); 1146 1147 return 0; 1148 } 1149 1150 static int get_clock(void *i2c_priv) 1151 { 1152 struct ast_i2c_chan *i2c = i2c_priv; 1153 struct ast_private *ast = to_ast_private(i2c->dev); 1154 uint32_t val, val2, count, pass; 1155 1156 count = 0; 1157 pass = 0; 1158 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1159 do { 1160 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1161 if (val == val2) { 1162 pass++; 1163 } else { 1164 pass = 0; 1165 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; 1166 } 1167 } while ((pass < 5) && (count++ < 0x10000)); 1168 1169 return val & 1 ? 1 : 0; 1170 } 1171 1172 static int get_data(void *i2c_priv) 1173 { 1174 struct ast_i2c_chan *i2c = i2c_priv; 1175 struct ast_private *ast = to_ast_private(i2c->dev); 1176 uint32_t val, val2, count, pass; 1177 1178 count = 0; 1179 pass = 0; 1180 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1181 do { 1182 val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1183 if (val == val2) { 1184 pass++; 1185 } else { 1186 pass = 0; 1187 val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; 1188 } 1189 } while ((pass < 5) && (count++ < 0x10000)); 1190 1191 return val & 1 ? 1 : 0; 1192 } 1193 1194 static void set_clock(void *i2c_priv, int clock) 1195 { 1196 struct ast_i2c_chan *i2c = i2c_priv; 1197 struct ast_private *ast = to_ast_private(i2c->dev); 1198 int i; 1199 u8 ujcrb7, jtemp; 1200 1201 for (i = 0; i < 0x10000; i++) { 1202 ujcrb7 = ((clock & 0x01) ? 0 : 1); 1203 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); 1204 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); 1205 if (ujcrb7 == jtemp) 1206 break; 1207 } 1208 } 1209 1210 static void set_data(void *i2c_priv, int data) 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 = ((data & 0x01) ? 0 : 1) << 2; 1219 ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); 1220 jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); 1221 if (ujcrb7 == jtemp) 1222 break; 1223 } 1224 } 1225 1226 static struct ast_i2c_chan *ast_i2c_create(struct drm_device *dev) 1227 { 1228 struct ast_i2c_chan *i2c; 1229 int ret; 1230 1231 i2c = kzalloc(sizeof(struct ast_i2c_chan), GFP_KERNEL); 1232 if (!i2c) 1233 return NULL; 1234 1235 i2c->adapter.owner = THIS_MODULE; 1236 i2c->adapter.class = I2C_CLASS_DDC; 1237 i2c->adapter.dev.parent = &dev->pdev->dev; 1238 i2c->dev = dev; 1239 i2c_set_adapdata(&i2c->adapter, i2c); 1240 snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), 1241 "AST i2c bit bus"); 1242 i2c->adapter.algo_data = &i2c->bit; 1243 1244 i2c->bit.udelay = 20; 1245 i2c->bit.timeout = 2; 1246 i2c->bit.data = i2c; 1247 i2c->bit.setsda = set_data; 1248 i2c->bit.setscl = set_clock; 1249 i2c->bit.getsda = get_data; 1250 i2c->bit.getscl = get_clock; 1251 ret = i2c_bit_add_bus(&i2c->adapter); 1252 if (ret) { 1253 drm_err(dev, "Failed to register bit i2c\n"); 1254 goto out_free; 1255 } 1256 1257 return i2c; 1258 out_free: 1259 kfree(i2c); 1260 return NULL; 1261 } 1262 1263 static void ast_i2c_destroy(struct ast_i2c_chan *i2c) 1264 { 1265 if (!i2c) 1266 return; 1267 i2c_del_adapter(&i2c->adapter); 1268 kfree(i2c); 1269 } 1270