Skip to content

Commit 85397f6

Browse files
committed
drm/mgag200: Initialize each model in separate function
Add a separate initializer function for each model. Add separate devic structures for G200 and G200SE, which require additional information. Also move G200's and G200SE's helpers for reading the BIOS and version id into model-specific code. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com> Tested-by: Jocelyn Falempe <jfalempe@redhat.com> Link: https://patchwork.freedesktop.org/patch/msgid/20220601112522.5774-3-tzimmermann@suse.de
1 parent 73f54d5 commit 85397f6

File tree

13 files changed

+603
-202
lines changed

13 files changed

+603
-202
lines changed

drivers/gpu/drm/mgag200/Makefile

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
# SPDX-License-Identifier: GPL-2.0-only
2-
mgag200-y := mgag200_drv.o mgag200_i2c.o mgag200_mm.o mgag200_mode.o mgag200_pll.o
2+
mgag200-y := \
3+
mgag200_drv.o \
4+
mgag200_g200.o \
5+
mgag200_g200eh.o \
6+
mgag200_g200eh3.o \
7+
mgag200_g200er.o \
8+
mgag200_g200ev.o \
9+
mgag200_g200ew3.o \
10+
mgag200_g200se.o \
11+
mgag200_g200wb.o \
12+
mgag200_i2c.o \
13+
mgag200_mm.o \
14+
mgag200_mode.o \
15+
mgag200_pll.o
316

417
obj-$(CONFIG_DRM_MGAG200) += mgag200.o

drivers/gpu/drm/mgag200/mgag200_drv.c

Lines changed: 32 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static bool mgag200_has_sgram(struct mga_device *mdev)
6060
return !!(option & PCI_MGA_OPTION_HARDPWMSK);
6161
}
6262

63-
static int mgag200_regs_init(struct mga_device *mdev)
63+
int mgag200_regs_init(struct mga_device *mdev)
6464
{
6565
struct drm_device *dev = &mdev->base;
6666
struct pci_dev *pdev = to_pci_dev(dev->dev);
@@ -133,178 +133,6 @@ static int mgag200_regs_init(struct mga_device *mdev)
133133
return 0;
134134
}
135135

