Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 12 Nov 2010 09:32:14 -0200
From:      Luiz Otavio O Souza <lists.br@gmail.com>
To:        freebsd-mips@freebsd.org
Subject:   [patch] RSPRO RTC hack
Message-ID:  <10D25047-014A-4FC9-B74D-655729053704@gmail.com>

index | next in thread | raw e-mail

[-- Attachment #1 --]
Hello mips,

Here are my patches for the RTC on RSPRO.

Please apply the ar71xx_spi_cs_mux.diff first and then the rspro-rtc.diff.

The first patch (ar71xx_spi_cs_mux.diff) is just a cleanup on code that does the CS selection on SPI driver. It _will_ change the CS number for onboard flash (please check the RSPRO.hints sample), but other than that it don't change the behaviour of spi driver (i.e. it doesn't fix the RTC problem).

The real fix (which is a hack) is the second patch (rspro-rtc.diff).

The problem with RSPRO RTC is that ar71xx_spi_chip_deactivate() wants to disable all chips in spi bus by setting all CS pins to high, but in RSPRO case the CS0 high enables the RTC chip, so (in short) it will never be disabled (well it is disabled only when flash is used)...

With this cenario the RTC chip got lost and fail to understand the first byte sent as 'command'.

My patch simply disables the chip for a while (100ms) before it get enabled again (it works on activate time). That is the simplest solution i've found, but it applies only for RSPRO and right now we don't have anything to track the board model we're running on and enable this (and others) software hacks as needed.

It should not break others boards, but it will add a 100ms delay for every spi access (without any good reason).

Cheers,
Luiz




[-- Attachment #2 --]
Index: mips/atheros/ar71xx_spi.c
===================================================================
--- mips/atheros/ar71xx_spi.c	(revision 215172)
+++ mips/atheros/ar71xx_spi.c	(working copy)
@@ -83,6 +83,7 @@
 static int
 ar71xx_spi_probe(device_t dev)
 {
+
 	device_set_desc(dev, "AR71XX SPI");
 	return (0);
 }
@@ -102,11 +103,10 @@
 		return (ENXIO);
 	}
 
-
 	SPI_WRITE(sc, AR71XX_SPI_FS, 1);
-	sc->sc_reg_ctrl  = SPI_READ(sc, AR71XX_SPI_CTRL);
+	sc->sc_reg_ctrl = SPI_READ(sc, AR71XX_SPI_CTRL);
 	SPI_WRITE(sc, AR71XX_SPI_CTRL, 0x43);
-	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CSMASK);
+	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS(0));
 
 	device_add_child(dev, "spibus", 0);
 	return (bus_generic_attach(dev));
