Skip to content

Commit

Permalink
MIPS: generic/yamon-dt: Pull YAMON DT shim code out of SEAD-3 board
Browse files Browse the repository at this point in the history
In preparation for supporting other YAMON-using boards (Malta) & sharing
code to translate information from YAMON into device tree properties,
pull the code doing so for the kernel command line, system memory &
serial configuration out of the SEAD-3 board code.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/16181/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Paul Burton authored and Ralf Baechle committed Jun 28, 2017
1 parent efe4a1a commit 571b7e6
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 174 deletions.
8 changes: 8 additions & 0 deletions arch/mips/generic/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@ config LEGACY_BOARDS
kernel is booted without being provided with an FDT via the UHI
boot protocol.

config YAMON_DT_SHIM
bool
help
Select this from your board if the board uses the YAMON bootloader
and you wish to include code which helps translate various
YAMON-provided environment variables into a device tree properties.

config LEGACY_BOARD_SEAD3
bool "Support MIPS SEAD-3 boards"
select LEGACY_BOARDS
select YAMON_DT_SHIM
help
Enable this to include support for booting on MIPS SEAD-3 FPGA-based
development boards, which boot using a legacy boot protocol.
Expand Down
1 change: 1 addition & 0 deletions arch/mips/generic/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ obj-y += init.o
obj-y += irq.o
obj-y += proc.o

obj-$(CONFIG_YAMON_DT_SHIM) += yamon-dt.o
obj-$(CONFIG_LEGACY_BOARD_SEAD3) += board-sead3.o
obj-$(CONFIG_KEXEC) += kexec.o
178 changes: 4 additions & 174 deletions arch/mips/generic/board-sead3.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <asm/fw/fw.h>
#include <asm/io.h>
#include <asm/machine.h>
#include <asm/yamon-dt.h>

#define SEAD_CONFIG CKSEG1ADDR(0x1b100110)
#define SEAD_CONFIG_GIC_PRESENT BIT(1)
Expand All @@ -33,98 +34,6 @@ static __init bool sead3_detect(void)
return (rev & MIPS_REVISION_MACHINE) == MIPS_REVISION_MACHINE_SEAD3;
}

static __init int append_cmdline(void *fdt)
{
int err, chosen_off;

/* find or add chosen node */
chosen_off = fdt_path_offset(fdt, "/chosen");
if (chosen_off == -FDT_ERR_NOTFOUND)
chosen_off = fdt_path_offset(fdt, "/chosen@0");
if (chosen_off == -FDT_ERR_NOTFOUND)
chosen_off = fdt_add_subnode(fdt, 0, "chosen");
if (chosen_off < 0) {
pr_err("Unable to find or add DT chosen node: %d\n",
chosen_off);
return chosen_off;
}

err = fdt_setprop_string(fdt, chosen_off, "bootargs", fw_getcmdline());
if (err) {
pr_err("Unable to set bootargs property: %d\n", err);
return err;
}

return 0;
}

static __init int append_memory(void *fdt)
{
unsigned long phys_memsize, memsize;
__be32 mem_array[2];
int err, mem_off;
char *var;

/* find memory size from the bootloader environment */
var = fw_getenv("memsize");
if (var) {
err = kstrtoul(var, 0, &phys_memsize);
if (err) {
pr_err("Failed to read memsize env variable '%s'\n",
var);
return -EINVAL;
}
} else {
pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
phys_memsize = 32 << 20;
}

/* default to using all available RAM */
memsize = phys_memsize;

/* allow the user to override the usable memory */
var = strstr(arcs_cmdline, "memsize=");
if (var)
memsize = memparse(var + strlen("memsize="), NULL);

/* if the user says there's more RAM than we thought, believe them */
phys_memsize = max_t(unsigned long, phys_memsize, memsize);

/* find or add a memory node */
mem_off = fdt_path_offset(fdt, "/memory");
if (mem_off == -FDT_ERR_NOTFOUND)
mem_off = fdt_add_subnode(fdt, 0, "memory");
if (mem_off < 0) {
pr_err("Unable to find or add memory DT node: %d\n", mem_off);
return mem_off;
}

err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
if (err) {
pr_err("Unable to set memory node device_type: %d\n", err);
return err;
}

mem_array[0] = 0;
mem_array[1] = cpu_to_be32(phys_memsize);
err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array));
if (err) {
pr_err("Unable to set memory regs property: %d\n", err);
return err;
}

