#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kobo_machdep.c,v 1.9 2023/04/20 08:28:05 skrll Exp $");
#include "opt_evbarm_boardtype.h"
#include "opt_arm_debug.h"
#include "opt_console.h"
#include "opt_cputypes.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "opt_md.h"
#include "opt_com.h"
#include "imxuart.h"
#include "opt_imxuart.h"
#include "opt_imx.h"
#include "opt_machdep.h"
#include <sys/param.h>
#include <sys/device.h>
#include <sys/reboot.h>
#include <sys/termios.h>
#include <sys/bus.h>
#include <machine/db_machdep.h>
#ifdef KGDB
#include <sys/kgdb.h>
#endif
#include <machine/bootconfig.h>
#include <arm/arm32/machdep.h>
#include <arm/imx/imx51reg.h>
#include <arm/imx/imx51var.h>
#include <arm/imx/imxuartreg.h>
#include <arm/imx/imxuartvar.h>
#include <arm/imx/imx50_iomuxreg.h>
#include <evbarm/kobo/kobo.h>
#include <evbarm/kobo/kobo_reg.h>
#define KERNEL_TEXT_BASE (KERNEL_BASE + 0x00100000)
BootConfig bootconfig;
static char bootargs[MAX_BOOT_STRING];
char *boot_args = NULL;
extern char KERNEL_BASE_phys[];
u_int uboot_args[4] __attribute__((__section__(".data")));
#define KERNEL_BASE_PHYS ((paddr_t)KERNEL_BASE_phys)
void consinit(void);
#ifdef KGDB
void kgdb_port_init(void);
#endif
static void init_clocks(void);
static void setup_ioports(void);
#ifndef CONSPEED
#define CONSPEED B115200
#endif
#ifndef CONMODE
#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
#endif
int comcnspeed = CONSPEED;
int comcnmode = CONMODE;
const struct pmap_devmap kobo_devmap[] = {
DEVMAP_ENTRY(
KOBO_IO_VBASE0,
KOBO_IO_PBASE0,
L1_S_SIZE * 4
),
DEVMAP_ENTRY_END
};
#ifndef MEMSTART
#define MEMSTART 0x70000000
#endif
#ifndef MEMSIZE
#define MEMSIZE 256
#endif
static void
init_clocks(void)
{
cortex_pmc_ccnt_init();
}
struct iomux_setup {
uint16_t reg;
uint16_t val;
};
#define IOMUX_M(padname, mux) \
IOMUX_DATA(__CONCAT(IOMUXC_SW_MUX_CTL_PAD_,padname), mux)
#define IOMUX_P(padname, pad) \
IOMUX_DATA(__CONCAT(IOMUXC_SW_PAD_CTL_PAD_,padname), pad)
#define IOMUX_MP(padname, mux, pad) \
IOMUX_M(padname, mux), \
IOMUX_P(padname, pad)
#define IOMUX_DATA(offset, value) \
{ \
.reg = (offset), \
.val = (value), \
}
const struct iomux_setup iomux_setup_data[] = {
#define HYS PAD_CTL_HYS
#define ODE PAD_CTL_ODE
#define DSEHIGH PAD_CTL_DSE_HIGH
#define DSEMID PAD_CTL_DSE_MID
#define DSELOW PAD_CTL_DSE_LOW
#define DSEMAX PAD_CTL_DSE_MAX
#define SRE PAD_CTL_SRE
#define KEEPER PAD_CTL_KEEPER
#define PULL PAD_CTL_PULL
#define PU_22K PAD_CTL_PUS_22K_PU
#define PU_47K PAD_CTL_PUS_47K_PU
#define PU_100K PAD_CTL_PUS_100K_PU
#define PD_100K PAD_CTL_PUS_100K_PD
#define HVE PAD_CTL_HVE
#define ALT0 IOMUX_CONFIG_ALT0
#define ALT1 IOMUX_CONFIG_ALT1
#define ALT2 IOMUX_CONFIG_ALT2
#define ALT3 IOMUX_CONFIG_ALT3
#define ALT4 IOMUX_CONFIG_ALT4
#define ALT5 IOMUX_CONFIG_ALT5
#define ALT6 IOMUX_CONFIG_ALT6
#define ALT7 IOMUX_CONFIG_ALT7
#define SION IOMUX_CONFIG_SION
IOMUX_MP(I2C1_SCL, ALT0 | SION, PULL | PU_100K | HYS | ODE | DSEHIGH),
IOMUX_MP(I2C1_SDA, ALT0 | SION, PULL | PU_100K | HYS | ODE | DSEHIGH),
IOMUX_MP(I2C2_SCL, ALT0 | SION, PULL | PU_100K | HYS | ODE | DSEHIGH),
IOMUX_MP(I2C2_SDA, ALT0 | SION, PULL | PU_100K | HYS | ODE | DSEHIGH),
IOMUX_MP(I2C3_SCL, ALT0 | SION, PULL | PU_100K | HYS | ODE | DSEHIGH),
IOMUX_MP(I2C3_SDA, ALT0 | SION, PULL | PU_100K | HYS | ODE | DSEHIGH),
IOMUX_MP(UART2_RXD, ALT0, HYS | PULL | DSEHIGH | SRE),
IOMUX_MP(UART2_TXD, ALT0, HYS | PULL | DSEHIGH | SRE),
IOMUX_MP(SD1_CMD, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD1_CLK, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD1_D0, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD1_D1, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD1_D2, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD1_D3, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD2_CMD, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD2_CLK, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD2_D0, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD2_D1, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD2_D2, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD2_D3, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD2_CD, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_DATA(IOMUXC_ESDHC2_IPP_CARD_DET_SELECT_INPUT, INPUT_DAISY_1),
IOMUX_MP(SD3_CMD, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD3_CLK, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD3_D0, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD3_D1, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD3_D2, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_MP(SD3_D3, ALT0, HVE | PU_22K | DSEMAX | SRE),
IOMUX_M(PWM2, ALT2),
IOMUX_M(EPDC_D0, ALT0),
IOMUX_M(EPDC_D1, ALT0),
IOMUX_M(EPDC_D2, ALT0),
IOMUX_M(EPDC_D3, ALT0),
IOMUX_M(EPDC_D4, ALT0),
IOMUX_M(EPDC_D5, ALT0),
IOMUX_M(EPDC_D6, ALT0),
IOMUX_M(EPDC_D7, ALT0),
IOMUX_M(EPDC_GDCLK, ALT0),
IOMUX_M(EPDC_GDSP, ALT0),
IOMUX_M(EPDC_GDOE, ALT0),
IOMUX_M(EPDC_GDRL, ALT0),
IOMUX_M(EPDC_SDCLK, ALT0),
IOMUX_M(EPDC_SDOE, ALT0),
IOMUX_M(EPDC_SDLE, ALT0),
IOMUX_M(EPDC_BDR0, ALT0),
IOMUX_M(EPDC_BDR1, ALT0),
IOMUX_M(EPDC_SDCE0, ALT0),
IOMUX_M(EPDC_PWRSTAT, ALT1),
IOMUX_M(EPDC_PWRCTRL0, ALT1),
IOMUX_M(EPDC_VCOM0, ALT1),
IOMUX_M(UART4_TXD, ALT1),
IOMUX_M(UART4_RXD, ALT1),
#undef ODE
#undef HYS
#undef SRE
#undef PULL
#undef KEEPER
#undef PU_22K
#undef PU_47K
#undef PU_100K
#undef PD_100K
#undef HVE
#undef DSEMAX
#undef DSEHIGH
#undef DSEMID
#undef DSELOW
#undef ALT0
#undef ALT1
#undef ALT2
#undef ALT3
#undef ALT4
#undef ALT5
#undef ALT6
#undef ALT7
#undef SION
};
static void
setup_ioports(void)
{
int i;
const struct iomux_setup *p;
for (i=0; i < __arraycount(iomux_setup_data); ++i) {
p = iomux_setup_data + i;
ioreg_write(KOBO_IOMUXC_VBASE + p->reg,
p->val);
}
}
#ifdef CONSDEVNAME
const char consdevname[] = CONSDEVNAME;
#ifndef CONMODE
#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
#endif
#ifndef CONSPEED
#define CONSPEED 115200
#endif
int consmode = CONMODE;
int consrate = CONSPEED;
#endif
#ifndef IMXUART_FREQ
#define IMXUART_FREQ 24000000
#endif
vaddr_t
initarm(void *arg)
{
if (set_cpufuncs())
panic("cpu not recognized!");
extern char ARM_BOOTSTRAP_LxPT[];
pmap_devmap_bootstrap((vaddr_t)ARM_BOOTSTRAP_LxPT, kobo_devmap);
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
setup_ioports();
consinit();
init_clocks();
#ifdef KGDB
kgdb_port_init();
#endif
printf("\nNetBSD/evbarm (" ___STRING(EVBARM_BOARDTYPE) ") booting ...\n");
#ifdef BOOT_ARGS
char mi_bootargs[] = BOOT_ARGS;
parse_mi_bootargs(mi_bootargs);
#endif
bootargs[0] = '\0';
#ifdef VERBOSE_INIT_ARM
printf("initarm: Configuring system");
printf(", CLIDR=%010o CTR=%#x",
armreg_clidr_read(), armreg_ctr_read());
printf("\n");
#endif
#ifdef VERBOSE_INIT_ARM
printf("initarm: Configuring system ...\n");
#endif
bootconfig.dramblocks = 1;
bootconfig.dram[0].address = MEMSTART;
bootconfig.dram[0].pages = (MEMSIZE * 1024 * 1024) / PAGE_SIZE;
psize_t ram_size = bootconfig.dram[0].pages * PAGE_SIZE;
#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
const bool mapallmem_p = true;
if (ram_size > (KERNEL_VM_BASE - KERNEL_BASE)) {
printf("%s: dropping RAM size from %luMB to %uMB\n",
__func__, (unsigned long) (ram_size >> 20),
(KERNEL_VM_BASE - KERNEL_BASE) >> 20);
ram_size = KERNEL_VM_BASE - KERNEL_BASE;
}
KASSERT(ram_size <= KERNEL_VM_BASE - KERNEL_BASE);
#else
const bool mapallmem_p = false;
#endif
arm32_bootmem_init(bootconfig.dram[0].address, ram_size,
KERNEL_BASE_PHYS);
arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_HIGH, 0,
kobo_devmap, mapallmem_p);
#ifdef BOOTHOWTO
boothowto |= BOOTHOWTO;
#endif
return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
}
void
consinit(void)
{
static int consinit_called = 0;
if (consinit_called)
return;
consinit_called = 1;
#ifdef CONSDEVNAME
#if NIMXUART > 0
imxuart_set_frequency(IMXUART_FREQ, 2);
#endif
#if (NIMXUART > 0) && defined(IMXUARTCONSOLE)
if (strcmp(consdevname, "imxuart") == 0) {
paddr_t consaddr;
#ifdef CONADDR
consaddr = CONADDR;
#else
consaddr = IMX51_UART2_BASE;
#endif
imxuart_cnattach(&armv7_generic_bs_tag, consaddr, consrate, consmode);
return;
}
#endif
#endif
#if (NWSDISPLAY > 0) && defined(IMXEPDCCONSOLE)
#if NUKBD > 0
ukbd_cnattach();
#endif
{
extern void kobo_cnattach(void);
kobo_cnattach();
}
#endif
}
#ifdef KGDB
#ifndef KGDB_DEVNAME
#define KGDB_DEVNAME "imxuart"
#endif
#ifndef KGDB_DEVMODE
#define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8)
#endif
const char kgdb_devname[20] = KGDB_DEVNAME;
int kgdb_mode = KGDB_DEVMODE;
int kgdb_addr = KGDB_DEVADDR;
extern int kgdb_rate;
void
kgdb_port_init(void)
{
#if (NIMXUART > 0)
if (strcmp(kgdb_devname, "imxuart") == 0) {
imxuart_kgdb_attach(&armv7_generic_bs_tag, kgdb_addr,
kgdb_rate, kgdb_mode);
return;
}
#endif
}
#endif