2 changes: 2 additions & 0 deletions src/mainboard/pcengines/apu2/bios_knobs.h
Expand Up @@ -28,5 +28,7 @@ bool check_ehci0(void);
bool check_mpcie2_clk(void);
int check_com2(void);
int check_boost(void);
bool check_sd3_mode(void);
u16 get_watchdog_timeout(void);

#endif
10 changes: 10 additions & 0 deletions src/mainboard/pcengines/apu2/bootorder_def
Expand Up @@ -2,6 +2,14 @@
/pci@i0cf8/usb@10/usb-*@2
/pci@i0cf8/usb@10/usb-*@3
/pci@i0cf8/usb@10/usb-*@4
/pci@i0cf8/usb@12/usb-*@1
/pci@i0cf8/usb@12/usb-*@2
/pci@i0cf8/usb@12/usb-*@3
/pci@i0cf8/usb@12/usb-*@4
/pci@i0cf8/usb@13/usb-*@1
/pci@i0cf8/usb@13/usb-*@2
/pci@i0cf8/usb@13/usb-*@3
/pci@i0cf8/usb@13/usb-*@4
/pci@i0cf8/*@14,7
/pci@i0cf8/*@11/drive@0/disk@0
/pci@i0cf8/*@11/drive@1/disk@0
Expand All @@ -17,3 +25,5 @@ ehcien0
mpcie2_clk0
com2en0
boosten1
sd3mode0
watchdog0000
16 changes: 12 additions & 4 deletions src/mainboard/pcengines/apu2/bootorder_map
@@ -1,7 +1,15 @@
a USB 1 / USB 2 SS and HS
a USB 1 / USB 2 SS and HS
a USB 1 / USB 2 SS and HS
a USB 1 / USB 2 SS and HS
a USB
a USB
a USB
a USB
a USB
a USB
a USB
a USB
a USB
a USB
a USB
a USB
b SDCARD
c mSATA
d SATA
Expand Down
147 changes: 147 additions & 0 deletions src/mainboard/pcengines/apu2/mainboard.c
Expand Up @@ -133,6 +133,14 @@ static void mainboard_enable(device_t dev)
sio_dev = dev_find_slot_pnp(0x2E, NCT5104D_GPIO1);
if ( sio_dev ) sio_dev->enabled = 1;
}

struct device *sd_dev = dev_find_slot(0, PCI_DEVFN(0x14, 7));

struct southbridge_amd_pi_hudson_config *sd_chip =
(struct southbridge_amd_pi_hudson_config *)(sd_dev->chip_info);

if (!check_sd3_mode())
sd_chip->sd_mode = 0;
}

static void mainboard_final(void *chip_info) {
Expand Down Expand Up @@ -284,6 +292,145 @@ const char *smbios_mainboard_serial_number(void)
return serial;
}

int fill_mainboard_smbios_type16(unsigned long *current, int *handle)
{
u8 spd_index = 0;
if ( ReadFchGpio(APU2_SPD_STRAP0_GPIO) ) spd_index |= BIT0;
if ( ReadFchGpio(APU2_SPD_STRAP1_GPIO) ) spd_index |= BIT1;

u8 spd_buffer[SPD_SIZE];
if (read_spd_from_cbfs(spd_buffer, spd_index) < 0) {
return 0;
}

struct smbios_type16 *t = (struct smbios_type16 *)*current;
int len = sizeof(struct smbios_type16) - 2;
memset(t, 0, sizeof(struct smbios_type16));

t->handle = *handle;
t->length = len;
t->type = SMBIOS_PHYS_MEMORY_ARRAY;
t->use = MEMORY_ARRAY_USE_SYSTEM;
t->location = MEMORY_ARRAY_LOCATION_SYSTEM_BOARD;
t->maximum_capacity = 4 * 1024 * 1024; // 4GB (in kB) due to board design
t->extended_maximum_capacity = 0;
t->memory_error_information_handle = 0xFFFE;
t->number_of_memory_devices = 1; // only 1 device soldered down to 1 channel

switch(spd_buffer[3]){
case 0x08:
t->memory_error_correction = MEMORY_ARRAY_ECC_MULTI_BIT;
break;
case 0x03:
t->memory_error_correction = MEMORY_ARRAY_ECC_NONE;
break;
default:
t->memory_error_correction = MEMORY_ARRAY_ECC_UNKNOWN;
break;
}
len = t->length + smbios_string_table_len(t->eos);
return len;
}

int fill_mainboard_smbios_type17(unsigned long *current, int *handle, int *type16_handle){

u8 spd_index = 0;
if ( ReadFchGpio(APU2_SPD_STRAP0_GPIO) ) spd_index |= BIT0;
if ( ReadFchGpio(APU2_SPD_STRAP1_GPIO) ) spd_index |= BIT1;

u8 spd_buffer[SPD_SIZE];
if (read_spd_from_cbfs(spd_buffer, spd_index) < 0) {
;
}

char locator[40];

struct smbios_type17 *t = (struct smbios_type17 *)*current;
int len = sizeof(struct smbios_type17) - 2;
memset(t, 0, sizeof(struct smbios_type17));

t->memory_error_information_handle = 0xFFFE;

/* There can be 2GB or 4GB RAM */
if((spd_buffer[4] & 0x07) == 3)
{
t->size = 0x800; /* 2048 MB size */
}
else if((spd_buffer[4] & 0x07) == 4)
{
t->size = 0x1000; /* 4096 MB size */
}

