1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/delay.h> 4 #include <linux/pci.h> 5 6 #include <drm/drm_atomic.h> 7 #include <drm/drm_atomic_helper.h> 8 #include <drm/drm_drv.h> 9 #include <drm/drm_gem_atomic_helper.h> 10 #include <drm/drm_print.h> 11 #include <drm/drm_probe_helper.h> 12 13 #include "mgag200_drv.h" 14 15 static int mgag200_g200se_init_pci_options(struct pci_dev *pdev) 16 { 17 struct device *dev = &pdev->dev; 18 bool has_sgram; 19 u32 option; 20 int err; 21 22 err = pci_read_config_dword(pdev, PCI_MGA_OPTION, &option); 23 if (err != PCIBIOS_SUCCESSFUL) { 24 dev_err(dev, "pci_read_config_dword(PCI_MGA_OPTION) failed: %d\n", err); 25 return pcibios_err_to_errno(err); 26 } 27 28 has_sgram = !!(option & PCI_MGA_OPTION_HARDPWMSK); 29 30 option = 0x40049120; 31 if (has_sgram) 32 option |= PCI_MGA_OPTION_HARDPWMSK; 33 34 return mgag200_init_pci_options(pdev, option, 0x00008000); 35 } 36 37 static void mgag200_g200se_init_registers(struct mgag200_g200se_device *g200se) 38 { 39 static const u8 dacvalue[] = { 40 MGAG200_DAC_DEFAULT(0x03, 41 MGA1064_PIX_CLK_CTL_SEL_PLL, 42 MGA1064_MISC_CTL_DAC_EN | 43 MGA1064_MISC_CTL_VGA8 | 44 MGA1064_MISC_CTL_DAC_RAM_CS, 45 0x00, 0x00, 0x00) 46 }; 47 48 struct mga_device *mdev = &g200se->base; 49 size_t i; 50 51 for (i = 0; i < ARRAY_SIZE(dacvalue); i++) { 52 if ((i <= 0x17) || 53 (i == 0x1b) || 54 (i == 0x1c) || 55 ((i >= 0x1f) && (i <= 0x29)) || 56 ((i == 0x2c) || (i == 0x2d) || (i == 0x2e)) || 57 ((i >= 0x30) && (i <= 0x37))) 58 continue; 59 WREG_DAC(i, dacvalue[i]); 60 } 61 62 mgag200_init_registers(mdev); 63 } 64 65 static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev, 66 const struct drm_display_mode *mode, 67 const struct drm_format_info *format) 68 { 69 struct mgag200_g200se_device *g200se = to_mgag200_g200se_device(&mdev->base); 70 unsigned int hiprilvl; 71 u8 crtcext6; 72 73 if (g200se->unique_rev_id >= 0x04) { 74 hiprilvl = 0; 75 } else if (g200se->unique_rev_id >= 0x02) { 76 unsigned int bpp; 77 unsigned long mb; 78 79 switch (format->format) { 80 case DRM_FORMAT_XRGB8888: 81 case DRM_FORMAT_RGB888: 82 bpp = 32; 83 break; 84 case DRM_FORMAT_RGB565: 85 case DRM_FORMAT_XRGB1555: 86 bpp = 16; 87 break; 88 case DRM_FORMAT_C8: 89 bpp = 8; 90 break; 91 } 92 93 mb = (mode->clock * bpp) / 1000; 94 if (mb > 3100) 95 hiprilvl = 0; 96 else if (mb > 2600) 97 hiprilvl = 1; 98 else if (mb > 1900) 99 hiprilvl = 2; 100 else if (mb > 1160) 101 hiprilvl = 3; 102 else if (mb > 440) 103 hiprilvl = 4; 104 else 105 hiprilvl = 5; 106 107 } else if (g200se->unique_rev_id >= 0x01) { 108 hiprilvl = 3; 109 } else { 110 hiprilvl = 4; 111 } 112 113 crtcext6 = hiprilvl; /* implicitly sets maxhipri to 0 */ 114 115 WREG_ECRT(0x06, crtcext6); 116 } 117 118 /* 119 * PIXPLLC 120 */ 121 122 static int mgag200_g200se_00_pixpllc_atomic_check(struct drm_crtc *crtc, 123 struct drm_atomic_commit *new_state) 124 { 125 static const unsigned int vcomax = 320000; 126 static const unsigned int vcomin = 160000; 127 static const unsigned int pllreffreq = 25000; 128 129 struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc); 130 struct mgag200_crtc_state *new_mgag200_crtc_state = to_mgag200_crtc_state(new_crtc_state); 131 long clock = new_crtc_state->mode.clock; 132 struct mgag200_pll_values *pixpllc = &new_mgag200_crtc_state->pixpllc; 133 unsigned int delta, tmpdelta, permitteddelta; 134 unsigned int testp, testm, testn; 135 unsigned int p, m, n, s; 136 unsigned int computed; 137 138 m = n = p = s = 0; 139 delta = 0xffffffff; 140 permitteddelta = clock * 5 / 1000; 141 142 for (testp = 8; testp > 0; testp /= 2) { 143 if (clock * testp > vcomax) 144 continue; 145 if (clock * testp < vcomin) 146 continue; 147 148 for (testn = 17; testn < 256; testn++) { 149 for (testm = 1; testm < 32; testm++) { 150 computed = (pllreffreq * testn) / (testm * testp); 151 if (computed > clock) 152 tmpdelta = computed - clock; 153 else 154 tmpdelta = clock - computed; 155 if (tmpdelta < delta) { 156 delta = tmpdelta; 157 m = testm; 158 n = testn; 159 p = testp; 160 } 161 } 162 } 163 } 164 165 if (delta > permitteddelta) { 166 pr_warn("PLL delta too large\n"); 167 return -EINVAL; 168 } 169 170 pixpllc->m = m; 171 pixpllc->n = n; 172 pixpllc->p = p; 173 pixpllc->s = s; 174 175 return 0; 176 } 177 178 static void mgag200_g200se_00_pixpllc_atomic_update(struct drm_crtc *crtc, 179 struct drm_atomic_commit *old_state) 180 { 181 struct drm_device *dev = crtc->dev; 182 struct mga_device *mdev = to_mga_device(dev); 183 struct drm_crtc_state *crtc_state = crtc->state; 184 struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); 185 struct mgag200_pll_values *pixpllc = &mgag200_crtc_state->pixpllc; 186 unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs; 187 u8 xpixpllcm, xpixpllcn, xpixpllcp; 188 189 pixpllcm = pixpllc->m - 1; 190 pixpllcn = pixpllc->n - 1; 191 pixpllcp = pixpllc->p - 1; 192 pixpllcs = pixpllc->s; 193 194 xpixpllcm = pixpllcm | ((pixpllcn & BIT(8)) >> 1); 195 xpixpllcn = pixpllcn; 196 xpixpllcp = (pixpllcs << 3) | pixpllcp; 197 198 WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); 199 200 WREG_DAC(MGA1064_PIX_PLLC_M, xpixpllcm); 201 WREG_DAC(MGA1064_PIX_PLLC_N, xpixpllcn); 202 WREG_DAC(MGA1064_PIX_PLLC_P, xpixpllcp); 203 } 204 205 static int mgag200_g200se_04_pixpllc_atomic_check(struct drm_crtc *crtc, 206 struct drm_atomic_commit *new_state) 207 { 208 static const unsigned int vcomax = 1600000; 209 static const unsigned int vcomin = 800000; 210 static const unsigned int pllreffreq = 25000; 211 static const unsigned int pvalues_e4[] = {16, 14, 12, 10, 8, 6, 4, 2, 1}; 212 213 struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc); 214 struct mgag200_crtc_state *new_mgag200_crtc_state = to_mgag200_crtc_state(new_crtc_state); 215 long clock = new_crtc_state->mode.clock; 216 struct mgag200_pll_values *pixpllc = &new_mgag200_crtc_state->pixpllc; 217 unsigned int delta, tmpdelta, permitteddelta; 218 unsigned int testp, testm, testn; 219 unsigned int p, m, n, s; 220 unsigned int computed; 221 unsigned int fvv; 222 unsigned int i; 223 224 m = n = p = s = 0; 225 delta = 0xffffffff; 226 227 if (clock < 25000) 228 clock = 25000; 229 clock = clock * 2; 230 231 /* Permited delta is 0.5% as VESA Specification */ 232 permitteddelta = clock * 5 / 1000; 233 234 for (i = 0 ; i < ARRAY_SIZE(pvalues_e4); i++) { 235 testp = pvalues_e4[i]; 236 237 if ((clock * testp) > vcomax) 238 continue; 239 if ((clock * testp) < vcomin) 240 continue; 241 242 for (testn = 50; testn <= 256; testn++) { 243 for (testm = 1; testm <= 32; testm++) { 244 computed = (pllreffreq * testn) / (testm * testp); 245 if (computed > clock) 246 tmpdelta = computed - clock; 247 else 248 tmpdelta = clock - computed; 249 250 if (tmpdelta < delta) { 251 delta = tmpdelta; 252 m = testm; 253 n = testn; 254 p = testp; 255 } 256 } 257 } 258 } 259 260 fvv = pllreffreq * n / m; 261 fvv = (fvv - 800000) / 50000; 262 if (fvv > 15) 263 fvv = 15; 264 s = fvv << 1; 265 266 if (delta > permitteddelta) { 267 pr_warn("PLL delta too large\n"); 268 return -EINVAL; 269 } 270 271 pixpllc->m = m; 272 pixpllc->n = n; 273 pixpllc->p = p; 274 pixpllc->s = s; 275 276 return 0; 277 } 278 279 static void mgag200_g200se_04_pixpllc_atomic_update(struct drm_crtc *crtc, 280 struct drm_atomic_commit *old_state) 281 { 282 struct drm_device *dev = crtc->dev; 283 struct mga_device *mdev = to_mga_device(dev); 284 struct drm_crtc_state *crtc_state = crtc->state; 285 struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); 286 struct mgag200_pll_values *pixpllc = &mgag200_crtc_state->pixpllc; 287 unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs; 288 u8 xpixpllcm, xpixpllcn, xpixpllcp; 289 290 pixpllcm = pixpllc->m - 1; 291 pixpllcn = pixpllc->n - 1; 292 pixpllcp = pixpllc->p - 1; 293 pixpllcs = pixpllc->s; 294 295 // For G200SE A, BIT(7) should be set unconditionally. 296 xpixpllcm = BIT(7) | pixpllcm; 297 xpixpllcn = pixpllcn; 298 xpixpllcp = (pixpllcs << 3) | pixpllcp; 299 300 WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); 301 302 WREG_DAC(MGA1064_PIX_PLLC_M, xpixpllcm); 303 WREG_DAC(MGA1064_PIX_PLLC_N, xpixpllcn); 304 WREG_DAC(MGA1064_PIX_PLLC_P, xpixpllcp); 305 306 WREG_DAC(0x1a, 0x09); 307 msleep(20); 308 WREG_DAC(0x1a, 0x01); 309 } 310 311 /* 312 * Mode-setting pipeline 313 */ 314 315 static const struct drm_plane_helper_funcs mgag200_g200se_primary_plane_helper_funcs = { 316 MGAG200_PRIMARY_PLANE_HELPER_FUNCS, 317 }; 318 319 static const struct drm_plane_funcs mgag200_g200se_primary_plane_funcs = { 320 MGAG200_PRIMARY_PLANE_FUNCS, 321 }; 322 323 static void mgag200_g200se_crtc_helper_atomic_enable(struct drm_crtc *crtc, 324 struct drm_atomic_commit *old_state) 325 { 326 struct drm_device *dev = crtc->dev; 327 struct mga_device *mdev = to_mga_device(dev); 328 const struct mgag200_device_funcs *funcs = mdev->funcs; 329 struct drm_crtc_state *crtc_state = crtc->state; 330 struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 331 struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); 332 const struct drm_format_info *format = mgag200_crtc_state->format; 333 334 mgag200_set_format_regs(mdev, format); 335 mgag200_set_mode_regs(mdev, adjusted_mode, mgag200_crtc_state->set_vidrst); 336 337 if (funcs->pixpllc_atomic_update) 338 funcs->pixpllc_atomic_update(crtc, old_state); 339 340 mgag200_g200se_set_hiprilvl(mdev, adjusted_mode, format); 341 342 if (crtc_state->gamma_lut) 343 mgag200_crtc_load_gamma(mdev, format, crtc_state->gamma_lut->data); 344 else 345 mgag200_crtc_fill_gamma(mdev, format); 346 347 mgag200_enable_display(mdev); 348 } 349 350 static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { 351 .mode_valid = mgag200_crtc_helper_mode_valid, 352 .atomic_check = mgag200_crtc_helper_atomic_check, 353 .atomic_flush = mgag200_crtc_helper_atomic_flush, 354 .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable, 355 .atomic_disable = mgag200_crtc_helper_atomic_disable 356 }; 357 358 static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = { 359 MGAG200_CRTC_FUNCS, 360 }; 361 362 static int mgag200_g200se_pipeline_init(struct mga_device *mdev) 363 { 364 struct drm_device *dev = &mdev->base; 365 struct drm_plane *primary_plane = &mdev->primary_plane; 366 struct drm_crtc *crtc = &mdev->crtc; 367 int ret; 368 369 ret = drm_universal_plane_init(dev, primary_plane, 0, 370 &mgag200_g200se_primary_plane_funcs, 371 mgag200_primary_plane_formats, 372 mgag200_primary_plane_formats_size, 373 mgag200_primary_plane_fmtmods, 374 DRM_PLANE_TYPE_PRIMARY, NULL); 375 if (ret) { 376 drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret); 377 return ret; 378 } 379 drm_plane_helper_add(primary_plane, &mgag200_g200se_primary_plane_helper_funcs); 380 drm_plane_enable_fb_damage_clips(primary_plane); 381 382 ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, 383 &mgag200_g200se_crtc_funcs, NULL); 384 if (ret) { 385 drm_err(dev, "drm_crtc_init_with_planes() failed: %d\n", ret); 386 return ret; 387 } 388 drm_crtc_helper_add(crtc, &mgag200_g200se_crtc_helper_funcs); 389 390 /* FIXME: legacy gamma tables, but atomic gamma doesn't work without */ 391 drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE); 392 drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE); 393 394 ret = mgag200_vga_bmc_output_init(mdev); 395 if (ret) 396 return ret; 397 398 return 0; 399 } 400 401 /* 402 * DRM device 403 */ 404 405 static const struct mgag200_device_info mgag200_g200se_a_01_device_info = 406 MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, 0, 1, true); 407 408 static const struct mgag200_device_info mgag200_g200se_a_02_device_info = 409 MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, 0, 1, true); 410 411 static const struct mgag200_device_info mgag200_g200se_a_03_device_info = 412 MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, 0, 1, false); 413 414 static const struct mgag200_device_info mgag200_g200se_b_01_device_info = 415 MGAG200_DEVICE_INFO_INIT(1600, 1200, 24400, false, 0, 1, false); 416 417 static const struct mgag200_device_info mgag200_g200se_b_02_device_info = 418 MGAG200_DEVICE_INFO_INIT(1920, 1200, 30100, false, 0, 1, false); 419 420 static const struct mgag200_device_info mgag200_g200se_b_03_device_info = 421 MGAG200_DEVICE_INFO_INIT(2048, 2048, 55000, false, 0, 1, false); 422 423 static int mgag200_g200se_init_unique_rev_id(struct mgag200_g200se_device *g200se) 424 { 425 struct mga_device *mdev = &g200se->base; 426 struct drm_device *dev = &mdev->base; 427 428 /* stash G200 SE model number for later use */ 429 g200se->unique_rev_id = RREG32(0x1e24); 430 if (!g200se->unique_rev_id) 431 return -ENODEV; 432 433 drm_dbg(dev, "G200 SE unique revision id is 0x%x\n", g200se->unique_rev_id); 434 435 return 0; 436 } 437 438 static const struct mgag200_device_funcs mgag200_g200se_00_device_funcs = { 439 .pixpllc_atomic_check = mgag200_g200se_00_pixpllc_atomic_check, 440 .pixpllc_atomic_update = mgag200_g200se_00_pixpllc_atomic_update, 441 }; 442 443 static const struct mgag200_device_funcs mgag200_g200se_04_device_funcs = { 444 .pixpllc_atomic_check = mgag200_g200se_04_pixpllc_atomic_check, 445 .pixpllc_atomic_update = mgag200_g200se_04_pixpllc_atomic_update, 446 }; 447 448 struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv, 449 enum mga_type type) 450 { 451 struct mgag200_g200se_device *g200se; 452 const struct mgag200_device_info *info; 453 const struct mgag200_device_funcs *funcs; 454 struct mga_device *mdev; 455 struct drm_device *dev; 456 resource_size_t vram_available; 457 int ret; 458 459 g200se = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200se_device, base.base); 460 if (IS_ERR(g200se)) 461 return ERR_CAST(g200se); 462 mdev = &g200se->base; 463 dev = &mdev->base; 464 465 pci_set_drvdata(pdev, dev); 466 467 ret = mgag200_g200se_init_pci_options(pdev); 468 if (ret) 469 return ERR_PTR(ret); 470 471 ret = mgag200_device_preinit(mdev); 472 if (ret) 473 return ERR_PTR(ret); 474 475 ret = mgag200_g200se_init_unique_rev_id(g200se); 476 if (ret) 477 return ERR_PTR(ret); 478 479 switch (type) { 480 case G200_SE_A: 481 if (g200se->unique_rev_id >= 0x03) 482 info = &mgag200_g200se_a_03_device_info; 483 else if (g200se->unique_rev_id >= 0x02) 484 info = &mgag200_g200se_a_02_device_info; 485 else 486 info = &mgag200_g200se_a_01_device_info; 487 break; 488 case G200_SE_B: 489 if (g200se->unique_rev_id >= 0x03) 490 info = &mgag200_g200se_b_03_device_info; 491 else if (g200se->unique_rev_id >= 0x02) 492 info = &mgag200_g200se_b_02_device_info; 493 else 494 info = &mgag200_g200se_b_01_device_info; 495 break; 496 default: 497 return ERR_PTR(-EINVAL); 498 } 499 500 if (g200se->unique_rev_id >= 0x04) 501 funcs = &mgag200_g200se_04_device_funcs; 502 else 503 funcs = &mgag200_g200se_00_device_funcs; 504 505 ret = mgag200_device_init(mdev, info, funcs); 506 if (ret) 507 return ERR_PTR(ret); 508 509 mgag200_g200se_init_registers(g200se); 510 511 vram_available = mgag200_device_probe_vram(mdev); 512 513 ret = mgag200_mode_config_init(mdev, vram_available); 514 if (ret) 515 return ERR_PTR(ret); 516 517 ret = mgag200_g200se_pipeline_init(mdev); 518 if (ret) 519 return ERR_PTR(ret); 520 521 drm_mode_config_reset(dev); 522 drm_kms_helper_poll_init(dev); 523 524 return mdev; 525 } 526