1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/pci.h> 4 #include <linux/vmalloc.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_probe_helper.h> 11 #include <drm/drm_vblank.h> 12 13 #include "mgag200_drv.h" 14 15 static int mgag200_g200_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 if (has_sgram) 31 option = 0x4049cd21; 32 else 33 option = 0x40499121; 34 35 return mgag200_init_pci_options(pdev, option, 0x00008000); 36 } 37 38 static void mgag200_g200_init_registers(struct mgag200_g200_device *g200) 39 { 40 static const u8 dacvalue[] = { 41 MGAG200_DAC_DEFAULT(0x00, 0xc9, 0x1f, 42 0x04, 0x2d, 0x19) 43 }; 44 45 struct mga_device *mdev = &g200->base; 46 size_t i; 47 48 for (i = 0; i < ARRAY_SIZE(dacvalue); ++i) { 49 if ((i <= 0x17) || 50 (i == 0x1b) || 51 (i == 0x1c) || 52 ((i >= 0x1f) && (i <= 0x29)) || 53 ((i >= 0x30) && (i <= 0x37))) 54 continue; 55 WREG_DAC(i, dacvalue[i]); 56 } 57 58 mgag200_init_registers(mdev); 59 } 60 61 /* 62 * PIXPLLC 63 */ 64 65 static int mgag200_g200_pixpllc_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *new_state) 66 { 67 static const int post_div_max = 7; 68 static const int in_div_min = 1; 69 static const int in_div_max = 6; 70 static const int feed_div_min = 7; 71 static const int feed_div_max = 127; 72 73 struct drm_device *dev = crtc->dev; 74 struct mgag200_g200_device *g200 = to_mgag200_g200_device(dev); 75 struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(new_state, crtc); 76 struct mgag200_crtc_state *new_mgag200_crtc_state = to_mgag200_crtc_state(new_crtc_state); 77 long clock = new_crtc_state->mode.clock; 78 struct mgag200_pll_values *pixpllc = &new_mgag200_crtc_state->pixpllc; 79 u8 testp, testm, testn; 80 u8 n = 0, m = 0, p, s; 81 long f_vco; 82 long computed; 83 long delta, tmp_delta; 84 long ref_clk = g200->ref_clk; 85 long p_clk_min = g200->pclk_min; 86 long p_clk_max = g200->pclk_max; 87 88 if (clock > p_clk_max) { 89 drm_err(dev, "Pixel Clock %ld too high\n", clock); 90 return -EINVAL; 91 } 92 93 if (clock < p_clk_min >> 3) 94 clock = p_clk_min >> 3; 95 96 f_vco = clock; 97 for (testp = 0; 98 testp <= post_div_max && f_vco < p_clk_min; 99 testp = (testp << 1) + 1, f_vco <<= 1) 100 ; 101 p = testp + 1; 102 103 delta = clock; 104 105 for (testm = in_div_min; testm <= in_div_max; testm++) { 106 for (testn = feed_div_min; testn <= feed_div_max; testn++) { 107 computed = ref_clk * (testn + 1) / (testm + 1); 108 if (computed < f_vco) 109 tmp_delta = f_vco - computed; 110 else 111 tmp_delta = computed - f_vco; 112 if (tmp_delta < delta) { 113 delta = tmp_delta; 114 m = testm + 1; 115 n = testn + 1; 116 } 117 } 118 } 119 f_vco = ref_clk * n / m; 120 if (f_vco < 100000) 121 s = 0; 122 else if (f_vco < 140000) 123 s = 1; 124 else if (f_vco < 180000) 125 s = 2; 126 else 127 s = 3; 128 129 drm_dbg_kms(dev, "clock: %ld vco: %ld m: %d n: %d p: %d s: %d\n", 130 clock, f_vco, m, n, p, s); 131 132 pixpllc->m = m; 133 pixpllc->n = n; 134 pixpllc->p = p; 135 pixpllc->s = s; 136 137 return 0; 138 } 139 140 static void mgag200_g200_pixpllc_atomic_update(struct drm_crtc *crtc, 141 struct drm_atomic_state *old_state) 142 { 143 struct drm_device *dev = crtc->dev; 144 struct mga_device *mdev = to_mga_device(dev); 145 struct drm_crtc_state *crtc_state = crtc->state; 146 struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); 147 struct mgag200_pll_values *pixpllc = &mgag200_crtc_state->pixpllc; 148 unsigned int pixpllcm, pixpllcn, pixpllcp, pixpllcs; 149 u8 xpixpllcm, xpixpllcn, xpixpllcp; 150 151 pixpllcm = pixpllc->m - 1; 152 pixpllcn = pixpllc->n - 1; 153 pixpllcp = pixpllc->p - 1; 154 pixpllcs = pixpllc->s; 155 156 xpixpllcm = pixpllcm; 157 xpixpllcn = pixpllcn; 158 xpixpllcp = (pixpllcs << 3) | pixpllcp; 159 160 WREG_MISC_MASKED(MGAREG_MISC_CLKSEL_MGA, MGAREG_MISC_CLKSEL_MASK); 161 162 WREG_DAC(MGA1064_PIX_PLLC_M, xpixpllcm); 163 WREG_DAC(MGA1064_PIX_PLLC_N, xpixpllcn); 164 WREG_DAC(MGA1064_PIX_PLLC_P, xpixpllcp); 165 } 166 167 /* 168 * Mode-setting pipeline 169 */ 170 171 static const struct drm_plane_helper_funcs mgag200_g200_primary_plane_helper_funcs = { 172 MGAG200_PRIMARY_PLANE_HELPER_FUNCS, 173 }; 174 175 static const struct drm_plane_funcs mgag200_g200_primary_plane_funcs = { 176 MGAG200_PRIMARY_PLANE_FUNCS, 177 }; 178 179 static const struct drm_crtc_helper_funcs mgag200_g200_crtc_helper_funcs = { 180 MGAG200_CRTC_HELPER_FUNCS, 181 }; 182 183 static const struct drm_crtc_funcs mgag200_g200_crtc_funcs = { 184 MGAG200_CRTC_FUNCS, 185 }; 186 187 static int mgag200_g200_pipeline_init(struct mga_device *mdev) 188 { 189 struct drm_device *dev = &mdev->base; 190 struct drm_plane *primary_plane = &mdev->primary_plane; 191 struct drm_crtc *crtc = &mdev->crtc; 192 int ret; 193 194 ret = drm_universal_plane_init(dev, primary_plane, 0, 195 &mgag200_g200_primary_plane_funcs, 196 mgag200_primary_plane_formats, 197 mgag200_primary_plane_formats_size, 198 mgag200_primary_plane_fmtmods, 199 DRM_PLANE_TYPE_PRIMARY, NULL); 200 if (ret) { 201 drm_err(dev, "drm_universal_plane_init() failed: %d\n", ret); 202 return ret; 203 } 204 drm_plane_helper_add(primary_plane, &mgag200_g200_primary_plane_helper_funcs); 205 drm_plane_enable_fb_damage_clips(primary_plane); 206 207 ret = drm_crtc_init_with_planes(dev, crtc, primary_plane, NULL, 208 &mgag200_g200_crtc_funcs, NULL); 209 if (ret) { 210 drm_err(dev, "drm_crtc_init_with_planes() failed: %d\n", ret); 211 return ret; 212 } 213 drm_crtc_helper_add(crtc, &mgag200_g200_crtc_helper_funcs); 214 215 /* FIXME: legacy gamma tables, but atomic gamma doesn't work without */ 216 drm_mode_crtc_set_gamma_size(crtc, MGAG200_LUT_SIZE); 217 drm_crtc_enable_color_mgmt(crtc, 0, false, MGAG200_LUT_SIZE); 218 219 ret = mgag200_vga_output_init(mdev); 220 if (ret) 221 return ret; 222 223 return 0; 224 } 225 226 /* 227 * DRM Device 228 */ 229 230 static const struct mgag200_device_info mgag200_g200_device_info = 231 MGAG200_DEVICE_INFO_INIT(2048, 2048, 0, false, 1, 3, false); 232 233 static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200, 234 const unsigned char *bios, size_t size) 235 { 236 static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'}; 237 static const unsigned int expected_length[6] = { 238 0, 64, 64, 64, 128, 128 239 }; 240 struct mga_device *mdev = &g200->base; 241 struct drm_device *dev = &mdev->base; 242 const unsigned char *pins; 243 unsigned int pins_len, version; 244 int offset; 245 int tmp; 246 247 /* Test for MATROX string. */ 248 if (size < 45 + sizeof(matrox)) 249 return; 250 if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0) 251 return; 252 253 /* Get the PInS offset. */ 254 if (size < MGA_BIOS_OFFSET + 2) 255 return; 256 offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET]; 257 258 /* Get PInS data structure. */ 259 260 if (size < offset + 6) 261 return; 262 pins = bios + offset; 263 if (pins[0] == 0x2e && pins[1] == 0x41) { 264 version = pins[5]; 265 pins_len = pins[2]; 266 } else { 267 version = 1; 268 pins_len = pins[0] + (pins[1] << 8); 269 } 270 271 if (version < 1 || version > 5) { 272 drm_warn(dev, "Unknown BIOS PInS version: %d\n", version); 273 return; 274 } 275 if (pins_len != expected_length[version]) { 276 drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n", 277 pins_len, expected_length[version]); 278 return; 279 } 280 if (size < offset + pins_len) 281 return; 282 283 drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n", version, pins_len); 284 285 /* Extract the clock values */ 286 287 switch (version) { 288 case 1: 289 tmp = pins[24] + (pins[25] << 8); 290 if (tmp) 291 g200->pclk_max = tmp * 10; 292 break; 293 case 2: 294 if (pins[41] != 0xff) 295 g200->pclk_max = (pins[41] + 100) * 1000; 296 break; 297 case 3: 298 if (pins[36] != 0xff) 299 g200->pclk_max = (pins[36] + 100) * 1000; 300 if (pins[52] & 0x20) 301 g200->ref_clk = 14318; 302 break; 303 case 4: 304 if (pins[39] != 0xff) 305 g200->pclk_max = pins[39] * 4 * 1000; 306 if (pins[92] & 0x01) 307 g200->ref_clk = 14318; 308 break; 309 case 5: 310 tmp = pins[4] ? 8000 : 6000; 311 if (pins[123] != 0xff) 312 g200->pclk_min = pins[123] * tmp; 313 if (pins[38] != 0xff) 314 g200->pclk_max = pins[38] * tmp; 315 if (pins[110] & 0x01) 316 g200->ref_clk = 14318; 317 break; 318 default: 319 break; 320 } 321 } 322 323 static void mgag200_g200_init_refclk(struct mgag200_g200_device *g200) 324 { 325 struct mga_device *mdev = &g200->base; 326 struct drm_device *dev = &mdev->base; 327 struct pci_dev *pdev = to_pci_dev(dev->dev); 328 unsigned char __iomem *rom; 329 unsigned char *bios; 330 size_t size; 331 332 g200->pclk_min = 50000; 333 g200->pclk_max = 230000; 334 g200->ref_clk = 27050; 335 336 rom = pci_map_rom(pdev, &size); 337 if (!rom) 338 return; 339 340 bios = vmalloc(size); 341 if (!bios) 342 goto out; 343 memcpy_fromio(bios, rom, size); 344 345 if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa) 346 mgag200_g200_interpret_bios(g200, bios, size); 347 348 drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n", 349 g200->pclk_min, g200->pclk_max, g200->ref_clk); 350 351 vfree(bios); 352 out: 353 pci_unmap_rom(pdev, rom); 354 } 355 356 static const struct mgag200_device_funcs mgag200_g200_device_funcs = { 357 .pixpllc_atomic_check = mgag200_g200_pixpllc_atomic_check, 358 .pixpllc_atomic_update = mgag200_g200_pixpllc_atomic_update, 359 }; 360 361 struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv) 362 { 363 struct mgag200_g200_device *g200; 364 struct mga_device *mdev; 365 struct drm_device *dev; 366 resource_size_t vram_available; 367 int ret; 368 369 g200 = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200_device, base.base); 370 if (IS_ERR(g200)) 371 return ERR_CAST(g200); 372 mdev = &g200->base; 373 dev = &mdev->base; 374 375 pci_set_drvdata(pdev, dev); 376 377 ret = mgag200_g200_init_pci_options(pdev); 378 if (ret) 379 return ERR_PTR(ret); 380 381 ret = mgag200_device_preinit(mdev); 382 if (ret) 383 return ERR_PTR(ret); 384 385 mgag200_g200_init_refclk(g200); 386 387 ret = mgag200_device_init(mdev, &mgag200_g200_device_info, 388 &mgag200_g200_device_funcs); 389 if (ret) 390 return ERR_PTR(ret); 391 392 mgag200_g200_init_registers(g200); 393 394 vram_available = mgag200_device_probe_vram(mdev); 395 396 ret = mgag200_mode_config_init(mdev, vram_available); 397 if (ret) 398 return ERR_PTR(ret); 399 400 ret = mgag200_g200_pipeline_init(mdev); 401 if (ret) 402 return ERR_PTR(ret); 403 404 drm_mode_config_reset(dev); 405 drm_kms_helper_poll_init(dev); 406 407 ret = drm_vblank_init(dev, 1); 408 if (ret) 409 return ERR_PTR(ret); 410 411 return mdev; 412 } 413