[U-Boot] [PATCH v2 10/10] boston: Introduce support for the MIPS Boston development board

Marek Vasut marex at denx.de
Sun Jul 31 17:56:08 CEST 2016


On 07/29/2016 10:36 AM, Paul Burton wrote:
[...]
>>> +#ifndef __ASSEMBLY__
>>> +
>>> +#include <asm/io.h>
>>> +
>>> +#define BUILD_PLAT_ACCESSORS(offset, name)                \
>>> +static inline uint32_t read_boston_##name(void)                \
>>> +{                                    \
>>> +    uint32_t *reg = (void *)CKSEG1ADDR(BOSTON_PLAT_BASE) + (offset);\
>>> +    return __raw_readl(reg);                    \
>>> +}
>>
>> Don't we have enough standard accessors to confuse people ?
>> Why do you add another custom ones ? Remove this and just use
>> standard accessors throughout the code.
> 
> Hi Marek,
> 
> These accessors are simple wrappers around __raw_readl, I'd hardly say
> they can be considered confusing. The alternative is lots of:
> 
>     val = __raw_readl((void *)CKSEG1ADDR(BOSTON_PLAT_BASE) + OFFSET);
> 
> ...and that is just plain ugly.

This should be map_physmem() + readl(), see ie. the ag7xxx.c driver or
whatever other stuff from the atheros ath79 port. Does this work ?

> Invoking readl on a field of a struct
> representing these registers would be nice, but some of them need to be
> accessed from assembly so that would involve duplication which isn't
> nice.

The struct based access is deprecated, don't bother with it.

> I think this way is the best option, where if you want to read the
> Boston core_cl register you call read_boston_core_cl() - it's hardly
> confusing what that does.

Now imagine what would happen if everyone introduced his own
my_platform_read_random_register() accessor(s) . This would be utter chaos.

