Maxim Polyakov | 82ec61e | 2020-04-26 22:12:01 +0300 | [diff] [blame] | 1 | package snr |
| 2 | |
Maxim Polyakov | 8b35851 | 2021-06-30 16:14:53 +0300 | [diff] [blame] | 3 | import ( |
| 4 | "strings" |
| 5 | "fmt" |
Maxim Polyakov | 593b0f1 | 2022-05-11 22:49:14 +0300 | [diff] [blame] | 6 | |
| 7 | "review.coreboot.org/coreboot.git/util/intelp2m/platforms/common" |
| 8 | "review.coreboot.org/coreboot.git/util/intelp2m/config" |
| 9 | "review.coreboot.org/coreboot.git/util/intelp2m/fields" |
Maxim Polyakov | 8b35851 | 2021-06-30 16:14:53 +0300 | [diff] [blame] | 10 | ) |
Maxim Polyakov | 82ec61e | 2020-04-26 22:12:01 +0300 | [diff] [blame] | 11 | |
| 12 | const ( |
| 13 | PAD_CFG_DW0_RO_FIELDS = (0x1 << 27) | (0x1 << 24) | (0x3 << 21) | (0xf << 16) | 0xfc |
| 14 | PAD_CFG_DW1_RO_FIELDS = 0xfdffc3ff |
| 15 | ) |
| 16 | |
| 17 | const ( |
| 18 | PAD_CFG_DW0 = common.PAD_CFG_DW0 |
| 19 | PAD_CFG_DW1 = common.PAD_CFG_DW1 |
| 20 | MAX_DW_NUM = common.MAX_DW_NUM |
| 21 | ) |
| 22 | |
| 23 | type PlatformSpecific struct {} |
| 24 | |
| 25 | // RemmapRstSrc - remmap Pad Reset Source Config |
| 26 | func (PlatformSpecific) RemmapRstSrc() { |
| 27 | macro := common.GetMacro() |
| 28 | if config.TemplateGet() != config.TempInteltool { |
| 29 | // Use reset source remapping only if the input file is inteltool.log dump |
| 30 | return |
| 31 | } |
| 32 | if strings.Contains(macro.PadIdGet(), "GPD") { |
| 33 | // See reset map for the Sunrise GPD Group in the Community 2: |
| 34 | // https://github.com/coreboot/coreboot/blob/master/src/soc/intel/skylake/gpio.c#L15 |
| 35 | // remmap is not required because it is the same as common. |
| 36 | return |
| 37 | } |
| 38 | |
| 39 | dw0 := macro.Register(PAD_CFG_DW0) |
| 40 | var remapping = map[uint8]uint32{ |
| 41 | 0: common.RST_RSMRST << common.PadRstCfgShift, |
| 42 | 1: common.RST_DEEP << common.PadRstCfgShift, |
| 43 | 2: common.RST_PLTRST << common.PadRstCfgShift, |
| 44 | } |
| 45 | resetsrc, valid := remapping[dw0.GetResetConfig()] |
| 46 | if valid { |
| 47 | // dw0.SetResetConfig(resetsrc) |
| 48 | ResetConfigFieldVal := (dw0.ValueGet() & 0x3fffffff) | remapping[dw0.GetResetConfig()] |
| 49 | dw0.ValueSet(ResetConfigFieldVal) |
| 50 | } else { |
| 51 | fmt.Println("Invalid Pad Reset Config [ 0x", resetsrc ," ] for ", macro.PadIdGet()) |
| 52 | } |
| 53 | dw0.CntrMaskFieldsClear(common.PadRstCfgMask) |
| 54 | } |
| 55 | |
| 56 | // Adds The Pad Termination (TERM) parameter from PAD_CFG_DW1 to the macro |
| 57 | // as a new argument |
| 58 | func (PlatformSpecific) Pull() { |
| 59 | macro := common.GetMacro() |
| 60 | dw1 := macro.Register(PAD_CFG_DW1) |
| 61 | var pull = map[uint8]string{ |
| 62 | 0x0: "NONE", |
Benjamin Doron | 7bb756f | 2020-10-22 17:26:18 +0000 | [diff] [blame] | 63 | 0x2: "DN_5K", |
| 64 | 0x4: "DN_20K", |
| 65 | 0x9: "UP_1K", |
| 66 | 0xa: "UP_5K", |
| 67 | 0xb: "UP_2K", |
| 68 | 0xc: "UP_20K", |
| 69 | 0xd: "UP_667", |
Maxim Polyakov | 82ec61e | 2020-04-26 22:12:01 +0300 | [diff] [blame] | 70 | 0xf: "NATIVE", |
| 71 | } |
| 72 | str, valid := pull[dw1.GetTermination()] |
| 73 | if !valid { |
| 74 | str = "INVALID" |
| 75 | fmt.Println("Error", |
| 76 | macro.PadIdGet(), |
| 77 | " invalid TERM value = ", |
| 78 | int(dw1.GetTermination())) |
| 79 | } |
| 80 | macro.Separator().Add(str) |
| 81 | } |
| 82 | |
| 83 | // Generate macro to cause peripheral IRQ when configured in GPIO input mode |
| 84 | func ioApicRoute() bool { |
| 85 | macro := common.GetMacro() |
| 86 | dw0 := macro.Register(PAD_CFG_DW0) |
| 87 | if dw0.GetGPIOInputRouteIOxAPIC() == 0 { |
| 88 | return false |
| 89 | } |
| 90 | |
| 91 | macro.Add("_APIC") |
| 92 | if dw0.GetRXLevelEdgeConfiguration() == common.TRIG_LEVEL { |
| 93 | if dw0.GetRxInvert() != 0 { |
Benjamin Doron | 1bb640d | 2020-11-06 17:19:44 +0000 | [diff] [blame] | 94 | // PAD_CFG_GPI_APIC_LOW(pad, pull, rst) |
Benjamin Doron | 7bb756f | 2020-10-22 17:26:18 +0000 | [diff] [blame] | 95 | macro.Add("_LOW") |
| 96 | } else { |
Benjamin Doron | 1bb640d | 2020-11-06 17:19:44 +0000 | [diff] [blame] | 97 | // PAD_CFG_GPI_APIC_HIGH(pad, pull, rst) |
Benjamin Doron | 7bb756f | 2020-10-22 17:26:18 +0000 | [diff] [blame] | 98 | macro.Add("_HIGH") |
Maxim Polyakov | 82ec61e | 2020-04-26 22:12:01 +0300 | [diff] [blame] | 99 | } |
Maxim Polyakov | 82ec61e | 2020-04-26 22:12:01 +0300 | [diff] [blame] | 100 | macro.Add("(").Id().Pull().Rstsrc().Add("),") |
| 101 | return true |
| 102 | } |
| 103 | |
| 104 | // e.g. PAD_CFG_GPI_APIC_IOS(pad, pull, rst, trig, inv, iosstate, iosterm) |
| 105 | macro.Add("_IOS(").Id().Pull().Rstsrc().Trig().Invert().Add(", TxLASTRxE, SAME),") |
| 106 | return true |
| 107 | } |
| 108 | |
| 109 | // Generate macro to cause NMI when configured in GPIO input mode |
| 110 | func nmiRoute() bool { |
| 111 | macro := common.GetMacro() |
| 112 | if macro.Register(PAD_CFG_DW0).GetGPIOInputRouteNMI() == 0 { |
| 113 | return false |
| 114 | } |
| 115 | // PAD_CFG_GPI_NMI(GPIO_24, UP_20K, DEEP, LEVEL, INVERT), |
| 116 | macro.Add("_NMI").Add("(").Id().Pull().Rstsrc().Trig().Invert().Add("),") |
| 117 | return true |
| 118 | } |
| 119 | |
| 120 | // Generate macro to cause SCI when configured in GPIO input mode |
| 121 | func sciRoute() bool { |
| 122 | macro := common.GetMacro() |
| 123 | dw0 := macro.Register(PAD_CFG_DW0) |
| 124 | if dw0.GetGPIOInputRouteSCI() == 0 { |
| 125 | return false |
| 126 | } |
Benjamin Doron | 1bb640d | 2020-11-06 17:19:44 +0000 | [diff] [blame] | 127 | // PAD_CFG_GPI_SCI(GPP_B18, UP_20K, PLTRST, LEVEL, INVERT), |
| 128 | macro.Add("_SCI").Add("(").Id().Pull().Rstsrc().Trig().Invert().Add("),") |
Maxim Polyakov | 82ec61e | 2020-04-26 22:12:01 +0300 | [diff] [blame] | 129 | return true |
| 130 | } |
| 131 | |
| 132 | // Generate macro to cause SMI when configured in GPIO input mode |
| 133 | func smiRoute() bool { |
| 134 | macro := common.GetMacro() |
| 135 | dw0 := macro.Register(PAD_CFG_DW0) |
| 136 | if dw0.GetGPIOInputRouteSMI() == 0 { |
| 137 | return false |
| 138 | } |
Benjamin Doron | 1bb640d | 2020-11-06 17:19:44 +0000 | [diff] [blame] | 139 | // PAD_CFG_GPI_SMI(GPP_E7, NONE, DEEP, LEVEL, NONE), |
| 140 | macro.Add("_SMI").Add("(").Id().Pull().Rstsrc().Trig().Invert().Add("),") |
Maxim Polyakov | 82ec61e | 2020-04-26 22:12:01 +0300 | [diff] [blame] | 141 | return true |
| 142 | } |
| 143 | |
| 144 | // Adds PAD_CFG_GPI macro with arguments |
| 145 | func (PlatformSpecific) GpiMacroAdd() { |
| 146 | macro := common.GetMacro() |
| 147 | var ids []string |
| 148 | macro.Set("PAD_CFG_GPI") |
| 149 | for routeid, isRoute := range map[string]func() (bool) { |
| 150 | "IOAPIC": ioApicRoute, |
| 151 | "SCI": sciRoute, |
| 152 | "SMI": smiRoute, |
| 153 | "NMI": nmiRoute, |
| 154 | } { |
| 155 | if isRoute() { |
| 156 | ids = append(ids, routeid) |
| 157 | } |
| 158 | } |
| 159 | |
| 160 | switch argc := len(ids); argc { |
| 161 | case 0: |
| 162 | // e.g. PAD_CFG_GPI_TRIG_OWN(pad, pull, rst, trig, own) |
| 163 | macro.Add("_TRIG_OWN").Add("(").Id().Pull().Rstsrc().Trig().Own().Add("),") |
| 164 | case 1: |
| 165 | // GPI with IRQ route |
| 166 | if config.AreFieldsIgnored() { |
| 167 | // Set Host Software Ownership to ACPI mode |
| 168 | macro.SetPadOwnership(common.PAD_OWN_ACPI) |
| 169 | } |
| 170 | |
| 171 | case 2: |
| 172 | // PAD_CFG_GPI_DUAL_ROUTE(pad, pull, rst, trig, inv, route1, route2) |
| 173 | macro.Set("PAD_CFG_GPI_DUAL_ROUTE(").Id().Pull().Rstsrc().Trig().Invert() |
| 174 | macro.Add(", " + ids[0] + ", " + ids[1] + "),") |
| 175 | if config.AreFieldsIgnored() { |
| 176 | // Set Host Software Ownership to ACPI mode |
| 177 | macro.SetPadOwnership(common.PAD_OWN_ACPI) |
| 178 | } |
| 179 | default: |
| 180 | // Clear the control mask so that the check fails and "Advanced" macro is |
| 181 | // generated |
| 182 | macro.Register(PAD_CFG_DW0).CntrMaskFieldsClear(common.AllFields) |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | // Adds PAD_CFG_GPO macro with arguments |
| 187 | func (PlatformSpecific) GpoMacroAdd() { |
| 188 | macro := common.GetMacro() |
| 189 | dw0 := macro.Register(PAD_CFG_DW0) |
| 190 | term := macro.Register(PAD_CFG_DW1).GetTermination() |
| 191 | |
| 192 | // #define PAD_CFG_GPO(pad, val, rst) \ |
| 193 | // _PAD_CFG_STRUCT(pad, \ |
| 194 | // PAD_FUNC(GPIO) | PAD_RESET(rst) | \ |
| 195 | // PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | !!val, \ |
| 196 | // PAD_PULL(NONE) | PAD_IOSSTATE(TxLASTRxE)) |
| 197 | if dw0.GetRXLevelEdgeConfiguration() != common.TRIG_OFF { |
| 198 | dw0.CntrMaskFieldsClear(common.RxLevelEdgeConfigurationMask) |
| 199 | } |
| 200 | macro.Set("PAD_CFG") |
| 201 | if macro.IsOwnershipDriver() { |
| 202 | // PAD_CFG_GPO_GPIO_DRIVER(pad, val, rst, pull) |
| 203 | macro.Add("_GPO_GPIO_DRIVER").Add("(").Id().Val().Rstsrc().Pull().Add("),") |
| 204 | return |
| 205 | } |
| 206 | if term != 0 { |
| 207 | // e.g. PAD_CFG_TERM_GPO(GPP_B23, 1, DN_20K, DEEP), |
| 208 | macro.Add("_TERM") |
| 209 | } |
| 210 | macro.Add("_GPO").Add("(").Id().Val() |
| 211 | if term != 0 { |
| 212 | macro.Pull() |
| 213 | } |
| 214 | macro.Rstsrc().Add("),") |
| 215 | } |
| 216 | |
| 217 | // Adds PAD_CFG_NF macro with arguments |
| 218 | func (PlatformSpecific) NativeFunctionMacroAdd() { |
| 219 | macro := common.GetMacro() |
| 220 | // e.g. PAD_CFG_NF(GPP_D23, NONE, DEEP, NF1) |
| 221 | macro.Set("PAD_CFG_NF") |
| 222 | if macro.Register(PAD_CFG_DW1).GetPadTol() != 0 { |
| 223 | macro.Add("_1V8") |
| 224 | } |
| 225 | macro.Add("(").Id().Pull().Rstsrc().Padfn().Add("),") |
| 226 | } |
| 227 | |
| 228 | // Adds PAD_NC macro |
| 229 | func (PlatformSpecific) NoConnMacroAdd() { |
| 230 | macro := common.GetMacro() |
| 231 | // #define PAD_NC(pad, pull) |
| 232 | // _PAD_CFG_STRUCT(pad, |
| 233 | // PAD_FUNC(GPIO) | PAD_RESET(DEEP) | PAD_TRIG(OFF) | PAD_BUF(TX_RX_DISABLE), |
| 234 | // PAD_PULL(pull) | PAD_IOSSTATE(TxDRxE)), |
| 235 | dw0 := macro.Register(PAD_CFG_DW0) |
| 236 | |
| 237 | // Some fields of the configuration registers are hidden inside the macros, |
| 238 | // we should check them to update the corresponding bits in the control mask. |
| 239 | if dw0.GetRXLevelEdgeConfiguration() != common.TRIG_OFF { |
| 240 | dw0.CntrMaskFieldsClear(common.RxLevelEdgeConfigurationMask) |
| 241 | } |
| 242 | if dw0.GetResetConfig() != 1 { // 1 = RST_DEEP |
| 243 | dw0.CntrMaskFieldsClear(common.PadRstCfgMask) |
| 244 | } |
| 245 | |
| 246 | macro.Set("PAD_NC").Add("(").Id().Pull().Add("),") |
| 247 | } |
| 248 | |
| 249 | // GenMacro - generate pad macro |
| 250 | // dw0 : DW0 config register value |
| 251 | // dw1 : DW1 config register value |
| 252 | // return: string of macro |
| 253 | // error |
| 254 | func (PlatformSpecific) GenMacro(id string, dw0 uint32, dw1 uint32, ownership uint8) string { |
| 255 | macro := common.GetInstanceMacro(PlatformSpecific{}, fields.InterfaceGet()) |
| 256 | macro.Clear() |
| 257 | macro.Register(PAD_CFG_DW0).CntrMaskFieldsClear(common.AllFields) |
| 258 | macro.Register(PAD_CFG_DW0).CntrMaskFieldsClear(common.AllFields) |
| 259 | macro.PadIdSet(id).SetPadOwnership(ownership) |
| 260 | macro.Register(PAD_CFG_DW0).ValueSet(dw0).ReadOnlyFieldsSet(PAD_CFG_DW0_RO_FIELDS) |
| 261 | macro.Register(PAD_CFG_DW1).ValueSet(dw1).ReadOnlyFieldsSet(PAD_CFG_DW1_RO_FIELDS) |
| 262 | return macro.Generate() |
| 263 | } |