Module Name:    src
Committed By:   matt
Date:           Sat Sep  7 19:48:57 UTC 2013

Modified Files:
        src/sys/arch/arm/allwinner: awin_ahcisata.c awin_usb.c
Added Files:
        src/sys/arch/arm/allwinner: sdxcreg.h

Log Message:
Add more initialization code for AHCI and USB.
Alas, neither still is coming up.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/allwinner/awin_ahcisata.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/allwinner/awin_usb.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/allwinner/sdxcreg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/allwinner/awin_ahcisata.c
diff -u src/sys/arch/arm/allwinner/awin_ahcisata.c:1.4 src/sys/arch/arm/allwinner/awin_ahcisata.c:1.5
--- src/sys/arch/arm/allwinner/awin_ahcisata.c:1.4	Sat Sep  7 02:10:02 2013
+++ src/sys/arch/arm/allwinner/awin_ahcisata.c	Sat Sep  7 19:48:57 2013
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_ahcisata.c,v 1.4 2013/09/07 02:10:02 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_ahcisata.c,v 1.5 2013/09/07 19:48:57 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -50,6 +50,7 @@ static void awin_ahci_attach(device_t, d
 
 struct awin_ahci_softc {
 	struct ahci_softc asc_sc;
+	struct awin_gpio_pindata asc_gpio_pin;
 	void *asc_ih;
 };
 
@@ -73,6 +74,70 @@ awin_ahci_match(device_t parent, cfdata_
 }
 
 static void
+awin_ahci_phy_init(struct awin_ahci_softc *asc)
+{
+	bus_space_tag_t bst = asc->asc_sc.sc_ahcit;
+	bus_space_handle_t bsh = asc->asc_sc.sc_ahcih;
+	u_int timeout;
+	uint32_t v;
+
+	/*
+	 * This is dark magic.
+	 */
+	bus_space_write_4(bst, bsh, AWIN_AHCI_RWCR_REG, 0);
+	delay(2);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS1R_REG, __BIT(19), 0);
+	delay(1);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS1R_REG,
+	    __BIT(23)|__BIT(18)|__SHIFTIN(5, __BITS(26,24)),
+	    __BITS(26,24));
+	delay(1);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS1R_REG,
+	    __BIT(17)|__BITS(10,9)|__BIT(7),
+	    __BIT(16)|__BITS(12,11)|__BIT(8)|__BIT(6));
+	delay(1);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS1R_REG,
+	    __BIT(28)|__BIT(15), 0);
+	delay(1);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS1R_REG, 0, __BIT(19));
+	delay(1);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS0R_REG,
+	    __BITS(21,20), __BIT(22));
+	delay(1);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS2R_REG,
+	    __BITS(9,8)|__BIT(5), __BITS(7,6));
+	delay(2);
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS0R_REG, __BIT(19), 0);
+	delay(2);
+
+	timeout = 100000;
+	do {
+		delay(1);
+		v = bus_space_read_4(bst, bsh, AWIN_AHCI_PHYCS0R_REG);
+	} while (--timeout && __SHIFTOUT(v, __BITS(30,28)) != 2);
+
+	if (!timeout) {
+		aprint_error_dev(
+		    asc->asc_sc.sc_atac.atac_dev,
+		    "SATA PHY power failed (%#x)\n", v);
+	}
+
+	awin_reg_set_clear(bst, bsh, AWIN_AHCI_PHYCS2R_REG, __BIT(24), 0);
+	timeout = 100000;
+	do {
+		delay(1);
+		v = bus_space_read_4(bst, bsh, AWIN_AHCI_PHYCS0R_REG);
+	} while (--timeout && (v & __BIT(24)));
+
+	if (!timeout) {
+		aprint_error_dev(
+		    asc->asc_sc.sc_atac.atac_dev,
+		    "SATA PHY calibration failed (%#x)\n", v);
+	}
+	bus_space_write_4(bst, bsh, AWIN_AHCI_RWCR_REG, 7);
+}
+
+static void
 awin_ahci_enable(bus_space_tag_t bst, bus_space_handle_t bsh)
 {
 	/*
@@ -85,7 +150,7 @@ awin_ahci_enable(bus_space_tag_t bst, bu
 	 */
 	awin_reg_set_clear(bst, bsh, AWIN_AHB_GATING0_REG,
 	    AWIN_AHB_GATING0_SATA, 0);
-	delay(10000);
+	delay(1000);
 
 	/*
 	 * Now turn it on.
@@ -114,6 +179,28 @@ awin_ahci_attach(device_t parent, device
 	aprint_naive(": AHCI SATA controller\n");
 	aprint_normal(": AHCI SATA controller\n");
 
+	/*
+	 * Bring up the PHY.
+	 */
+	awin_ahci_phy_init(asc);
+
+	/*
+	 * If there is a GPIO to turn on power, do it now.
+	 */
+	const char *pin_name;
+	prop_dictionary_t dict = device_properties(self);
+	if (prop_dictionary_get_cstring_nocopy(dict, "power-gpio", &pin_name)) {
+		if (awin_gpio_pin_reserve(pin_name, &asc->asc_gpio_pin)) {
+			awin_gpio_pindata_write(&asc->asc_gpio_pin, 1);
+		} else {
+			aprint_error_dev(self,
+			    "failed to reserve GPIO \"%s\"\n", pin_name);
+		}
+	}
+
+	/*
+	 * Establish the interrupt
+	 */
 	asc->asc_ih = intr_establish(loc->loc_intr, IPL_VM, IST_LEVEL,
 	    ahci_intr, sc);
 	if (asc->asc_ih == NULL) {

Index: src/sys/arch/arm/allwinner/awin_usb.c
diff -u src/sys/arch/arm/allwinner/awin_usb.c:1.6 src/sys/arch/arm/allwinner/awin_usb.c:1.7
--- src/sys/arch/arm/allwinner/awin_usb.c:1.6	Sat Sep  7 10:46:18 2013
+++ src/sys/arch/arm/allwinner/awin_usb.c	Sat Sep  7 19:48:57 2013
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_usb.c,v 1.6 2013/09/07 10:46:18 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_usb.c,v 1.7 2013/09/07 19:48:57 matt Exp $");
 
 #include <sys/bus.h>
 #include <sys/device.h>
@@ -67,6 +67,9 @@ struct awinusb_softc {
 	bus_space_tag_t usbsc_bst;
 	bus_space_handle_t usbsc_ehci_bsh;
 	bus_space_handle_t usbsc_ohci_bsh;
+	bus_space_handle_t usbsc_usb0_phy_csr_bsh;
+	u_int usbsc_number;
+	struct awin_gpio_pindata usbsc_drv_pin;
 
 	device_t usbsc_ohci_dev;
 	device_t usbsc_ehci_dev;
@@ -246,6 +249,42 @@ ehci_awinusb_attach(device_t parent, dev
 }
 #endif /* NEHCI > 0 */
 
+static void
+awin_usb_phy_write(struct awinusb_softc *usbsc, u_int bit_addr, u_int bits,
+	u_int len)
+{
+	bus_space_tag_t bst = usbsc->usbsc_bst;
+	bus_space_handle_t bsh = usbsc->usbsc_usb0_phy_csr_bsh;
+	uint32_t clk = AWIN_USB0_PHY_CSR_CLK0 << usbsc->usbsc_number;
+
+	uint32_t v = bus_space_read_4(bst, bsh, 0);
+
+	KASSERT((v & AWIN_USB0_PHY_CSR_CLK0) == 0);
+	KASSERT((v & AWIN_USB0_PHY_CSR_CLK1) == 0);
+	KASSERT((v & AWIN_USB0_PHY_CSR_CLK2) == 0);
+
+	v &= ~AWIN_USB0_PHY_CSR_ADDR;
+	v &= ~AWIN_USB0_PHY_CSR_DAT;
+
+	v |= __SHIFTIN(bit_addr, AWIN_USB0_PHY_CSR_ADDR);
+
+	/*
+	 * Bitbang the data to the phy, bit by bit, incrementing bit address
+	 * as we go.
+	 */
+	for (; len > 0; bit_addr++, bits >>= 1, len--) {
+		v |= __SHIFTIN(bits & 1, AWIN_USB0_PHY_CSR_DAT);
+		bus_space_write_4(bst, bsh, 0, v);
+		delay(1);
+		bus_space_write_4(bst, bsh, 0, v | clk);
+		delay(1);
+		bus_space_write_4(bst, bsh, 0, v);
+		delay(1);
+		v += __LOWEST_SET_BIT(AWIN_USB0_PHY_CSR_ADDR);
+		v &= ~AWIN_USB0_PHY_CSR_DAT;
+	}
+}
+
 static int awinusb_match(device_t, cfdata_t, void *);
 static void awinusb_attach(device_t, device_t, void *);
 
@@ -254,6 +293,12 @@ CFATTACH_DECL_NEW(awin_usb, sizeof(struc
 
 static int awinusb_ports;
 
+static const char awinusb_drvpin_names[2][8] = { "usb1drv", "usb2drv" };
+static const bus_size_t awinusb_dram_hpcr_regs[2] = {
+	AWIN_DRAM_HPCR_USB1_REG,
+	AWIN_DRAM_HPCR_USB2_REG,
+};
+
 int
 awinusb_match(device_t parent, cfdata_t cf, void *aux)
 {
@@ -277,8 +322,10 @@ awinusb_attach(device_t parent, device_t
 	const struct awin_locators * const loc = &aio->aio_loc;
 
 	awinusb_ports |= __BIT(loc->loc_port);
+
 	usbsc->usbsc_bst = aio->aio_core_bst;
 	usbsc->usbsc_dmat = aio->aio_dmat;
+	usbsc->usbsc_number = loc->loc_port + 1;
 
 	bus_space_subregion(usbsc->usbsc_bst, aio->aio_core_bsh,
 	    loc->loc_offset + AWIN_EHCI_OFFSET, AWIN_EHCI_SIZE,
@@ -286,6 +333,46 @@ awinusb_attach(device_t parent, device_t
 	bus_space_subregion(usbsc->usbsc_bst, aio->aio_core_bsh,
 	    loc->loc_offset + AWIN_OHCI_OFFSET, AWIN_OHCI_SIZE,
 	    &usbsc->usbsc_ohci_bsh);
+	bus_space_subregion(usbsc->usbsc_bst, aio->aio_core_bsh,
+	    AWIN_USB0_OFFSET + AWIN_USB0_PHY_CSR_REG, 4,
+	    &usbsc->usbsc_usb0_phy_csr_bsh);
+
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+	/*
+	 * Access to the USB phy is off USB0 so make sure it's on.
+	*/
+	awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_ccm_bsh,
+	    AWIN_AHB_GATING0_REG, AWIN_AHB_GATING0_USB0, 0);
+
+	awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_core_bsh,
+	    loc->loc_offset + AWIN_USB_PMU_IRQ_REG,
+	    AWIN_USB_PMU_IRQ_AHB_INCR8 | AWIN_USB_PMU_IRQ_AHB_INCR4
+	       | AWIN_USB_PMU_IRQ_AHB_INCRX | AWIN_USB_PMU_IRQ_ULPI_BYPASS,
+	    0);
+
+	/*
+	 * Allow USB DMA engine access to the DRAM.
+	 */
+	awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_core_bsh,
+	    AWIN_DRAM_OFFSET + awinusb_dram_hpcr_regs[loc->loc_port],
+	    AWIN_DRAM_HPCR_ACCESS_EN, 0);
+
+	/* initialize the USB phy */
+	awin_usb_phy_write(usbsc, 0x20, 0x14, 5);
+	awin_usb_phy_write(usbsc, 0x2a, 0x03, 2);
+
+	/*
+	 * Now get the GPIO that enables the power to the port and
+	 * turn it on.
+	 */
+	if (awin_gpio_pin_reserve(awinusb_drvpin_names[loc->loc_port],
+		    &usbsc->usbsc_drv_pin)) {
+		awin_gpio_pindata_write(&usbsc->usbsc_drv_pin, 1);
+	} else {
+		aprint_error_dev(self, "no power gpio found\n");
+	}
 
 	/*
 	 * Disable interrupts
@@ -301,9 +388,6 @@ awinusb_attach(device_t parent, device_t
 	    caplength + EHCI_USBINTR, 0);
 #endif
 
-	aprint_naive("\n");
-	aprint_normal("\n");
-
 #if NOHCI > 0
 	struct awinusb_attach_args usbaa_ohci = {
 		.usbaa_name = "ohci",

Added files:

Index: src/sys/arch/arm/allwinner/sdxcreg.h
diff -u /dev/null src/sys/arch/arm/allwinner/sdxcreg.h:1.1
--- /dev/null	Sat Sep  7 19:48:57 2013
+++ src/sys/arch/arm/allwinner/sdxcreg.h	Sat Sep  7 19:48:57 2013
@@ -0,0 +1,131 @@
+/* $NetBSD: sdxcreg.h,v 1.1 2013/09/07 19:48:57 matt Exp $ */
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ARM_ALLWINNER_SDXCREG_H_
+#define _ARM_ALLWINNER_SDXCREG_H_
+
+/* SDXC definitions */
+#define SDXC_GCTRL_REG			0x0000
+#define SDXC_CLKCR_REG			0x0004
+#define SDXC_TIMEOUT_REG		0x0008
+#define SDXC_WIDTH_REG			0x000c
+#define SDXC_BLKSZ_REG			0x0010
+#define SDXC_BYTECNT_REG		0x0014
+#define SDXC_CMD_REG			0x0018
+#define SDXC_ARG_REG			0x001c
+#define SDXC_RESP0_REG			0x0020
+#define SDXC_RESP1_REG			0x0024
+#define SDXC_RESP2_REG			0x0028
+#define SDXC_RESP3_REG			0x002c
+#define SDXC_IMASK_REG			0x0030
+#define SDXC_MINT_REG			0x0034
+#define SDXC_RINT_REG			0x0038
+#define SDXC_STATUS_REG			0x003c
+#define SDXC_FTRGLVL_REG		0x0040
+#define SDXC_FUNCSEL_REG		0x0044
+#define SDXC_CBCR_REG			0x0048
+#define SDXC_BBCR_REG			0x004c
+#define SDXC_DMAC_REG			0x0080
+#define SDXC_DLBA_REG			0x0084
+#define SDXC_IDST_REG			0x0088
+#define SDXC_IDIE_REG			0x008c
+#define SDXC_CHDA_REG			0x0090
+#define SDXC_CBDA_REG			0x0094
+#define SDXC_FIFO_REG			0x0100
+
+#define	SDXC_GCTRL_AHB_ACCESS		__BIT(31)
+#define	SDXC_GCTRL_DDR_MODE		__BIT(10)
+#define	SDXC_GCTRL_POS_EDGE_LATCH_DATA	__BIT(9)
+#define	SDXC_GCTRL_DEBOUNCE_ENABLE	__BIT(8)
+#define	SDXC_GCTRL_DMA_ENABLE		__BIT(5)
+#define	SDXC_GCTRL_INT_ENABLE		__BIT(4)
+#define	SDXC_GCTRL_DMA_RESET		__BIT(2)
+#define	SDXC_GCTRL_FIFO_RESET		__BIT(1)
+#define	SDXC_GCTRL_SOFT_RESET		__BIT(0)
+
+#define	SDXC_CARD_LOW_POWER_ON		__BIT(17)
+#define	SDXC_CARD_CLK_ON		__BIT(16)
+
+#define SDXC_BUS_WIDTH_1		(0)
+#define SDXC_BUS_WIDTH_4		(1)
+#define SDXC_BUS_WIDTH_8		(2)
+
+#define SDXC_CMD_START			__BIT(31)
+#define SDXC_CMD_VOL_SWITCH		__BIT(27)
+#define SDXC_CMD_DISBALE_BOOT		__BIT(26)
+#define SDXC_CMD_BOOT_ACK_EXP		__BIT(25)
+#define SDXC_CMD_ALT_BOOT_OP		__BIT(24)
+#define SDXC_CMD_END_BOOT		__BIT(24)
+#define SDXC_CMD_CCS_EXP		__BIT(23)
+#define SDXC_CMD_RD_CE_ATA_DEV		__BIT(22)
+#define SDXC_CMD_UP_CLK_ONLY		__BIT(21)
+#define SDXC_CMD_SEND_INIT_SEQ		__BIT(15)
+#define SDXC_CMD_STOP_ABORT_CMD		__BIT(11)
+#define SDXC_CMD_WAIT_PRE_OVER		__BIT(11)
+#define SDXC_CMD_SEND_AUTO_STOP		__BIT(11)
+#define SDXC_CMD_SEQ_MODE		__BIT(11)
+#define SDXC_CMD_WRITE			__BIT(10)
+#define SDXC_CMD_DATA_EXP		__BIT(9)
+#define SDXC_CMD_CHECK_RESP_CRC		__BIT(8)
+#define SDXC_CMD_LONG_RESP		__BIT(7)
+#define SDXC_CMD_RESP_EXP		__BIT(6)
+
+#define SDXC_INT_ERR_SUM		( SDXC_INT_END_BIT_ERR \
+					| SDXC_INT_START_BIT_ERR \
+					| SDXC_INT_HARDWARE_LOCKED \
+					| SDXC_INT_FIFO_RUN_ERR \
+					| SDXC_INT_DATA_TIMEOUT \
+					| SDXC_INT_RESP_TIMEOUT \
+					| SDXC_INT_RESP_CRC_ERR \
+					| SDXC_INT_DATA_CRC_ERR \
+					| SDXC_INT_RESP_ERR )
+#define SDXC_INT_CARD_REMOVE		__BIT(31)
+#define SDXC_INT_CARD_INSERT		__BIT(30)
+#define SDXC_INT_SDIO_INT		__BIT(16)
+#define SDXC_INT_END_BIT_ERR		__BIT(15)
+#define SDXC_INT_AUTO_CMD_DONE		__BIT(14)
+#define SDXC_INT_START_BIT_ERR		__BIT(13)
+#define SDXC_INT_HARDWARE_LOCKED	__BIT(12)
+#define SDXC_INT_FIFO_RUN_ERR		__BIT(11)
+#define SDXC_INT_VOL_CHG_DONE		__BIT(10)
+#define SDXC_INT_DATA_STARVE		__BIT(10)
+#define SDXC_INT_BOOT_START		__BIT(9)
+#define SDXC_INT_DATA_TIMEOUT		__BIT(9)
+#define SDXC_INT_ACK_RCV		__BIT(8)
+#define SDXC_INT_RESP_TIMEOUT		__BIT(8)
+#define SDXC_INT_DATA_CRC_ERR		__BIT(7)
+#define SDXC_INT_RESP_CRC_ERR		__BIT(6)
+#define SDXC_INT_RX_DATA_REQ		__BIT(5)
+#define SDXC_INT_TX_DATA_REQ		__BIT(4)
+#define SDXC_INT_DATA_OVER		__BIT(3)
+#define SDXC_INT_CMD_DONE		__BIT(2)
+#define SDXC_INT_RESP_ERR		__BIT(1)
+
+#endif /* _ARM_ALLWINNER_SDXCREG_H_ */

Reply via email to