mc_tcu3: Switch to hwilib instead of own hwinfo implementation
Use hwilib in vendorcode/siemens/hwilib to get fields from hwinfo instead of having mainboard specific hwinfo code. This patch does not change the functional behavior in any way. Change-Id: Idb226a82a08b1b753f654c5cde106236e72f33c3 Signed-off-by: Werner Zeh <werner.zeh@siemens.com> Reviewed-on: https://review.coreboot.org/14506 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
223498fa16
commit
bf13d3f567
|
@ -30,6 +30,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
|
||||||
select USE_BLOBS
|
select USE_BLOBS
|
||||||
select CBFS_AUTOGEN_ATTRIBUTES
|
select CBFS_AUTOGEN_ATTRIBUTES
|
||||||
select FSP_BAYTRAIL_GFX_INIT
|
select FSP_BAYTRAIL_GFX_INIT
|
||||||
|
select USE_SIEMENS_HWILIB
|
||||||
|
|
||||||
config MAINBOARD_DIR
|
config MAINBOARD_DIR
|
||||||
string
|
string
|
||||||
|
|
|
@ -13,11 +13,8 @@
|
||||||
## GNU General Public License for more details.
|
## GNU General Public License for more details.
|
||||||
##
|
##
|
||||||
|
|
||||||
romstage-y += modhwinfo.c
|
|
||||||
|
|
||||||
ramstage-y += gpio.c
|
ramstage-y += gpio.c
|
||||||
ramstage-y += irqroute.c
|
ramstage-y += irqroute.c
|
||||||
ramstage-y += modhwinfo.c
|
|
||||||
ramstage-y += lcd_panel.c
|
ramstage-y += lcd_panel.c
|
||||||
ramstage-y += ptn3460.c
|
ramstage-y += ptn3460.c
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
#include <cbfs.h>
|
#include <cbfs.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "modhwinfo.h"
|
|
||||||
#include "soc/gpio.h"
|
#include "soc/gpio.h"
|
||||||
#include "lcd_panel.h"
|
#include "lcd_panel.h"
|
||||||
#include "ptn3460.h"
|
#include "ptn3460.h"
|
||||||
|
|
||||||
|
|
||||||
/** \brief Reads GPIOs used for LCD panel encoding and returns the 4 bit value
|
/** \brief Reads GPIOs used for LCD panel encoding and returns the 4 bit value
|
||||||
* @param no parameters
|
* @param no parameters
|
||||||
* @return LCD panel type encoded in 4 bits
|
* @return LCD panel type encoded in 4 bits
|
||||||
|
@ -44,8 +44,6 @@ int setup_lcd_panel(void)
|
||||||
{
|
{
|
||||||
u8 lcd_type;
|
u8 lcd_type;
|
||||||
int status;
|
int status;
|
||||||
struct edidinfo *eib = NULL;
|
|
||||||
struct shortinfo *sib = NULL;
|
|
||||||
char blockname[33];
|
char blockname[33];
|
||||||
|
|
||||||
lcd_type = get_lcd_panel_type();
|
lcd_type = get_lcd_panel_type();
|
||||||
|
@ -71,20 +69,12 @@ int setup_lcd_panel(void)
|
||||||
status = 1;
|
status = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
/* Now that we have the panel type, setup the DP2LVDS converter */
|
||||||
/* Now that we have the panel type, get the matching block and setup */
|
status = ptn3460_init(blockname);
|
||||||
/* the DP2LVDS converter accordingly */
|
if (status)
|
||||||
eib = get_edidinfo(blockname);
|
printk(BIOS_ERR, "LCD: Setup PTN with status 0x%x\n", status);
|
||||||
sib = get_shortinfo(blockname);
|
else
|
||||||
|
|
||||||
if ((!eib) || (!sib)) {
|
|
||||||
printk(BIOS_ERR, "LCD: Info block named \"%s\" not found!\n", blockname);
|
|
||||||
status = 1;
|
|
||||||
} else {
|
|
||||||
printk(BIOS_INFO, "LCD: Found SIB at 0x%x, EIB at 0x%x\n",
|
|
||||||
(int)sib, (int)eib);
|
|
||||||
status = ptn3460_init(lcd_type, eib, sib);
|
|
||||||
printk(BIOS_INFO, "LCD: Setup PTN with status 0x%x\n", status);
|
printk(BIOS_INFO, "LCD: Setup PTN with status 0x%x\n", status);
|
||||||
}
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,9 +29,47 @@
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <arch/interrupt.h>
|
#include <arch/interrupt.h>
|
||||||
#include <boot/coreboot_tables.h>
|
#include <boot/coreboot_tables.h>
|
||||||
|
#include <hwilib.h>
|
||||||
#include "lcd_panel.h"
|
#include "lcd_panel.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief This function will search for a MAC address which can be assigned
|
||||||
|
* to a MACPHY.
|
||||||
|
* @param pci_bdf Bus, device and function of the given PCI-device
|
||||||
|
* @param mac buffer where to store the MAC address
|
||||||
|
* @return cb_err CB_ERR or CB_SUCCESS
|
||||||
|
*/
|
||||||
|
enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6])
|
||||||
|
{
|
||||||
|
uint8_t mac_adr[6];
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
/* Open main hwinfo block */
|
||||||
|
if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
|
||||||
|
return CB_ERR;
|
||||||
|
/* Get first MAC address from hwinfo. */
|
||||||
|
if (hwilib_get_field(Mac1, mac_adr, sizeof(mac_adr)) != sizeof(mac_adr))
|
||||||
|
return CB_ERR;
|
||||||
|
/* Ensure the first MAC-Address is not completely 0x00 or 0xff */
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
if (mac_adr[i] != 0xFF)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == 6){
|
||||||
|
return CB_ERR;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
if (mac_adr[i] != 0x00)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == 6){
|
||||||
|
return CB_ERR;
|
||||||
|
} else {
|
||||||
|
memcpy(mac, mac_adr, 6);
|
||||||
|
return CB_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mainboard_enable is executed as first thing after enumerate_buses().
|
* mainboard_enable is executed as first thing after enumerate_buses().
|
||||||
* This is the earliest point to add customization.
|
* This is the earliest point to add customization.
|
||||||
|
|
|
@ -1,144 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the coreboot project.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2014 Siemens AG.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "modhwinfo.h"
|
|
||||||
#include "lcd_panel.h"
|
|
||||||
#include <cbfs.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/** \brief This function will find the first linked info block.
|
|
||||||
* @param *filename Filename in cbfs
|
|
||||||
* @param *file_offset Pointer to the offset of the cbfs file contents
|
|
||||||
* @return u8* Pointer to the found block
|
|
||||||
*/
|
|
||||||
u8* get_first_linked_block(char *filename, u8 **file_offset)
|
|
||||||
{
|
|
||||||
u8* block_ptr = NULL;
|
|
||||||
|
|
||||||
block_ptr = cbfs_boot_map_with_leak(filename, 0x50, NULL);
|
|
||||||
if (!block_ptr)
|
|
||||||
return NULL;
|
|
||||||
if (!strncmp((char*)block_ptr, "H1W2M3I4", LEN_MAGIC_NUM)) {
|
|
||||||
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET)) == LEN_MAIN_HWINFO) &&
|
|
||||||
(*((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) != 0x00)) {
|
|
||||||
*file_offset = block_ptr;
|
|
||||||
return *((s32*)(block_ptr + NEXT_OFFSET_HWINFO)) + block_ptr;
|
|
||||||
} else
|
|
||||||
return NULL;
|
|
||||||
} else if (!strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)) {
|
|
||||||
*file_offset = block_ptr;
|
|
||||||
return block_ptr;
|
|
||||||
} else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief This function will find the main info block
|
|
||||||
* @param *filename Filename in cbfs
|
|
||||||
* @return *hwinfo Pointer to the data of the main info block
|
|
||||||
*/
|
|
||||||
struct hwinfo* get_hwinfo(char *filename)
|
|
||||||
{
|
|
||||||
struct hwinfo* main_hwinfo;
|
|
||||||
|
|
||||||
main_hwinfo = cbfs_boot_map_with_leak(filename, 0x50, NULL);
|
|
||||||
if ((main_hwinfo) &&
|
|
||||||
(!strncmp(main_hwinfo->magicNumber, "H1W2M3I4", LEN_MAGIC_NUM)) &&
|
|
||||||
(main_hwinfo->length == LEN_MAIN_HWINFO))
|
|
||||||
return main_hwinfo;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief This function will find the short info block
|
|
||||||
* @param *filename Filename in cbfs
|
|
||||||
* @return *shortinfo Pointer to the data of the short info block
|
|
||||||
*/
|
|
||||||
struct shortinfo* get_shortinfo(char *filename)
|
|
||||||
{
|
|
||||||
u8 *block_ptr = NULL;
|
|
||||||
u8 *file_offset = NULL;
|
|
||||||
|
|
||||||
block_ptr = get_first_linked_block(filename, &file_offset);
|
|
||||||
if ((block_ptr == NULL) ||
|
|
||||||
(strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
|
|
||||||
return (struct shortinfo *)block_ptr;
|
|
||||||
|
|
||||||
block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_EDID)));
|
|
||||||
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_SHORT_INFO)
|
|
||||||
return (struct shortinfo *)block_ptr;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief This function will find the edid info block
|
|
||||||
* @param *filename Filename in cbfs
|
|
||||||
* @return *edidinfo Pointer to the data of the edid info block
|
|
||||||
*/
|
|
||||||
struct edidinfo* get_edidinfo(char *filename)
|
|
||||||
{
|
|
||||||
u8 *block_ptr = NULL;
|
|
||||||
u8 *file_offset = NULL;
|
|
||||||
|
|
||||||
block_ptr = get_first_linked_block(filename, &file_offset);
|
|
||||||
if ((block_ptr == NULL) ||
|
|
||||||
(strncmp((char*)block_ptr, "H1W2M3I5", LEN_MAGIC_NUM)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
|
|
||||||
return (struct edidinfo *)block_ptr;
|
|
||||||
|
|
||||||
block_ptr = (file_offset + *((s32*)(block_ptr + NEXT_OFFSET_SIB)));
|
|
||||||
if ((*((u16*)(block_ptr + HWI_LEN_OFFSET))) == LEN_EDID_INFO)
|
|
||||||
return (struct edidinfo *)block_ptr;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \brief This function will search for a MAC address which can be assigned
|
|
||||||
* to a MACPHY.
|
|
||||||
* @param pci_bdf Bus, device and function of the given PCI-device
|
|
||||||
* @param mac buffer where to store the MAC address
|
|
||||||
* @return cb_err CB_ERR or CB_SUCCESS
|
|
||||||
*/
|
|
||||||
enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6])
|
|
||||||
{
|
|
||||||
struct hwinfo* main_hwinfo;
|
|
||||||
u32 i;
|
|
||||||
|
|
||||||
main_hwinfo = get_hwinfo((char*)"hwinfo.hex");
|
|
||||||
if (!main_hwinfo)
|
|
||||||
return CB_ERR;
|
|
||||||
/* Ensure the first MAC-Address is not completely 0x00 or 0xff */
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
if (main_hwinfo->macAddress1[i] != 0xFF)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i == 6){
|
|
||||||
return CB_ERR;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 6; i++) {
|
|
||||||
if (main_hwinfo->macAddress1[i] != 0x00)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i == 6){
|
|
||||||
return CB_ERR;
|
|
||||||
} else {
|
|
||||||
memcpy(mac, main_hwinfo->macAddress1, 6);
|
|
||||||
return CB_SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,166 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the coreboot project.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2014 Siemens AG
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _MODHWINFO_H_
|
|
||||||
#define _MODHWINFO_H_
|
|
||||||
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
#define LEN_MAGIC_NUM 8
|
|
||||||
#define LEN_MLFB 20
|
|
||||||
#define LEN_SERIAL_NUM 16
|
|
||||||
#define LEN_HW_REVISION 2
|
|
||||||
#define LEN_MAC_ADDRESS 6
|
|
||||||
#define LEN_SPD 128
|
|
||||||
#define NUMBER_OF_MAC_ADDR 4
|
|
||||||
#define LEN_EDID 128
|
|
||||||
#define LEN_MAIN_HWINFO 509
|
|
||||||
#define LEN_SHORT_INFO 289
|
|
||||||
#define LEN_EDID_INFO 181
|
|
||||||
#define NEXT_OFFSET_HWINFO 476
|
|
||||||
#define NEXT_OFFSET_SIB 260
|
|
||||||
#define NEXT_OFFSET_EDID 176
|
|
||||||
#define HWI_LEN_OFFSET 12
|
|
||||||
|
|
||||||
/* Define some masks and values */
|
|
||||||
#define SIB_HWINIT_IDX 0x0e
|
|
||||||
#define SIB_COLOR_6BIT 0x00
|
|
||||||
#define SIB_COLOR_8BIT 0x01
|
|
||||||
#define SIB_COLOR_10BIT 0x02
|
|
||||||
#define SIB_DISP_CON_IDX 0x16
|
|
||||||
#define SIB_LVDS_SINGLE_LANE 0x00
|
|
||||||
#define SIB_LVDS_DUAL_LANE 0x05
|
|
||||||
|
|
||||||
struct PhysDevStruc {
|
|
||||||
u8 bustype;
|
|
||||||
u8 devfn;
|
|
||||||
u16 bus;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
|
|
||||||
struct hwinfo {
|
|
||||||
// Offset 0x0
|
|
||||||
char magicNumber[LEN_MAGIC_NUM];
|
|
||||||
// Offset 0x08
|
|
||||||
u8 versionID[4];
|
|
||||||
// Offset 0x0c
|
|
||||||
u16 length;
|
|
||||||
// Offset 0x0e
|
|
||||||
char BGR_Name[128];
|
|
||||||
//Offset 0x8e
|
|
||||||
char MLFB[LEN_MLFB];
|
|
||||||
// Offset 0xa2
|
|
||||||
u8 uniqueNumber[16];
|
|
||||||
// Offset 0xb2
|
|
||||||
u8 fill_1[12];
|
|
||||||
// Offset 0xbe
|
|
||||||
u8 hwRevision[LEN_HW_REVISION];
|
|
||||||
//Offset 0xc0
|
|
||||||
u8 macAddress1[LEN_MAC_ADDRESS];
|
|
||||||
u8 numOfAuxMacAddr1;
|
|
||||||
u8 fill_2;
|
|
||||||
//Offset 0xc8
|
|
||||||
u8 macAddress2[LEN_MAC_ADDRESS];
|
|
||||||
u8 numOfAuxMacAddr2;
|
|
||||||
u8 fill_3;
|
|
||||||
//Offset 0xd0
|
|
||||||
u8 macAddress3[LEN_MAC_ADDRESS];
|
|
||||||
u8 numOfAuxMacAddr3;
|
|
||||||
u8 fill_4;
|
|
||||||
//Offset 0xd8
|
|
||||||
u8 macAddress4[LEN_MAC_ADDRESS];
|
|
||||||
u8 numOfAuxMacAddr4;
|
|
||||||
u8 fill_5;
|
|
||||||
// Offset 0xe0
|
|
||||||
u8 SPD[LEN_SPD];
|
|
||||||
// Offset 0x160
|
|
||||||
u8 fill_6[88];
|
|
||||||
// Offset 0x1b8
|
|
||||||
u32 featureFlags;
|
|
||||||
// Offset 0x1bc
|
|
||||||
u8 fill_7[4];
|
|
||||||
// Offset 0x1c0
|
|
||||||
u32 biosFlags;
|
|
||||||
// Offset 0x1c4
|
|
||||||
u8 fill_8[8];
|
|
||||||
//Offset 0x1cc
|
|
||||||
struct PhysDevStruc etherDev[NUMBER_OF_MAC_ADDR];
|
|
||||||
// Offset 0x1dc
|
|
||||||
s32 nextInfoOffset;
|
|
||||||
// Offset 0x1e0
|
|
||||||
u8 fill_9[4];
|
|
||||||
// Offset 0x1e4
|
|
||||||
u32 portRTC;
|
|
||||||
// Offset 0x1e8
|
|
||||||
u8 typeRTC;
|
|
||||||
// Offset 0x1e9
|
|
||||||
u8 fill_10[20];
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct shortinfo {
|
|
||||||
// Offset 0x0
|
|
||||||
char magicNumber[LEN_MAGIC_NUM];
|
|
||||||
// Offset 0x08
|
|
||||||
u8 versionID[4];
|
|
||||||
// Offset 0x0c
|
|
||||||
u16 length;
|
|
||||||
// Offset 0x0e
|
|
||||||
char BGR_Name[128];
|
|
||||||
//Offset 0x8e
|
|
||||||
char MLFB[LEN_MLFB];
|
|
||||||
// Offset 0xa2
|
|
||||||
u8 uniqueNumber[26];
|
|
||||||
// Offset 0xbc
|
|
||||||
u8 fill_1[12];
|
|
||||||
//Offset 0xc8
|
|
||||||
u8 hwRevision[2];
|
|
||||||
// Offset 0xca
|
|
||||||
u8 fill_2[18];
|
|
||||||
// Offset 0xdc
|
|
||||||
u8 panelFeatures[32];
|
|
||||||
// Offset 0xfc
|
|
||||||
u8 fill_3[8];
|
|
||||||
// Offset 0x104
|
|
||||||
s32 nextInfoOffset;
|
|
||||||
// Offset 0x108
|
|
||||||
u8 fill_4[25];
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
struct edidinfo {
|
|
||||||
// Offset 0x0
|
|
||||||
char magicNumber[LEN_MAGIC_NUM];
|
|
||||||
// Offset 0x08
|
|
||||||
u8 versionID[4];
|
|
||||||
// Offset 0x0c
|
|
||||||
u16 length;
|
|
||||||
// Offset 0x0e
|
|
||||||
u8 fill_1[2];
|
|
||||||
// Offset 0x10
|
|
||||||
u8 edid[LEN_EDID];
|
|
||||||
// Offset 0x90
|
|
||||||
u8 fill_2[32];
|
|
||||||
// Offset 0xb0
|
|
||||||
s32 nextInfoOffset;
|
|
||||||
// Offset 0xb4
|
|
||||||
u8 fill_3;
|
|
||||||
} __attribute__ ((packed));
|
|
||||||
|
|
||||||
u8* get_first_linked_block(char *filename, u8 **starting_adr);
|
|
||||||
struct hwinfo* get_hwinfo(char *filename);
|
|
||||||
struct shortinfo* get_shortinfo(char *filename);
|
|
||||||
struct edidinfo* get_edidinfo(char *filename);
|
|
||||||
enum cb_err mainboard_get_mac_address(u16 bus, u8 devfn, u8 mac[6]);
|
|
||||||
|
|
||||||
#endif /* _MODHWINFO_H_ */
|
|
|
@ -14,33 +14,52 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
#include <hwilib.h>
|
||||||
#include "soc/i2c.h"
|
#include "soc/i2c.h"
|
||||||
#include "ptn3460.h"
|
#include "ptn3460.h"
|
||||||
|
|
||||||
/** \brief This functions sets up the DP2LVDS-converter to be used with the
|
/** \brief This functions sets up the DP2LVDS-converter to be used with the
|
||||||
* appropriate lcd panel
|
* appropriate lcd panel
|
||||||
* @param lcd_type Type of LCD we should set up the converter for
|
* @param *hwi_block Filename in CBFS of the block to use as HW-Info
|
||||||
* @param *sib Pointer to short info block structure
|
|
||||||
* @param *eib Pointer to EDID info block structure
|
|
||||||
* @return 0 on success or error code
|
* @return 0 on success or error code
|
||||||
*/
|
*/
|
||||||
int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib)
|
int ptn3460_init(char *hwi_block)
|
||||||
{
|
{
|
||||||
struct ptn_3460_config cfg;
|
struct ptn_3460_config cfg;
|
||||||
int status;
|
int status;
|
||||||
|
uint8_t disp_con = 0, color_depth = 0;
|
||||||
|
uint8_t edid_data[0x80];
|
||||||
|
|
||||||
|
if (!hwi_block || hwilib_find_blocks(hwi_block) != CB_SUCCESS) {
|
||||||
|
printk(BIOS_ERR, "LCD: Info block \"%s\" not found!\n",
|
||||||
|
hwi_block);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
status = i2c_init(PTN_I2C_CONTROLER);
|
status = i2c_init(PTN_I2C_CONTROLER);
|
||||||
if (status)
|
if (status)
|
||||||
return (PTN_BUS_ERROR | status);
|
return (PTN_BUS_ERROR | status);
|
||||||
|
|
||||||
/* If we are here, we have all the desired information for setting up */
|
/* Get all needed information from hwinfo block */
|
||||||
/* DP2LVDS converter. In addition, the information matches the connected */
|
if (hwilib_get_field(Edid, edid_data, 0x80) != sizeof(edid_data)) {
|
||||||
/* LCD-panel and therefore, we do not have to distinguish between */
|
printk(BIOS_ERR, "LCD: No EDID data available in %s\n",
|
||||||
/* different panels here for the timing. Inside the converter, table 6 */
|
hwi_block);
|
||||||
/* will be used for the timings. */
|
return 1;
|
||||||
status = ptn3460_write_edid(6, eib->edid);
|
}
|
||||||
if (status)
|
if ((hwilib_get_field(PF_DisplCon, &disp_con, 1) != 1)) {
|
||||||
|
printk(BIOS_ERR, "LCD: Missing panel features from %s\n",
|
||||||
|
hwi_block);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (hwilib_get_field(PF_Color_Depth ,&color_depth, 1) != 1) {
|
||||||
|
printk(BIOS_ERR, "LCD: Missing panel features from %s\n",
|
||||||
|
hwi_block);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* Here, all the desired information for setting up DP2LVDS converter*/
|
||||||
|
/* are present. Inside the converter, table 6 will be used for */
|
||||||
|
/* the timings. */
|
||||||
|
if ((status = ptn3460_write_edid(6, edid_data)) != 0)
|
||||||
return status;
|
return status;
|
||||||
/* Select this table to be emulated */
|
/* Select this table to be emulated */
|
||||||
ptn_select_edid(6);
|
ptn_select_edid(6);
|
||||||
|
@ -50,12 +69,12 @@ int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib)
|
||||||
if (status)
|
if (status)
|
||||||
return (PTN_BUS_ERROR | status);
|
return (PTN_BUS_ERROR | status);
|
||||||
|
|
||||||
/* Set up configuration data according to the information blocks we get */
|
/* Set up configuration data according to the hwinfo blocks we get */
|
||||||
cfg.dp_interface_ctrl = 0;
|
cfg.dp_interface_ctrl = 0;
|
||||||
cfg.lvds_interface_ctrl1 = 0x00;
|
cfg.lvds_interface_ctrl1 = 0x00;
|
||||||
if (sib->panelFeatures[SIB_DISP_CON_IDX] == SIB_LVDS_DUAL_LANE)
|
if (disp_con == PF_DISPLCON_LVDS_DUAL)
|
||||||
cfg.lvds_interface_ctrl1 |= 0x0b; /* Turn on dual LVDS lane and clock */
|
cfg.lvds_interface_ctrl1 |= 0x0b; /* Turn on dual LVDS lane and clock */
|
||||||
if ((sib->panelFeatures[SIB_HWINIT_IDX] & 0x03) == SIB_COLOR_6BIT)
|
if (color_depth == PF_COLOR_DEPTH_6BIT)
|
||||||
cfg.lvds_interface_ctrl1 |= 0x20; /* Use 18 bits per pixel */
|
cfg.lvds_interface_ctrl1 |= 0x20; /* Use 18 bits per pixel */
|
||||||
|
|
||||||
cfg.lvds_interface_ctrl2 = 0x03; /* no clock spreading, 300 mV LVDS swing */
|
cfg.lvds_interface_ctrl2 = 0x03; /* no clock spreading, 300 mV LVDS swing */
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#define PTN3460_H_
|
#define PTN3460_H_
|
||||||
|
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include "modhwinfo.h"
|
|
||||||
#include "lcd_panel.h"
|
#include "lcd_panel.h"
|
||||||
|
|
||||||
#define PTN_SLAVE_ADR 0x20
|
#define PTN_SLAVE_ADR 0x20
|
||||||
|
@ -66,7 +65,7 @@ struct ptn_3460_flash{
|
||||||
}__attribute__((packed));
|
}__attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
int ptn3460_init(char lcd_type, struct edidinfo *eib, struct shortinfo *sib);
|
int ptn3460_init(char *hwi_block);
|
||||||
int ptn3460_read_edid(u8 edid_num, u8 *data);
|
int ptn3460_read_edid(u8 edid_num, u8 *data);
|
||||||
int ptn3460_write_edid(u8 edid_num, u8 *data);
|
int ptn3460_write_edid(u8 edid_num, u8 *data);
|
||||||
int ptn_select_edid(u8 edid_num);
|
int ptn_select_edid(u8 edid_num);
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include <soc/acpi.h>
|
#include <soc/acpi.h>
|
||||||
#include <soc/baytrail.h>
|
#include <soc/baytrail.h>
|
||||||
#include <drivers/intel/fsp1_0/fsp_util.h>
|
#include <drivers/intel/fsp1_0/fsp_util.h>
|
||||||
#include "modhwinfo.h"
|
#include <hwilib.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* /brief mainboard call for setup that needs to be done before fsp init
|
* /brief mainboard call for setup that needs to be done before fsp init
|
||||||
|
@ -166,35 +166,44 @@ const PCH_AZALIA_CONFIG mainboard_AzaliaConfig = {
|
||||||
*/
|
*/
|
||||||
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer)
|
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer)
|
||||||
{
|
{
|
||||||
struct hwinfo *hwi_main;
|
uint8_t spd[0x80];
|
||||||
UPD_DATA_REGION *UpdData = FspRtBuffer->Common.UpdDataRgnPtr;
|
UPD_DATA_REGION *UpdData = FspRtBuffer->Common.UpdDataRgnPtr;
|
||||||
|
|
||||||
/* Initialize the Azalia Verb Tables to mainboard specific version */
|
/* Initialize the Azalia Verb Tables to mainboard specific version. */
|
||||||
UpdData->AzaliaConfigPtr = (UINT32)&mainboard_AzaliaConfig;
|
UpdData->AzaliaConfigPtr = (UINT32)&mainboard_AzaliaConfig;
|
||||||
|
|
||||||
/* Get SPD data from hardware information block and setup memory down */
|
/* Get SPD data from hwinfo block and set up memory down */
|
||||||
/* parameters for FSP accordingly */
|
/* parameters for FSP accordingly. */
|
||||||
hwi_main = get_hwinfo((char*)"hwinfo.hex");
|
if (hwilib_find_blocks("hwinfo.hex")) {
|
||||||
if (hwi_main) {
|
printk(BIOS_ERR,
|
||||||
|
"HWInfo not found, use default timings for DDR3.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hwilib_get_field(SPD, spd, sizeof(spd)) != sizeof(spd)) {
|
||||||
|
printk(BIOS_ERR,
|
||||||
|
"SPD not found in HWInfo, use defaults for DDR3.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*Set up DDR timings from HWInfo. */
|
||||||
UpdData->PcdMemoryParameters.EnableMemoryDown = 1;
|
UpdData->PcdMemoryParameters.EnableMemoryDown = 1;
|
||||||
UpdData->PcdMemoryParameters.DRAMType = hwi_main->SPD[2];
|
UpdData->PcdMemoryParameters.DRAMType = spd[2];
|
||||||
UpdData->PcdMemoryParameters.DIMM0Enable = hwi_main->SPD[3] & 0x01;
|
UpdData->PcdMemoryParameters.DIMM0Enable = spd[3] & 0x01;
|
||||||
UpdData->PcdMemoryParameters.DIMM1Enable = (hwi_main->SPD[3] >> 1) & 0x01;
|
UpdData->PcdMemoryParameters.DIMM1Enable = (spd[3] >> 1) & 0x01;
|
||||||
UpdData->PcdMemoryParameters.DIMMDensity = hwi_main->SPD[4];
|
UpdData->PcdMemoryParameters.DIMMDensity = spd[4];
|
||||||
UpdData->PcdMemoryParameters.DIMMDWidth = hwi_main->SPD[5];
|
UpdData->PcdMemoryParameters.DIMMDWidth = spd[5];
|
||||||
UpdData->PcdMemoryParameters.DIMMSides = hwi_main->SPD[7];
|
UpdData->PcdMemoryParameters.DIMMSides = spd[7];
|
||||||
UpdData->PcdMemoryParameters.DIMMBusWidth = hwi_main->SPD[8];
|
UpdData->PcdMemoryParameters.DIMMBusWidth = spd[8];
|
||||||
UpdData->PcdMemoryParameters.DRAMSpeed = hwi_main->SPD[12];
|
UpdData->PcdMemoryParameters.DRAMSpeed = spd[12];
|
||||||
UpdData->PcdMemoryParameters.DIMMtCL = hwi_main->SPD[14];
|
UpdData->PcdMemoryParameters.DIMMtCL = spd[14];
|
||||||
UpdData->PcdMemoryParameters.DIMMtWR = hwi_main->SPD[17];
|
UpdData->PcdMemoryParameters.DIMMtWR = spd[17];
|
||||||
UpdData->PcdMemoryParameters.DIMMtRPtRCD = hwi_main->SPD[18];
|
UpdData->PcdMemoryParameters.DIMMtRPtRCD = spd[18];
|
||||||
UpdData->PcdMemoryParameters.DIMMtRRD = hwi_main->SPD[19];
|
UpdData->PcdMemoryParameters.DIMMtRRD = spd[19];
|
||||||
UpdData->PcdMemoryParameters.DIMMtWTR = hwi_main->SPD[26];
|
UpdData->PcdMemoryParameters.DIMMtWTR = spd[26];
|
||||||
UpdData->PcdMemoryParameters.DIMMtRTP = hwi_main->SPD[27];
|
UpdData->PcdMemoryParameters.DIMMtRTP = spd[27];
|
||||||
UpdData->PcdMemoryParameters.DIMMtFAW = hwi_main->SPD[28];
|
UpdData->PcdMemoryParameters.DIMMtFAW = spd[28];
|
||||||
|
|
||||||
/*If one need output from MRC to be used in Intel RMT, simply */
|
/*If one need output from MRC to be used in Intel RMT, simply */
|
||||||
/*enable the following line */
|
/*enable the following line */
|
||||||
//UpdData->PcdMrcDebugMsg = 1;
|
//UpdData->PcdMrcDebugMsg = 1;
|
||||||
} else
|
|
||||||
printk(BIOS_ERR, "HWInfo not found, leave default timings for DDR3.\n");
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue