From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C62EAC433EF for ; Wed, 1 Jun 2022 11:25:45 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 07EA110E842; Wed, 1 Jun 2022 11:25:28 +0000 (UTC) Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by gabe.freedesktop.org (Postfix) with ESMTPS id A4F4110E737 for ; Wed, 1 Jun 2022 11:25:25 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 4795821B07; Wed, 1 Jun 2022 11:25:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1654082724; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S1fsR/03PVCDNSvbh9ZuHuudcxYkfpFrK+RJjecslIY=; b=y/TbDnLJUiTTJg+7Ye1tamNNx95YQ4hkuy4zgAcotmJ5IcoS6nfzumAEPyaQO/sNOpLtlv OexWZ4Q/+wc51pC86yYZnASCrcRUeKzyHHXcKSwhgsZnYvK7brqcbsvrVmdfUfZR6siRwT hjq3DGa+9ygPEw1OX/BBnlMA5BgUdUI= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1654082724; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S1fsR/03PVCDNSvbh9ZuHuudcxYkfpFrK+RJjecslIY=; b=iU5MFVmrgaQCCZMEOTvxapt8PYkUjd08mS+A3Ql4FaMxngfsMpF8kappqXtrV3iAumbZkp 01DwIw5GT+KTn8Cg== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 1BD011330F; Wed, 1 Jun 2022 11:25:24 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id YEniBaRMl2JqMQAAMHmgww (envelope-from ); Wed, 01 Jun 2022 11:25:24 +0000 From: Thomas Zimmermann To: airlied@redhat.com, jfalempe@redhat.com, airlied@linux.ie, daniel@ffwll.ch Subject: [PATCH 02/10] drm/mgag200: Initialize each model in separate function Date: Wed, 1 Jun 2022 13:25:14 +0200 Message-Id: <20220601112522.5774-3-tzimmermann@suse.de> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220601112522.5774-1-tzimmermann@suse.de> References: <20220601112522.5774-1-tzimmermann@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 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 --- drivers/gpu/drm/mgag200/Makefile | 15 +- drivers/gpu/drm/mgag200/mgag200_drv.c | 206 ++++------------------ drivers/gpu/drm/mgag200/mgag200_drv.h | 59 +++++-- drivers/gpu/drm/mgag200/mgag200_g200.c | 170 ++++++++++++++++++ drivers/gpu/drm/mgag200/mgag200_g200eh.c | 43 +++++ drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 44 +++++ drivers/gpu/drm/mgag200/mgag200_g200er.c | 43 +++++ drivers/gpu/drm/mgag200/mgag200_g200ev.c | 43 +++++ drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 44 +++++ drivers/gpu/drm/mgag200/mgag200_g200se.c | 58 ++++++ drivers/gpu/drm/mgag200/mgag200_g200wb.c | 43 +++++ drivers/gpu/drm/mgag200/mgag200_mode.c | 25 +-- drivers/gpu/drm/mgag200/mgag200_pll.c | 12 +- 13 files changed, 603 insertions(+), 202 deletions(-) create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200eh3.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200er.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ev.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200ew3.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200se.c create mode 100644 drivers/gpu/drm/mgag200/mgag200_g200wb.c diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile index d4f766522483..0c515a3b073d 100644 --- a/drivers/gpu/drm/mgag200/Makefile +++ b/drivers/gpu/drm/mgag200/Makefile @@ -1,4 +1,17 @@ # SPDX-License-Identifier: GPL-2.0-only -mgag200-y := mgag200_drv.o mgag200_i2c.o mgag200_mm.o mgag200_mode.o mgag200_pll.o +mgag200-y := \ + mgag200_drv.o \ + mgag200_g200.o \ + mgag200_g200eh.o \ + mgag200_g200eh3.o \ + mgag200_g200er.o \ + mgag200_g200ev.o \ + mgag200_g200ew3.o \ + mgag200_g200se.o \ + mgag200_g200wb.o \ + mgag200_i2c.o \ + mgag200_mm.o \ + mgag200_mode.o \ + mgag200_pll.o obj-$(CONFIG_DRM_MGAG200) += mgag200.o diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 08839460606f..e5f06f44ec90 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -60,7 +60,7 @@ static bool mgag200_has_sgram(struct mga_device *mdev) return !!(option & PCI_MGA_OPTION_HARDPWMSK); } -static int mgag200_regs_init(struct mga_device *mdev) +int mgag200_regs_init(struct mga_device *mdev) { struct drm_device *dev = &mdev->base; struct pci_dev *pdev = to_pci_dev(dev->dev); @@ -133,178 +133,6 @@ static int mgag200_regs_init(struct mga_device *mdev) return 0; } -static void mgag200_g200_interpret_bios(struct mga_device *mdev, - const unsigned char *bios, - size_t size) -{ - static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'}; - static const unsigned int expected_length[6] = { - 0, 64, 64, 64, 128, 128 - }; - struct drm_device *dev = &mdev->base; - const unsigned char *pins; - unsigned int pins_len, version; - int offset; - int tmp; - - /* Test for MATROX string. */ - if (size < 45 + sizeof(matrox)) - return; - if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0) - return; - - /* Get the PInS offset. */ - if (size < MGA_BIOS_OFFSET + 2) - return; - offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET]; - - /* Get PInS data structure. */ - - if (size < offset + 6) - return; - pins = bios + offset; - if (pins[0] == 0x2e && pins[1] == 0x41) { - version = pins[5]; - pins_len = pins[2]; - } else { - version = 1; - pins_len = pins[0] + (pins[1] << 8); - } - - if (version < 1 || version > 5) { - drm_warn(dev, "Unknown BIOS PInS version: %d\n", version); - return; - } - if (pins_len != expected_length[version]) { - drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n", - pins_len, expected_length[version]); - return; - } - if (size < offset + pins_len) - return; - - drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n", - version, pins_len); - - /* Extract the clock values */ - - switch (version) { - case 1: - tmp = pins[24] + (pins[25] << 8); - if (tmp) - mdev->model.g200.pclk_max = tmp * 10; - break; - case 2: - if (pins[41] != 0xff) - mdev->model.g200.pclk_max = (pins[41] + 100) * 1000; - break; - case 3: - if (pins[36] != 0xff) - mdev->model.g200.pclk_max = (pins[36] + 100) * 1000; - if (pins[52] & 0x20) - mdev->model.g200.ref_clk = 14318; - break; - case 4: - if (pins[39] != 0xff) - mdev->model.g200.pclk_max = pins[39] * 4 * 1000; - if (pins[92] & 0x01) - mdev->model.g200.ref_clk = 14318; - break; - case 5: - tmp = pins[4] ? 8000 : 6000; - if (pins[123] != 0xff) - mdev->model.g200.pclk_min = pins[123] * tmp; - if (pins[38] != 0xff) - mdev->model.g200.pclk_max = pins[38] * tmp; - if (pins[110] & 0x01) - mdev->model.g200.ref_clk = 14318; - break; - default: - break; - } -} - -static void mgag200_g200_init_refclk(struct mga_device *mdev) -{ - struct drm_device *dev = &mdev->base; - struct pci_dev *pdev = to_pci_dev(dev->dev); - unsigned char __iomem *rom; - unsigned char *bios; - size_t size; - - mdev->model.g200.pclk_min = 50000; - mdev->model.g200.pclk_max = 230000; - mdev->model.g200.ref_clk = 27050; - - rom = pci_map_rom(pdev, &size); - if (!rom) - return; - - bios = vmalloc(size); - if (!bios) - goto out; - memcpy_fromio(bios, rom, size); - - if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa) - mgag200_g200_interpret_bios(mdev, bios, size); - - drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n", - mdev->model.g200.pclk_min, mdev->model.g200.pclk_max, - mdev->model.g200.ref_clk); - - vfree(bios); -out: - pci_unmap_rom(pdev, rom); -} - -static void mgag200_g200se_init_unique_id(struct mga_device *mdev) -{ - struct drm_device *dev = &mdev->base; - - /* stash G200 SE model number for later use */ - mdev->model.g200se.unique_rev_id = RREG32(0x1e24); - - drm_dbg(dev, "G200 SE unique revision id is 0x%x\n", - mdev->model.g200se.unique_rev_id); -} - -static struct mga_device * -mgag200_device_create(struct pci_dev *pdev, enum mga_type type, unsigned long flags) -{ - struct mga_device *mdev; - struct drm_device *dev; - int ret; - - mdev = devm_drm_dev_alloc(&pdev->dev, &mgag200_driver, struct mga_device, base); - if (IS_ERR(mdev)) - return mdev; - dev = &mdev->base; - - pci_set_drvdata(pdev, dev); - - mdev->flags = flags; - mdev->type = type; - - ret = mgag200_regs_init(mdev); - if (ret) - return ERR_PTR(ret); - - if (mdev->type == G200_PCI || mdev->type == G200_AGP) - mgag200_g200_init_refclk(mdev); - else if (IS_G200_SE(mdev)) - mgag200_g200se_init_unique_id(mdev); - - ret = mgag200_mm_init(mdev); - if (ret) - return ERR_PTR(ret); - - ret = mgag200_modeset_init(mdev); - if (ret) - return ERR_PTR(ret); - - return mdev; -} - /* * PCI driver */ @@ -354,7 +182,37 @@ mgag200_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) return ret; - mdev = mgag200_device_create(pdev, type, flags); + switch (type) { + case G200_PCI: + case G200_AGP: + mdev = mgag200_g200_device_create(pdev, &mgag200_driver, type, flags); + break; + case G200_SE_A: + case G200_SE_B: + mdev = mgag200_g200se_device_create(pdev, &mgag200_driver, type, flags); + break; + case G200_WB: + mdev = mgag200_g200wb_device_create(pdev, &mgag200_driver, type, flags); + break; + case G200_EV: + mdev = mgag200_g200ev_device_create(pdev, &mgag200_driver, type, flags); + break; + case G200_EH: + mdev = mgag200_g200eh_device_create(pdev, &mgag200_driver, type, flags); + break; + case G200_EH3: + mdev = mgag200_g200eh3_device_create(pdev, &mgag200_driver, type, flags); + break; + case G200_ER: + mdev = mgag200_g200er_device_create(pdev, &mgag200_driver, type, flags); + break; + case G200_EW3: + mdev = mgag200_g200ew3_device_create(pdev, &mgag200_driver, type, flags); + break; + default: + dev_err(&pdev->dev, "Device type %d is unsupported\n", type); + return -ENODEV; + } if (IS_ERR(mdev)) return PTR_ERR(mdev); dev = &mdev->base; diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 5634fc003ca4..99a9446b7df5 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -218,18 +218,6 @@ struct mga_device { enum mga_type type; - union { - struct { - long ref_clk; - long pclk_min; - long pclk_max; - } g200; - struct { - /* SE model number stored in reg 0x1e24 */ - u32 unique_rev_id; - } g200se; - } model; - struct mgag200_pll pixpll; struct mga_i2c_chan i2c; struct drm_connector connector; @@ -241,6 +229,53 @@ static inline struct mga_device *to_mga_device(struct drm_device *dev) return container_of(dev, struct mga_device, base); } +struct mgag200_g200_device { + struct mga_device base; + + /* PLL constants */ + long ref_clk; + long pclk_min; + long pclk_max; +}; + +static inline struct mgag200_g200_device *to_mgag200_g200_device(struct drm_device *dev) +{ + return container_of(to_mga_device(dev), struct mgag200_g200_device, base); +} + +struct mgag200_g200se_device { + struct mga_device base; + + /* SE model number stored in reg 0x1e24 */ + u32 unique_rev_id; +}; + +static inline struct mgag200_g200se_device *to_mgag200_g200se_device(struct drm_device *dev) +{ + return container_of(to_mga_device(dev), struct mgag200_g200se_device, base); +} + + /* mgag200_drv.c */ +int mgag200_regs_init(struct mga_device *mdev); + + /* mgag200_.c */ +struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); +struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); +struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); +struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); +struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); +struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); +struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); +struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags); + /* mgag200_mode.c */ int mgag200_modeset_init(struct mga_device *mdev); diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c b/drivers/gpu/drm/mgag200/mgag200_g200.c new file mode 100644 index 000000000000..ca9522daf6e1 --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM Device + */ + +static void mgag200_g200_interpret_bios(struct mgag200_g200_device *g200, + const unsigned char *bios, size_t size) +{ + static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'}; + static const unsigned int expected_length[6] = { + 0, 64, 64, 64, 128, 128 + }; + struct mga_device *mdev = &g200->base; + struct drm_device *dev = &mdev->base; + const unsigned char *pins; + unsigned int pins_len, version; + int offset; + int tmp; + + /* Test for MATROX string. */ + if (size < 45 + sizeof(matrox)) + return; + if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0) + return; + + /* Get the PInS offset. */ + if (size < MGA_BIOS_OFFSET + 2) + return; + offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET]; + + /* Get PInS data structure. */ + + if (size < offset + 6) + return; + pins = bios + offset; + if (pins[0] == 0x2e && pins[1] == 0x41) { + version = pins[5]; + pins_len = pins[2]; + } else { + version = 1; + pins_len = pins[0] + (pins[1] << 8); + } + + if (version < 1 || version > 5) { + drm_warn(dev, "Unknown BIOS PInS version: %d\n", version); + return; + } + if (pins_len != expected_length[version]) { + drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n", + pins_len, expected_length[version]); + return; + } + if (size < offset + pins_len) + return; + + drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n", version, pins_len); + + /* Extract the clock values */ + + switch (version) { + case 1: + tmp = pins[24] + (pins[25] << 8); + if (tmp) + g200->pclk_max = tmp * 10; + break; + case 2: + if (pins[41] != 0xff) + g200->pclk_max = (pins[41] + 100) * 1000; + break; + case 3: + if (pins[36] != 0xff) + g200->pclk_max = (pins[36] + 100) * 1000; + if (pins[52] & 0x20) + g200->ref_clk = 14318; + break; + case 4: + if (pins[39] != 0xff) + g200->pclk_max = pins[39] * 4 * 1000; + if (pins[92] & 0x01) + g200->ref_clk = 14318; + break; + case 5: + tmp = pins[4] ? 8000 : 6000; + if (pins[123] != 0xff) + g200->pclk_min = pins[123] * tmp; + if (pins[38] != 0xff) + g200->pclk_max = pins[38] * tmp; + if (pins[110] & 0x01) + g200->ref_clk = 14318; + break; + default: + break; + } +} + +static void mgag200_g200_init_refclk(struct mgag200_g200_device *g200) +{ + struct mga_device *mdev = &g200->base; + struct drm_device *dev = &mdev->base; + struct pci_dev *pdev = to_pci_dev(dev->dev); + unsigned char __iomem *rom; + unsigned char *bios; + size_t size; + + g200->pclk_min = 50000; + g200->pclk_max = 230000; + g200->ref_clk = 27050; + + rom = pci_map_rom(pdev, &size); + if (!rom) + return; + + bios = vmalloc(size); + if (!bios) + goto out; + memcpy_fromio(bios, rom, size); + + if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa) + mgag200_g200_interpret_bios(g200, bios, size); + + drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n", + g200->pclk_min, g200->pclk_max, g200->ref_clk); + + vfree(bios); +out: + pci_unmap_rom(pdev, rom); +} + +struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mgag200_g200_device *g200; + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + g200 = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200_device, base.base); + if (IS_ERR(g200)) + return ERR_CAST(g200); + mdev = &g200->base; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + mgag200_g200_init_refclk(g200); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c b/drivers/gpu/drm/mgag200/mgag200_g200eh.c new file mode 100644 index 000000000000..67c7c75ea791 --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM device + */ + +struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base); + if (IS_ERR(mdev)) + return mdev; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c new file mode 100644 index 000000000000..b7a3f9551bfd --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM device + */ + +struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, + const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base); + if (IS_ERR(mdev)) + return mdev; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c b/drivers/gpu/drm/mgag200/mgag200_g200er.c new file mode 100644 index 000000000000..1c5e757ec016 --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM device + */ + +struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base); + if (IS_ERR(mdev)) + return mdev; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c b/drivers/gpu/drm/mgag200/mgag200_g200ev.c new file mode 100644 index 000000000000..f8afd05913fd --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM device + */ + +struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base); + if (IS_ERR(mdev)) + return mdev; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c new file mode 100644 index 000000000000..f65bb94e0b3d --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM device + */ + +struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, + const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base); + if (IS_ERR(mdev)) + return mdev; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c b/drivers/gpu/drm/mgag200/mgag200_g200se.c new file mode 100644 index 000000000000..d809cc680024 --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM device + */ + +static void mgag200_g200se_init_unique_id(struct mgag200_g200se_device *g200se) +{ + struct mga_device *mdev = &g200se->base; + struct drm_device *dev = &mdev->base; + + /* stash G200 SE model number for later use */ + g200se->unique_rev_id = RREG32(0x1e24); + + drm_dbg(dev, "G200 SE unique revision id is 0x%x\n", g200se->unique_rev_id); +} + +struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mgag200_g200se_device *g200se; + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + g200se = devm_drm_dev_alloc(&pdev->dev, drv, struct mgag200_g200se_device, base.base); + if (IS_ERR(g200se)) + return ERR_CAST(g200se); + mdev = &g200se->base; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + mgag200_g200se_init_unique_id(g200se); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c b/drivers/gpu/drm/mgag200/mgag200_g200wb.c new file mode 100644 index 000000000000..67b28646386d --- /dev/null +++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include + +#include + +#include "mgag200_drv.h" + +/* + * DRM device + */ + +struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const struct drm_driver *drv, + enum mga_type type, unsigned long flags) +{ + struct mga_device *mdev; + struct drm_device *dev; + int ret; + + mdev = devm_drm_dev_alloc(&pdev->dev, drv, struct mga_device, base); + if (IS_ERR(mdev)) + return mdev; + dev = &mdev->base; + + pci_set_drvdata(pdev, dev); + + mdev->flags = flags; + mdev->type = type; + + ret = mgag200_regs_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_mm_init(mdev); + if (ret) + return ERR_PTR(ret); + + ret = mgag200_modeset_init(mdev); + if (ret) + return ERR_PTR(ret); + + return mdev; +} diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 8cb72e11a2ea..2b034255a4af 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -583,13 +583,13 @@ static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev, const struct drm_display_mode *mode, const struct drm_framebuffer *fb) { - u32 unique_rev_id = mdev->model.g200se.unique_rev_id; + struct mgag200_g200se_device *g200se = to_mgag200_g200se_device(&mdev->base); unsigned int hiprilvl; u8 crtcext6; - if (unique_rev_id >= 0x04) { + if (g200se->unique_rev_id >= 0x04) { hiprilvl = 0; - } else if (unique_rev_id >= 0x02) { + } else if (g200se->unique_rev_id >= 0x02) { unsigned int bpp; unsigned long mb; @@ -614,7 +614,7 @@ static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev, else hiprilvl = 5; - } else if (unique_rev_id >= 0x01) { + } else if (g200se->unique_rev_id >= 0x01) { hiprilvl = 3; } else { hiprilvl = 4; @@ -725,17 +725,19 @@ static enum drm_mode_status mgag200_simple_display_pipe_mode_valid(struct drm_simple_display_pipe *pipe, const struct drm_display_mode *mode) { - struct mga_device *mdev = to_mga_device(pipe->crtc.dev); + struct drm_device *dev = pipe->crtc.dev; + struct mga_device *mdev = to_mga_device(dev); + struct mgag200_g200se_device *g200se; if (IS_G200_SE(mdev)) { - u32 unique_rev_id = mdev->model.g200se.unique_rev_id; + g200se = to_mgag200_g200se_device(dev); - if (unique_rev_id == 0x01) { + if (g200se->unique_rev_id == 0x01) { if (mode->hdisplay > 1600) return MODE_VIRTUAL_X; if (mode->vdisplay > 1200) return MODE_VIRTUAL_Y; - } else if (unique_rev_id == 0x02) { + } else if (g200se->unique_rev_id == 0x02) { if (mode->hdisplay > 1920) return MODE_VIRTUAL_X; if (mode->vdisplay > 1200) @@ -1026,6 +1028,7 @@ static enum drm_mode_status mgag200_mode_config_mode_valid(struct drm_device *de static const unsigned int max_bpp = 4; // DRM_FORMAT_XRGB8888 struct mga_device *mdev = to_mga_device(dev); unsigned long fbsize, fbpages, max_fbpages; + struct mgag200_g200se_device *g200se; max_fbpages = mdev->vram_fb_available >> PAGE_SHIFT; @@ -1036,12 +1039,12 @@ static enum drm_mode_status mgag200_mode_config_mode_valid(struct drm_device *de return MODE_MEM; if (IS_G200_SE(mdev)) { - u32 unique_rev_id = mdev->model.g200se.unique_rev_id; + g200se = to_mgag200_g200se_device(dev); - if (unique_rev_id == 0x01) { + if (g200se->unique_rev_id == 0x01) { if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (24400 * 1024)) return MODE_BAD; - } else if (unique_rev_id == 0x02) { + } else if (g200se->unique_rev_id == 0x02) { if (mgag200_calculate_mode_bandwidth(mode, max_bpp * 8) > (30100 * 1024)) return MODE_BAD; } else { diff --git a/drivers/gpu/drm/mgag200/mgag200_pll.c b/drivers/gpu/drm/mgag200/mgag200_pll.c index 52be08b744ad..8065ca5d8de9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_pll.c +++ b/drivers/gpu/drm/mgag200/mgag200_pll.c @@ -13,6 +13,7 @@ static int mgag200_pixpll_compute_g200(struct mgag200_pll *pixpll, long clock, { struct mga_device *mdev = pixpll->mdev; struct drm_device *dev = &mdev->base; + struct mgag200_g200_device *g200 = to_mgag200_g200_device(dev); const int post_div_max = 7; const int in_div_min = 1; const int in_div_max = 6; @@ -23,9 +24,9 @@ static int mgag200_pixpll_compute_g200(struct mgag200_pll *pixpll, long clock, long f_vco; long computed; long delta, tmp_delta; - long ref_clk = mdev->model.g200.ref_clk; - long p_clk_min = mdev->model.g200.pclk_min; - long p_clk_max = mdev->model.g200.pclk_max; + long ref_clk = g200->ref_clk; + long p_clk_min = g200->pclk_min; + long p_clk_max = g200->pclk_max; if (clock > p_clk_max) { drm_err(dev, "Pixel Clock %ld too high\n", clock); @@ -951,6 +952,7 @@ static const struct mgag200_pll_funcs mgag200_pixpll_funcs_g200ew3 = { int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev) { struct drm_device *dev = &mdev->base; + struct mgag200_g200se_device *g200se; pixpll->mdev = mdev; @@ -961,7 +963,9 @@ int mgag200_pixpll_init(struct mgag200_pll *pixpll, struct mga_device *mdev) break; case G200_SE_A: case G200_SE_B: - if (mdev->model.g200se.unique_rev_id >= 0x04) + g200se = to_mgag200_g200se_device(dev); + + if (g200se->unique_rev_id >= 0x04) pixpll->funcs = &mgag200_pixpll_funcs_g200se_04; else pixpll->funcs = &mgag200_pixpll_funcs_g200se_00; -- 2.36.1