8 changes: 3 additions & 5 deletions src/mainboard/pcengines/apu2/BiosCallOuts.c
Expand Up @@ -28,6 +28,7 @@
#endif
#include "hudson.h"
#include <stdlib.h>
#include "bios_knobs.h"

static AGESA_STATUS Fch_Oem_config(UINT32 Func, UINT32 FchData, VOID *ConfigPtr);
static AGESA_STATUS board_ReadSpd_from_cbfs(UINT32 Func, UINTN Data, VOID *ConfigPtr);
Expand Down Expand Up @@ -100,11 +101,8 @@ static AGESA_STATUS Fch_Oem_config(UINT32 Func, UINT32 FchData, VOID *ConfigPtr)
/* EHCI configuration */
FchParams->Usb.Ehci3Enable = !IS_ENABLED(CONFIG_HUDSON_XHCI_ENABLE);

#if CONFIG_BOARD_PCENGINES_APU2
FchParams->Usb.Ehci1Enable = FALSE; // Disable EHCI 0 (port 0 to 3)
#else
FchParams->Usb.Ehci1Enable = TRUE; // Enable EHCI 0 (port 0 to 3)
#endif

FchParams->Usb.Ehci1Enable = check_ehci0(); // Enable EHCI 0 (port 0 to 3)
FchParams->Usb.Ehci2Enable = TRUE; // Enable EHCI 1 ( port 4 to 7) port 4 and 5 to EHCI header port 6 and 7 to PCIe slot.

/* sata configuration */
Expand Down
2 changes: 2 additions & 0 deletions src/mainboard/pcengines/apu2/Makefile.inc
Expand Up @@ -13,10 +13,12 @@
# GNU General Public License for more details.
#

romstage-y += bios_knobs.c
romstage-y += BiosCallOuts.c
romstage-y += OemCustomize.c
romstage-y += gpio_ftns.c

ramstage-y += bios_knobs.c
ramstage-y += BiosCallOuts.c
ramstage-y += OemCustomize.c
ramstage-y += gpio_ftns.c
Expand Down
194 changes: 194 additions & 0 deletions src/mainboard/pcengines/apu2/bios_knobs.c
@@ -0,0 +1,194 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 3mdeb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include <console/console.h>
#include <program_loading.h>
#include <cbfs.h>
#include <commonlib/cbfs.h>
#include <commonlib/region.h>
#include <commonlib/cbfs_serialized.h>
#include "bios_knobs.h"

#define BOOTORDER_FILE "bootorder"

static char * findstr(const char *s, const char *pattern)
{
char *result = (char *) s;
char *lpattern = (char *) pattern;

while (*result && *pattern ) {
if ( *lpattern == 0) // the pattern matches return the pointer
return result;
if ( *result == 0) // We're at the end of the file content but don't have a patter match yet
return NULL;
if (*result == *lpattern ) {
// The string matches, simply advance
result++;
lpattern++;
} else {
// The string doesn't match restart the pattern
result++;
lpattern = (char *) pattern;
}
}

return NULL;
}

static u8 check_knob_value(const char *s)
{
const char *boot_file = NULL;
size_t boot_file_len = 0;
char * token = NULL;

//
// This function locates a file in cbfs, maps it to memory and returns
// a void* pointer
//
boot_file = cbfs_boot_map_with_leak(BOOTORDER_FILE, CBFS_TYPE_RAW, &boot_file_len);
if (boot_file == NULL)
printk(BIOS_ALERT, "file [%s] not found in CBFS\n", BOOTORDER_FILE);
if (boot_file_len < 4096)
printk(BIOS_ALERT, "Missing bootorder data.\n");
if (boot_file == NULL || boot_file_len < 4096)
return -1;

token = findstr( boot_file, s );

if (token) {
if (*token == '0') return 0;
if (*token == '1') return 1;
}

return -1;
}

bool check_console(void)
{
u8 scon;

//
// Find the serial console item
//
scon = check_knob_value("scon");

switch (scon) {
case 0:
return false;
break;
case 1:
return true;
break;
default:
printk(BIOS_EMERG, "Missing or invalid scon knob, enable console.\n");
break;
}

return true;
}

