Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
reform-boundary-uboot
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Reform
reform-boundary-uboot
Commits
121cb96d
Commit
121cb96d
authored
22 years ago
by
Wolfgang Denk
Browse files
Options
Downloads
Patches
Plain Diff
Initial revision
parent
82e299bf
No related branches found
No related tags found
No related merge requests found
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
cpu/mpc8260/commproc.c
+209
-0
209 additions, 0 deletions
cpu/mpc8260/commproc.c
include/asm-ppc/cpm_8260.h
+740
-0
740 additions, 0 deletions
include/asm-ppc/cpm_8260.h
post/uart.c
+583
-0
583 additions, 0 deletions
post/uart.c
with
1532 additions
and
0 deletions
cpu/mpc8260/commproc.c
0 → 100644
+
209
−
0
View file @
121cb96d
/*
* This file is based on "arch/ppc/8260_io/commproc.c" - here is it's
* copyright notice:
*
* General Purpose functions for the global management of the
* 8260 Communication Processor Module.
* Copyright (c) 1999 Dan Malek (dmalek@jlc.net)
* Copyright (c) 2000 MontaVista Software, Inc (source@mvista.com)
* 2.3.99 Updates
*
* In addition to the individual control of the communication
* channels, there are a few functions that globally affect the
* communication processor.
*
* Buffer descriptors must be allocated from the dual ported memory
* space. The allocator for that is here. When the communication
* process is reset, we reclaim the memory available. There is
* currently no deallocator for this memory.
*/
#include
<common.h>
#include
<asm/cpm_8260.h>
/*
* because we have stack and init data in dual port ram
* we must reduce the size
*/
#undef CPM_DATAONLY_SIZE
#define CPM_DATAONLY_SIZE ((uint)(8 * 1024) - CPM_DATAONLY_BASE)
void
m8260_cpm_reset
(
void
)
{
DECLARE_GLOBAL_DATA_PTR
;
volatile
immap_t
*
immr
=
(
immap_t
*
)
CFG_IMMR
;
volatile
ulong
count
;
/* Reclaim the DP memory for our use.
*/
gd
->
dp_alloc_base
=
CPM_DATAONLY_BASE
;
gd
->
dp_alloc_top
=
gd
->
dp_alloc_base
+
CPM_DATAONLY_SIZE
;
/*
* Reset CPM
*/
immr
->
im_cpm
.
cp_cpcr
=
CPM_CR_RST
;
count
=
0
;
do
{
/* Spin until command processed */
__asm__
__volatile__
(
"eieio"
);
}
while
((
immr
->
im_cpm
.
cp_cpcr
&
CPM_CR_FLG
)
&&
++
count
<
1000000
);
#ifdef CONFIG_HARD_I2C
*
((
unsigned
short
*
)(
&
immr
->
im_dprambase
[
PROFF_I2C_BASE
]))
=
0
;
#endif
}
/* Allocate some memory from the dual ported ram.
* To help protocols with object alignment restrictions, we do that
* if they ask.
*/
uint
m8260_cpm_dpalloc
(
uint
size
,
uint
align
)
{
DECLARE_GLOBAL_DATA_PTR
;
volatile
immap_t
*
immr
=
(
immap_t
*
)
CFG_IMMR
;
uint
retloc
;
uint
align_mask
,
off
;
uint
savebase
;
align_mask
=
align
-
1
;
savebase
=
gd
->
dp_alloc_base
;
if
((
off
=
(
gd
->
dp_alloc_base
&
align_mask
))
!=
0
)
gd
->
dp_alloc_base
+=
(
align
-
off
);
if
((
off
=
size
&
align_mask
)
!=
0
)
size
+=
align
-
off
;
if
((
gd
->
dp_alloc_base
+
size
)
>=
gd
->
dp_alloc_top
)
{
gd
->
dp_alloc_base
=
savebase
;
panic
(
"m8260_cpm_dpalloc: ran out of dual port ram!"
);
}
retloc
=
gd
->
dp_alloc_base
;
gd
->
dp_alloc_base
+=
size
;
memset
((
void
*
)
&
immr
->
im_dprambase
[
retloc
],
0
,
size
);
return
(
retloc
);
}
/* We also own one page of host buffer space for the allocation of
* UART "fifos" and the like.
*/
uint
m8260_cpm_hostalloc
(
uint
size
,
uint
align
)
{
/* the host might not even have RAM yet - just use dual port RAM */
return
(
m8260_cpm_dpalloc
(
size
,
align
));
}
/* Set a baud rate generator. This needs lots of work. There are
* eight BRGs, which can be connected to the CPM channels or output
* as clocks. The BRGs are in two different block of internal
* memory mapped space.
* The baud rate clock is the system clock divided by something.
* It was set up long ago during the initial boot phase and is
* is given to us.
* Baud rate clocks are zero-based in the driver code (as that maps
* to port numbers). Documentation uses 1-based numbering.
*/
#define BRG_INT_CLK gd->brg_clk
#define BRG_UART_CLK ((BRG_INT_CLK + 15) / 16)
/* This function is used by UARTS, or anything else that uses a 16x
* oversampled clock.
*/
void
m8260_cpm_setbrg
(
uint
brg
,
uint
rate
)
{
DECLARE_GLOBAL_DATA_PTR
;
volatile
immap_t
*
immr
=
(
immap_t
*
)
CFG_IMMR
;
volatile
uint
*
bp
;
/* This is good enough to get SMCs running.....
*/
if
(
brg
<
4
)
{
bp
=
(
uint
*
)
&
immr
->
im_brgc1
;
}
else
{
bp
=
(
uint
*
)
&
immr
->
im_brgc5
;
brg
-=
4
;
}
bp
+=
brg
;
*
bp
=
(((((
BRG_UART_CLK
+
rate
-
1
)
/
rate
)
-
1
)
&
0xfff
)
<<
1
)
|
CPM_BRG_EN
;
}
/* This function is used to set high speed synchronous baud rate
* clocks.
*/
void
m8260_cpm_fastbrg
(
uint
brg
,
uint
rate
,
int
div16
)
{
DECLARE_GLOBAL_DATA_PTR
;
volatile
immap_t
*
immr
=
(
immap_t
*
)
CFG_IMMR
;
volatile
uint
*
bp
;
/* This is good enough to get SMCs running.....
*/
if
(
brg
<
4
)
{
bp
=
(
uint
*
)
&
immr
->
im_brgc1
;
}
else
{
bp
=
(
uint
*
)
&
immr
->
im_brgc5
;
brg
-=
4
;
}
bp
+=
brg
;
*
bp
=
(((((
BRG_INT_CLK
+
rate
-
1
)
/
rate
)
-
1
)
&
0xfff
)
<<
1
)
|
CPM_BRG_EN
;
if
(
div16
)
*
bp
|=
CPM_BRG_DIV16
;
}
/* This function is used to set baud rate generators using an external
* clock source and 16x oversampling.
*/
void
m8260_cpm_extcbrg
(
uint
brg
,
uint
rate
,
uint
extclk
,
int
pinsel
)
{
volatile
immap_t
*
immr
=
(
immap_t
*
)
CFG_IMMR
;
volatile
uint
*
bp
;
if
(
brg
<
4
)
{
bp
=
(
uint
*
)
&
immr
->
im_brgc1
;
}
else
{
bp
=
(
uint
*
)
&
immr
->
im_brgc5
;
brg
-=
4
;
}
bp
+=
brg
;
*
bp
=
((((((
extclk
/
16
)
+
rate
-
1
)
/
rate
)
-
1
)
&
0xfff
)
<<
1
)
|
CPM_BRG_EN
;
if
(
pinsel
==
0
)
*
bp
|=
CPM_BRG_EXTC_CLK3_9
;
else
*
bp
|=
CPM_BRG_EXTC_CLK5_15
;
}
#ifdef CONFIG_POST
void
post_word_store
(
ulong
a
)
{
volatile
ulong
*
save_addr
=
(
volatile
ulong
*
)(
CFG_IMMR
+
CPM_POST_WORD_ADDR
);
*
save_addr
=
a
;
}
ulong
post_word_load
(
void
)
{
volatile
ulong
*
save_addr
=
(
volatile
ulong
*
)(
CFG_IMMR
+
CPM_POST_WORD_ADDR
);
return
*
save_addr
;
}
#endif
/* CONFIG_POST */
This diff is collapsed.
Click to expand it.
include/asm-ppc/cpm_8260.h
0 → 100644
+
740
−
0
View file @
121cb96d
This diff is collapsed.
Click to expand it.
post/uart.c
0 → 100644
+
583
−
0
View file @
121cb96d
/*
* (C) Copyright 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include
<common.h>
/*
* UART test
*
* The Serial Management Controllers (SMC) and the Serial Communication
* Controllers (SCC) listed in ctlr_list array below are tested in
* the loopback UART mode.
* The controllers are configured accordingly and several characters
* are transmitted. The configurable test parameters are:
* MIN_PACKET_LENGTH - minimum size of packet to transmit
* MAX_PACKET_LENGTH - maximum size of packet to transmit
* TEST_NUM - number of tests
*/
#ifdef CONFIG_POST
#include
<post.h>
#if defined(CONFIG_8xx)
#include
<commproc.h>
#elif defined(CONFIG_MPC8260)
#include
<asm/cpm_8260.h>
#else
#error "Apparently a bad configuration, please fix."
#endif
#include
<command.h>
#include
<net.h>
#if CONFIG_POST & CFG_POST_UART
#define CTLR_SMC 0
#define CTLR_SCC 1
/* The list of controllers to test */
#if defined(CONFIG_MPC823)
static
int
ctlr_list
[][
2
]
=
{
{
CTLR_SMC
,
0
},
{
CTLR_SMC
,
1
},
{
CTLR_SCC
,
1
}
};
#else
static
int
ctlr_list
[][
2
]
=
{
};
#endif
#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0]))
static
struct
{
void
(
*
init
)
(
int
index
);
void
(
*
putc
)
(
int
index
,
const
char
c
);
int
(
*
getc
)
(
int
index
);
}
ctlr_proc
[
2
];
static
char
*
ctlr_name
[
2
]
=
{
"SMC"
,
"SCC"
};
static
int
used_by_uart
[
2
]
=
{
-
1
,
-
1
};
static
int
used_by_ether
[
2
]
=
{
-
1
,
-
1
};
static
int
proff_smc
[]
=
{
PROFF_SMC1
,
PROFF_SMC2
};
static
int
proff_scc
[]
=
{
PROFF_SCC1
,
PROFF_SCC2
,
PROFF_SCC3
,
PROFF_SCC4
};
/*
* SMC callbacks
*/
static
void
smc_init
(
int
smc_index
)
{
DECLARE_GLOBAL_DATA_PTR
;
static
int
cpm_cr_ch
[]
=
{
CPM_CR_CH_SMC1
,
CPM_CR_CH_SMC2
};
volatile
immap_t
*
im
=
(
immap_t
*
)
CFG_IMMR
;
volatile
smc_t
*
sp
;
volatile
smc_uart_t
*
up
;
volatile
cbd_t
*
tbdf
,
*
rbdf
;
volatile
cpm8xx_t
*
cp
=
&
(
im
->
im_cpm
);
uint
dpaddr
;
/* initialize pointers to SMC */
sp
=
(
smc_t
*
)
&
(
cp
->
cp_smc
[
smc_index
]);
up
=
(
smc_uart_t
*
)
&
cp
->
cp_dparam
[
proff_smc
[
smc_index
]];
/* Disable transmitter/receiver.
*/
sp
->
smc_smcmr
&=
~
(
SMCMR_REN
|
SMCMR_TEN
);
/* Enable SDMA.
*/
im
->
im_siu_conf
.
sc_sdcr
=
1
;
/* clear error conditions */
#ifdef CFG_SDSR
im
->
im_sdma
.
sdma_sdsr
=
CFG_SDSR
;
#else
im
->
im_sdma
.
sdma_sdsr
=
0x83
;
#endif
/* clear SDMA interrupt mask */
#ifdef CFG_SDMR
im
->
im_sdma
.
sdma_sdmr
=
CFG_SDMR
;
#else
im
->
im_sdma
.
sdma_sdmr
=
0x00
;
#endif
#if defined(CONFIG_FADS)
/* Enable RS232 */
*
((
uint
*
)
BCSR1
)
&=
~
(
smc_index
==
1
?
BCSR1_RS232EN_1
:
BCSR1_RS232EN_2
);
#endif
#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC)
/* Enable Monitor Port Transceiver */
*
((
uchar
*
)
BCSR0
)
|=
BCSR0_ENMONXCVR
;
#endif
/* Set the physical address of the host memory buffers in
* the buffer descriptors.
*/
#ifdef CFG_ALLOC_DPRAM
dpaddr
=
dpram_alloc_align
(
sizeof
(
cbd_t
)
*
2
+
2
,
8
);
#else
dpaddr
=
CPM_POST_BASE
;
#endif
/* Allocate space for two buffer descriptors in the DP ram.
* For now, this address seems OK, but it may have to
* change with newer versions of the firmware.
* damm: allocating space after the two buffers for rx/tx data
*/
rbdf
=
(
cbd_t
*
)
&
cp
->
cp_dpmem
[
dpaddr
];
rbdf
->
cbd_bufaddr
=
(
uint
)
(
rbdf
+
2
);
rbdf
->
cbd_sc
=
0
;
tbdf
=
rbdf
+
1
;
tbdf
->
cbd_bufaddr
=
((
uint
)
(
rbdf
+
2
))
+
1
;
tbdf
->
cbd_sc
=
0
;
/* Set up the uart parameters in the parameter ram.
*/
up
->
smc_rbase
=
dpaddr
;
up
->
smc_tbase
=
dpaddr
+
sizeof
(
cbd_t
);
up
->
smc_rfcr
=
SMC_EB
;
up
->
smc_tfcr
=
SMC_EB
;
#if defined(CONFIG_MBX)
board_serial_init
();
#endif
/* Set UART mode, 8 bit, no parity, one stop.
* Enable receive and transmit.
* Set local loopback mode.
*/
sp
->
smc_smcmr
=
smcr_mk_clen
(
9
)
|
SMCMR_SM_UART
|
(
ushort
)
0x0004
;
/* Mask all interrupts and remove anything pending.
*/
sp
->
smc_smcm
=
0
;
sp
->
smc_smce
=
0xff
;
/* Set up the baud rate generator.
*/
cp
->
cp_simode
=
0x00000000
;
cp
->
cp_brgc1
=
(((
gd
->
cpu_clk
/
16
/
gd
->
baudrate
)
-
1
)
<<
1
)
|
CPM_BRG_EN
;
/* Make the first buffer the only buffer.
*/
tbdf
->
cbd_sc
|=
BD_SC_WRAP
;
rbdf
->
cbd_sc
|=
BD_SC_EMPTY
|
BD_SC_WRAP
;
/* Single character receive.
*/
up
->
smc_mrblr
=
1
;
up
->
smc_maxidl
=
0
;
/* Initialize Tx/Rx parameters.
*/
while
(
cp
->
cp_cpcr
&
CPM_CR_FLG
)
/* wait if cp is busy */
;
cp
->
cp_cpcr
=
mk_cr_cmd
(
cpm_cr_ch
[
smc_index
],
CPM_CR_INIT_TRX
)
|
CPM_CR_FLG
;
while
(
cp
->
cp_cpcr
&
CPM_CR_FLG
)
/* wait if cp is busy */
;
/* Enable transmitter/receiver.
*/
sp
->
smc_smcmr
|=
SMCMR_REN
|
SMCMR_TEN
;
}
static
void
smc_putc
(
int
smc_index
,
const
char
c
)
{
volatile
cbd_t
*
tbdf
;
volatile
char
*
buf
;
volatile
smc_uart_t
*
up
;
volatile
immap_t
*
im
=
(
immap_t
*
)
CFG_IMMR
;
volatile
cpm8xx_t
*
cpmp
=
&
(
im
->
im_cpm
);
up
=
(
smc_uart_t
*
)
&
cpmp
->
cp_dparam
[
proff_smc
[
smc_index
]];
tbdf
=
(
cbd_t
*
)
&
cpmp
->
cp_dpmem
[
up
->
smc_tbase
];
/* Wait for last character to go.
*/
buf
=
(
char
*
)
tbdf
->
cbd_bufaddr
;
#if 0
__asm__ ("eieio");
while (tbdf->cbd_sc & BD_SC_READY)
__asm__ ("eieio");
#endif
*
buf
=
c
;
tbdf
->
cbd_datlen
=
1
;
tbdf
->
cbd_sc
|=
BD_SC_READY
;
__asm__
(
"eieio"
);
#if 1
while
(
tbdf
->
cbd_sc
&
BD_SC_READY
)
__asm__
(
"eieio"
);
#endif
}
static
int
smc_getc
(
int
smc_index
)
{
volatile
cbd_t
*
rbdf
;
volatile
unsigned
char
*
buf
;
volatile
smc_uart_t
*
up
;
volatile
immap_t
*
im
=
(
immap_t
*
)
CFG_IMMR
;
volatile
cpm8xx_t
*
cpmp
=
&
(
im
->
im_cpm
);
unsigned
char
c
;
int
i
;
up
=
(
smc_uart_t
*
)
&
cpmp
->
cp_dparam
[
proff_smc
[
smc_index
]];
rbdf
=
(
cbd_t
*
)
&
cpmp
->
cp_dpmem
[
up
->
smc_rbase
];
/* Wait for character to show up.
*/
buf
=
(
unsigned
char
*
)
rbdf
->
cbd_bufaddr
;
#if 0
while (rbdf->cbd_sc & BD_SC_EMPTY);
#else
for
(
i
=
100
;
i
>
0
;
i
--
)
{
if
(
!
(
rbdf
->
cbd_sc
&
BD_SC_EMPTY
))
break
;
udelay
(
1000
);
}
if
(
i
==
0
)
return
-
1
;
#endif
c
=
*
buf
;
rbdf
->
cbd_sc
|=
BD_SC_EMPTY
;
return
(
c
);
}
/*
* SCC callbacks
*/
static
void
scc_init
(
int
scc_index
)
{
DECLARE_GLOBAL_DATA_PTR
;
static
int
cpm_cr_ch
[]
=
{
CPM_CR_CH_SCC1
,
CPM_CR_CH_SCC2
,
CPM_CR_CH_SCC3
,
CPM_CR_CH_SCC4
,
};
volatile
immap_t
*
im
=
(
immap_t
*
)
CFG_IMMR
;
volatile
scc_t
*
sp
;
volatile
scc_uart_t
*
up
;
volatile
cbd_t
*
tbdf
,
*
rbdf
;
volatile
cpm8xx_t
*
cp
=
&
(
im
->
im_cpm
);
uint
dpaddr
;
/* initialize pointers to SCC */
sp
=
(
scc_t
*
)
&
(
cp
->
cp_scc
[
scc_index
]);
up
=
(
scc_uart_t
*
)
&
cp
->
cp_dparam
[
proff_scc
[
scc_index
]];
/* Disable transmitter/receiver.
*/
sp
->
scc_gsmrl
&=
~
(
SCC_GSMRL_ENR
|
SCC_GSMRL_ENT
);
/* Allocate space for two buffer descriptors in the DP ram.
*/
#ifdef CFG_ALLOC_DPRAM
dpaddr
=
dpram_alloc_align
(
sizeof
(
cbd_t
)
*
2
+
2
,
8
);
#else
dpaddr
=
CPM_POST_BASE
;
#endif
/* Enable SDMA.
*/
im
->
im_siu_conf
.
sc_sdcr
=
0x0001
;
/* Set the physical address of the host memory buffers in
* the buffer descriptors.
*/
rbdf
=
(
cbd_t
*
)
&
cp
->
cp_dpmem
[
dpaddr
];
rbdf
->
cbd_bufaddr
=
(
uint
)
(
rbdf
+
2
);
rbdf
->
cbd_sc
=
0
;
tbdf
=
rbdf
+
1
;
tbdf
->
cbd_bufaddr
=
((
uint
)
(
rbdf
+
2
))
+
1
;
tbdf
->
cbd_sc
=
0
;
/* Set up the baud rate generator.
*/
cp
->
cp_sicr
&=
~
(
0x000000FF
<<
(
8
*
scc_index
));
/* no |= needed, since BRG1 is 000 */
cp
->
cp_brgc1
=
(((
gd
->
cpu_clk
/
16
/
gd
->
baudrate
)
-
1
)
<<
1
)
|
CPM_BRG_EN
;
/* Set up the uart parameters in the parameter ram.
*/
up
->
scc_genscc
.
scc_rbase
=
dpaddr
;
up
->
scc_genscc
.
scc_tbase
=
dpaddr
+
sizeof
(
cbd_t
);
/* Initialize Tx/Rx parameters.
*/
while
(
cp
->
cp_cpcr
&
CPM_CR_FLG
)
/* wait if cp is busy */
;
cp
->
cp_cpcr
=
mk_cr_cmd
(
cpm_cr_ch
[
scc_index
],
CPM_CR_INIT_TRX
)
|
CPM_CR_FLG
;
while
(
cp
->
cp_cpcr
&
CPM_CR_FLG
)
/* wait if cp is busy */
;
up
->
scc_genscc
.
scc_rfcr
=
SCC_EB
|
0x05
;
up
->
scc_genscc
.
scc_tfcr
=
SCC_EB
|
0x05
;
up
->
scc_genscc
.
scc_mrblr
=
1
;
/* Single character receive */
up
->
scc_maxidl
=
0
;
/* disable max idle */
up
->
scc_brkcr
=
1
;
/* send one break character on stop TX */
up
->
scc_parec
=
0
;
up
->
scc_frmec
=
0
;
up
->
scc_nosec
=
0
;
up
->
scc_brkec
=
0
;
up
->
scc_uaddr1
=
0
;
up
->
scc_uaddr2
=
0
;
up
->
scc_toseq
=
0
;
up
->
scc_char1
=
0x8000
;
up
->
scc_char2
=
0x8000
;
up
->
scc_char3
=
0x8000
;
up
->
scc_char4
=
0x8000
;
up
->
scc_char5
=
0x8000
;
up
->
scc_char6
=
0x8000
;
up
->
scc_char7
=
0x8000
;
up
->
scc_char8
=
0x8000
;
up
->
scc_rccm
=
0xc0ff
;
/* Set low latency / small fifo.
*/
sp
->
scc_gsmrh
=
SCC_GSMRH_RFW
;
/* Set UART mode
*/
sp
->
scc_gsmrl
&=
~
0xF
;
sp
->
scc_gsmrl
|=
SCC_GSMRL_MODE_UART
;
/* Set local loopback mode.
*/
sp
->
scc_gsmrl
&=
~
SCC_GSMRL_DIAG_LE
;
sp
->
scc_gsmrl
|=
SCC_GSMRL_DIAG_LOOP
;
/* Set clock divider 16 on Tx and Rx
*/
sp
->
scc_gsmrl
|=
(
SCC_GSMRL_TDCR_16
|
SCC_GSMRL_RDCR_16
);
sp
->
scc_psmr
|=
SCU_PSMR_CL
;
/* Mask all interrupts and remove anything pending.
*/
sp
->
scc_sccm
=
0
;
sp
->
scc_scce
=
0xffff
;
sp
->
scc_dsr
=
0x7e7e
;
sp
->
scc_psmr
=
0x3000
;
/* Make the first buffer the only buffer.
*/
tbdf
->
cbd_sc
|=
BD_SC_WRAP
;
rbdf
->
cbd_sc
|=
BD_SC_EMPTY
|
BD_SC_WRAP
;
/* Enable transmitter/receiver.
*/
sp
->
scc_gsmrl
|=
(
SCC_GSMRL_ENR
|
SCC_GSMRL_ENT
);
}
static
void
scc_putc
(
int
scc_index
,
const
char
c
)
{
volatile
cbd_t
*
tbdf
;
volatile
char
*
buf
;
volatile
scc_uart_t
*
up
;
volatile
immap_t
*
im
=
(
immap_t
*
)
CFG_IMMR
;
volatile
cpm8xx_t
*
cpmp
=
&
(
im
->
im_cpm
);
up
=
(
scc_uart_t
*
)
&
cpmp
->
cp_dparam
[
proff_scc
[
scc_index
]];
tbdf
=
(
cbd_t
*
)
&
cpmp
->
cp_dpmem
[
up
->
scc_genscc
.
scc_tbase
];
/* Wait for last character to go.
*/
buf
=
(
char
*
)
tbdf
->
cbd_bufaddr
;
#if 0
__asm__ ("eieio");
while (tbdf->cbd_sc & BD_SC_READY)
__asm__ ("eieio");
#endif
*
buf
=
c
;
tbdf
->
cbd_datlen
=
1
;
tbdf
->
cbd_sc
|=
BD_SC_READY
;
__asm__
(
"eieio"
);
#if 1
while
(
tbdf
->
cbd_sc
&
BD_SC_READY
)
__asm__
(
"eieio"
);
#endif
}
static
int
scc_getc
(
int
scc_index
)
{
volatile
cbd_t
*
rbdf
;
volatile
unsigned
char
*
buf
;
volatile
scc_uart_t
*
up
;
volatile
immap_t
*
im
=
(
immap_t
*
)
CFG_IMMR
;
volatile
cpm8xx_t
*
cpmp
=
&
(
im
->
im_cpm
);
unsigned
char
c
;
int
i
;
up
=
(
scc_uart_t
*
)
&
cpmp
->
cp_dparam
[
proff_scc
[
scc_index
]];
rbdf
=
(
cbd_t
*
)
&
cpmp
->
cp_dpmem
[
up
->
scc_genscc
.
scc_rbase
];
/* Wait for character to show up.
*/
buf
=
(
unsigned
char
*
)
rbdf
->
cbd_bufaddr
;
#if 0
while (rbdf->cbd_sc & BD_SC_EMPTY);
#else
for
(
i
=
100
;
i
>
0
;
i
--
)
{
if
(
!
(
rbdf
->
cbd_sc
&
BD_SC_EMPTY
))
break
;
udelay
(
1000
);
}
if
(
i
==
0
)
return
-
1
;
#endif
c
=
*
buf
;
rbdf
->
cbd_sc
|=
BD_SC_EMPTY
;
return
(
c
);
}
/*
* Test routines
*/
static
int
test_ctlr
(
int
ctlr
,
int
index
)
{
int
res
=
-
1
;
char
test_str
[]
=
"*** UART Test String ***
\r\n
"
;
int
i
;
#if !defined(CONFIG_8xx_CONS_NONE)
if
(
used_by_uart
[
ctlr
]
==
index
)
{
while
(
ctlr_proc
[
ctlr
].
getc
(
index
)
!=
-
1
);
}
#endif
ctlr_proc
[
ctlr
].
init
(
index
);
for
(
i
=
0
;
i
<
sizeof
(
test_str
)
-
1
;
i
++
)
{
ctlr_proc
[
ctlr
].
putc
(
index
,
test_str
[
i
]);
if
(
ctlr_proc
[
ctlr
].
getc
(
index
)
!=
test_str
[
i
])
goto
Done
;
}
res
=
0
;
Done:
#if !defined(CONFIG_8xx_CONS_NONE)
if
(
used_by_uart
[
ctlr
]
==
index
)
{
serial_init
();
}
#endif
#if defined(SCC_ENET)
if
(
used_by_ether
[
ctlr
]
==
index
)
{
DECLARE_GLOBAL_DATA_PTR
;
eth_init
(
gd
->
bd
);
}
#endif
if
(
res
!=
0
)
{
post_log
(
"uart %s%d test failed
\n
"
,
ctlr_name
[
ctlr
],
index
+
1
);
}
return
res
;
}
int
uart_post_test
(
int
flags
)
{
int
res
=
0
;
int
i
;
#if defined(CONFIG_8xx_CONS_SMC1)
used_by_uart
[
CTLR_SMC
]
=
0
;
#elif defined(CONFIG_8xx_CONS_SMC2)
used_by_uart
[
CTLR_SMC
]
=
1
;
#elif defined(CONFIG_8xx_CONS_SCC1)
used_by_uart
[
CTLR_SCC
]
=
0
;
#elif defined(CONFIG_8xx_CONS_SCC2)
used_by_uart
[
CTLR_SCC
]
=
1
;
#elif defined(CONFIG_8xx_CONS_SCC3)
used_by_uart
[
CTLR_SCC
]
=
2
;
#elif defined(CONFIG_8xx_CONS_SCC4)
used_by_uart
[
CTLR_SCC
]
=
3
;
#endif
#if defined(SCC_ENET)
used_by_ether
[
CTLR_SCC
]
=
SCC_ENET
;
#endif
ctlr_proc
[
CTLR_SMC
].
init
=
smc_init
;
ctlr_proc
[
CTLR_SMC
].
putc
=
smc_putc
;
ctlr_proc
[
CTLR_SMC
].
getc
=
smc_getc
;
ctlr_proc
[
CTLR_SCC
].
init
=
scc_init
;
ctlr_proc
[
CTLR_SCC
].
putc
=
scc_putc
;
ctlr_proc
[
CTLR_SCC
].
getc
=
scc_getc
;
for
(
i
=
0
;
i
<
CTRL_LIST_SIZE
;
i
++
)
{
if
(
test_ctlr
(
ctlr_list
[
i
][
0
],
ctlr_list
[
i
][
1
])
!=
0
)
{
res
=
-
1
;
}
}
return
res
;
}
#endif
/* CONFIG_POST & CFG_POST_UART */
#endif
/* CONFIG_POST */
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment