MFC r257170, r257171, r257172, r257240, r257278, r257279, r257280, r257281,

r257282, r257332

  Wait for DesignWare UART transfers completion before accessing line control

  Enable UART busy detection handling for Armada XP - based board

  Enable SATA interface on Armada XP
  Run mvs SATA driver on Armada XP instead of old mv_sata

  Retire arm_remap_nocache() and the data and constants associated with it.

  Remove hard-coded mappings related to Armada XP support

  Fix-up DTB for Armada XP registers' base according to the actual settings

  Change Armada XP kernel load address to the u-boot's end address

  Remove not working and deprecated PJ4Bv6 support

  Switch off explicit broadcasting of the TLB flush operations for PJ4B CPU

  Add missing ARMv6 CPU functions to ARM Makefile
This commit is contained in:
ian 2014-05-14 16:32:27 +00:00
parent bb1ce472d7
commit 13afdc288f
17 changed files with 141 additions and 282 deletions

View File

@ -541,65 +541,6 @@ struct cpu_functions pj4bv7_cpufuncs = {
pj4bv7_setup /* cpu setup */
};
struct cpu_functions pj4bv6_cpufuncs = {
/* CPU functions */
cpufunc_id, /* id */
arm11_drain_writebuf, /* cpwait */
/* MMU functions */
cpufunc_control, /* control */
cpufunc_domains, /* Domain */
pj4b_setttb, /* Setttb */
cpufunc_faultstatus, /* Faultstatus */
cpufunc_faultaddress, /* Faultaddress */
/* TLB functions */
arm11_tlb_flushID, /* tlb_flushID */
arm11_tlb_flushID_SE, /* tlb_flushID_SE */
arm11_tlb_flushI, /* tlb_flushI */
arm11_tlb_flushI_SE, /* tlb_flushI_SE */
arm11_tlb_flushD, /* tlb_flushD */
arm11_tlb_flushD_SE, /* tlb_flushD_SE */
/* Cache operations */
armv6_icache_sync_all, /* icache_sync_all */
pj4b_icache_sync_range, /* icache_sync_range */
armv6_dcache_wbinv_all, /* dcache_wbinv_all */
pj4b_dcache_wbinv_range, /* dcache_wbinv_range */
pj4b_dcache_inv_range, /* dcache_inv_range */
pj4b_dcache_wb_range, /* dcache_wb_range */
armv6_idcache_wbinv_all, /* idcache_wbinv_all */
pj4b_idcache_wbinv_range, /* idcache_wbinv_all */
(void *)cpufunc_nullop, /* l2cache_wbinv_all */
(void *)cpufunc_nullop, /* l2cache_wbinv_range */
(void *)cpufunc_nullop, /* l2cache_inv_range */
(void *)cpufunc_nullop, /* l2cache_wb_range */
/* Other functions */
pj4b_drain_readbuf, /* flush_prefetchbuf */
arm11_drain_writebuf, /* drain_writebuf */
pj4b_flush_brnchtgt_all, /* flush_brnchtgt_C */
pj4b_flush_brnchtgt_va, /* flush_brnchtgt_E */
(void *)cpufunc_nullop, /* sleep */
/* Soft functions */
cpufunc_null_fixup, /* dataabt_fixup */
cpufunc_null_fixup, /* prefetchabt_fixup */
arm11_context_switch, /* context_switch */
pj4bv6_setup /* cpu setup */
};
#endif /* CPU_MV_PJ4B */
#ifdef CPU_SA110
@ -1496,27 +1437,14 @@ set_cpufuncs()
#endif /* CPU_CORTEXA */
#if defined(CPU_MV_PJ4B)
if (cputype == CPU_ID_MV88SV581X_V6 ||
cputype == CPU_ID_MV88SV581X_V7 ||
if (cputype == CPU_ID_MV88SV581X_V7 ||
cputype == CPU_ID_MV88SV584X_V7 ||
cputype == CPU_ID_ARM_88SV581X_V6 ||
cputype == CPU_ID_ARM_88SV581X_V7) {
if (cpu_pfr(0) & ARM_PFR0_THUMBEE_MASK)
cpufuncs = pj4bv7_cpufuncs;
else
cpufuncs = pj4bv6_cpufuncs;
get_cachetype_cp15();
pmap_pte_init_mmu_v6();
goto out;
} else if (cputype == CPU_ID_ARM_88SV584X_V6 ||
cputype == CPU_ID_MV88SV584X_V6) {
cpufuncs = pj4bv6_cpufuncs;
cpufuncs = pj4bv7_cpufuncs;
get_cachetype_cp15();
pmap_pte_init_mmu_v6();
goto out;
}
#endif /* CPU_MV_PJ4B */
#ifdef CPU_SA110
if (cputype == CPU_ID_SA110) {
@ -2445,44 +2373,6 @@ arm11x6_setup(char *args)
#endif /* CPU_ARM1136 || CPU_ARM1176 */
#ifdef CPU_MV_PJ4B
void
pj4bv6_setup(char *args)
{
int cpuctrl;
pj4b_config();
cpuctrl = CPU_CONTROL_MMU_ENABLE;
#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
#endif
cpuctrl |= CPU_CONTROL_DC_ENABLE;
cpuctrl |= (0xf << 3);
#ifdef __ARMEB__
cpuctrl |= CPU_CONTROL_BEND_ENABLE;
#endif
cpuctrl |= CPU_CONTROL_SYST_ENABLE;
cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
cpuctrl |= CPU_CONTROL_IC_ENABLE;
if (vector_page == ARM_VECTORS_HIGH)
cpuctrl |= CPU_CONTROL_VECRELOC;
cpuctrl |= (0x5 << 16);
cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
/* XXX not yet */
/* cpuctrl |= CPU_CONTROL_L2_ENABLE; */
/* Make sure caches are clean. */
cpu_idcache_wbinv_all();
cpu_l2cache_wbinv_all();
/* Set the control register */
ctrl = cpuctrl;
cpu_control(0xffffffff, cpuctrl);
cpu_idcache_wbinv_all();
cpu_l2cache_wbinv_all();
}
void
pj4bv7_setup(args)
char *args;

View File

@ -34,9 +34,6 @@ __FBSDID("$FreeBSD$");
#include <machine/param.h>
.Lpj4b_cache_line_size:
.word _C_LABEL(arm_pdcache_line_size)
.Lpj4b_sf_ctrl_reg:
.word 0xf1021820
@ -52,135 +49,6 @@ ENTRY(pj4b_setttb)
RET
END(pj4b_setttb)
ENTRY_NP(armv6_icache_sync_all)
/*
* We assume that the code here can never be out of sync with the
* dcache, so that we can safely flush the Icache and fall through
* into the Dcache cleaning code.
*/
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 /* Invalidate ICache */
mcr p15, 0, r0, c7, c10, 0 /* Clean (don't invalidate) DCache */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(armv6_icache_sync_all)
ENTRY(pj4b_icache_sync_range)
sub r1, r1, #1
add r1, r0, r1
mcrr p15, 0, r1, r0, c5 /* invalidate IC range */
mcrr p15, 0, r1, r0, c12 /* clean DC range */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(pj4b_icache_sync_range)
ENTRY(pj4b_dcache_inv_range)
ldr ip, .Lpj4b_cache_line_size
ldr ip, [ip]
sub r1, r1, #1 /* Don't overrun */
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
mcr p15, 0, r0, c7, c10, 5 /* Data Memory Barrier err:4413 */
1:
mcr p15, 0, r0, c7, c6, 1
add r0, r0, ip
subs r1, r1, ip
bpl 1b
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(pj4b_dcache_inv_range)
ENTRY(armv6_idcache_wbinv_all)
mov r0, #0
mcr p15, 0, r0, c7, c5, 0 /* invalidate ICache */
mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate DCache */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(armv6_idcache_wbinv_all)
ENTRY(armv6_dcache_wbinv_all)
mov r0, #0
mcr p15, 0, r0, c7, c14, 0 /* clean and invalidate DCache */
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(armv6_dcache_wbinv_all)
ENTRY(pj4b_idcache_wbinv_range)
ldr ip, .Lpj4b_cache_line_size
ldr ip, [ip]
sub r1, r1, #1 /* Don't overrun */
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
mcr p15, 0, r0, c7, c10, 5 /* Data Memory Barrier err:4611 */
1:
#ifdef SMP
/* Request for ownership */
ldr r2, [r0]
str r2, [r0]
#endif
mcr p15, 0, r0, c7, c5, 1
mcr p15, 0, r0, c7, c14, 1 /* L2C clean and invalidate entry */
add r0, r0, ip
subs r1, r1, ip
bpl 1b
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(pj4b_idcache_wbinv_range)
ENTRY(pj4b_dcache_wbinv_range)
ldr ip, .Lpj4b_cache_line_size
ldr ip, [ip]
sub r1, r1, #1 /* Don't overrun */
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
mcr p15, 0, r0, c7, c10, 5 /* Data Memory Barrier err:4611 */
1:
#ifdef SMP
/* Request for ownership */
ldr r2, [r0]
str r2, [r0]
#endif
mcr p15, 0, r0, c7, c14, 1
add r0, r0, ip
subs r1, r1, ip
bpl 1b
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(pj4b_dcache_wbinv_range)
ENTRY(pj4b_dcache_wb_range)
ldr ip, .Lpj4b_cache_line_size
ldr ip, [ip]
sub r1, r1, #1 /* Don't overrun */
sub r3, ip, #1
and r2, r0, r3
add r1, r1, r2
bic r0, r0, r3
mcr p15, 0, r0, c7, c10, 5 /* Data Memory Barrier err:4611 */
1:
#ifdef SMP
/* Request for ownership */
ldr r2, [r0]
str r2, [r0]
#endif
mcr p15, 0, r0, c7, c10, 1 /* L2C clean single entry by MVA */
add r0, r0, ip
subs r1, r1, ip
bpl 1b
mcr p15, 0, r0, c7, c10, 4 /* drain the write buffer */
RET
END(pj4b_dcache_wb_range)
ENTRY(pj4b_drain_readbuf)
mcr p15, 0, r0, c7, c5, 4 /* flush prefetch buffers */
RET

View File

@ -321,18 +321,10 @@ const struct cpuidtab cpuids[] = {
{ CPU_ID_MV88FR571_VD, CPU_CLASS_MARVELL, "Feroceon 88FR571-VD",
generic_steppings },
{ CPU_ID_MV88SV581X_V6, CPU_CLASS_MARVELL, "Sheeva 88SV581x",
generic_steppings },
{ CPU_ID_ARM_88SV581X_V6, CPU_CLASS_MARVELL, "Sheeva 88SV581x",
generic_steppings },
{ CPU_ID_MV88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x",
generic_steppings },
{ CPU_ID_ARM_88SV581X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV581x",
generic_steppings },
{ CPU_ID_MV88SV584X_V6, CPU_CLASS_MARVELL, "Sheeva 88SV584x",
generic_steppings },
{ CPU_ID_ARM_88SV584X_V6, CPU_CLASS_MARVELL, "Sheeva 88SV584x",
generic_steppings },
{ CPU_ID_MV88SV584X_V7, CPU_CLASS_MARVELL, "Sheeva 88SV584x",
generic_steppings },

View File

@ -266,10 +266,6 @@ mmu_init_table:
/* map VA 0xc0000000..0xc3ffffff to PA */
MMU_INIT(KERNBASE, PHYSADDR, 64, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW))
MMU_INIT(0x48000000, 0x48000000, 1, L1_TYPE_S|L1_SHARED|L1_S_C|L1_S_AP(AP_KRW))
#if defined(CPU_MV_PJ4B)
/* map VA 0xf1000000..0xf1100000 to PA 0xd0000000 */
MMU_INIT(0xf1000000, 0xd0000000, 1, L1_TYPE_S|L1_SHARED|L1_S_B|L1_S_AP(AP_KRW))
#endif /* CPU_MV_PJ4B */
#endif /* SMP */
.word 0 /* end of table */
#endif

View File

@ -52,6 +52,10 @@ __FBSDID("$FreeBSD$");
#ifdef VFP
#include <machine/vfp.h>
#endif
#ifdef CPU_MV_PJ4B
#include <arm/mv/mvwin.h>
#include <dev/fdt/fdt_common.h>
#endif
#include "opt_smp.h"
@ -131,8 +135,8 @@ cpu_mp_start(void)
#if defined(CPU_MV_PJ4B)
/* Add ARMADAXP registers required for snoop filter initialization */
((int *)(temp_pagetable_va))[0xf1000000 >> L1_S_SHIFT] =
L1_TYPE_S|L1_SHARED|L1_S_B|L1_S_AP(AP_KRW)|0xd0000000;
((int *)(temp_pagetable_va))[MV_BASE >> L1_S_SHIFT] =
L1_TYPE_S|L1_SHARED|L1_S_B|L1_S_AP(AP_KRW)|fdt_immr_pa;
#endif
temp_pagetable = (void*)(vtophys(temp_pagetable_va));

View File

@ -76,8 +76,7 @@ device pass
device da
# SATA
device ata
#device mvs
device mvs
# Serial ports
device uart

View File

@ -172,14 +172,10 @@
#define CPU_ID_MV88FR571_41 0x41159260 /* Marvell Feroceon 88FR571-VD Core (actual ID from CPU reg) */
#endif
#define CPU_ID_MV88SV581X_V6 0x560F5810 /* Marvell Sheeva 88SV581x v6 Core */
#define CPU_ID_MV88SV581X_V7 0x561F5810 /* Marvell Sheeva 88SV581x v7 Core */
#define CPU_ID_MV88SV584X_V6 0x561F5840 /* Marvell Sheeva 88SV584x v6 Core */
#define CPU_ID_MV88SV584X_V7 0x562F5840 /* Marvell Sheeva 88SV584x v7 Core */
/* Marvell's CPUIDs with ARM ID in implementor field */
#define CPU_ID_ARM_88SV581X_V6 0x410fb760 /* Marvell Sheeva 88SV581x v6 Core */
#define CPU_ID_ARM_88SV581X_V7 0x413FC080 /* Marvell Sheeva 88SV581x v7 Core */
#define CPU_ID_ARM_88SV584X_V6 0x410FB020 /* Marvell Sheeva 88SV584x v6 Core */
#define CPU_ID_FA526 0x66015260
#define CPU_ID_FA626TE 0x66056260

View File

@ -188,7 +188,7 @@ extern u_int cputype;
#else
void tlb_broadcast(int);
#ifdef CPU_CORTEXA
#if defined(CPU_CORTEXA) || defined(CPU_MV_PJ4B)
#define TLB_BROADCAST /* No need to explicitely send an IPI */
#else
#define TLB_BROADCAST tlb_broadcast(7)
@ -482,14 +482,6 @@ void arm11_drain_writebuf (void);
void pj4b_setttb (u_int);
void pj4b_icache_sync_range (vm_offset_t, vm_size_t);
void pj4b_dcache_wbinv_range (vm_offset_t, vm_size_t);
void pj4b_dcache_inv_range (vm_offset_t, vm_size_t);
void pj4b_dcache_wb_range (vm_offset_t, vm_size_t);
void pj4b_idcache_wbinv_range (vm_offset_t, vm_size_t);
void pj4b_drain_readbuf (void);
void pj4b_flush_brnchtgt_all (void);
void pj4b_flush_brnchtgt_va (u_int);
@ -523,7 +515,6 @@ void armv7_drain_writebuf (void);
void armv7_sev (void);
u_int armv7_auxctrl (u_int, u_int);
void pj4bv7_setup (char *string);
void pj4bv6_setup (char *string);
void pj4b_config (void);
int get_core_id (void);

View File

@ -1,16 +1,16 @@
# $FreeBSD$
# kernel gets loaded at 0x00f00000 by the loader, but runs at virtual address
# 0xc0f00000. RAM starts at 0. We put the pagetable at a reasonable place
# kernel gets loaded at 0x00200000 by the loader, but runs at virtual address
# 0xc0200000. RAM starts at 0. We put the pagetable at a reasonable place
# in memory, but may need to bounce it higher if there's a problem with this.
# We could paper over this by loading the kernel at 0xc0000000 virtual, but
# that leads to other complications, so we'll just reclaim the lower region of
# ram after we're loaded. Put the page tables for startup at 1MB.
makeoptions KERNPHYSADDR=0x00f00000
makeoptions KERNVIRTADDR=0xc0f00000
makeoptions KERNPHYSADDR=0x00200000
makeoptions KERNVIRTADDR=0xc0200000
options KERNPHYSADDR=0x00f00000
options KERNVIRTADDR=0xc0f00000
options KERNPHYSADDR=0x00200000
options KERNVIRTADDR=0xc0200000
options PHYSADDR=0x00000000
options STARTUP_PAGETABLE_ADDR=0x00100000

View File

@ -2078,9 +2078,79 @@ fdt_fixup_busfreq(phandle_t root)
OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq));
}
static void
fdt_fixup_ranges(phandle_t root)
{
phandle_t node;
pcell_t par_addr_cells, addr_cells, size_cells;
pcell_t ranges[3], reg[2], *rangesptr;
int len, tuple_size, tuples_count;
uint32_t base;
/* Fix-up SoC ranges according to real fdt_immr_pa */
if ((node = fdt_find_compatible(root, "simple-bus", 1)) != 0) {
if (fdt_addrsize_cells(node, &addr_cells, &size_cells) == 0 &&
(par_addr_cells = fdt_parent_addr_cells(node) <= 2)) {
tuple_size = sizeof(pcell_t) * (par_addr_cells +
addr_cells + size_cells);
len = OF_getprop(node, "ranges", ranges,
sizeof(ranges));
tuples_count = len / tuple_size;
/* Unexpected settings are not supported */
if (tuples_count != 1)
goto fixup_failed;
rangesptr = &ranges[0];
rangesptr += par_addr_cells;
base = fdt_data_get((void *)rangesptr, addr_cells);
*rangesptr = cpu_to_fdt32(fdt_immr_pa);
if (OF_setprop(node, "ranges", (void *)&ranges[0],
sizeof(ranges)) < 0)
goto fixup_failed;
}
}
/* Fix-up PCIe reg according to real PCIe registers' PA */
if ((node = fdt_find_compatible(root, "mrvl,pcie", 1)) != 0) {
if (fdt_addrsize_cells(OF_parent(node), &par_addr_cells,
&size_cells) == 0) {
tuple_size = sizeof(pcell_t) * (par_addr_cells +
size_cells);
len = OF_getprop(node, "reg", reg, sizeof(reg));
tuples_count = len / tuple_size;
/* Unexpected settings are not supported */
if (tuples_count != 1)
goto fixup_failed;
base = fdt_data_get((void *)&reg[0], par_addr_cells);
base &= ~0xFF000000;
base |= fdt_immr_pa;
reg[0] = cpu_to_fdt32(base);
if (OF_setprop(node, "reg", (void *)&reg[0],
sizeof(reg)) < 0)
goto fixup_failed;
}
}
/* Fix-up succeeded. May return and continue */
return;
fixup_failed:
while (1) {
/*
* In case of any error while fixing ranges just hang.
* 1. No message can be displayed yet since console
* is not initialized.
* 2. Going further will cause failure on bus_space_map()
* relying on the wrong ranges or data abort when
* accessing PCIe registers.
*/
}
}
struct fdt_fixup_entry fdt_fixup_table[] = {
{ "mrvl,DB-88F6281", &fdt_fixup_busfreq },
{ "mrvl,DB-78460", &fdt_fixup_busfreq },
{ "mrvl,DB-78460", &fdt_fixup_ranges },
{ NULL, NULL }
};

