Introduce framework to configure the multiplexed pins on boot.

	Since the USART supprots RS-485 multidrop mode, it allows the
	TX pins to float.  However, for RS-232 operations, we don't
	want these pins to float.  Instead, they should be pulled up
	to avoid mismatches.  Linux does something similar when it
	configures the TX lines.  This implies that we also allow the
	RX lines to float rather than be in the state they are left in
	by the boot loader.  Since they are input pins, I think that
	this is the right thing to do.

	Plus minor for our board.
This commit is contained in:
Warner Losh 2006-07-14 22:22:57 +00:00
parent fa543fe2fa
commit 546bbbb56f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=160363
3 changed files with 66 additions and 8 deletions

View File

@ -280,21 +280,29 @@ at91_pio_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
* them.
*/
void
at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask)
at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
PIO[PIO_ASR / 4] = periph_a_mask;
PIO[PIO_PDR / 4] = periph_a_mask;
if (use_pullup)
PIO[PIO_PUER / 4] = periph_a_mask;
else
PIO[PIO_PUDR / 4] = periph_a_mask;
}
void
at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask)
at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
PIO[PIO_BSR / 4] = periph_b_mask;
PIO[PIO_PDR / 4] = periph_b_mask;
if (use_pullup)
PIO[PIO_PUER / 4] = periph_b_mask;
else
PIO[PIO_PUDR / 4] = periph_b_mask;
}
void
@ -314,11 +322,15 @@ at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask)
}
void
at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask)
at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask, int use_pullup)
{
uint32_t *PIO = (uint32_t *)(AT91RM92_BASE + pio);
PIO[PIO_OER / 4] = output_enable_mask;
if (use_pullup)
PIO[PIO_PUER / 4] = output_enable_mask;
else
PIO[PIO_PUDR / 4] = output_enable_mask;
}
void

View File

@ -27,11 +27,12 @@
#ifndef ARM_AT91_AT91_PIOVAR_H
#define ARM_AT91_AT91_PIOVAR_H
void at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask);
void at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask);
void at91_pio_use_periph_a(uint32_t pio, uint32_t periph_a_mask, int use_pullup);
void at91_pio_use_periph_b(uint32_t pio, uint32_t periph_b_mask, int use_pullup);
void at91_pio_use_gpio(uint32_t pio, uint32_t gpio_mask);
void at91_pio_gpio_input(uint32_t pio, uint32_t input_enable_mask);
void at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask);
void at91_pio_gpio_output(uint32_t pio, uint32_t output_enable_mask,
int use_pullup);
void at91_pio_gpio_set(uint32_t pio, uint32_t data_mask);
void at91_pio_gpio_clear(uint32_t pio, uint32_t data_mask);

View File

@ -45,6 +45,7 @@
#include "opt_msgbuf.h"
#include "opt_ddb.h"
#include "opt_at91.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@ -93,6 +94,8 @@ __FBSDID("$FreeBSD$");
#include <sys/reboot.h>
#include <arm/at91/at91rm92reg.h>
#include <arm/at91/at91_piovar.h>
#include <arm/at91/at91_pio_rm9200.h>
#define KERNEL_PT_SYS 0 /* Page table for mapping proc0 zero page */
#define KERNEL_PT_KERN 1
@ -185,11 +188,11 @@ extern vm_offset_t ksym_start, ksym_end;
#endif
static long
board_init(void)
ramsize(void)
{
uint32_t *SDRAMC = (uint32_t *)(AT91RM92_BASE + AT91RM92_SDRAMC_BASE);
uint32_t cr, mr;
int banks, rows, cols, bw; /* log2 size */
int banks, rows, cols, bw;
cr = SDRAMC[AT91RM92_SDRAMC_CR / 4];
mr = SDRAMC[AT91RM92_SDRAMC_MR / 4];
@ -200,6 +203,48 @@ board_init(void)
return (1 << (cols + rows + banks + bw));
}
static long
board_init(void)
{
/*
* Since the USART supprots RS-485 multidrop mode, it allows the
* TX pins to float. However, for RS-232 operations, we don't want
* these pins to float. Instead, they should be pulled up to avoid
* mismatches. Linux does something similar when it configures the
* TX lines. This implies that we also allow the RX lines to float
* rather than be in the state they are left in by the boot loader.
* Since they are input pins, I think that this is the right thing
* to do.
*/
/* PIOA's A periph: Turn USART 0 and 2's TX/RX pins */
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
AT91C_PA18_RXD0 | AT91C_PA22_RXD2, 0);
at91_pio_use_periph_a(AT91RM92_PIOA_BASE,
AT91C_PA17_TXD0 | AT91C_PA23_TXD2, 1);
/* PIOA's B periph: Turn USART 3's TX/RX pins */
at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PA6_RXD3, 0);
at91_pio_use_periph_b(AT91RM92_PIOA_BASE, AT91C_PA5_TXD3, 1);
#if AT91_TSC
/* We're using TC0's A1 and A2 input */
at91_pio_use_periph_b(AT91RM92_PIOA_BASE,
AT91C_PA19_TIOA1 | AT91C_PA21_TIOA2, 0);
#endif
/* PIOB's A periph: Turn USART 1's TX/RX pins */
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB21_RXD1, 0);
at91_pio_use_periph_a(AT91RM92_PIOB_BASE, AT91C_PB20_TXD1, 1);
/* Pin assignment */
#if AT91_TSC
/* Assert PA24 low -- talk to rubidium */
at91_pio_use_gpio(AT91RM92_PIOA_BASE, AT91C_PIO_PA24);
at91_pio_gpio_output(AT91RM92_PIOA_BASE, AT91C_PIO_PA24, 0);
at91_pio_gpio_clear(AT91RM92_PIOA_BASE, AT91C_PIO_PA24);
#endif
return (ramsize());
}
void *
initarm(void *arg, void *arg2)
{