From patchwork Mon Feb 8 19:45:47 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Deucher X-Patchwork-Id: 77801 Received: from lists.sourceforge.net (lists.sourceforge.net [216.34.181.88]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o18Jkx4m013869 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 8 Feb 2010 19:47:35 GMT Received: from localhost ([127.0.0.1] helo=sfs-ml-2.v29.ch3.sourceforge.com) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1NeZYT-0002fZ-Ew; Mon, 08 Feb 2010 19:45:57 +0000 Received: from sfi-mx-4.v28.ch3.sourceforge.com ([172.29.28.124] helo=mx.sourceforge.net) by sfs-ml-2.v29.ch3.sourceforge.com with esmtp (Exim 4.69) (envelope-from ) id 1NeZYS-0002fT-4P for dri-devel@lists.sourceforge.net; Mon, 08 Feb 2010 19:45:56 +0000 Received-SPF: pass (sfi-mx-4.v28.ch3.sourceforge.com: domain of gmail.com designates 209.85.220.216 as permitted sender) client-ip=209.85.220.216; envelope-from=alexdeucher@gmail.com; helo=mail-fx0-f216.google.com; Received: from mail-fx0-f216.google.com ([209.85.220.216]) by sfi-mx-4.v28.ch3.sourceforge.com with esmtp (Exim 4.69) id 1NeZYR-00060g-04 for dri-devel@lists.sourceforge.net; Mon, 08 Feb 2010 19:45:56 +0000 Received: by fxm8 with SMTP id 8so5786315fxm.6 for ; Mon, 08 Feb 2010 11:45:49 -0800 (PST) MIME-Version: 1.0 Received: by 10.223.101.143 with SMTP id c15mr6244886fao.91.1265658348843; Mon, 08 Feb 2010 11:45:48 -0800 (PST) Date: Mon, 8 Feb 2010 14:45:47 -0500 Message-ID: Subject: [PATCH] drm/radeon/kms: fix prescale calculations From: Alex Deucher To: Dave Airlie , DRI Development Mailing List X-Spam-Score: -1.5 (-) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain -0.0 SPF_PASS SPF: sender matches SPF record -0.0 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.0 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.0 AWL AWL: From: address is in the auto white-list X-Headers-End: 1NeZYR-00060g-04 X-BeenThere: dri-devel@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.sourceforge.net X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 08 Feb 2010 19:47:35 +0000 (UTC) diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 272c45d..d15fa5e 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -181,6 +181,87 @@ static void set_data(void *i2c_priv, int data) WREG32(rec->en_data_reg, val); } +static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) +{ + struct radeon_pll *spll = &rdev->clock.spll; + u32 sclk = radeon_get_engine_clock(rdev); + u32 prescale = 0; + u32 n, m; + u8 loop; + int i2c_clock; + + switch (rdev->family) { + case CHIP_R100: + case CHIP_RV100: + case CHIP_RS100: + case CHIP_RV200: + case CHIP_RS200: + case CHIP_R200: + case CHIP_RV250: + case CHIP_RS300: + case CHIP_RV280: + case CHIP_R300: + case CHIP_R350: + case CHIP_RV350: + n = (spll->reference_freq) / (4 * 6); + for (loop = 1; loop < 255; loop++) { + if ((loop * (loop - 1)) > n) + break; + } + m = loop - 1; + prescale = m | (loop << 8); + break; + case CHIP_RV380: + case CHIP_RS400: + case CHIP_RS480: + case CHIP_R420: + case CHIP_R423: + case CHIP_RV410: + sclk = radeon_get_engine_clock(rdev); + prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; + break; + case CHIP_RS600: + case CHIP_RS690: + case CHIP_RS740: + /* todo */ + break; + case CHIP_RV515: + case CHIP_R520: + case CHIP_RV530: + case CHIP_RV560: + case CHIP_RV570: + case CHIP_R580: + i2c_clock = 50; + sclk = radeon_get_engine_clock(rdev); + if (rdev->family == CHIP_R520) + prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock)); + else + prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; + break; + case CHIP_R600: + case CHIP_RV610: + case CHIP_RV630: + case CHIP_RV670: + /* todo */ + break; + case CHIP_RV620: + case CHIP_RV635: + case CHIP_RS780: + case CHIP_RS880: + case CHIP_RV770: + case CHIP_RV730: + case CHIP_RV710: + case CHIP_RV740: + /* todo */ + break; + default: + DRM_ERROR("i2c: unhandled radeon chip\n"); + break; + } + return prescale; +} + + /* hw i2c engine for r1xx-4xx hardware * hw can buffer up to 15 bytes */ @@ -192,7 +273,7 @@ static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap, struct radeon_i2c_bus_rec *rec = &i2c->rec; struct i2c_msg *p; int i, j, k, ret = num; - u32 sclk, prescale; + u32 prescale; u32 i2c_cntl_0, i2c_cntl_1, i2c_data; u32 tmp, reg; @@ -200,8 +281,7 @@ static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap, /* take the pm lock since we need a constant sclk */ mutex_lock(&rdev->pm.mutex); - sclk = radeon_get_engine_clock(rdev); - prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; + prescale = radeon_get_i2c_prescale(rdev); reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | RADEON_I2C_START | @@ -444,9 +524,8 @@ static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap, struct radeon_device *rdev = i2c->dev->dev_private; struct radeon_i2c_bus_rec *rec = &i2c->rec; struct i2c_msg *p; - int i2c_clock = 50; int i, j, remaining, current_count, buffer_offset, ret = num; - u32 sclk, prescale; + u32 prescale; u32 tmp, reg; u32 saved1, saved2; @@ -454,11 +533,7 @@ static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap, /* take the pm lock since we need a constant sclk */ mutex_lock(&rdev->pm.mutex); - sclk = radeon_get_engine_clock(rdev); - if (rdev->family == CHIP_R520) - prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock)); - else - prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; + prescale = radeon_get_i2c_prescale(rdev); /* clear gpio mask bits */ tmp = RREG32(rec->mask_clk_reg);