View File

@ -329,6 +329,19 @@ initarm_devmap_init(void)
i = 0;
arm_devmap_register_table(&fdt_devmap[0]);
#ifdef SOC_MV_ARMADAXP
vm_paddr_t cur_immr_pa;
/*
* Acquire SoC registers' base passed by u-boot and fill devmap
* accordingly. DTB is going to be modified basing on this data
* later.
*/
__asm __volatile("mrc p15, 4, %0, c15, c0, 0" : "=r" (cur_immr_pa));
cur_immr_pa = (cur_immr_pa << 13) & 0xff000000;
if (cur_immr_pa != 0)
fdt_immr_pa = cur_immr_pa;
#endif
/*
* IMMR range.
*/

View File

@ -200,6 +200,7 @@ sata_probe(device_t dev)
case MV_DEV_88F6282:
case MV_DEV_MV78100:
case MV_DEV_MV78100_Z0:
case MV_DEV_MV78460:
sc->sc_version = 2;
sc->sc_edma_qlen = 32;
break;

View File

@ -116,6 +116,7 @@
reg-shift = <2>;
current-speed = <115200>;
clock-frequency = <0>;
busy-detect = <1>;
interrupts = <41>;
interrupt-parent = <&MPIC>;
};
@ -126,6 +127,7 @@
reg-shift = <2>;
current-speed = <115200>;
clock-frequency = <0>;
busy-detect = <1>;
interrupts = <42>;
interrupt-parent = <&MPIC>;
};
@ -136,6 +138,7 @@
reg-shift = <2>;
current-speed = <115200>;
clock-frequency = <0>;
busy-detect = <1>;
interrupts = <43>;
interrupt-parent = <&MPIC>;
};
@ -146,6 +149,7 @@
reg-shift = <2>;
current-speed = <115200>;
clock-frequency = <0>;
busy-detect = <1>;
interrupts = <44>;
interrupt-parent = <&MPIC>;
};
@ -279,6 +283,13 @@
};
};
};
sata@A0000 {
compatible = "mrvl,sata";
reg = <0xA0000 0x6000>;
interrupts = <55>;
interrupt-parent = <&MPIC>;
};
};
pci0: pcie@d0040000 {

View File

@ -75,7 +75,8 @@ FILES_CPU_FUNC = $S/$M/$M/cpufunc_asm_arm7tdmi.S \
$S/$M/$M/cpufunc_asm_xscale.S $S/$M/$M/cpufunc_asm.S \
$S/$M/$M/cpufunc_asm_xscale_c3.S $S/$M/$M/cpufunc_asm_armv5_ec.S \
$S/$M/$M/cpufunc_asm_fa526.S $S/$M/$M/cpufunc_asm_sheeva.S \
$S/$M/$M/cpufunc_asm_pj4b.S $S/$M/$M/cpufunc_asm_armv7.S
$S/$M/$M/cpufunc_asm_pj4b.S $S/$M/$M/cpufunc_asm_armv6.S \
$S/$M/$M/cpufunc_asm_armv7.S
KERNEL_EXTRA=trampoline
KERNEL_EXTRA_INSTALL=kernel.gz.tramp

View File

@ -185,6 +185,7 @@
#define DW_REG_USR 31 /* DesignWare derived Uart Status Reg */
#define com_usr 39 /* Octeon 16750/16550 Uart Status Reg */
#define REG_USR com_usr
#define USR_BUSY 1 /* Uart Busy. Serial transfer in progress */
#define USR_TXFIFO_NOTFULL 2 /* Uart TX FIFO Not full */
/* 16950 register #1. Access enabled by ACR[7]. Also requires !LCR[7]. */

View File

@ -66,6 +66,8 @@ static struct {
{MV_DEV_88F6282, 0x00, "Marvell 88F6282", 2, MVS_Q_GENIIE|MVS_Q_SOC},
{MV_DEV_MV78100, 0x00, "Marvell MV78100", 2, MVS_Q_GENIIE|MVS_Q_SOC},
{MV_DEV_MV78100_Z0, 0x00,"Marvell MV78100", 2, MVS_Q_GENIIE|MVS_Q_SOC},
{MV_DEV_MV78260, 0x00, "Marvell MV78260", 2, MVS_Q_GENIIE|MVS_Q_SOC},
{MV_DEV_MV78460, 0x00, "Marvell MV78460", 2, MVS_Q_GENIIE|MVS_Q_SOC},
{0, 0x00, NULL, 0, 0}
};

View File

@ -649,11 +649,35 @@ int
ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
int stopbits, int parity)
{
struct ns8250_softc *ns8250;
struct uart_bas *bas;
int error;
int error, limit;
ns8250 = (struct ns8250_softc*)sc;
bas = &sc->sc_bas;
uart_lock(sc->sc_hwmtx);
/*
* When using DW UART with BUSY detection it is necessary to wait
* until all serial transfers are finished before manipulating the
* line control. LCR will not be affected when UART is busy.
*/
if (ns8250->busy_detect != 0) {
/*
* Pick an arbitrary high limit to avoid getting stuck in
* an infinite loop in case when the hardware is broken.
*/
limit = 10 * 1024;
while (((uart_getreg(bas, DW_REG_USR) & USR_BUSY) != 0) &&
--limit)
DELAY(4);
if (limit <= 0) {
/* UART appears to be stuck */
uart_unlock(sc->sc_hwmtx);
return (EIO);
}
}
error = ns8250_param(bas, baudrate, databits, stopbits, parity);
uart_unlock(sc->sc_hwmtx);
return (error);