136-
static void mgag200_g200_interpret_bios(struct mga_device *mdev,
137-
const unsigned char *bios,
138-
size_t size)
139-
{
140-
static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'};
141-
static const unsigned int expected_length[6] = {
142-
0, 64, 64, 64, 128, 128
143-
};
144-
struct drm_device *dev = &mdev->base;
145-
const unsigned char *pins;
146-
unsigned int pins_len, version;
147-
int offset;
148-
int tmp;
149-
150-
/* Test for MATROX string. */
151-
if (size < 45 + sizeof(matrox))
152-
return;
153-
if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0)
154-
return;
155-
156-
/* Get the PInS offset. */
157-
if (size < MGA_BIOS_OFFSET + 2)
158-
return;
159-
offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET];
160-
161-
/* Get PInS data structure. */
162-
163-
if (size < offset + 6)
164-
return;
165-
pins = bios + offset;
166-
if (pins[0] == 0x2e && pins[1] == 0x41) {
167-
version = pins[5];
168-
pins_len = pins[2];
169-
} else {
170-
version = 1;
171-
pins_len = pins[0] + (pins[1] << 8);
172-
}
173-
174-
if (version < 1 || version > 5) {
175-
drm_warn(dev, "Unknown BIOS PInS version: %d\n", version);
176-
return;
177-
}
178-
if (pins_len != expected_length[version]) {
179-
drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n",
180-
pins_len, expected_length[version]);
181-
return;
182-
}
183-
if (size < offset + pins_len)
184-
return;
185-
186-
drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n",
187-
version, pins_len);
188-
189-
/* Extract the clock values */
190-
191-
switch (version) {
192-
case 1:
193-
tmp = pins[24] + (pins[25] << 8);
194-
if (tmp)
195-
mdev->model.g200.pclk_max = tmp * 10;
196-
break;
197-
case 2:
198-
if (pins[41] != 0xff)
199-
mdev->model.g200.pclk_max = (pins[41] + 100) * 1000;
200-
break;
201-
case 3:
202-
if (pins[36] != 0xff)
203-
mdev->model.g200.pclk_max = (pins[36] + 100) * 1000;
204-
if (pins[52] & 0x20)
205-
mdev->model.g200.ref_clk = 14318;
206-
break;
207-
case 4:
208-
if (pins[39] != 0xff)
209-
mdev->model.g200.pclk_max = pins[39] * 4 * 1000;
210-
if (pins[92] & 0x01)
211-
mdev->model.g200.ref_clk = 14318;
212-
break;
213-
case 5:
214-
tmp = pins[4] ? 8000 : 6000;
215-
if (pins[123] != 0xff)
216-
mdev->model.g200.pclk_min = pins[123] * tmp;
217-
if (pins[38] != 0xff)
218-
mdev->model.g200.pclk_max = pins[38] * tmp;
219-
if (pins[110] & 0x01)
220-
mdev->model.g200.ref_clk = 14318;
221-
break;
222-
default:
223-
break;
224-
}
225-
}
226-
227-
static void mgag200_g200_init_refclk(struct mga_device *mdev)
228-
{
229-
struct drm_device *dev = &mdev->base;
230-
struct pci_dev *pdev = to_pci_dev(dev->dev);
231-
unsigned char __iomem *rom;
232-
unsigned char *bios;
233-
size_t size;
234-
235-
mdev->model.g200.pclk_min = 50000;
236-
mdev->model.g200.pclk_max = 230000;
237-
mdev->model.g200.ref_clk = 27050;
238-
239-
rom = pci_map_rom(pdev, &size);
240-
if (!rom)
241-
return;
242-
243-
bios = vmalloc(size);
244-
if (!bios)
245-
goto out;
246-
memcpy_fromio(bios, rom, size);
247-
248-
if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa)
249-
mgag200_g200_interpret_bios(mdev, bios, size);
250-
251-
drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n",
252-
mdev->model.g200.pclk_min, mdev->model.g200.pclk_max,
253-
mdev->model.g200.ref_clk);
254-
255-
vfree(bios);
256-
out:
257-
pci_unmap_rom(pdev, rom);
258-
}
259-
260-
static void mgag200_g200se_init_unique_id(struct mga_device *mdev)
261-
{
262-
struct drm_device *dev = &mdev->base;
263-
264-
/* stash G200 SE model number for later use */
265-
mdev->model.g200se.unique_rev_id = RREG32(0x1e24);
266-
267-
drm_dbg(dev, "G200 SE unique revision id is 0x%x\n",
268-
mdev->model.g200se.unique_rev_id);
269-
}
270-
271-
static struct mga_device *
272-
mgag200_device_create(struct pci_dev *pdev, enum mga_type type, unsigned long flags)
273-
{
274-
struct mga_device *mdev;
275-
struct drm_device *dev;
276-
int ret;
277-
278-
mdev = devm_drm_dev_alloc(&pdev->dev, &mgag200_driver, struct mga_device, base);
279-
if (IS_ERR(mdev))
280-
return mdev;
281-
dev = &mdev->base;
282-
283-
pci_set_drvdata(pdev, dev);
284-
285-
mdev->flags = flags;
286-
mdev->type = type;
287-
288-
ret = mgag200_regs_init(mdev);
289-
if (ret)
290-
return ERR_PTR(ret);
291-
292-
if (mdev->type == G200_PCI || mdev->type == G200_AGP)
293-
mgag200_g200_init_refclk(mdev);
294-
else if (IS_G200_SE(mdev))
295-
mgag200_g200se_init_unique_id(mdev);
296-
297-
ret = mgag200_mm_init(mdev);
298-
if (ret)
299-
return ERR_PTR(ret);
300-
301-
ret = mgag200_modeset_init(mdev);
302-
if (ret)
303-
return ERR_PTR(ret);
304-
305-
return mdev;
306-
}
307-
308136
/*
309137
* PCI driver
310138
*/
@@ -354,7 +182,37 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
354182
if (ret)
355183
return ret;
356184