static bool check_uart(char uart_letter)
{
u8 uarten;

switch (uart_letter) {
case 'c':
uarten = check_knob_value("uartc");
break;
case 'd':
uarten = check_knob_value("uartd");
break;
default:
uarten = -1;
break;
}

switch (uarten) {
case 0:
return false;
break;
case 1:
return true;
break;
default:
printk(BIOS_EMERG, "Missing or invalid uart knob, disable port.\n");
break;
}

return false;
}

inline bool check_uartc(void)
{
return check_uart('c');
}

inline bool check_uartd(void)
{
return check_uart('d');
}

bool check_ehci0(void)
{
u8 ehci0;

//
// Find the serial console item
//
ehci0 = check_knob_value("ehcien");

switch (ehci0) {
case 0:
return false;
break;
case 1:
return true;
break;
default:
printk(BIOS_EMERG, "Missing or invalid ehci0 knob, enable ehci0.\n");
break;
}

return true;
}

bool check_mpcie2_clk(void)
{
u8 mpcie2_clk;

//
// Find the serial console item
//
mpcie2_clk = check_knob_value("mpcie2_clk");

switch (mpcie2_clk) {
case 0:
return false;
break;
case 1:
return true;
break;
default:
printk(BIOS_EMERG, "Missing or invalid mpcie2_clk knob, forcing CLK of mPCIe2 slot is not enabled .\n");
break;
}

return false;
}
31 changes: 31 additions & 0 deletions src/mainboard/pcengines/apu2/bios_knobs.h
@@ -0,0 +1,31 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2017 3mdeb
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _BIOS_KNOBS_H
#define _BIOS_KNOBS_H

bool check_console(void);
bool check_uartc(void);
bool check_uartd(void);
bool check_ehci0(void);
bool check_mpcie2_clk(void);


#endif
74 changes: 54 additions & 20 deletions src/mainboard/pcengines/apu2/mainboard.c
Expand Up @@ -33,6 +33,7 @@
#include <cpu/amd/mtrr.h>
#include <spd_bin.h>
#include "gpio_ftns.h"
#include "bios_knobs.h"

#define PM_RTC_CONTROL 0x56
#define PM_RTC_SHADOW 0x5B
Expand Down Expand Up @@ -141,25 +142,55 @@ static void pirq_setup(void)
/* Wrapper to enable GPIO/UART devices under menuconfig. Revisit
* once configuration file format for SPI flash storage is complete.
*/
#define SIO_PORT 0x2e
#define SIO_PORT 0x2E

static void config_gpio_mux(void)
{
struct device *uart, *gpio;

uart = dev_find_slot_pnp(SIO_PORT, NCT5104D_SP3);
gpio = dev_find_slot_pnp(SIO_PORT, NCT5104D_GPIO0);
if (uart)
uart->enabled = CONFIG_APU2_PINMUX_UART_C;
if (gpio)
gpio->enabled = CONFIG_APU2_PINMUX_GPIO0;

uart = dev_find_slot_pnp(SIO_PORT, NCT5104D_SP4);
gpio = dev_find_slot_pnp(SIO_PORT, NCT5104D_GPIO1);
if (uart)
uart->enabled = CONFIG_APU2_PINMUX_UART_D;
if (gpio)
gpio->enabled = CONFIG_APU2_PINMUX_GPIO1;
if (check_uartc()) {
printk(BIOS_INFO, "UARTC enabled\n");

uart = dev_find_slot_pnp(SIO_PORT, NCT5104D_SP3);
if (uart)
uart->enabled = 1;

gpio = dev_find_slot_pnp(SIO_PORT, NCT5104D_GPIO0);
if (gpio)
gpio->enabled = 0;
} else {
printk(BIOS_INFO, "UARTC disabled\n");

uart = dev_find_slot_pnp(SIO_PORT, NCT5104D_SP3);
if (uart)
uart->enabled = 0;

gpio = dev_find_slot_pnp(SIO_PORT, NCT5104D_GPIO0);
if (gpio)
gpio->enabled = 1;
}

if (check_uartd()) {
printk(BIOS_INFO, "UARTD enabled\n");

uart = dev_find_slot_pnp(SIO_PORT, NCT5104D_SP4);
if (uart)
uart->enabled = 1;

gpio = dev_find_slot_pnp(SIO_PORT, NCT5104D_GPIO1);
if (gpio)
gpio->enabled = 0;
} else {
printk(BIOS_INFO, "UARTD disabled\n");

uart = dev_find_slot_pnp(SIO_PORT, NCT5104D_SP4);
if (uart)
uart->enabled = 0;

gpio = dev_find_slot_pnp(SIO_PORT, NCT5104D_GPIO1);
if (gpio)
gpio->enabled = 1;
}
}