@@ -115,34 +115,37 @@
 static void
 ar71xx_spi_chip_activate(struct ar71xx_spi_softc *sc, int cs)
 {
-	uint32_t ioctrl = SPI_IO_CTRL_CSMASK;
+
 	/*
-	 * Put respective CSx to low
+	 * Activate the respective device (we have three CS pins allowing
+	 * 7 muxed devices on bus).
+	 * At any given moment only one device should be selected on bus. 
+	 * if cs is set to 0 it will be the same as SPI_IO_CTRL_CSMASK
+	 * (0x7 - all pins high - no device selected).
 	 */
-	ioctrl &= ~(SPI_IO_CTRL_CS0 << cs);
-
-	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, ioctrl);
+	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS(cs));
 }
 
 static void
 ar71xx_spi_chip_deactivate(struct ar71xx_spi_softc *sc, int cs)
 {
+
 	/*
-	 * Put all CSx to high
+	 * Deactivate all devices, put all CSx to high
 	 */
-	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CSMASK);
+	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS(0));
 }
 
 static uint8_t
 ar71xx_spi_txrx(struct ar71xx_spi_softc *sc, int cs, uint8_t data)
 {
 	int bit;
-	/* CS0 */
-	uint32_t ioctrl = SPI_IO_CTRL_CSMASK;
+	uint32_t ioctrl;
+
 	/*
-	 * low-level for selected CS
+	 * activate the selected CS
 	 */
-	ioctrl &= ~(SPI_IO_CTRL_CS0 << cs);
+	ioctrl = SPI_IO_CTRL_CS(cs);
 
 	uint32_t iod, rds;
 	for (bit = 7; bit >=0; bit--) {
Index: mips/atheros/ar71xxreg.h
===================================================================
--- mips/atheros/ar71xxreg.h	(revision 215172)
+++ mips/atheros/ar71xxreg.h	(working copy)
@@ -480,7 +480,7 @@
 #define			SPI_IO_CTRL_CS2			(1 << 18)
 #define			SPI_IO_CTRL_CS1			(1 << 17)
 #define			SPI_IO_CTRL_CS0			(1 << 16)
-#define			SPI_IO_CTRL_CSMASK		(7 << 16)
+#define			SPI_IO_CTRL_CS(cs)		((7 - cs) << 16)
 #define			SPI_IO_CTRL_CLK			(1 << 8)
 #define			SPI_IO_CTRL_DO			1
 #define		AR71XX_SPI_RDS		0x0C

[-- Attachment #3 --]
--- mips/atheros/ar71xx_spi.c.orig	2010-11-12 08:14:40.000000000 -0200
+++ mips/atheros/ar71xx_spi.c	2010-11-12 08:49:12.000000000 -0200
@@ -117,6 +117,14 @@
 {
 
 	/*
+	 * This is a hack to deactivate the chip before it get really
+	 * activate right bellow.
+	 * This is only needed by RSPRO RTC (active with high CS0).
+	 */
+	SPI_WRITE(sc, AR71XX_SPI_IO_CTRL, SPI_IO_CTRL_CS(cs + 1));
+	DELAY(100);
+
+	/*
 	 * Activate the respective device (we have three CS pins allowing
 	 * 7 muxed devices on bus).
 	 * At any given moment only one device should be selected on bus. 

[-- Attachment #4 --]
# $FreeBSD: head/sys/mips/conf/AR71XX.hints 202839 2010-01-22 22:14:12Z gonzo $
hint.apb.0.at="nexus0"
hint.apb.0.irq=4

# uart0
hint.uart.0.at="apb0"
# see atheros/uart_cpu_ar71xx.c why +3
hint.uart.0.maddr=0x18020003
hint.uart.0.msize=0x18
hint.uart.0.irq=3

#ohci
hint.ohci.0.at="apb0"
hint.ohci.0.maddr=0x1c000000
hint.ohci.0.msize=0x01000000
hint.ohci.0.irq=6

#ehci
hint.ehci.0.at="nexus0"
hint.ehci.0.maddr=0x1b000000
hint.ehci.0.msize=0x01000000
hint.ehci.0.irq=1

# pci
hint.pcib.0.at="nexus0"
hint.pcib.0.irq=0

hint.arge.0.at="nexus0"
hint.arge.0.maddr=0x19000000
hint.arge.0.msize=0x1000
hint.arge.0.irq=2
# PHY4 = 1 << 4
hint.arge.0.phymask=0x10

hint.arge.1.at="nexus0"
hint.arge.1.maddr=0x1a000000
hint.arge.1.msize=0x1000
hint.arge.1.irq=3
# PHY1, PHY2, PHY3 
hint.arge.1.phymask=0x0e
hint.arge.1.media=1000
hint.arge.1.fduplex=1
# RSPRO _really_ need the above two lines !

# SPIBUS 
hint.spi.0.at="nexus0"
hint.spi.0.maddr=0x1f000000
hint.spi.0.msize=0x10

# SPI flash
hint.mx25l.0.at="spibus0"
hint.mx25l.0.cs=1

# shares the same bus with mx25l. 
# CE low for flash, CE high for RTC
hint.rtc.0.at="spibus0"
hint.rtc.0.cs=0

# Watchdog
hint.ar71xx_wdog.0.at="nexus0"

# GPIO
hint.gpio.0.at="apb0"
hint.gpio.0.maddr=0x18040000
hint.gpio.0.msize=0x1000
hint.gpio.0.irq=2

# RF led - pin 2
hint.gpioled.0.at="gpiobus0"
hint.gpioled.0.name="rfled"
hint.gpioled.0.pins=0x0004

# gpio i2c
# Pin 1 - SCL
# Pin 2 - SDA 
hint.gpioiic.0.at="gpiobus0"
hint.gpioiic.0.pins=0x0003

help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?10D25047-014A-4FC9-B74D-655729053704>