/* Memory speed */
switch (spd_buffer[12])
{
case 0x0a:
t->speed = 1600;
t->clock_speed = 1600;
break;
case 0x0c:
t->speed = 1333;
t->clock_speed = 1333;
break;
default:
t->speed = 0;
t->clock_speed = 0;
break;
}

/* Data width bus is always 64 bits */
t->data_width = 64;

/* Checking if there is ECC correction
If there is - total width is 72b
If not total width is the same as data width - 64b */
if(((spd_buffer[8] & 0x18) >> 3) == 1)
{
t->total_width = t->data_width + 8;
}
else
{
t->total_width = t->data_width;
}

t->type_detail = 0x0080;
t->memory_type = MEMORY_TYPE_DDR3;

/* Retrieve information about memory form factor*/
switch(spd_buffer[3] & 0x0f)
{
case 0x01:
case 0x10:
t->form_factor = MEMORY_FORMFACTOR_RIMM;
break;
case 0x02:
case 0x08:
case 0x20:
t->form_factor = MEMORY_FORMFACTOR_DIMM;
break;
case 0x04:
t->form_factor = MEMORY_FORMFACTOR_SODIMM;
break;
default:
t->form_factor = MEMORY_FORMFACTOR_UNKNOWN;
break;
}

snprintf(locator, sizeof(locator), "Channel-%d-DIMM-%d", 0, 0);
t->device_locator = smbios_add_string(t->eos, locator);

snprintf(locator, sizeof(locator), "BANK %d", 0);
t->bank_locator = smbios_add_string(t->eos, locator);

t->device_set = 0; /* None information about device set */
t->type = SMBIOS_MEMORY_DEVICE;
t->length = len;
t->handle = *handle; /* Handle is incremented in outside function */
t->phys_memory_array_handle = *type16_handle;

return t->length + smbios_string_table_len(t->eos);
}

const char *smbios_mainboard_sku(void)
{
static char sku[5];
Expand Down
19 changes: 19 additions & 0 deletions src/mainboard/pcengines/apu2/romstage.c
Expand Up @@ -194,6 +194,25 @@ void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
// data |= 3 << (3 * 2); // CLK3
//
// *((u32 *)(ACPI_MMIO_BASE + MISC_BASE+FCH_MISC_REG24)) = data;

volatile u32 *ptr = (u32 *)(ACPI_MMIO_BASE + WATCHDOG_BASE);
u16 watchdog_timeout = get_watchdog_timeout();

if (watchdog_timeout == 0) {
//disable watchdog
printk(BIOS_WARNING, "Watchdog is disabled\n");
*ptr |= (1 << 3);
} else {
// enable
*ptr &= ~(1 << 3);
*ptr |= (1 << 0);
// configure timeout
*(ptr + 1) = (u16) watchdog_timeout;
// trigger
*ptr |= (1 << 7);

printk(BIOS_WARNING, "Watchdog is enabled, state = 0x%x, time = %d\n", *ptr, *(ptr + 1));
}
}

/* Halt if there was a built in self test failure */
Expand Down
Binary file modified src/mainboard/pcengines/apu2/variants/apu2/bootorder
Binary file not shown.
2 changes: 1 addition & 1 deletion src/mainboard/pcengines/apu2/variants/apu2/devicetree.cb
Expand Up @@ -79,7 +79,7 @@ chip northbridge/amd/pi/00730F01/root_complex
device pnp 2e.e off end
end # SIO NCT5104D
end # LPC 0x439d