mem_array[0] = 0;
mem_array[1] = cpu_to_be32(memsize);
err = fdt_setprop(fdt, mem_off, "linux,usable-memory",
mem_array, sizeof(mem_array));
if (err) {
pr_err("Unable to set linux,usable-memory property: %d\n", err);
return err;
}

return 0;
}

static __init int remove_gic(void *fdt)
{
const unsigned int cpu_ehci_int = 2;
Expand Down Expand Up @@ -214,85 +123,6 @@ static __init int remove_gic(void *fdt)
return 0;
}

static __init int serial_config(void *fdt)
{
const char *yamontty, *mode_var;
char mode_var_name[9], path[18], parity;
unsigned int uart, baud, stop_bits;
bool hw_flow;
int chosen_off, err;

yamontty = fw_getenv("yamontty");
if (!yamontty || !strcmp(yamontty, "tty0")) {
uart = 0;
} else if (!strcmp(yamontty, "tty1")) {
uart = 1;
} else {
pr_warn("yamontty environment variable '%s' invalid\n",
yamontty);
uart = 0;
}

baud = stop_bits = 0;
parity = 0;
hw_flow = false;

snprintf(mode_var_name, sizeof(mode_var_name), "modetty%u", uart);
mode_var = fw_getenv(mode_var_name);
if (mode_var) {
while (mode_var[0] >= '0' && mode_var[0] <= '9') {
baud *= 10;
baud += mode_var[0] - '0';
mode_var++;
}
if (mode_var[0] == ',')
mode_var++;
if (mode_var[0])
parity = mode_var[0];
if (mode_var[0] == ',')
mode_var++;
if (mode_var[0])
stop_bits = mode_var[0] - '0';
if (mode_var[0] == ',')
mode_var++;
if (!strcmp(mode_var, "hw"))
hw_flow = true;
}

if (!baud)
baud = 38400;

if (parity != 'e' && parity != 'n' && parity != 'o')
parity = 'n';

if (stop_bits != 7 && stop_bits != 8)
stop_bits = 8;

WARN_ON(snprintf(path, sizeof(path), "uart%u:%u%c%u%s",
uart, baud, parity, stop_bits,
hw_flow ? "r" : "") >= sizeof(path));

/* find or add chosen node */
chosen_off = fdt_path_offset(fdt, "/chosen");
if (chosen_off == -FDT_ERR_NOTFOUND)
chosen_off = fdt_path_offset(fdt, "/chosen@0");
if (chosen_off == -FDT_ERR_NOTFOUND)
chosen_off = fdt_add_subnode(fdt, 0, "chosen");
if (chosen_off < 0) {
pr_err("Unable to find or add DT chosen node: %d\n",
chosen_off);
return chosen_off;
}

err = fdt_setprop_string(fdt, chosen_off, "stdout-path", path);
if (err) {
pr_err("Unable to set stdout-path property: %d\n", err);
return err;
}

return 0;
}

static __init const void *sead3_fixup_fdt(const void *fdt,
const void *match_data)
{
Expand All @@ -311,19 +141,19 @@ static __init const void *sead3_fixup_fdt(const void *fdt,
if (err)
panic("Unable to open FDT: %d", err);

err = append_cmdline(fdt_buf);
err = yamon_dt_append_cmdline(fdt_buf);
if (err)
panic("Unable to patch FDT: %d", err);

err = append_memory(fdt_buf);
err = yamon_dt_append_memory(fdt_buf);
if (err)
panic("Unable to patch FDT: %d", err);

err = remove_gic(fdt_buf);
if (err)
panic("Unable to patch FDT: %d", err);

err = serial_config(fdt_buf);
err = yamon_dt_serial_config(fdt_buf);
if (err)
panic("Unable to patch FDT: %d", err);

Expand Down
Loading

0 comments on commit 571b7e6

Please sign in to comment.