2 * This file is part of the coreboot project.
4 * Copyright (C) 2011 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 #include <northbridge/amd/agesa/agesawrapper.h>
19 #include <northbridge/amd/agesa/BiosCallOuts.h>
21 #include "OptionsIds.h"
22 #include "heapManager.h"
26 /* These defines are used to select the appropriate socket for the SPD read
27 * because this is a multi-socket design.
29 #define PCI_REG_GPIO_56_to_53_CNTRL (0x52)
30 #define GPIO_OUT_BIT_GPIO53 (BIT0)
31 #define GPIO_OUT_BIT_GPIO54 (BIT1)
32 #define GPIO_OUT_ENABLE_BIT_GPIO53 (BIT4)
33 #define GPIO_OUT_ENABLE_BIT_GPIO54 (BIT5)
35 #define GPIO_OUT_BIT_GPIO54_to_53_MASK \
36 (GPIO_OUT_BIT_GPIO54 | GPIO_OUT_BIT_GPIO53)
37 #define GPIO_OUT_ENABLE_BIT_GPIO54_to_53_MASK \
38 (GPIO_OUT_ENABLE_BIT_GPIO54 | GPIO_OUT_ENABLE_BIT_GPIO53)
40 static UINT8
select_socket(UINT8 socket_id
)
42 device_t sm_dev
= PCI_DEV(0, 0x14, 0); //SMBus
44 UINT8 gpio56_to_53
= 0;
46 /* Configure GPIO54,53 to select the desired socket
47 * GPIO54,53 control the HC4052 S1,S0
49 * 0 0 channel 1 (Socket1)
50 * 0 1 channel 2 (Socket2)
51 * 1 0 channel 3 (Socket3)
52 * 1 1 channel 4 (Socket4)
54 gpio56_to_53
= pci_read_config8(sm_dev
, PCI_REG_GPIO_56_to_53_CNTRL
);
55 value
= gpio56_to_53
& (~GPIO_OUT_BIT_GPIO54_to_53_MASK
);
57 value
&= (~GPIO_OUT_ENABLE_BIT_GPIO54_to_53_MASK
); // 0=Output Enabled, 1=Tristate
58 pci_write_config8(sm_dev
, PCI_REG_GPIO_56_to_53_CNTRL
, value
);
63 static void restore_socket(UINT8 original_value
)
65 device_t sm_dev
= PCI_DEV(0, 0x14, 0); //SMBus
66 pci_write_config8(sm_dev
, PCI_REG_GPIO_56_to_53_CNTRL
, original_value
);
70 static AGESA_STATUS
board_ReadSpd (UINT32 Func
, UINTN Data
, VOID
*ConfigPtr
);
73 const BIOS_CALLOUT_STRUCT BiosCallouts
[] =
75 {AGESA_DO_RESET
, agesa_Reset
},
76 {AGESA_READ_SPD
, board_ReadSpd
},
77 {AGESA_READ_SPD_RECOVERY
, agesa_NoopUnsupported
},
78 {AGESA_RUNFUNC_ONAP
, agesa_RunFuncOnAp
},
79 {AGESA_GET_IDS_INIT_DATA
, agesa_EmptyIdsInitData
},
80 {AGESA_HOOKBEFORE_DQS_TRAINING
, agesa_NoopSuccess
},
81 {AGESA_HOOKBEFORE_DRAM_INIT
, agesa_NoopSuccess
},
82 {AGESA_HOOKBEFORE_EXIT_SELF_REF
, agesa_NoopSuccess
},
84 const int BiosCalloutsLen
= ARRAY_SIZE(BiosCallouts
);
86 static AGESA_STATUS
board_ReadSpd (UINT32 Func
, UINTN Data
, VOID
*ConfigPtr
)
90 UINT8 original_value
= 0;
92 if (ConfigPtr
== NULL
)
95 original_value
= select_socket(((AGESA_READ_SPD_PARAMS
*)ConfigPtr
)->SocketId
);
97 Status
= agesa_ReadSpd (Func
, Data
, ConfigPtr
);
99 restore_socket(original_value
);
101 Status
= AGESA_UNSUPPORTED
;
107 const struct OEM_HOOK OemCustomize
= {