register "sd_mode" = "3"
device pci 14.7 on end # SD
device pci 16.0 on end # USB EHCI2 usb[8:7] - muxed with XHCI
end #chip southbridge/amd/pi/hudson
Expand Down
Binary file modified src/mainboard/pcengines/apu2/variants/apu3/bootorder
Binary file not shown.
2 changes: 1 addition & 1 deletion src/mainboard/pcengines/apu2/variants/apu3/devicetree.cb
Expand Up @@ -79,7 +79,7 @@ chip northbridge/amd/pi/00730F01/root_complex
device pnp 2e.e off end
end # SIO NCT5104D
end # LPC 0x439d

register "sd_mode" = "3"
device pci 14.7 on end # SD
device pci 16.0 on end # USB EHCI2 usb[8:7] - muxed with XHCI
end #chip southbridge/amd/pi/hudson
Expand Down
Binary file modified src/mainboard/pcengines/apu2/variants/apu4/bootorder
Binary file not shown.
2 changes: 1 addition & 1 deletion src/mainboard/pcengines/apu2/variants/apu4/devicetree.cb
Expand Up @@ -78,7 +78,7 @@ chip northbridge/amd/pi/00730F01/root_complex
device pnp 2e.e off end
end # SIO NCT5104D
end # LPC 0x439d

register "sd_mode" = "3"
device pci 14.7 on end # SD
device pci 16.0 on end # USB EHCI2 usb[8:7] - muxed with XHCI
end #chip southbridge/amd/pi/hudson
Expand Down
Binary file modified src/mainboard/pcengines/apu2/variants/apu5/bootorder
Binary file not shown.
2 changes: 1 addition & 1 deletion src/mainboard/pcengines/apu2/variants/apu5/devicetree.cb
Expand Up @@ -79,7 +79,7 @@ chip northbridge/amd/pi/00730F01/root_complex
device pnp 2e.e off end
end # SIO NCT5104D
end # LPC 0x439d

register "sd_mode" = "3"
device pci 14.7 on end # SD
device pci 16.0 on end # USB EHCI2 usb[8:7] - muxed with XHCI
end #chip southbridge/amd/pi/hudson
Expand Down
28 changes: 14 additions & 14 deletions src/southbridge/amd/pi/hudson/sd.c
Expand Up @@ -29,31 +29,31 @@ static void sd_init(struct device *dev)
{
u32 stepping;

stepping = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xFC);
stepping = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)),
0xFC);

// Force to use SD host in 2.0 mode for APU2
// struct southbridge_amd_pi_hudson_config *sd_chip =
// (struct southbridge_amd_pi_hudson_config *)(dev->chip_info);
struct southbridge_amd_pi_hudson_config *sd_chip =
(struct southbridge_amd_pi_hudson_config *)(dev->chip_info);

// if (sd_chip->sd_mode == 3) { /* SD 3.0 mode */
// pci_write_config32(dev, 0xA4, 0x31FEC8B2);
// pci_write_config32(dev, 0xA8, 0x00002503);
// pci_write_config32(dev, 0xB0, 0x02180C19);
// pci_write_config32(dev, 0xD0, 0x0000078B);
// }
// else { /* SD 2.0 mode */
if (sd_chip->sd_mode == 3) { /* SD 3.0 mode */
pci_write_config32(dev, 0xA4, 0x21FEC8B2);
pci_write_config32(dev, 0xA8, 0x00002503);
pci_write_config32(dev, 0xB0, 0x02180C19);
pci_write_config32(dev, 0xD0, 0x0000078B);
}
else { /* SD 2.0 mode */
if ((stepping & 0x0000000F) == 0) { /* Stepping A0 */
pci_write_config32(dev, 0xA4, 0x21DE32B2);
pci_write_config32(dev, 0xB0, 0x01180C01);
pci_write_config32(dev, 0xB0, 0x01180C19);
pci_write_config32(dev, 0xD0, 0x0000058B);
}
else { /* Stepping >= A1 */
pci_write_config32(dev, 0xA4, 0x21FE32B2);
pci_write_config32(dev, 0xA8, 0x00000070);
pci_write_config32(dev, 0xB0, 0x01180C01);
pci_write_config32(dev, 0xB0, 0x01180C19);
pci_write_config32(dev, 0xD0, 0x0000078B);
}
// }
}
}

static struct device_operations sd_ops = {
Expand Down