357-
mdev = mgag200_device_create(pdev, type, flags);
185+
switch (type) {
186+
case G200_PCI:
187+
case G200_AGP:
188+
mdev = mgag200_g200_device_create(pdev, &mgag200_driver, type, flags);
189+
break;
190+
case G200_SE_A:
191+
case G200_SE_B:
192+
mdev = mgag200_g200se_device_create(pdev, &mgag200_driver, type, flags);
193+
break;
194+
case G200_WB:
195+
mdev = mgag200_g200wb_device_create(pdev, &mgag200_driver, type, flags);
196+
break;
197+
case G200_EV:
198+
mdev = mgag200_g200ev_device_create(pdev, &mgag200_driver, type, flags);
199+
break;
200+
case G200_EH:
201+
mdev = mgag200_g200eh_device_create(pdev, &mgag200_driver, type, flags);
202+
break;
203+
case G200_EH3:
204+
mdev = mgag200_g200eh3_device_create(pdev, &mgag200_driver, type, flags);
205+
break;
206+
case G200_ER:
207+
mdev = mgag200_g200er_device_create(pdev, &mgag200_driver, type, flags);
208+
break;
209+
case G200_EW3:
210+
mdev = mgag200_g200ew3_device_create(pdev, &mgag200_driver, type, flags);
211+
break;
212+
default:
213+
dev_err(&pdev->dev, "Device type %d is unsupported\n", type);
214+
return -ENODEV;
215+
}
358216
if (IS_ERR(mdev))
359217
return PTR_ERR(mdev);
360218
dev = &mdev->base;

drivers/gpu/drm/mgag200/mgag200_drv.h

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -218,18 +218,6 @@ struct mga_device {
218218

219219
enum mga_type type;
220220

221-
union {
222-
struct {
223-
long ref_clk;
224-
long pclk_min;
225-
long pclk_max;
226-
} g200;
227-
struct {
228-
/* SE model number stored in reg 0x1e24 */
229-
u32 unique_rev_id;
230-
} g200se;
231-
} model;
232-
233221
struct mgag200_pll pixpll;
234222
struct mga_i2c_chan i2c;
235223
struct drm_connector connector;
@@ -241,6 +229,53 @@ static inline struct mga_device *to_mga_device(struct drm_device *dev)
241229
return container_of(dev, struct mga_device, base);
242230
}
243231

232+
struct mgag200_g200_device {
233+
struct mga_device base;
234+
235+
/* PLL constants */
236+
long ref_clk;
237+
long pclk_min;
238+
long pclk_max;
239+
};
240+
241+
static inline struct mgag200_g200_device *to_mgag200_g200_device(struct drm_device *dev)
242+
{
243+
return container_of(to_mga_device(dev), struct mgag200_g200_device, base);
244+
}
245+
246+
struct mgag200_g200se_device {
247+
struct mga_device base;
248+
249+
/* SE model number stored in reg 0x1e24 */
250+
u32 unique_rev_id;
251+
};
252+
253+
static inline struct mgag200_g200se_device *to_mgag200_g200se_device(struct drm_device *dev)
254+
{
255+
return container_of(to_mga_device(dev), struct mgag200_g200se_device, base);
256+
}
257+
258+
/* mgag200_drv.c */
259+
int mgag200_regs_init(struct mga_device *mdev);
260+
261+
/* mgag200_<device type>.c */
262+
struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
263+
enum mga_type type, unsigned long flags);
264+
struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
265+
enum mga_type type, unsigned long flags);
266+
struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
267+
enum mga_type type, unsigned long flags);
268+
struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
269+
enum mga_type type, unsigned long flags);
270+
struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
271+
enum mga_type type, unsigned long flags);
272+
struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
273+
enum mga_type type, unsigned long flags);
274+
struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
275+
enum mga_type type, unsigned long flags);
276+
struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, const struct drm_driver *drv,
277+
enum mga_type type, unsigned long flags);
278+
244279
/* mgag200_mode.c */
245280
int mgag200_modeset_init(struct mga_device *mdev);
246281

0 commit comments

Comments
 (0)