/**********************************************
Expand All @@ -168,6 +199,7 @@ static void config_gpio_mux(void)

static void mainboard_enable(device_t dev)
{
bool scon = check_console();

config_gpio_mux();

Expand All @@ -176,8 +208,9 @@ static void mainboard_enable(device_t dev)
if (bsp_topmem2() > 0)
total_mem += (bsp_topmem2() / (1024 * 1024)) - 4 * 1024;

printk(BIOS_ALERT, "%d MB", total_mem);

if(scon) {
printk(BIOS_ALERT, "%d MB", total_mem);
}
//
// Read memory configuration from GPIO 49 and 50
//
Expand All @@ -189,11 +222,12 @@ static void mainboard_enable(device_t dev)
spd_buffer[3] = 3;
}

if (spd_buffer[3] == 8) {
printk(BIOS_ALERT, " ECC");
}
printk(BIOS_ALERT, " DRAM\n\n");
if (scon) {
if (spd_buffer[3] == 8)
printk(BIOS_ALERT, " ECC");

printk(BIOS_ALERT, " DRAM\n\n");
}
//
// Enable the RTC output
//
Expand Down
24 changes: 19 additions & 5 deletions src/mainboard/pcengines/apu2/romstage.c
Expand Up @@ -33,6 +33,7 @@
#include <Fch/Fch.h>
#include "gpio_ftns.h"
#include <build.h>
#include "bios_knobs.h"

static void early_lpc_init(void);

Expand Down Expand Up @@ -76,11 +77,14 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
data = *memptr;
printk(BIOS_INFO, "FCH_MISC_REG40 is 0x%08x \n", data);

// sign of life strings
printk(BIOS_ALERT, CONFIG_MAINBOARD_PART_NUMBER "\n");
printk(BIOS_ALERT, "coreboot build %s\n", COREBOOT_DMI_DATE);
printk(BIOS_ALERT, "BIOS version %s\n", COREBOOT_ORIGIN_GIT_TAG);
bool scon = check_console();

if(scon) {
// sign of life strings
printk(BIOS_ALERT, CONFIG_MAINBOARD_PART_NUMBER "\n");
printk(BIOS_ALERT, "coreboot build %s\n", COREBOOT_DMI_DATE);
printk(BIOS_ALERT, "BIOS version %s\n", COREBOOT_ORIGIN_GIT_TAG);
}
//
// Configure clock request
//
Expand All @@ -106,7 +110,17 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
// force it to be always on
data |= 0xF << (1 * 4); // CLKREQ GFX to GFXCLK
#else
data |= 0xA << (1 * 4); // CLKREQ GFX to GFXCLK
bool mpcie2_clk = check_mpcie2_clk();
if (mpcie2_clk) {
// make GFXCLK to ignore CLKREQ# input
// force it to be always on
data |= 0xF << (1 * 4); // CLKREQ GFX to GFXCLK
printk(BIOS_DEBUG, "mPCIe clock enabled\n");
}
else {
data |= 0xA << (1 * 4); // CLKREQ GFX to GFXCLK
printk(BIOS_DEBUG, "mPCIe clock disabled\n");
}
#endif

*((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG04)) = data;
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.