>>
>>> +BUILD_PLAT_ACCESSORS(BOSTON_PLAT_CORE_CL, core_cl)
>>> +BUILD_PLAT_ACCESSORS(BOSTON_PLAT_MMCMDIV, mmcmdiv)
>>> +BUILD_PLAT_ACCESSORS(BOSTON_PLAT_DDRCONF0, ddrconf0)
>>> +
>>> +#endif /* !__ASSEMBLY__ */
>>> +
>>> +#endif /* __BOARD_BOSTON_REGS_H__ */
>>> diff --git a/board/imgtec/boston/checkboard.c
>>> b/board/imgtec/boston/checkboard.c
>>> new file mode 100644
>>> index 0000000..417ac4e
>>> --- /dev/null
>>> +++ b/board/imgtec/boston/checkboard.c
>>> @@ -0,0 +1,29 @@
>>> +/*
>>> + * Copyright (C) 2016 Imagination Technologies
>>> + *
>>> + * SPDX-License-Identifier:    GPL-2.0
>>> + */
>>> +
>>> +#include <common.h>
>>> +
>>> +#include <asm/mipsregs.h>
>>> +
>>> +#include "boston-lcd.h"
>>> +#include "boston-regs.h"
>>>
>>> +int checkboard(void)
>>> +{
>>> +    u32 changelist;
>>> +
>>> +    lowlevel_display("U-boot  ");
>>> +
>>> +    printf("Board: MIPS Boston\n");
>>> +
>>> +    printf("CPU:   0x%08x", read_c0_prid());
>>
>> This should be in print_cpuinfo()
> 
> I don't agree. This goes on to read a board-specific register to
> determine information about the CPU (the revision of its RTL) and that
> should not be done in arch-level code, which is what every other
> implementation of print_cpuinfo is.

Ah, so the register used to determine CPU info is board-specific ? That
is utterly braindead design in my mind. The read_c0_prid() looked like
it is reading some standard register, maybe that's not true ...

> Perhaps it would be better if we had
> a nice DM-using CPU driver which Boston could have an extension of, but
> we don't have that for MIPS right now & this series is not the place to
> add it.
> 
>>
>>> +    changelist = read_boston_core_cl();
>>> +    if (changelist > 1)
>>> +        printf(" cl%x", changelist);
>>> +    putc('\n');
>>> +
>>> +    return 0;
>>> +}
>>> diff --git a/board/imgtec/boston/ddr.c b/board/imgtec/boston/ddr.c
>>> new file mode 100644
>>> index 0000000..7caed4b
>>> --- /dev/null
>>> +++ b/board/imgtec/boston/ddr.c
>>> @@ -0,0 +1,30 @@
>>> +/*
>>> + * Copyright (C) 2016 Imagination Technologies
>>> + *
>>> + * SPDX-License-Identifier:    GPL-2.0
>>> + */
>>> +
>>> +#include <common.h>
>>> +
>>> +#include <asm/addrspace.h>
>>> +
>>> +#include "boston-regs.h"
>>> +
>>> +phys_size_t initdram(int board_type)
>>> +{
>>> +    u32 ddrconf0 = read_boston_ddrconf0();
>>> +
>>> +    return (phys_size_t)(ddrconf0 & BOSTON_PLAT_DDRCONF0_SIZE) << 30;
>>> +}
>>> +
>>> +ulong board_get_usable_ram_top(ulong total_size)
>>> +{
>>> +    DECLARE_GLOBAL_DATA_PTR;
>>> +
>>> +    if (gd->ram_top < CONFIG_SYS_SDRAM_BASE) {
>>> +        /* 2GB wrapped around to 0 */
>>> +        return CKSEG0ADDR(256 << 20);
>>> +    }
>>> +
>>> +    return min_t(unsigned long, gd->ram_top, CKSEG0ADDR(256 << 20));
>>> +}
>>> diff --git a/board/imgtec/boston/lowlevel_init.S
>>> b/board/imgtec/boston/lowlevel_init.S
>>> new file mode 100644
>>> index 0000000..8928172
>>> --- /dev/null
>>> +++ b/board/imgtec/boston/lowlevel_init.S
>>> @@ -0,0 +1,56 @@
>>> +/*
>>> + * Copyright (C) 2016 Imagination Technologies
>>> + *
>>> + * SPDX-License-Identifier:    GPL-2.0
>>> + */
>>> +
>>> +#include <config.h>
>>> +
>>> +#include <asm/addrspace.h>
>>> +#include <asm/asm.h>
>>> +#include <asm/mipsregs.h>
>>> +#include <asm/regdef.h>
>>> +
>>> +#include "boston-regs.h"
>>> +
>>> +.data
>>> +
>>> +msg_ddr_cal:    .ascii "DDR Cal "
>>> +msg_ddr_ok:    .ascii "DDR OK  "
>>> +
>>> +.text
>>> +
>>> +LEAF(lowlevel_init)
>>> +    move    s0, ra
>>> +
>>> +    PTR_LA    a0, msg_ddr_cal
>>> +    bal    lowlevel_display
>>
>> Don't you need nop after branch on mips ?
> 
> No. Branch delay slots are filled automatically by the assembler unless
> you explicitly tell it not to with a ".set noreorder" directive, and
> they're not just filled with NOPs - they can contain essentially any
> non-control-flow-affecting instruction that it's safe to execute
> regardless of the outcome of the branch. They're also somewhat optional
> in MIPSr6 where "compact" branches don't have delay slots, and gone
> entirely in microMIPSr6.

Oh ok.

>>> +
>>> +    PTR_LI    t0, CKSEG1ADDR(BOSTON_PLAT_BASE)
>>> +1:    lw    t1, BOSTON_PLAT_DDR3STAT(t0)
>>> +    andi    t1, t1, BOSTON_PLAT_DDR3STAT_CALIB
>>> +    beqz    t1, 1b


-- 
Best regards,
Marek Vasut


More information about the U-Boot mailing list