From patchwork Wed Sep 28 10:50:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 610370 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2420C04A95 for ; Wed, 28 Sep 2022 10:53:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233874AbiI1Kxy (ORCPT ); Wed, 28 Sep 2022 06:53:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233994AbiI1Kxa (ORCPT ); Wed, 28 Sep 2022 06:53:30 -0400 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2985BEE35 for ; Wed, 28 Sep 2022 03:50:27 -0700 (PDT) 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 22A2521E2A; Wed, 28 Sep 2022 10:50:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1664362213; 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=yL/5P6b+NuYxDajkrD28IlObmzAosyZjt4EJQhJQMz4=; b=qUgyoaPzhCpQVD4u1vywaELjSDXD6acXRqh+2Z/uMC2zIH8AZyC87fBG6Dqdp4ZHMLz4os zZR/KxRaySrhY1gPMm39uTai8wBleG07kQI5IRPkQ1/nCkixkPXGa4a3tUx72Ad7GiiaYc HIVHPdzGFr4PX8ImJZrkToqgLpuL6p4= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1664362213; 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=yL/5P6b+NuYxDajkrD28IlObmzAosyZjt4EJQhJQMz4=; b=qGbm+soisFuZ+XpHL/YLnbYSnVZE3CAGppNBwR6+3MNUR893UlDvnVlw2ZDTmpWzkgSNLn kwiB7X7iZRcia2Cw== 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 CE06B13A86; Wed, 28 Sep 2022 10:50:12 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id gEJ6MeQmNGMUEwAAMHmgww (envelope-from ); Wed, 28 Sep 2022 10:50:12 +0000 From: Thomas Zimmermann To: javierm@redhat.com, airlied@linux.ie, daniel@ffwll.ch, deller@gmx.de, maxime@cerno.tech, sam@ravnborg.org, msuchanek@suse.de, mpe@ellerman.id.au, benh@kernel.crashing.org, paulus@samba.org, geert@linux-m68k.org, mark.cave-ayland@ilande.co.uk Cc: linux-fbdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, dri-devel@lists.freedesktop.org, Thomas Zimmermann Subject: [PATCH v4 3/5] drm/ofdrm: Add per-model device function Date: Wed, 28 Sep 2022 12:50:08 +0200 Message-Id: <20220928105010.18880-4-tzimmermann@suse.de> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220928105010.18880-1-tzimmermann@suse.de> References: <20220928105010.18880-1-tzimmermann@suse.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org Add a per-model device-function structure in preparation of adding color-management support. Detection of the individual models has been taken from fbdev's offb. v3: * define constants for PCI ids (Javier) Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas --- drivers/gpu/drm/tiny/ofdrm.c | 125 +++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c index d53ca70934b5..5abed3ec0a35 100644 --- a/drivers/gpu/drm/tiny/ofdrm.c +++ b/drivers/gpu/drm/tiny/ofdrm.c @@ -28,6 +28,21 @@ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 +#define PCI_VENDOR_ID_ATI_R520 0x7100 +#define PCI_VENDOR_ID_ATI_R600 0x9400 + +enum ofdrm_model { + OFDRM_MODEL_UNKNOWN, + OFDRM_MODEL_MACH64, /* ATI Mach64 */ + OFDRM_MODEL_RAGE128, /* ATI Rage128 */ + OFDRM_MODEL_RAGE_M3A, /* ATI Rage Mobility M3 Head A */ + OFDRM_MODEL_RAGE_M3B, /* ATI Rage Mobility M3 Head B */ + OFDRM_MODEL_RADEON, /* ATI Radeon */ + OFDRM_MODEL_GXT2000, /* IBM GXT2000 */ + OFDRM_MODEL_AVIVO, /* ATI R5xx */ + OFDRM_MODEL_QEMU, /* QEMU VGA */ +}; + /* * Helpers for display nodes */ @@ -148,14 +163,63 @@ static u64 display_get_address_of(struct drm_device *dev, struct device_node *of return address; } +static bool is_avivo(__be32 vendor, __be32 device) +{ + /* This will match most R5xx */ + return (vendor == PCI_VENDOR_ID_ATI) && + ((device >= PCI_VENDOR_ID_ATI_R520 && device < 0x7800) || + (PCI_VENDOR_ID_ATI_R600 >= 0x9400)); +} + +static enum ofdrm_model display_get_model_of(struct drm_device *dev, struct device_node *of_node) +{ + enum ofdrm_model model = OFDRM_MODEL_UNKNOWN; + + if (of_node_name_prefix(of_node, "ATY,Rage128")) { + model = OFDRM_MODEL_RAGE128; + } else if (of_node_name_prefix(of_node, "ATY,RageM3pA") || + of_node_name_prefix(of_node, "ATY,RageM3p12A")) { + model = OFDRM_MODEL_RAGE_M3A; + } else if (of_node_name_prefix(of_node, "ATY,RageM3pB")) { + model = OFDRM_MODEL_RAGE_M3B; + } else if (of_node_name_prefix(of_node, "ATY,Rage6")) { + model = OFDRM_MODEL_RADEON; + } else if (of_node_name_prefix(of_node, "ATY,")) { + return OFDRM_MODEL_MACH64; + } else if (of_device_is_compatible(of_node, "pci1014,b7") || + of_device_is_compatible(of_node, "pci1014,21c")) { + model = OFDRM_MODEL_GXT2000; + } else if (of_node_name_prefix(of_node, "vga,Display-")) { + struct device_node *of_parent; + const __be32 *vendor_p, *device_p; + + /* Look for AVIVO initialized by SLOF */ + of_parent = of_get_parent(of_node); + vendor_p = of_get_property(of_parent, "vendor-id", NULL); + device_p = of_get_property(of_parent, "device-id", NULL); + if (vendor_p && device_p && is_avivo(*vendor_p, *device_p)) + model = OFDRM_MODEL_AVIVO; + of_node_put(of_parent); + } else if (of_device_is_compatible(of_node, "qemu,std-vga")) { + model = OFDRM_MODEL_QEMU; + } + + return model; +} + /* * Open Firmware display device */ +struct ofdrm_device_funcs { +}; + struct ofdrm_device { struct drm_device dev; struct platform_device *pdev; + const struct ofdrm_device_funcs *funcs; + /* firmware-buffer settings */ struct iosys_map screen_base; struct drm_display_mode mode; @@ -519,6 +583,33 @@ static const struct drm_mode_config_funcs ofdrm_mode_config_funcs = { * Init / Cleanup */ +static const struct ofdrm_device_funcs ofdrm_unknown_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_mach64_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_rage128_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_rage_m3a_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_rage_m3b_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_radeon_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_gxt2000_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_avivo_device_funcs = { +}; + +static const struct ofdrm_device_funcs ofdrm_qemu_device_funcs = { +}; + static struct drm_display_mode ofdrm_mode(unsigned int width, unsigned int height) { /* @@ -540,6 +631,7 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, struct device_node *of_node = pdev->dev.of_node; struct ofdrm_device *odev; struct drm_device *dev; + enum ofdrm_model model; int width, height, depth, linebytes; const struct drm_format_info *format; u64 address; @@ -568,6 +660,39 @@ static struct ofdrm_device *ofdrm_device_create(struct drm_driver *drv, * OF display-node settings */ + model = display_get_model_of(dev, of_node); + drm_dbg(dev, "detected model %d\n", model); + + switch (model) { + case OFDRM_MODEL_UNKNOWN: + odev->funcs = &ofdrm_unknown_device_funcs; + break; + case OFDRM_MODEL_MACH64: + odev->funcs = &ofdrm_mach64_device_funcs; + break; + case OFDRM_MODEL_RAGE128: + odev->funcs = &ofdrm_rage128_device_funcs; + break; + case OFDRM_MODEL_RAGE_M3A: + odev->funcs = &ofdrm_rage_m3a_device_funcs; + break; + case OFDRM_MODEL_RAGE_M3B: + odev->funcs = &ofdrm_rage_m3b_device_funcs; + break; + case OFDRM_MODEL_RADEON: + odev->funcs = &ofdrm_radeon_device_funcs; + break; + case OFDRM_MODEL_GXT2000: + odev->funcs = &ofdrm_gxt2000_device_funcs; + break; + case OFDRM_MODEL_AVIVO: + odev->funcs = &ofdrm_avivo_device_funcs; + break; + case OFDRM_MODEL_QEMU: + odev->funcs = &ofdrm_qemu_device_funcs; + break; + } + width = display_get_width_of(dev, of_node); if (width < 0) return ERR_PTR(width);