2 * BCM47XX support code for some chipcommon (old extif) facilities (uart)
4 * Copyright 2006, Broadcom Corporation
7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
12 * $Id: hndchipc.c,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $
28 * Returns TRUE if an external UART exists at the given base
32 BCMINITFN(serial_exists
)(osl_t
*osh
, uint8
*regs
)
34 uint8 save_mcr
, status1
;
36 save_mcr
= R_REG(osh
, ®s
[UART_MCR
]);
37 W_REG(osh
, ®s
[UART_MCR
], UART_MCR_LOOP
| 0x0a);
38 status1
= R_REG(osh
, ®s
[UART_MSR
]) & 0xf0;
39 W_REG(osh
, ®s
[UART_MCR
], save_mcr
);
41 return (status1
== 0x90);
45 * Initializes UART access. The callback function will be called once
49 BCMINITFN(sb_serial_init
)(sb_t
*sbh
, void (*add
)(void *regs
, uint irq
, uint baud_base
,
60 if ((regs
= sb_setcore(sbh
, SB_EXTIF
, 0))) {
61 extifregs_t
*eir
= (extifregs_t
*) regs
;
64 /* Determine external UART register base */
65 sb
= (sbconfig_t
*)((ulong
) eir
+ SBCONFIGOFF
);
66 base
= EXTIF_CFGIF_BASE(sb_base(R_REG(osh
, &sb
->sbadmatch1
)));
71 /* Disable GPIO interrupt initially */
72 W_REG(osh
, &eir
->gpiointpolarity
, 0);
73 W_REG(osh
, &eir
->gpiointmask
, 0);
75 /* Search for external UARTs */
77 for (i
= 0; i
< 2; i
++) {
78 regs
= (void *) REG_MAP(base
+ (i
* 8), 8);
79 if (serial_exists(osh
, regs
)) {
80 /* Set GPIO 1 to be the external UART IRQ */
81 W_REG(osh
, &eir
->gpiointmask
, 2);
82 /* XXXDetermine external UART clock */
84 add(regs
, irq
, 13500000, 0);
88 /* Add internal UART if enabled */
89 if (R_REG(osh
, &eir
->corecontrol
) & CC_UE
)
91 add((void *) &eir
->uartdata
, irq
, sb_clock(sbh
), 2);
92 } else if ((regs
= sb_setcore(sbh
, SB_CC
, 0))) {
93 chipcregs_t
*cc
= (chipcregs_t
*) regs
;
94 uint32 rev
, cap
, pll
, baud_base
, div
;
96 /* Determine core revision and capabilities */
97 rev
= sb_corerev(sbh
);
98 cap
= R_REG(osh
, &cc
->capabilities
);
99 pll
= cap
& CAP_PLL_MASK
;
104 if (pll
== PLL_TYPE1
) {
106 baud_base
= sb_clock_rate(pll
,
107 R_REG(osh
, &cc
->clockcontrol_n
),
108 R_REG(osh
, &cc
->clockcontrol_m2
));
111 /* Fixed ALP clock */
112 if (rev
>= 11 && rev
!= 15) {
113 baud_base
= 20000000;
115 /* Set the override bit so we don't divide it */
116 W_REG(osh
, &cc
->corecontrol
, CC_UARTCLKO
);
118 /* Internal backplane clock */
120 baud_base
= sb_clock(sbh
);
121 div
= 2; /* Minimum divisor */
122 W_REG(osh
, &cc
->clkdiv
,
123 ((R_REG(osh
, &cc
->clkdiv
) & ~CLKD_UART
) | div
));
125 /* Fixed internal backplane clock */
127 baud_base
= 88000000;
131 /* Clock source depends on strapping if UartClkOverride is unset */
133 ((R_REG(osh
, &cc
->corecontrol
) & CC_UARTCLKO
) == 0)) {
134 if ((cap
& CAP_UCLKSEL
) == CAP_UINTCLK
) {
135 /* Internal divided backplane clock */
138 /* Assume external clock of 1.8432 MHz */
144 /* Add internal UARTs */
145 n
= cap
& CAP_UARTS_MASK
;
146 for (i
= 0; i
< n
; i
++) {
147 /* Register offset changed after revision 0 */
149 regs
= (void *)((ulong
) &cc
->uart0data
+ (i
* 256));
151 regs
= (void *)((ulong
) &cc
->uart0data
+ (i
* 8));
154 add(regs
, irq
, baud_base
, 0);
This page took 0.054371 seconds and 5 git commands to generate.