1package snr 2 3import ( 4 "strings" 5 "fmt" 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" 10) 11 12const ( 13 PAD_CFG_DW0_RO_FIELDS = (0x1 << 27) | (0x1 << 24) | (0x3 << 21) | (0xf << 16) | 0xfc 14 PAD_CFG_DW1_RO_FIELDS = 0xfdffc3ff 15) 16 17const ( 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 23type PlatformSpecific struct {} 24 25// RemmapRstSrc - remmap Pad Reset Source Config 26func (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 58func (PlatformSpecific) Pull() { 59 macro := common.GetMacro() 60 dw1 := macro.Register(PAD_CFG_DW1) 61 var pull = map[uint8]string{ 62 0x0: "NONE", 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", 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 84func 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 { 94 // PAD_CFG_GPI_APIC_LOW(pad, pull, rst) 95 macro.Add("_LOW") 96 } else { 97 // PAD_CFG_GPI_APIC_HIGH(pad, pull, rst) 98 macro.Add("_HIGH") 99 } 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 110func 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 121func sciRoute() bool { 122 macro := common.GetMacro() 123 dw0 := macro.Register(PAD_CFG_DW0) 124 if dw0.GetGPIOInputRouteSCI() == 0 { 125 return false 126 } 127 // PAD_CFG_GPI_SCI(GPP_B18, UP_20K, PLTRST, LEVEL, INVERT), 128 macro.Add("_SCI").Add("(").Id().Pull().Rstsrc().Trig().Invert().Add("),") 129 return true 130} 131 132// Generate macro to cause SMI when configured in GPIO input mode 133func smiRoute() bool { 134 macro := common.GetMacro() 135 dw0 := macro.Register(PAD_CFG_DW0) 136 if dw0.GetGPIOInputRouteSMI() == 0 { 137 return false 138 } 139 // PAD_CFG_GPI_SMI(GPP_E7, NONE, DEEP, LEVEL, NONE), 140 macro.Add("_SMI").Add("(").Id().Pull().Rstsrc().Trig().Invert().Add("),") 141 return true 142} 143 144// Adds PAD_CFG_GPI macro with arguments 145func (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 187func (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 218func (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 229func (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 254func (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_DW1).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} 264