From patchwork Fri Aug 21 13:24:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathieu Larouche X-Patchwork-Id: 7053721 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 3519A9F373 for ; Fri, 21 Aug 2015 19:53:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1888C2053F for ; Fri, 21 Aug 2015 19:53:49 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id E91142054D for ; Fri, 21 Aug 2015 19:53:47 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 19D686E572; Fri, 21 Aug 2015 12:53:33 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org X-Greylist: delayed 319 seconds by postgrey-1.34 at gabe; Fri, 21 Aug 2015 06:30:22 PDT Received: from mtxmxout2.matrox.com (mtxmxout2.matrox.com [138.11.2.92]) by gabe.freedesktop.org (Postfix) with ESMTPS id 36FD56E620 for ; Fri, 21 Aug 2015 06:30:21 -0700 (PDT) Received: from venus.matrox.com (unknown [192.168.1.36]) by mtxmxout2.matrox.com (Postfix) with ESMTP id 1044C98348 for ; Fri, 21 Aug 2015 09:25:19 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=matrox.com; s=dkim; t=1440163519; bh=/xFns1WM8PxF+KEGc77F5MeW5O55o8wsT8bCp2IwKtY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=wjBRQdbRwlpKZkDkdrNM1/RyTd6Jzqg3TuVGb3vUvPzPos+KhUW0OkK4wdr99Zz3e eQlIYD5KaOIMdwIa7cet/g7Z5nAtOPTnBUtJA3GMz49KUklCFq+MMMGdI5Kj/+wdES Awy3nC6bYKujsPgLTVt8gDUiBF94t8gRnaL7dPxc= Received: (from ssmsp@localhost) by venus.matrox.com (8.14.6/8.13.2) id t7LDPJFB017753 for dri-devel@lists.freedesktop.org; Fri, 21 Aug 2015 09:25:19 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by venus.matrox.com (Postfix) with ESMTP id F080C5F757 for ; Fri, 21 Aug 2015 09:25:18 -0400 (EDT) X-Virus-MTX-Scanned: by Matrox Virus scanner at venus.matrox.com Received: from venus.matrox.com ([127.0.0.1]) by localhost (venus.matrox.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Y2rADNGqOlFJ for ; Fri, 21 Aug 2015 09:25:18 -0400 (EDT) Received: from venus-in.matrox.com (localhost.localdomain [127.0.0.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by venus.matrox.com (Postfix) with ESMTPS id DD84B5F747 for ; Fri, 21 Aug 2015 09:25:18 -0400 (EDT) Received: from mlaroucheRHEL.matrox.com (dyn-152-65.matrox.com [192.168.152.65]) by venus-in.matrox.com (Postfix) with ESMTP id DAD5861BE0; Fri, 21 Aug 2015 09:25:18 -0400 (EDT) From: mathieu.larouche@matrox.com To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/2] drm/mgag200: Add support for a new G200eW3 chipset Date: Fri, 21 Aug 2015 09:24:05 -0400 Message-Id: <8446d91a8ab4644cd5493903d084d5405c244952.1440084513.git.mathieu.larouche@matrox.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: References: X-Mailman-Approved-At: Fri, 21 Aug 2015 12:53:30 -0700 Cc: Mathieu Larouche X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Mathieu Larouche - Added support for the new deviceID for G200eW3 - Added PLL algorithm for the G200eW3 - Added some initialization code for G200eW3 Signed-off-by: Mathieu Larouche --- drivers/gpu/drm/mgag200/mgag200_drv.c | 1 + drivers/gpu/drm/mgag200/mgag200_drv.h | 1 + drivers/gpu/drm/mgag200/mgag200_i2c.c | 1 + drivers/gpu/drm/mgag200/mgag200_main.c | 15 +++-- drivers/gpu/drm/mgag200/mgag200_mode.c | 108 +++++++++++++++++++++++---------- 5 files changed, 91 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 9774599..b0af774 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -35,6 +35,7 @@ static const struct pci_device_id pciidlist[] = { { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB }, { PCI_VENDOR_ID_MATROX, 0x533, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EH }, { PCI_VENDOR_ID_MATROX, 0x534, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_ER }, + { PCI_VENDOR_ID_MATROX, 0x536, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EW3 }, {0,} }; diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index e9eea1d..912151c 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -180,6 +180,7 @@ enum mga_type { G200_EV, G200_EH, G200_ER, + G200_EW3, }; #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index d3dcf54..10535e3 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -101,6 +101,7 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev) case G200_SE_B: case G200_EV: case G200_WB: + case G200_EW3: data = 1; clock = 2; break; diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index f6b283b..4281cc8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -82,12 +82,19 @@ static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem) int orig; int test1, test2; int orig1, orig2; + unsigned int vram_size; - /* Probe */ - orig = ioread16(mem); - iowrite16(0, mem); + /* Probe */ + orig = ioread16(mem); + iowrite16(0, mem); - for (offset = 0x100000; offset < mdev->mc.vram_window; offset += 0x4000) { + vram_size = mdev->mc.vram_window; + + if ((mdev->type == G200_EW3) && (vram_size >= 0x1000000)) { + vram_size = vram_size - 0x400000; + } + + for (offset = 0x100000; offset < vram_size; offset += 0x4000) { orig1 = ioread8(mem + offset); orig2 = ioread8(mem + offset + 0x100); diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index ad4b901..9abc06f 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -159,7 +159,7 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) { unsigned int vcomax, vcomin, pllreffreq; unsigned int delta, tmpdelta, permitteddelta; - unsigned int testp, testm, testn; + unsigned int testp, testm, testn, testp2; unsigned int p, m, n; unsigned int computed; int i, j, tmpcount, vcount; @@ -167,36 +167,76 @@ static int mga_g200wb_set_plls(struct mga_device *mdev, long clock) u8 tmp; m = n = p = 0; - vcomax = 550000; - vcomin = 150000; - pllreffreq = 48000; delta = 0xffffffff; permitteddelta = clock * 5 / 1000; - for (testp = 1; testp < 9; testp++) { - if (clock * testp > vcomax) - continue; - if (clock * testp < vcomin) - continue; - - for (testm = 1; testm < 17; testm++) { - for (testn = 1; testn < 151; testn++) { - computed = (pllreffreq * testn) / - (testm * testp); - if (computed > clock) - tmpdelta = computed - clock; - else - tmpdelta = clock - computed; - if (tmpdelta < delta) { - delta = tmpdelta; - n = testn - 1; - m = (testm - 1) | ((n >> 1) & 0x80); - p = testp - 1; - } - } - } - } + if (mdev->type == G200_EW3) { + + vcomax = 800000; + vcomin = 400000; + pllreffreq = 25000; + + for (testp = 1; testp < 8; testp++) { + for (testp2 = 1; testp2 < 8; testp2++) { + if (testp < testp2) + continue; + if ((clock * testp * testp2) > vcomax) + continue; + if ((clock * testp * testp2) < vcomin) + continue; + for (testm = 1; testm < 26; testm++) { + for (testn = 32; testn < 2048 ; testn++) { + computed = (pllreffreq * testn) / + (testm * testp * testp2); + if (computed > clock) + tmpdelta = computed - clock; + else + tmpdelta = clock - computed; + if (tmpdelta < delta) { + delta = tmpdelta; + m = ((testn & 0x100) >> 1) | + (testm); + n = (testn & 0xFF); + p = ((testn & 0x600) >> 3) | + (testp2 << 3) | + (testp); + } + } + } + } + } + } else { + + vcomax = 550000; + vcomin = 150000; + pllreffreq = 48000; + + for (testp = 1; testp < 9; testp++) { + if (clock * testp > vcomax) + continue; + if (clock * testp < vcomin) + continue; + + for (testm = 1; testm < 17; testm++) { + for (testn = 1; testn < 151; testn++) { + computed = (pllreffreq * testn) / + (testm * testp); + if (computed > clock) + tmpdelta = computed - clock; + else + tmpdelta = clock - computed; + if (tmpdelta < delta) { + delta = tmpdelta; + n = testn - 1; + m = (testm - 1) | + ((n >> 1) & 0x80); + p = testp - 1; + } + } + } + } + } for (i = 0; i <= 32 && pll_locked == false; i++) { if (i > 0) { @@ -572,6 +611,7 @@ static int mga_crtc_set_plls(struct mga_device *mdev, long clock) return mga_g200se_set_plls(mdev, clock); break; case G200_WB: + case G200_EW3: return mga_g200wb_set_plls(mdev, clock); break; case G200_EV: @@ -823,6 +863,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, option2 = 0x00008000; break; case G200_WB: + case G200_EW3: dacvalue[MGA1064_VREF_CTL] = 0x07; option = 0x41049120; option2 = 0x0000b000; @@ -878,7 +919,10 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if (IS_G200_SE(mdev) && ((i == 0x2c) || (i == 0x2d) || (i == 0x2e))) continue; - if ((mdev->type == G200_EV || mdev->type == G200_WB || mdev->type == G200_EH) && + if ((mdev->type == G200_EV || + mdev->type == G200_WB || + mdev->type == G200_EH || + mdev->type == G200_EW3) && (i >= 0x44) && (i <= 0x4e)) continue; @@ -980,7 +1024,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, else ext_vga[3] = ((1 << bppshift) - 1) | 0x80; ext_vga[4] = 0; - if (mdev->type == G200_WB) + if (mdev->type == G200_WB || mdev->type == G200_EW3) ext_vga[1] |= 0x88; /* Set pixel clocks */ @@ -996,6 +1040,9 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, if (mdev->type == G200_ER) WREG_ECRT(0x24, 0x5); + if (mdev->type == G200_EW3) + WREG_ECRT(0x34, 0x5); + if (mdev->type == G200_EV) { WREG_ECRT(6, 0); } @@ -1208,7 +1255,7 @@ static void mga_crtc_prepare(struct drm_crtc *crtc) WREG_SEQ(1, tmp | 0x20); } - if (mdev->type == G200_WB) + if (mdev->type == G200_WB || mdev->type == G200_EW3) mga_g200wb_prepare(crtc); WREG_CRT(17, 0); @@ -1225,7 +1272,7 @@ static void mga_crtc_commit(struct drm_crtc *crtc) const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; u8 tmp; - if (mdev->type == G200_WB) + if (mdev->type == G200_WB || mdev->type == G200_EW3) mga_g200wb_commit(crtc); if (mdev->type == G200_SE_A || mdev->type == G200_SE_B) {