From owner-svn-src-head@FreeBSD.ORG Fri Aug 16 19:40:01 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id A92B6E43; Fri, 16 Aug 2013 19:40:01 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 7CF502CF6; Fri, 16 Aug 2013 19:40:01 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r7GJe1Y5025946; Fri, 16 Aug 2013 19:40:01 GMT (envelope-from ian@svn.freebsd.org) Received: (from ian@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r7GJe17H025945; Fri, 16 Aug 2013 19:40:01 GMT (envelope-from ian@svn.freebsd.org) Message-Id: <201308161940.r7GJe17H025945@svn.freebsd.org> From: Ian Lepore Date: Fri, 16 Aug 2013 19:40:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r254423 - head/sys/dev/sdhci X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Aug 2013 19:40:01 -0000 Author: ian Date: Fri Aug 16 19:40:00 2013 New Revision: 254423 URL: http://svnweb.freebsd.org/changeset/base/254423 Log: When the timeout clock is based on the SD clock, the timeout counter has to be recalculated every time the SD clock frequency changes. Also, tidy up the counter calculation... it makes no sense to calculate a value one larger than the limit, then whine that it's too large and truncate it to the limit. If the BROKEN_TIMEOUT quirk is set, don't calculate the counter at all, just set it to the limit value. Modified: head/sys/dev/sdhci/sdhci.c Modified: head/sys/dev/sdhci/sdhci.c ============================================================================== --- head/sys/dev/sdhci/sdhci.c Fri Aug 16 19:33:36 2013 (r254422) +++ head/sys/dev/sdhci/sdhci.c Fri Aug 16 19:40:00 2013 (r254423) @@ -238,6 +238,11 @@ sdhci_set_clock(struct sdhci_slot *slot, /* If no clock requested - left it so. */ if (clock == 0) return; + + /* Recalculate timeout clock frequency based on the new sd clock. */ + if (slot->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) + slot->timeout_clk = slot->clock / 1000; + if (slot->version < SDHCI_SPEC_300) { /* Looking for highest freq <= clock. */ res = slot->max_clk; @@ -545,7 +550,8 @@ sdhci_init_slot(device_t dev, struct sdh if (slot->timeout_clk == 0) { device_printf(dev, "Hardware doesn't specify timeout clock " - "frequency.\n"); + "frequency, setting BROKEN_TIMEOUT quirk.\n"); + slot->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; } slot->host.f_min = SDHCI_MIN_FREQ(slot->bus, slot); @@ -855,24 +861,22 @@ sdhci_start_data(struct sdhci_slot *slot /* Calculate and set data timeout.*/ /* XXX: We should have this from mmc layer, now assume 1 sec. */ - target_timeout = 1000000; - div = 0; - current_timeout = (1 << 13) * 1000 / slot->timeout_clk; - while (current_timeout < target_timeout) { - div++; - current_timeout <<= 1; - if (div >= 0xF) - break; - } - /* Compensate for an off-by-one error in the CaFe chip.*/ - if (slot->quirks & SDHCI_QUIRK_INCR_TIMEOUT_CONTROL) - div++; - if (div >= 0xF) { - slot_printf(slot, "Timeout too large!\n"); + if (slot->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) { div = 0xE; + } else { + target_timeout = 1000000; + div = 0; + current_timeout = (1 << 13) * 1000 / slot->timeout_clk; + while (current_timeout < target_timeout && div < 0xE) { + ++div; + current_timeout <<= 1; + } + /* Compensate for an off-by-one error in the CaFe chip.*/ + if (div < 0xE && + (slot->quirks & SDHCI_QUIRK_INCR_TIMEOUT_CONTROL)) { + ++div; + } } - if (slot->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL) - div = 0xE; WR1(slot, SDHCI_TIMEOUT_CONTROL, div); if (data == NULL)