From owner-svn-src-head@FreeBSD.ORG Fri Mar 20 16:54:23 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 5D2A4F4C; Fri, 20 Mar 2015 16:54:23 +0000 (UTC) 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)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 4797C871; Fri, 20 Mar 2015 16:54:23 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2KGsNcx037702; Fri, 20 Mar 2015 16:54:23 GMT (envelope-from andrew@FreeBSD.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2KGsMNO037699; Fri, 20 Mar 2015 16:54:22 GMT (envelope-from andrew@FreeBSD.org) Message-Id: <201503201654.t2KGsMNO037699@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: andrew set sender to andrew@FreeBSD.org using -f From: Andrew Turner Date: Fri, 20 Mar 2015 16:54:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r280294 - head/sys/arm/broadcom/bcm2835 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.18-1 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, 20 Mar 2015 16:54:23 -0000 Author: andrew Date: Fri Mar 20 16:54:21 2015 New Revision: 280294 URL: https://svnweb.freebsd.org/changeset/base/280294 Log: Add a helper function to read clock frequencies from videocore and use this to get the default frequency of the sdhci device. While here use a u_int to hold the frequency as it may be too large to fit in a 32-bit signed integer. This is the case when we have a 250MHz clock. Modified: head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c head/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Modified: head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c ============================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c Fri Mar 20 16:05:13 2015 (r280293) +++ head/sys/arm/broadcom/bcm2835/bcm2835_mbox.c Fri Mar 20 16:54:21 2015 (r280294) @@ -284,53 +284,63 @@ bcm2835_mbox_dma_cb(void *arg, bus_dma_s *addr = PHYS_TO_VCBUS(segs[0].ds_addr); } -int -bcm2835_mbox_set_power_state(device_t dev, uint32_t device_id, boolean_t on) +static void * +bcm2835_mbox_init_dma(device_t dev, size_t len, bus_dma_tag_t *tag, + bus_dmamap_t *map, bus_addr_t *phys) { - struct msg_set_power_state *msg; - bus_dma_tag_t msg_tag; - bus_dmamap_t msg_map; - bus_addr_t msg_phys; - void *msg_buf; - uint32_t reg; - device_t mbox; + void *buf; int err; - /* get mbox device */ - mbox = devclass_get_device(devclass_find("mbox"), 0); - if (mbox == NULL) { - device_printf(dev, "can't find mbox\n"); - return (ENXIO); - } - err = bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, - sizeof(struct msg_set_power_state), 1, - sizeof(struct msg_set_power_state), 0, - NULL, NULL, &msg_tag); + len, 1, len, 0, NULL, NULL, tag); if (err != 0) { device_printf(dev, "can't create DMA tag\n"); - return (ENXIO); + return (NULL); } - err = bus_dmamem_alloc(msg_tag, (void **)&msg_buf, 0, &msg_map); + err = bus_dmamem_alloc(*tag, &buf, 0, map); if (err != 0) { - bus_dma_tag_destroy(msg_tag); + bus_dma_tag_destroy(*tag); device_printf(dev, "can't allocate dmamem\n"); - return (ENXIO); + return (NULL); } - err = bus_dmamap_load(msg_tag, msg_map, msg_buf, + err = bus_dmamap_load(*tag, *map, buf, sizeof(struct msg_set_power_state), bcm2835_mbox_dma_cb, - &msg_phys, 0); + phys, 0); if (err != 0) { - bus_dmamem_free(msg_tag, msg_buf, msg_map); - bus_dma_tag_destroy(msg_tag); + bus_dmamem_free(*tag, buf, *map); + bus_dma_tag_destroy(*tag); device_printf(dev, "can't load DMA map\n"); + return (NULL); + } + + return (buf); +} + +int +bcm2835_mbox_set_power_state(device_t dev, uint32_t device_id, boolean_t on) +{ + struct msg_set_power_state *msg; + bus_dma_tag_t msg_tag; + bus_dmamap_t msg_map; + bus_addr_t msg_phys; + uint32_t reg; + device_t mbox; + + /* get mbox device */ + mbox = devclass_get_device(devclass_find("mbox"), 0); + if (mbox == NULL) { + device_printf(dev, "can't find mbox\n"); return (ENXIO); } - msg = msg_buf; + /* Allocate memory for the message */ + msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map, + &msg_phys); + if (msg == NULL) + return (ENOMEM); memset(msg, 0, sizeof(*msg)); msg->hdr.buf_size = sizeof(*msg); @@ -350,7 +360,56 @@ bcm2835_mbox_set_power_state(device_t de MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, ®); bus_dmamap_unload(msg_tag, msg_map); - bus_dmamem_free(msg_tag, msg_buf, msg_map); + bus_dmamem_free(msg_tag, msg, msg_map); + bus_dma_tag_destroy(msg_tag); + + return (0); +} + +int +bcm2835_mbox_get_clock_rate(device_t dev, uint32_t clock_id, uint32_t *hz) +{ + struct msg_get_clock_rate *msg; + bus_dma_tag_t msg_tag; + bus_dmamap_t msg_map; + bus_addr_t msg_phys; + uint32_t reg; + device_t mbox; + + /* get mbox device */ + mbox = devclass_get_device(devclass_find("mbox"), 0); + if (mbox == NULL) { + device_printf(dev, "can't find mbox\n"); + return (ENXIO); + } + + /* Allocate memory for the message */ + msg = bcm2835_mbox_init_dma(dev, sizeof(*msg), &msg_tag, &msg_map, + &msg_phys); + if (msg == NULL) + return (ENOMEM); + + memset(msg, 0, sizeof(*msg)); + msg->hdr.buf_size = sizeof(*msg); + msg->hdr.code = BCM2835_MBOX_CODE_REQ; + msg->tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE; + msg->tag_hdr.val_buf_size = sizeof(msg->body); + msg->tag_hdr.val_len = sizeof(msg->body.req); + msg->body.req.clock_id = clock_id; + msg->end_tag = 0; + + bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREWRITE); + MBOX_WRITE(mbox, BCM2835_MBOX_CHAN_PROP, (uint32_t)msg_phys); + bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTWRITE); + + bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_PREREAD); + MBOX_READ(mbox, BCM2835_MBOX_CHAN_PROP, ®); + bus_dmamap_sync(msg_tag, msg_map, BUS_DMASYNC_POSTREAD); + + *hz = msg->body.resp.rate_hz; + + bus_dmamap_unload(msg_tag, msg_map); + bus_dmamem_free(msg_tag, msg, msg_map); bus_dma_tag_destroy(msg_tag); return (0); Modified: head/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h ============================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h Fri Mar 20 16:05:13 2015 (r280293) +++ head/sys/arm/broadcom/bcm2835/bcm2835_mbox_prop.h Fri Mar 20 16:54:21 2015 (r280294) @@ -179,6 +179,8 @@ struct msg_get_min_clock_rate { uint32_t end_tag; }; +int bcm2835_mbox_get_clock_rate(device_t, uint32_t, uint32_t *); + #define BCM2835_MBOX_TURBO_ON 1 #define BCM2835_MBOX_TURBO_OFF 0 Modified: head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c ============================================================================== --- head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Fri Mar 20 16:05:13 2015 (r280293) +++ head/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c Fri Mar 20 16:54:21 2015 (r280294) @@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$"); #include "sdhci_if.h" #include "bcm2835_dma.h" +#include #include "bcm2835_vcbus.h" #define BCM2835_DEFAULT_SDHCI_FREQ 50 @@ -154,18 +155,38 @@ bcm_sdhci_attach(device_t dev) int rid, err; phandle_t node; pcell_t cell; - int default_freq; + u_int default_freq; sc->sc_dev = dev; sc->sc_req = NULL; - err = 0; - default_freq = BCM2835_DEFAULT_SDHCI_FREQ; + err = bcm2835_mbox_set_power_state(dev, BCM2835_MBOX_POWER_ID_EMMC, + TRUE); + if (err != 0) { + if (bootverbose) + device_printf(dev, "Unable to enable the power\n"); + return (err); + } + + default_freq = 0; + err = bcm2835_mbox_get_clock_rate(dev, BCM2835_MBOX_CLOCK_ID_EMMC, + &default_freq); + if (err == 0) { + /* Convert to MHz */ + default_freq /= 1000000; + if (bootverbose) + device_printf(dev, "default frequency: %dMHz\n", + default_freq); + } + if (default_freq == 0) + default_freq = BCM2835_DEFAULT_SDHCI_FREQ; + node = ofw_bus_get_node(sc->sc_dev); if ((OF_getprop(node, "clock-frequency", &cell, sizeof(cell))) > 0) - default_freq = (int)fdt32_to_cpu(cell)/1000000; + default_freq = fdt32_to_cpu(cell)/1000000; - dprintf("SDHCI frequency: %dMHz\n", default_freq); + if (bootverbose) + device_printf(dev, "SDHCI frequency: %dMHz\n", default_freq); mtx_init(&sc->sc_mtx, "bcm sdhci", "sdhci", MTX_DEF);