xref: /linux/drivers/gpu/drm/mgag200/mgag200_g200se.c (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
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