diff options
180 files changed, 6225 insertions, 1330 deletions
@@ -15,12 +15,14 @@ Aaron Durbin Abe Levkoy Abel Briggs Abhinav Hardikar +Abhishek Pandit-Subedi AdaCore Adam Liu Adam Mills Advanced Computing Lab, LANL Advanced Micro Devices, Inc. AG Electronics Ltd. +Agogo Ahamed Husni Akshu Agrawal Al Hirani @@ -41,24 +43,30 @@ Alexey Vazhnov Alice Sell Alicja Michalska Allen-KH Cheng +Alok Agarwal Alper Nebi Yasak Amanda Hwang American Megatrends International, LLC Amersel Amit Caleechurn +Ana Carolina Cabral Analog Devices Inc. Analogix Semiconductor Anand Mistry Anand Vaikar +Anastasios Koutian +Andre Andre Heider Andrew McRae Andrew SH Cheng Andrey Pronin Andriy Gapon +Andy Andy Fleming Andy Pont Andy-ld Lu Angel Pons +Angela Czubak Anil Kumar K Anna KaraÅ› Annie Chen @@ -68,6 +76,7 @@ Appukuttan V K Arashk Mahshidfar Arec Kao Ariel Fang +Ariel Otilibili ARM Limited and Contributors Arthur Heymans Asami Doi @@ -77,9 +86,12 @@ Ashqti ASPEED Technology Inc. Atheros Corporation Atmel Corporation +Avi Uday +Avinash Munduru Balaji Manigandan Balázs Vinarz BAP - Bruhnspace Advanced Projects +BartÅ‚omiej Grzesik Baruch Siach Ben Chuang Ben Kao @@ -90,6 +102,7 @@ Bernardo Perez Priego Bhanu Prakash Maiya Bill Xie Bin Meng +Bincai Liu Bitland Tech Inc. Bob Moragues Bora Guvendik @@ -97,10 +110,13 @@ Boris Barbulovski Boris Mittelberg Brandon Breitenstein Brandon Weeks +Brian Hsu Brian Norris Bryant Ou Carl-Daniel Hailfinger +Carlos López Casper Chang +Cathy Xu Caveh Jalali Cavium Inc. Chao Gui @@ -125,6 +141,7 @@ Cong Yang CoolStar coresystems GmbH Corey Osgood +Crystal Guo Curt Brune Curtis Chen Custom Ideas @@ -144,6 +161,7 @@ Dave Airlie David Brownell David Greenman David Hendricks +David Li David Lin David Milosevic David Mosberger-Tang @@ -153,6 +171,7 @@ David Wu Dawei Chien Deepika Punyamurtula Deepti Deshatty +Dehui Sun Denis 'GNUtoo' Carikli Denis Dowling DENX Software Engineering @@ -166,6 +185,7 @@ Divya S Sasidharan Dmitry Ponamorev Dmitry Torokhov DMP Electronics Inc. +Dolan Liu Dominik Behr Donghwa Lee Drew Eckhardt @@ -186,6 +206,7 @@ ELSOFT AG Eltan B.V Eltan B.V. Elyes Haouas +Emilie Roberts Eran Mitrani Eren Peng Eric Biederman @@ -205,11 +226,13 @@ Fabian Meyer Fabio Aiuto Fabrice Bellard Facebook, Inc. +Federico Amedeo Izzo Fei Yan Felix Friedlander Felix Held Felix Singer Fengquan Chen +Filip Brozovic Filip LewiÅ„ski Flora Fu Florian Laufenböck @@ -225,8 +248,12 @@ Freescale Semiconductor, Inc. Furquan Shaikh Gaggery Tsai Gang C Chen +Garen Wu +Gareth Yu Garmin Chang Gary Jennejohn +Gavin Liu +George Burgess George Trudeau Gerald Van Baren Gerd Hoffmann @@ -234,6 +261,7 @@ Gergely Kiss Google LLC Greg Watson Grzegorz Bernacki +Guangjie Song Guennadi Liakhovetski Guodong Liu Gwendal Grignou @@ -241,6 +269,7 @@ Hal Martin Hao Chou Hao Wang HardenedLinux +Harrie Paijmans Harsha B R Harshit Sharma Henry C Chen @@ -248,11 +277,13 @@ Herbert Wu Hewlett Packard Enterprise Development LP Hewlett-Packard Development Company, L.P. Himanshu Sahdev +Hope Wang Housong Zhang Hsiao Chien Sung Hsin-hsiung wang Hsin-Te Yuan Hsuan Ting Chen +Hualin Wei Huaqin Technology Co., Ltd Huaqin Telecom Inc. Hui Liu @@ -267,6 +298,7 @@ Igor Pavlov Ikjoon Jang Imagination Technologies Infineon Technologies +Ingo Reitz InKi Dae INSPUR Co., Ltd Intel Corporation @@ -284,11 +316,14 @@ Jakub Czapiga James Chao James Lo James Ye +Jameson Thies Jamie Chen Jamie Ryu Jan Dabros +Jan Philipp Groß Jan Samek Jan Tatje +Jarried Lin Jason Glenesk Jason Nein Jason V Le @@ -297,7 +332,9 @@ Jason Zhao jason-ch chen Jason-jh Lin Jay Patel +Jayvik Desai Jean Lucas +JÄ™drzej Ciupis Jeff Chase Jeff Daly Jeff Li @@ -318,10 +355,12 @@ Jingle Hsu Jitao Shi Joe Pillow Joe Tessler +Joel Bueno Joel Kitching Joel Linn Joey Peng Johanna Schander +Johannes Hahn John Su John Zhao Johnny Li @@ -339,7 +378,9 @@ Jörg Mische Joseph Smith Josie Nordrum Juan José GarcÃa-Castro Crespo +Julia Kittlinger Julia Tsai +Julian Intronati Julian Schroeder Julian Stecklina Julien Viard de Galbert @@ -351,6 +392,7 @@ Kangheui Won Kapil Porwal Karol Zmyslowski Karthik Ramasubramanian +Ke Zheng Kei Hiroyoshi Keith Hui Keith Packard @@ -362,10 +404,12 @@ Kevin Chowski Kevin Cody-Little Kevin Keijzer Kevin O'Connor +Kevin Yang Kevin3 Yang kewei xu Kilari Raasi Kirk Wang +Kiwi Liu Konrad Adamczyk Kontron Europe GmbH Kornel DulÄ™ba @@ -375,6 +419,7 @@ Kshitij Kshitiz Godara Kulkarni. Srinivas Kun Liu +KunYi Chen Kyle Lin Kyösti Mälkki Lance Zhao @@ -397,9 +442,13 @@ linear Linus Torvalds Linux Networx, Inc. LiPPERT ADLINK Technology GmbH +Liu Liu Liya Li +Lu Tang +Lu. Pen-ChunX Lubomir Rintel Luc Verhaegen +Luca Lai Lucas Chen Mac Chiang Maciej Matuszczyk @@ -420,6 +469,7 @@ Mario Scheithauer Marius Gröger Mariusz Szafranski Mariusz SzafraÅ„ski +Mark Chang Mark Hasemeyer Mark Hsieh Mars Chen @@ -430,6 +480,7 @@ Martin Roth Marvell International Ltd. Marvell Semiconductor Inc. Marx Wang +Masa Nakura Masanori Ogino Máté Kukri Matei Dibu @@ -438,6 +489,7 @@ Matt Chen Matt Delco Matt DeVillier Matt Papageorge +Matt Turner Matthew Blecker Matthew Ziegelbaum Mattias Nissler @@ -450,6 +502,7 @@ Maximilian Brune Mediatek Inc. MediaTek Inc. Meera Ravindranath +Melongmelong Meng-Huan Yu Meta Platforms, Inc mgabryelski1 @@ -462,15 +515,20 @@ Michael Strosche Michael Walle MichaÅ‚ Kopeć Michal Suchanek +MichaÅ‚ ZieliÅ„ski MichaÅ‚ Å»ygowski Micro-Star INT'L CO., LTD. Mika Westerberg Mike Banon +Mike Lin Mike Shih +Mingjin Ge Miriam Polzer mkurumel Moises Garcia +Momoko Hattori Mondrian Nuessle +Monika A Monikaanan MontaVista Software, Inc. Morgan Jang @@ -480,7 +538,7 @@ mtk15698 mturney mturney Musse Abdullahi Myles Watson -Nancy.Lin +Nancy Lin Naresh Solanki Nathan Lu Naveen R. Iyer @@ -491,12 +549,14 @@ Nicholas Sielicki Nicholas Sudsgaard Nick Barker Nick Chen +Nick Kochlowski Nick Vaccaro Nico Huber Nico Rikken Nicola Corna Nicolas Boichat Nicole Faerber +Nigel Tao Nikolai Vyssotski Nils Jacobs Nina Wu @@ -510,6 +570,10 @@ Omar Pakker Online SAS Opal Voravootivat Orion Technologies, LLC +Ot_chhao.chang +Ot_hao.han +Ot_song Fan +Pablo Pablo Ceballos Pablo Stebler Pan Gao @@ -542,13 +606,14 @@ Philipp Hug Piotr Kleinschmidt Po Xu Poornima Tom +Pranava Y N Prasad Malisetty Prashant Malani Pratik Vishwakarma Pratikkumar Prajapati Pratikkumar V Prajapati Protectli -Purism SPC +PugzAreCute Purism, SPC Qii Wang Qinghong Zeng @@ -566,6 +631,7 @@ Ravindra Ravishankar Sarawadi Ray Han Lim Ng Raymond Chung +Reagan Red Hat, Inc ReddestDream Rehan Ghori @@ -583,6 +649,7 @@ Richard Woodruff Rick Lee Ricky Chang Riku Viitanen +Rishika Raj Ritul Guru Rizwan Qureshi Rnhmjoj @@ -602,6 +669,7 @@ Roman Zippel Ron Lee Ron Minnich Ronak Kanabar +Ronald Claveau Ronald G. Minnich Rory Liu Rudolf Marek @@ -623,6 +691,7 @@ Samuel Holland Sandeep Maheswaram Sathya Prakash M R Satya Priya Kakitapalli +Satya SreenivasL Saurabh Mishra SciTech Software, Inc. Scott Chao @@ -650,6 +719,7 @@ Shiyu Sun Shon Wang Shou-Chieh Hsu Shreesh Chhabbi +Shunxi Zhang Shuo Liu Siemens AG SiFive, Inc @@ -662,10 +732,12 @@ Simon Zhou Sindhoor Tilak Solomon Alan-Dei Song Fan +Sowmya Aralguppe Sridhar Siricilla Srinidhi N Kaushik Srinivasa Rao Mandadapu ST Microelectronics +StanisÅ‚aw Kardach Stanley Wu Star Labs Online Ltd Stefan Binding @@ -693,6 +765,7 @@ Tao Xia Tarun Tuli Teddy Shih Terry Chen +Terry Cheong Texas Instruments The Android Open Source Project The ChromiumOS Authors @@ -712,6 +785,7 @@ tinghan shen Tobias Diedrich Tom Hiller Tommie Lin +Tongtong Pan Tony Huang Tracy Wu Trevor Wu @@ -730,8 +804,10 @@ Uwe Poeche V Sowmya Václav Straka Vadim Bendebury +Valentyn Sudomyr Van Chen Varshit B Pandya +Varun Upadhyay Veerabhadrarao Badiganti Venkat Thogaru Venkata Krishna Nimmagadda @@ -740,6 +816,7 @@ Victor Ding Vidya Gopalakrishnan Vikram Narayanan Vikrant L Jadeja +Vince Liu Vinod Polimera Vipin Kumar Vitaly Rodionov @@ -752,8 +829,10 @@ Ward Vandewege Wayne Wang Weimin Wu Weiyi Lu +Wen Zhang Wenbin Mei Wentao Qin +Wenzhen Yu Werner Zeh Wilbert Duijvenvoorde William Wei @@ -772,7 +851,10 @@ Wonkyu Kim Wuxy Xiang W Xin Ji +Xiwen Shao Xixi Chen +Xue Yao +Xueqi Zhang Xuxin Xiong YADRO Yan Liu @@ -792,14 +874,18 @@ Yu-Ping Wu Yuanliding Yuchen He Yuchen Huang +Yuchiche Yunlong Jia Yuval Peress Zachary Yedidia Zanxi Chen +Zebreus Zhanyong Wang +Zhaoqing Jiu Zheng Bao Zhenguo Li Zhi7 Li +Zhigang Qin Zhiqiang Ma Zhixing Ma Zhiyong Tao diff --git a/Documentation/drivers/smmstorev2.md b/Documentation/drivers/smmstorev2.md index cf714835a51f..b29ffa886f07 100644 --- a/Documentation/drivers/smmstorev2.md +++ b/Documentation/drivers/smmstorev2.md @@ -74,19 +74,30 @@ has to read the coreboot table with tag `0x0039`, containing: struct lb_smmstorev2 { uint32_t tag; uint32_t size; - uint32_t num_blocks; /* Number of writeable blocks in SMM */ - uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ - uint32_t mmap_addr; /* MMIO address of the store for read only access */ - uint32_t com_buffer; /* Physical address of the communication buffer */ - uint32_t com_buffer_size; /* Size of the communication buffer in byte */ - uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ - uint8_t unused[3]; /* Set to zero */ + uint32_t num_blocks; /* Number of writable blocks in SMM */ + uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ + uint32_t mmap_addr_deprecated; /* 32-bit MMIO address of the store for read only access. + Prefer 'mmap_addr' for new software. + Zero when the address won't fit into 32-bits. */ + uint32_t com_buffer; /* Physical address of the communication buffer */ + uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ + uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ + uint8_t unused[3]; /* Set to zero */ + uint64_t mmap_addr; /* 64-bit MMIO address of the store for read only access. + Introduced after the initial implementation. Users of + this table must check the 'size' field to detect if its + written out by coreboot. */ }; ``` The absence of this coreboot table entry indicates that there's no SMMSTOREv2 support. +`mmap_addr` is an optional field added after the initial implementation. +Users of this table must check the size field to know if it's written by coreboot. +In case it's not present 'mmap_addr_deprecated' is to be used as the SPI ROM MMIO +address and it must be below 4 GiB. + ### Blocks The SMMSTOREv2 splits the SMMSTORE FMAP partition into smaller chunks diff --git a/Documentation/internals/chip_operations.md b/Documentation/internals/chip_operations.md new file mode 100644 index 000000000000..636b51372b5b --- /dev/null +++ b/Documentation/internals/chip_operations.md @@ -0,0 +1,537 @@ +# The `chip_operations` Structure in coreboot + +## Introduction + +The `chip_operations` structure is a fundamental component of coreboot's +chipset abstraction layer. It provides a standardized interface for chipset- +specific code to interact with coreboot's device initialization framework. +This structure enables coreboot to support a wide variety of chipsets +while maintaining a consistent initialization flow across different hardware +platforms. + +In coreboot's architecture, a "chip" refers to a collection of hardware +components that form a logical unit, such as a System-on-Chip (SoC), +a CPU, or a distinct southbridge/northbridge. The `chip_operations` +structure provides the hooks necessary for coreboot to discover, configure, +and initialize these components during the boot process. + +The `chip_operations` structure is particularly crucial for the ramstage +portion of coreboot, where it connects the static device tree definitions +with the actual hardware initialization code. It serves as the bridge +between the declarative device descriptions and the imperative code that +brings those devices to life. + + +## Structure Definition + +The `chip_operations` structure is defined in `src/include/device/device.h` +as follows: + +```c +struct chip_operations { + void (*enable_dev)(struct device *dev); + void (*init)(void *chip_info); + void (*final)(void *chip_info); + unsigned int initialized : 1; + unsigned int finalized : 1; + const char *name; +}; +``` + + +### Field Descriptions + +- **enable_dev**: A function pointer that takes a `struct device*` +parameter. This function is called for each device associated with the +chip during the device enumeration phase (specifically, within the +`scan_bus` operations triggered by `dev_enumerate`). Its primary +purpose is to set up device operations (`dev->ops`) based on the +device's role in the system. + +- **init**: A function pointer that takes a `void*` parameter pointing to +the chip's configuration data (typically cast to a chip-specific struct). +This function is called during the chip initialization phase +(`BS_DEV_INIT_CHIPS`), before device enumeration. It usually performs +early hardware setup needed before individual devices can be configured. + +- **final**: A function pointer that takes a `void*` parameter pointing to +the chip's configuration data (typically cast to a chip-specific struct). +This function is called during the final table writing phase of coreboot +initialization (`BS_WRITE_TABLES`), after all devices have been +initialized. It performs any necessary cleanup or late initialization +operations. + +- **initialized**: A bit flag indicating whether the chip's init function +has been called. + +- **finalized**: A bit flag indicating whether the chip's final function +has been called. + +- **name**: A string containing the human-readable name of the chip, used +for debugging and logging purposes. + + +## Initialization Sequence and `chip_operations` + +The `chip_operations` structure integrates with coreboot's boot state +machine, which is defined in `src/lib/hardwaremain.c`. The functions in +this structure are called at specific points during the boot process: + +1. **BS_DEV_INIT_CHIPS** state: The `init` function is called for each +chip in the device tree. This is handled by `dev_initialize_chips()` +which iterates through all devices, identifies unique chip instances, +and invokes their `init` functions. + +2. **BS_DEV_ENUMERATE** state: During the execution of this state, +`dev_enumerate()` is called, which triggers bus scanning +(e.g., `pci_scan_bus`). Within these scan routines, the `enable_dev` +function is called for devices associated with a chip. This commonly +assigns the appropriate `device_operations` structure to each device +based on its type and purpose. + +3. **BS_WRITE_TABLES** state: The `final` function is called for each +chip by `dev_finalize_chips()` after all devices have been initialized +and just before payloads are loaded. + +This sequence ensures that chips can perform necessary setup before their +individual devices are configured, and also perform cleanup or finalization +after all devices have been initialized but before the final tables are +written and the payload is executed. + + +## Relationship Between `chip_operations` and `device_operations` + +It's important to understand the distinction and relationship between +`chip_operations` and `device_operations`: + +- **chip_operations**: Operates at the chipset or SoC level, providing +hooks for chip-wide initialization. It's responsible for the overall +setup of a collection of devices that belong to the same logical chip. + +- **device_operations**: Operates at the individual device level, +providing functions to manage specific devices within a chip. These +operations include resource allocation, device initialization, and device- +specific functionality. + +The key relationship is that `chip_operations.enable_dev` is typically +responsible for assigning the appropriate `device_operations` structure +to each device based on its type and function. This is where the bridge +between the chip-level and device-level abstractions occurs. + +For example, a typical implementation of the `enable_dev` function might +look like this: + +```c +static void soc_enable(struct device *dev) +{ + if (dev->path.type == DEVICE_PATH_DOMAIN) + dev->ops = &pci_domain_ops; + else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) + dev->ops = &cpu_bus_ops; + else if (dev->path.type == DEVICE_PATH_GPIO) + block_gpio_enable(dev); + else if (dev->path.type == DEVICE_PATH_PCI && + dev->path.pci.devfn == PCH_DEVFN_PMC) + dev->ops = &pmc_ops; +} +``` + +This function examines each device's path type and assigns the appropriate +operations based on the device's role in the system. + + +## Integration with the Devicetree + +The `chip_operations` structure is tightly integrated with coreboot's +devicetree mechanism. The devicetree is a hierarchical description of the +hardware platform, defined in `.cb` files (typically `chipset.cb`, +`devicetree.cb`, and optionally `overridetree.cb`). + +In the devicetree, a `chip` directive starts a collection of devices +associated with a particular chip driver. The path specified with the +`chip` directive corresponds to a directory in the coreboot source tree +that contains the chip driver code, including a `chip.c` file that defines +the `chip_operations` structure for that chip. + +For example, a devicetree might contain: + +``` +chip soc/intel/cannonlake + device domain 0 on + device pci 00.0 on end # Host Bridge + device pci 12.0 on end # Thermal Subsystem + # ... more devices ... + end +end +``` + +This connects the devices under this chip directive with the +`chip_operations` structure defined in +`src/soc/intel/cannonlake/chip.c`: + +```c +struct chip_operations soc_intel_cannonlake_ops = { + .name = "Intel Cannonlake", + .enable_dev = &soc_enable, + .init = &soc_init_pre_device, +}; +``` + +During coreboot's build process, the `sconfig` utility processes the +devicetree files and generates code that links the devices defined in the +devicetree with their corresponding `chip_operations` structures. + + +## Chip Configuration Data + +Each chip typically defines a configuration structure in a `chip.h` file +within its source directory. This structure contains configuration settings +that can be specified in the devicetree using `register` directives. + +For example, a chip might define a configuration structure like: + +```c +/* In src/soc/intel/cannonlake/chip.h */ +struct soc_intel_cannonlake_config { + uint8_t pcie_rp_aspm[CONFIG_MAX_ROOT_PORTS]; + uint8_t usb2_ports[16]; + uint8_t usb3_ports[10]; + /* ... more configuration options ... */ +}; +``` + +In the devicetree, you would configure these options using register +directives: + +``` +chip soc/intel/cannonlake + register "pcie_rp_aspm[0]" = "ASPM_AUTO" + register "usb2_ports[5]" = "USB2_PORT_MID(OC_SKIP)" + # ... more register settings ... + + device domain 0 on + # ... devices ... + end +end +``` + +These configuration values are made available to the chip's `init` and +`final` functions through the `chip_info` parameter, which points to +an instance of the chip's configuration structure (after appropriate +casting from `void *`). + + +## Implementation Examples + +### Minimal Implementation + +Some chips may not need extensive initialization and can provide a +minimal implementation of the `chip_operations` structure: + +```c +struct chip_operations soc_ucb_riscv_ops = { + .name = "UCB RISC-V", +}; +``` + +This implementation only provides a name for debugging purposes but +doesn't define any initialization functions. + + +### Basic Implementation with Initialization + +A more typical implementation includes at least initialization hooks: + +```c +struct chip_operations soc_amd_genoa_poc_ops = { + .name = "AMD Genoa SoC Proof of Concept", + .init = soc_init, + .final = soc_final, +}; +``` + +The `init` function might perform chip-wide initialization: + +```c +static void soc_init(void *chip_info) +{ + default_dev_ops_root.write_acpi_tables = soc_acpi_write_tables; + amd_opensil_silicon_init(); + data_fabric_print_mmio_conf(); + fch_init(chip_info); +} +``` + + +### Complete Implementation + +A complete implementation includes all three function pointers: + +```c +struct chip_operations soc_intel_xeon_sp_cpx_ops = { + .name = "Intel Cooper Lake-SP", + .enable_dev = chip_enable_dev, + .init = chip_init, + .final = chip_final, +}; +``` + +The `enable_dev` function would typically assign device operations +based on device types: + +```c +static void chip_enable_dev(struct device *dev) +{ + /* PCI root complex */ + if (dev->path.type == DEVICE_PATH_DOMAIN) + dev->ops = &pci_domain_ops; + /* CPU cluster */ + else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) + dev->ops = &cpu_cluster_ops; + /* PCIe root ports */ + else if (dev->path.type == DEVICE_PATH_PCI && + PCI_SLOT(dev->path.pci.devfn) == PCIE_PORT1_SLOT) + dev->ops = &pcie_rp_ops; + /* ... other device types ... */ +} +``` + + +### Mainboard Implementation + +It's also common for the mainboard-specific code (e.g., +`src/mainboard/vendor/board/mainboard.c`) to define its own +`chip_operations`, often named `mainboard_ops`. The `mainboard_ops.init` +can perform early board-level setup, and `mainboard_ops.enable_dev` can +assign operations for devices specific to the mainboard or set default +operations. + +```c +/* Example from src/mainboard/google/zork/mainboard.c */ +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, + .init = mainboard_init, + .final = mainboard_final, +}; +``` + + +## Device Registration and Discovery + +The `chip_operations` structure plays a key role in device registration +and discovery within coreboot. Here's how it fits into this process: + +1. **Static Device Definition**: Devices are statically defined in the +devicetree files (`chipset.cb`, `devicetree.cb`, `overridetree.cb`). + +2. **Code Generation**: The `sconfig` utility processes these files and +generates code in `build/static.c` that creates the device structures +and links them to their corresponding chip configuration data. + +3. **Chip Initialization**: During the `BS_DEV_INIT_CHIPS` boot state, +`dev_initialize_chips()` calls each chip's `init` function to perform +chip-wide setup. + +4. **Device Enumeration and Enabling**: During the `BS_DEV_ENUMERATE` + boot state, `dev_enumerate()` initiates bus scanning. The scan + functions call the associated chip's `enable_dev` function for each + device, which assigns the appropriate device operations (`dev->ops`). + +5. **Device Configuration and Initialization**: Subsequent boot states + (`BS_DEV_RESOURCES`, `BS_DEV_ENABLE`, `BS_DEV_INIT`) configure and + initialize the devices according to their assigned device operations. + +6. **Chip Finalization**: After all devices have been initialized, + `dev_finalize_chips()` calls each chip's `final` function during the + `BS_WRITE_TABLES` boot state. + + +## Build Process Integration + +The `chip_operations` structures are integrated into the coreboot build +process through several mechanisms: + +1. **Devicetree Processing**: The `sconfig` utility processes the +devicetree files and generates code that creates and links the device +structures. + +2. **Static Structure Declaration**: Each chip (and often the mainboard) + defines its `chip_operations` structure in its respective `.c` file. + These structures are collected during the build process. + +3. **External References**: The generated code in `build/static.c` +includes external references to these `chip_operations` structures. + +4. **Linking**: The linker collects all the `chip_operations` structures +and includes them in the final firmware image. + +This process ensures that the appropriate chip operations are available +during the boot process for each chip included in the devicetree. + + +## Best Practices for Implementing `chip_operations` + +When implementing the `chip_operations` structure for a new chip, +follow these best practices: + +1. **Provide a Meaningful Name**: The `name` field should be descriptive +and identify the chip clearly for debugging purposes. + +2. **Implement `enable_dev` Correctly**: The `enable_dev` function should +assign the appropriate device operations based on device types and +functions. It should handle all device types that might be part of the chip. +Consider interactions with the mainboard `enable_dev`. + +3. **Use Configuration Data**: The `init` and `final` functions should +make use of the chip configuration data passed via the `chip_info` +parameter (casting it to the correct type) to configure the chip +according to the settings specified in the devicetree. + +4. **Minimize Dependencies**: The `init` function should minimize +dependencies on other chips being initialized, as the order of chip +initialization is not guaranteed. + +5. **Handle Resources Properly**: If the chip manages resources (memory +regions, I/O ports, etc.), ensure that these are properly allocated and +assigned to devices, usually within the associated `device_operations`. + +6. **Implement Error Handling**: Include appropriate error handling in +the initialization functions to handle hardware initialization failures +gracefully. + +7. **Document Special Requirements**: If the chip has special +requirements or dependencies, document these clearly in comments or +accompanying documentation. + + +## Troubleshooting `chip_operations` Issues + +When implementing or debugging `chip_operations`, you might encounter +certain issues: + +1. **Missing Device Operations**: If devices are not being initialized +properly, check that the `enable_dev` function is correctly +assigning device operations based on device types. Ensure it's being +called during bus scanning. + +2. **Initialization Order Problems**: If a chip's initialization depends +on another chip being initialized first, you might need to adjust the +initialization sequence or add explicit dependencies, possibly using +boot state callbacks if necessary. + +3. **Configuration Data Issues**: If chip configuration settings are not +being applied correctly, check that the configuration structure is +correctly defined in `chip.h`, that the register values in the +devicetree match the expected format, and that the `chip_info` pointer +is cast correctly in the `init`/`final` functions. + +4. **Build Errors**: If you encounter build errors related to +`chip_operations`, check that the structure is correctly defined and +that all required symbols are properly exported and linked. Check for +conflicts if multiple files define the same symbol. + +5. **Runtime Failures**: If the chip initialization fails at runtime, +add debug logging (using `printk`) to the `init`, `enable_dev`, and +`final` functions to identify the specific point of failure. + + +## Advanced `chip_operations` Patterns + +### Hierarchical Chip Initialization + +For complex chips with multiple components, you can implement a +hierarchical initialization pattern within the `init` function: + +```c +static void soc_init(void *chip_info) +{ + /* Initialize common components first */ + common_init(chip_info); + + /* Initialize specific blocks */ + pcie_init(chip_info); + usb_init(chip_info); + sata_init(chip_info); + + /* Final SoC-wide configuration */ + power_management_init(chip_info); +} +``` + + +### Variant Support + +For chips with multiple variants, you can implement variant detection +and specific initialization within the `init` function: + +```c +static void soc_init(void *chip_info) +{ + uint32_t variant = read_chip_variant(); + + /* Common initialization */ + common_init(chip_info); + + /* Variant-specific initialization */ + switch (variant) { + case VARIANT_A: + variant_a_init(chip_info); + break; + case VARIANT_B: + variant_b_init(chip_info); + break; + default: + printk(BIOS_WARNING, "Unknown variant %u\\n", variant); + break; + } +} +``` + + +### Conditional Feature Initialization + +You can conditionally initialize features based on configuration settings +passed via `chip_info`: + +```c +static void soc_init(void *chip_info) +{ + struct soc_config *config = chip_info; + + /* Always initialize core components */ + core_init(); + + /* Conditionally initialize optional features */ + if (config->enable_xhci) + xhci_init(config); + + if (config->enable_sata) + sata_init(config); + + if (config->enable_pcie) + pcie_init(config); +} +``` + + +## Conclusion + +The `chip_operations` structure is a fundamental component of coreboot's +chipset abstraction layer. It provides a standardized interface for chipset- +specific code to interact with coreboot's device initialization framework, +enabling support for a wide variety of chipsets while maintaining a +consistent initialization flow. + +By implementing the `chip_operations` structure for a specific chipset +(and often for the mainboard), developers can integrate their +hardware-specific code with coreboot's device enumeration, configuration, +and initialization process. This structure serves as the bridge between +the declarative device descriptions in the devicetree and the imperative +code that initializes the hardware. + +Understanding the `chip_operations` structure and its role in the +coreboot boot process is essential for anyone working on chipset or +mainboard support in coreboot. By following the best practices and +patterns outlined in this document, developers can create robust and +maintainable hardware support code that integrates seamlessly with the +coreboot firmware ecosystem. diff --git a/Documentation/internals/device_operations.md b/Documentation/internals/device_operations.md new file mode 100644 index 000000000000..c0c98d0ebf68 --- /dev/null +++ b/Documentation/internals/device_operations.md @@ -0,0 +1,696 @@ +# Device Operations in coreboot Firmware + +## Introduction + +The `device_operations` structure is a cornerstone of coreboot's +hardware abstraction layer. It represents a set of function pointers +defining how the firmware interacts with a specific hardware device +during various boot stages. This structure lets the coreboot +architecture establish a consistent interface for device initialization, +configuration, resource allocation, and ACPI table generation, while +allowing device-specific implementations behind this common interface. + +At its core, `device_operations` applies the strategy pattern in +systems programming. It decouples algorithms (device operations) from +the core boot sequence, allowing devices to define their own behavior +while the boot process follows a predictable flow. This pattern enables +coreboot to support a wide range of hardware platforms with minimal +changes to the core boot sequence code. + + +## Structure Definition + +The `device_operations` structure, defined in +`src/include/device/device.h`, consists of several function pointers, +each representing a specific operation performed on a device during +boot: + +```c +struct device_operations { + void (*read_resources)(struct device *dev); + void (*set_resources)(struct device *dev); + void (*enable_resources)(struct device *dev); + void (*init)(struct device *dev); + void (*final)(struct device *dev); + void (*scan_bus)(struct device *bus); + void (*enable)(struct device *dev); + void (*vga_disable)(struct device *dev); + void (*reset_bus)(struct bus *bus); + + int (*get_smbios_data)(struct device *dev, int *handle, + unsigned long *current); + void (*get_smbios_strings)(struct device *dev, struct smbios_type11 *t); + + unsigned long (*write_acpi_tables)(const struct device *dev, + unsigned long start, struct acpi_rsdp *rsdp); + void (*acpi_fill_ssdt)(const struct device *dev); + const char *(*acpi_name)(const struct device *dev); + const char *(*acpi_hid)(const struct device *dev); + + const struct pci_operations *ops_pci; + const struct i2c_bus_operations *ops_i2c_bus; + const struct spi_bus_operations *ops_spi_bus; + const struct smbus_bus_operations *ops_smbus_bus; + const struct pnp_mode_ops *ops_pnp_mode; + const struct gpio_operations *ops_gpio; + const struct mdio_bus_operations *ops_mdio; +}; +``` + + +### Core Resource Management Functions + +* `read_resources`: Discovers and collects resources required by the + device (I/O ports, memory regions, IRQs, etc.). This typically + involves reading configuration registers or static device tree + information. +* `set_resources`: Assigns finalized resources to the device after the + resource allocation phase. This writes the assigned base addresses, + lengths, and other parameters back to the device structure, but not + necessarily to hardware registers yet. +* `enable_resources`: Activates the assigned resources in the device's + hardware registers (e.g., writing to PCI BARs, enabling memory + decoding). + + +### Device Lifecycle Functions + +* `init`: Performs device-specific initialization, often requiring + access to the device's assigned resources. This is called after + resources have been enabled. +* `final`: Executes final setup or cleanup operations before the + payload is loaded. This is useful for tasks that depend on other + devices being initialized. +* `enable`: Enables the device in the hardware, often setting bits in + configuration registers to make the device active. Called after + `enable_resources`. + + +### Bus Management Functions + +* `scan_bus`: Enumerates child devices on a bus device (e.g., scanning + a PCI bus for devices, probing I2C devices). Only applicable to + devices that act as buses. +* `reset_bus`: Resets all devices on a specific bus. +* `vga_disable`: Disables VGA decoding on a PCI device when another VGA + device is active. Used to manage legacy VGA resources. + + +### System Table Generation Functions + +* `get_smbios_data`: Provides SMBIOS data specific to the device for + Type 9 (System Slots) or Type 41 (Onboard Devices Extended + Information). +* `get_smbios_strings`: Supplies string information for SMBIOS tables, + often related to the data provided by `get_smbios_data`. +* `write_acpi_tables`: Generates device-specific ACPI tables (like SSDTs) + or contributes data to system-wide tables. +* `acpi_fill_ssdt`: Adds device-specific objects (scopes, methods, data) + to the Secondary System Description Table (SSDT). +* `acpi_name`: Returns the ACPI name for the device (e.g., + `\_SB.PCI0.GFX0`). This defines the device's path in the ACPI + namespace. +* `acpi_hid`: Returns the ACPI Hardware ID (HID) for the device (e.g., + `PNP0A08`). Used by the OS to match drivers. + + +### Bus-Specific Operation Pointers + +These fields point to bus-specific operation structures when a device +functions as a bus controller (or exposes bus-like functionality). See +the "Bus-Specific Operations" section for details. + +* `ops_pci`: Operations for PCI configuration space access. +* `ops_i2c_bus`: Operations for I2C bus transactions (read, write, + transfer). +* `ops_spi_bus`: Operations for SPI bus transactions. +* `ops_smbus_bus`: Operations for SMBus transactions. +* `ops_pnp_mode`: Operations for Plug-and-Play device configuration. +* `ops_gpio`: Operations for GPIO control (get, set, configure + direction/pulls). +* `ops_mdio`: Operations for MDIO (Management Data Input/Output) bus + access, used for Ethernet PHYs. + + +## Device Lifecycle in coreboot + +The function pointers in `device_operations` are called at specific +stages during the boot process, following a sequence defined in +coreboot's boot state machine (`src/lib/hardwaremain.c`). Understanding +this lifecycle helps developers implement appropriate behavior for each +function pointer. + + +### Boot Sequence and Device Operations + +coreboot's main device initialization sequence involves these boot +states: + +1. **BS_DEV_INIT_CHIPS** (`dev_initialize_chips()`): Initializes chip + drivers (`chip_operations`). +2. **BS_DEV_ENUMERATE** (`dev_enumerate()`): Discovers and enumerates + devices. + * Calls `scan_bus()` for each bus to detect child devices. +3. **BS_DEV_RESOURCES** (`dev_configure()`): Allocates resources across + all enumerated devices. + * Calls `read_resources()` for each device to discover required + resources. + * Calls `set_resources()` for each device to assign allocated + resources back to the `struct device`. +4. **BS_DEV_ENABLE** (`dev_enable()`): Enables devices and their + resources. + * Calls `enable_resources()` for each device to activate assigned + resources in hardware. + * Calls `enable()` for each device to perform general hardware + enablement. +5. **BS_DEV_INIT** (`dev_initialize()`): Initializes devices. + * Calls `init()` for each device to perform device-specific setup. +6. **BS_POST_DEVICE** (`dev_finalize()`): Finalizes devices before + payload loading. + * Calls `final()` for each device for any final cleanup or setup. + +The sequence is primarily driven by the `boot_states` array in +`src/lib/hardwaremain.c`: + +```c +static struct boot_state boot_states[] = { + /* ... other states ... */ + BS_INIT_ENTRY(BS_PRE_DEVICE, bs_pre_device), + BS_INIT_ENTRY(BS_DEV_INIT_CHIPS, bs_dev_init_chips), + BS_INIT_ENTRY(BS_DEV_ENUMERATE, bs_dev_enumerate), + BS_INIT_ENTRY(BS_DEV_RESOURCES, bs_dev_resources), + BS_INIT_ENTRY(BS_DEV_ENABLE, bs_dev_enable), + BS_INIT_ENTRY(BS_DEV_INIT, bs_dev_init), + BS_INIT_ENTRY(BS_POST_DEVICE, bs_post_device), + /* ... other states ... */ +}; +``` + +Later stages include ACPI and SMBIOS table generation, where functions +like `write_acpi_tables()`, `acpi_fill_ssdt()`, `get_smbios_data()`, and +`get_smbios_strings()` are invoked as part of the table construction +process. + + +## Inheritance and Code Reuse Patterns + +The `device_operations` structure enables several patterns for code +reuse: + + +### 1. Default Implementations + +coreboot provides default implementations for common device types (like +root devices, PCI devices, PCI bridges), which can be used directly or +extended. Chip or mainboard code often assigns these defaults if no +specific driver is found. + +```c +/* From src/device/root_device.c */ +struct device_operations default_dev_ops_root = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .scan_bus = scan_static_bus, + .reset_bus = root_dev_reset, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = root_dev_acpi_name, +#endif +}; +``` + + +### 2. No-op Functions + +Simple shim functions (often static inline) are provided for cases where +a device doesn't need to implement specific operations. Using these avoids +leaving function pointers NULL. + +```c +/* From src/include/device/device.h */ +static inline void noop_read_resources(struct device *dev) {} +static inline void noop_set_resources(struct device *dev) {} +``` + + +### 3. Chain of Responsibility / Delegation + +Some implementations delegate to parent devices or use helper functions +when they can't handle an operation themselves or when common logic can +be shared. For example, ACPI name generation often traverses up the +device tree. + +```c +/* Simplified example logic */ +const char *acpi_device_name(const struct device *dev) +{ + const char *name = NULL; + const struct device *pdev = dev; + + /* Check for device specific handler */ + if (dev->ops && dev->ops->acpi_name) { + name = dev->ops->acpi_name(dev); + if (name) + return name; /* Device handled it */ + } + + /* Walk up the tree to find if any parent can provide a name */ + while (pdev->upstream && pdev->upstream->dev) { + pdev = pdev->upstream->dev; + if (pdev->ops && pdev->ops->acpi_name) { + /* Note: Parent's acpi_name might handle the original child 'dev' */ + name = pdev->ops->acpi_name(dev); + if (name) + return name; /* Parent handled it */ + } + } + + /* Fallback or default logic if needed */ + return NULL; +} +``` +This pattern allows parent devices (like buses) to provide default +behavior or naming schemes if a child device doesn't specify its own. + + +## Implementation Examples + +These examples show typical `device_operations` assignments. Actual +implementations might involve more conditional compilation based on +Kconfig options. + + +### PCI Device Operations (Default) + +```c +/* From src/device/pci_device.c */ +struct device_operations default_pci_ops_dev = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, +#if CONFIG(HAVE_ACPI_TABLES) + .write_acpi_tables = pci_rom_write_acpi_tables, + .acpi_fill_ssdt = pci_rom_ssdt, +#endif + .init = pci_dev_init, + /* Assigns PCI-specific operations */ + .ops_pci = &pci_dev_ops_pci, +}; +``` + + +### CPU Cluster Operations + +```c +/* From src/soc/intel/alderlake/chip.c (representative example) */ +static struct device_operations cpu_bus_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + .enable_resources = cpu_set_north_irqs, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_fill_ssdt = cpu_fill_ssdt, +#endif + /* CPU clusters often don't need scan_bus, init, etc. */ +}; +``` + + +### GPIO Controller Operations + +```c +/* From src/soc/intel/common/block/gpio/gpio_dev.c */ +static struct gpio_operations gpio_ops = { + .get = gpio_get, + .set = gpio_set, + /* ... other GPIO functions ... */ +}; + +struct device_operations block_gpio_ops = { + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, + /* Assigns GPIO-specific operations */ + .ops_gpio = &gpio_ops, +}; +``` + + +## Registration and Discovery + +How are `device_operations` structures associated with `struct device` +instances? + + +### 1. Static Assignment (via `chip_operations`) + +For devices known at build time (defined in devicetree.cb), the +`device_operations` structure is often assigned in the SOC's or +mainboard's `chip_operations->enable_dev()` function based on the +device path type or other properties. + +```c +/* Example from src/soc/intel/alderlake/chip.c */ +static void soc_enable(struct device *dev) +{ + /* Assign ops based on the device's role in the tree */ + if (dev->path.type == DEVICE_PATH_DOMAIN) + dev->ops = &pci_domain_ops; /* Handles PCI domain resources */ + else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) + dev->ops = &cpu_bus_ops; /* Handles CPU cluster setup */ + else if (dev->path.type == DEVICE_PATH_GPIO) + block_gpio_enable(dev); /* Assigns block_gpio_ops */ + /* ... other assignments for specific PCI devices, etc. ... */ +} +``` +The `enable_dev` function is part of `struct chip_operations`, which +handles broader chip-level initialization (see "Relationship with +`chip_operations`" section). + + +### 2. Dynamic Detection (PCI Drivers) + +For PCI devices discovered during bus scanning (`scan_bus`), coreboot +looks through a list of registered PCI drivers (`_pci_drivers` array) +to find one matching the device's vendor and device IDs. + +```c +/* Logic from src/device/pci_device.c::set_pci_ops() */ +static void set_pci_ops(struct device *dev) +{ + struct pci_driver *driver; + + /* Check if ops already assigned (e.g., by chip_ops->enable_dev) */ + if (dev->ops) + return; + + /* Look through registered PCI drivers */ + for (driver = &_pci_drivers[0]; driver != &_epci_drivers[0]; driver++) { + if ((driver->vendor == dev->vendor) && + device_id_match(driver, dev->device)) { + /* Found a matching driver, assign its ops */ + dev->ops = (struct device_operations *)driver->ops; + printk(BIOS_SPEW, "%s: Assigned ops from driver for %04x:%04x\n", + dev_path(dev), driver->vendor, driver->device); + return; /* Stop searching */ + } + } + + /* Fall back to default operations if no specific driver found */ + if (!dev->ops) { + if ((dev->hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) { + dev->ops = get_pci_bridge_ops(dev); /* Special ops for bridges */ + } else { + dev->ops = &default_pci_ops_dev; /* Default for normal devices */ + } + printk(BIOS_SPEW, "%s: Assigned default PCI ops\n", dev_path(dev)); + } +} +``` + + +## Build Process Integration + +The `device_operations` structures are integrated into the coreboot +build process: + +1. **Static Device Tree**: The mainboard's `devicetree.cb` defines the + initial device hierarchy. The build process converts this into C + code (`static.c`) containing `struct device` instances. +2. **PCI Driver Registration**: PCI drivers (containing their own + `device_operations`) register themselves using the `__pci_driver` + linker set macro. + + ```c + /* Example pattern */ + struct pci_driver example_pci_driver __pci_driver = { + .ops = &example_device_ops, /* Pointer to device_operations */ + .vendor = VENDOR_ID, + .device = DEVICE_ID, /* Or .devices for a list */ + }; + ``` +3. **Linking**: The build system collects all structures placed in the + `__pci_driver` section and creates the `_pci_drivers` array used by + `set_pci_ops()`. It ensures all necessary code (default ops, driver + ops, core device functions) is linked into the final firmware image. + + +## Relationship with `chip_operations` + +It's important to distinguish `device_operations` from +`chip_operations` (defined in `src/include/chip.h`). + +* `chip_operations`: Defines operations related to the overall chipset + or mainboard logic. It includes functions called earlier in the boot + process, like `enable_dev`, `init`, and `final`. + * `chip_operations->enable_dev()` is crucial as it often performs + initial setup for static devices and is the primary place where + `device_operations` pointers are *assigned* for non-PCI devices + based on their path or type. + * `chip_operations->init()` runs during `BS_DEV_INIT_CHIPS`, before + most `device_operations` functions. +* `device_operations`: Defines operations for *individual* devices + within the device tree. These are called *after* the corresponding + `chip_operations` stage and operate on a specific `struct device`. + +Essentially, `chip_operations` sets the stage at the SoC/mainboard level, +including assigning the correct `device_operations` to static devices, +while `device_operations` handles the specific actions for each device +later in the boot process. + + +## Bus-Specific Operations + +The `ops_*` pointers within `struct device_operations` (e.g., `ops_pci`, +`ops_i2c_bus`, `ops_spi_bus`, `ops_gpio`) provide a way for devices that +act as bus controllers or expose bus-like interfaces to offer +standardized access methods. + +* **Purpose:** They abstract the low-level details of interacting with + that specific bus type. For example, a PCI host bridge device will + implement `struct pci_operations` via its `ops_pci` pointer, + allowing other code to perform PCI config reads/writes through it + without knowing the exact hardware mechanism. Similarly, an I2C + controller device implements `struct i2c_bus_operations` via + `ops_i2c_bus` to provide standard `read`, `write`, and `transfer` + functions for that bus segment. +* **Usage:** Code needing to interact with a bus first finds the + controller `struct device` in the tree, then accesses the relevant + bus operations through the appropriate `ops_*` pointer, passing the + target address or parameters. For instance, to talk to an I2C device + at address `0x50` on the bus controlled by `i2c_controller_dev`, one + might call: + `i2c_controller_dev->ops->ops_i2c_bus->transfer(...)`. Helper + functions often wrap this access pattern. +* **Implementation:** The structures like `struct pci_operations`, + `struct i2c_bus_operations`, etc., are defined in corresponding + header files (e.g., `src/include/device/pci_ops.h`, + `src/include/drivers/i2c/i2c_bus.h`). Devices acting as controllers + provide concrete implementations of these functions, tailored to their + hardware. + +This mechanism allows coreboot to manage diverse bus types using a +consistent device model, where the controller device itself exposes the +necessary functions for interacting with devices on its bus. + + +## Best Practices + +When implementing `device_operations`: + +1. **Leverage Defaults/No-ops**: Use default or no-op implementations + whenever possible. Only override functions that require custom + behavior for your specific device. +2. **Error Handling**: Check return values from functions called within + your ops implementations and handle errors gracefully (e.g., log an + error, return an error code if applicable). +3. **Resource Management**: In `read_resources`, accurately declare all + resources (MMIO, I/O ports, IRQs) your device needs, specifying + flags like fixed vs. alignment, or bridge vs. standard device. + Incorrect resource declaration is a common source of issues. +4. **Initialization Order**: Be mindful of dependencies in `init`. If + your device relies on another device being fully initialized, consider + deferring that part of the initialization to the `final` callback, + which runs later. +5. **Minimal Implementation**: Only implement the functions relevant to + your device type. A simple MMIO device might only need + `read_resources`, `set_resources`, `enable_resources`, and perhaps + ACPI functions. A bus device additionally needs `scan_bus`. +6. **Bus Operations**: If implementing a bus controller, correctly + implement the corresponding bus operations structure (e.g., + `struct pci_operations`, `struct i2c_bus_operations`) and assign it + to the appropriate `ops_*` field. +7. **ACPI/SMBIOS**: If the device needs OS visibility via ACPI or + SMBIOS, implement the relevant functions (`acpi_name`, `acpi_hid`, + `acpi_fill_ssdt`, `get_smbios_data`, etc.). Ensure ACPI names and + HIDs are correct according to specifications and platform needs. + + +## Logging and Debugging + +Use coreboot's logging facilities (`printk`) within your `device_operations` +functions to provide visibility during development and debugging. Use +appropriate log levels (e.g., `BIOS_DEBUG`, `BIOS_INFO`, `BIOS_ERR`). + +```c +static void example_device_init(struct device *dev) +{ + printk(BIOS_DEBUG, "%s: Initializing device at %s\n", __func__, + dev_path(dev)); + + /* ... Device initialization code ... */ + if (/* some condition */) { + printk(BIOS_SPEW, "%s: Condition met, applying setting X\n", + dev_path(dev)); + /* ... */ + } + + if (/* error condition */) { + printk(BIOS_ERR, "%s: Failed to initialize feature Y!\n", + dev_path(dev)); + /* Handle error */ + } + + printk(BIOS_DEBUG, "%s: Initialization complete for %s\n", __func__, + dev_path(dev)); +} +``` +Consistent logging helps trace the boot process and pinpoint where issues +occur. + + +## Common Troubleshooting + +* **Missing Resource Declarations**: + * *Problem*: Device fails to function, or conflicts arise because a + required resource (MMIO range, I/O port, IRQ) was not declared + in `read_resources`. The resource allocator is unaware of the + need. + * *Solution*: Verify that `read_resources` correctly calls functions + like `pci_dev_read_resources` or manually adds all necessary + resources using functions like `mmio_resource()`, + `io_resource()`, etc. Check PCI BARs or device datasheets. +* **Initialization Order Issues**: + * *Problem*: `init()` fails because it depends on another device + that hasn't been fully initialized yet (e.g., accessing a shared + resource like SMBus before the SMBus controller is ready). + * *Solution*: Move the dependent initialization code to the `final` + callback if possible. Alternatively, ensure the dependency is met + by careful ordering in the device tree or using boot state + callbacks if necessary for complex scenarios. +* **Resource Conflicts**: + * *Problem*: Boot fails during resource allocation, or devices + misbehave because multiple devices requested the same + non-sharable resource (e.g., conflicting fixed MMIO regions). + * *Solution*: Review resource declarations in `read_resources` across + all relevant devices. Ensure fixed resources don't overlap. Check + if bridge windows are correctly defined and large enough. Use + coreboot's resource reporting logs to identify overlaps. +* **ACPI Table Generation Errors**: + * *Problem*: The operating system fails to recognize the device, + assigns the wrong driver, or the device doesn't function correctly + (e.g., power management issues). + * *Solution*: Double-check the `acpi_name`, `acpi_hid`, `_CRS` + (generated from assigned resources), and `acpi_fill_ssdt` + implementations. Verify names match the ACPI hierarchy and HIDs + match expected driver bindings. Ensure SSDT methods correctly + access hardware. Use OS debugging tools (e.g., `acpidump`, Device + Manager errors) to diagnose. +* **Incorrect `ops` Pointer Assigned**: + * *Problem*: Device behaves incorrectly because the wrong + `device_operations` structure was assigned (e.g., default PCI ops + assigned to a device needing a specific driver's ops). + * *Solution*: Check the logic in `chip_operations->enable_dev` (for + static devices) or the PCI driver registration (`__pci_driver` + macro and `set_pci_ops` fallback logic) to ensure the correct + `ops` structure is being selected and assigned based on device + type, path, or PCI ID. Add debug prints to verify which `ops` + structure is assigned. + + +## Advanced Usage + +### Complex Device Hierarchies + +For devices with non-standard interactions or complex initialization, +custom `device_operations` can be created, often inheriting from defaults +but overriding specific functions. + +```c +static void advanced_device_init(struct device *dev) +{ + /* First, perform standard PCI init */ + pci_dev_init(dev); + + /* Then, add custom initialization steps */ + printk(BIOS_DEBUG, "%s: Performing advanced init\n", dev_path(dev)); + /* ... custom register writes, configuration ... */ +} + +static const char *advanced_device_acpi_name(const struct device *dev) +{ + /* Provide a custom ACPI name based on some property */ + if (/* condition */) + return "ADV0001"; + else + return "ADV0002"; +} + +/* Combine default and custom operations */ +static struct device_operations advanced_device_ops = { + /* Inherit resource handling from default PCI ops */ + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + + /* Override init */ + .init = advanced_device_init, + + /* Override ACPI naming */ + .acpi_name = advanced_device_acpi_name, + /* Other functions might use defaults or no-ops */ +}; +``` + +### Dynamic Configuration based on Probing + +Some `init` or other op implementations might probe the device's +capabilities or read configuration data (e.g., from SPD, VPD, or straps) +and alter their behavior accordingly. + +```c +static void conditional_device_init(struct device *dev) +{ + uint8_t feature_flags; + + /* Read capability register from the device */ + feature_flags = pci_read_config8(dev, EXAMPLE_CAP_REG); + + printk(BIOS_DEBUG, "%s: Feature flags: 0x%02x\n", dev_path(dev), + feature_flags); + + /* Conditional initialization based on detected features */ + if (feature_flags & FEATURE_X_ENABLED) { + printk(BIOS_INFO, "%s: Initializing Feature X\n", dev_path(dev)); + init_feature_x(dev); + } + if (feature_flags & FEATURE_Y_ENABLED) { + printk(BIOS_INFO, "%s: Initializing Feature Y\n", dev_path(dev)); + init_feature_y(dev); + } +} +``` + + +## Conclusion + +The `device_operations` structure is a powerful abstraction mechanism in +coreboot. It enables consistent handling of diverse hardware while +allowing for device-specific behavior. By providing a standard interface +for device operations throughout the boot process, it simplifies the +codebase, enhances maintainability, and provides the extensibility needed +to support new hardware platforms. + +Understanding this structure, its relationship with `chip_operations`, +and its role in the boot process is essential for coreboot developers, +particularly when adding support for new devices or debugging hardware +initialization issues. By following the patterns and best practices +outlined here, developers can create robust and reusable device driver +implementations that integrate smoothly into the coreboot architecture. diff --git a/Documentation/internals/index.md b/Documentation/internals/index.md index 17dee55ada3b..56c822179376 100644 --- a/Documentation/internals/index.md +++ b/Documentation/internals/index.md @@ -10,5 +10,6 @@ programming APIs internal to coreboot coreboot devicetree <devicetree.md> coreboot devicetree language <devicetree_language.md> - +Chip Operations <chip_operations.md> +Device Operations <device_operations> ``` diff --git a/Documentation/mainboard/topton/adl/x2f-n100.md b/Documentation/mainboard/topton/adl/x2f-n100.md index c386ad35a114..941c8a7cb09e 100644 --- a/Documentation/mainboard/topton/adl/x2f-n100.md +++ b/Documentation/mainboard/topton/adl/x2f-n100.md @@ -28,26 +28,26 @@ Doing so **may kill your device**. You have been warned :) ### Internally Vendor of this motherboard hasn't locked any flash regions, resulting -in [flashprog] having full access to the SPI chip. -Assuming that user had booted Linux with `iomem=relaxed`, they can: +in internal programmers such as [flashrom]/[flashprog] having full access +to the SPI chip. Assuming that user had booted Linux with `iomem=relaxed`, +they can: - Flash coreboot from stock firmware - Flash stock firmware from coreboot - Update coreboot build to a newer version Without opening the case and connecting the SPI flasher. -Please note that for AlderLake-N platform you will need to use -[flashprog] v1.3.0 or newer. +Note: some users have reported bricked devices when using [flashrom] to +flash the board, so the current recommendation is to use [flashprog] +v1.3.0 or newer. -[flashrom] is broken due to regressions, which results in -failed flashes, bricking the device. +Since we only need to flash the `bios` region of the flash chip, there is +no need to extract the `ifd` or `me` regions from your backup of the stock +firmware. One can flash the `bios` region only using the following command: +`flashprog -p internal --ifd -i bios -w ./build/coreboot.rom -N` -[flashprog] is a better maintained fork of [flashrom], which -works flawlessly. - -You can skip extracting `SI_BIOS` and `SI_ME` regions from your ROM -and flash coreboot to `SI_BIOS` region by issuing the following command: -`flashprog -p internal --ifd -i SI_BIOS -w ./build/coreboot.rom` +The `-N` tells [flashprog`] to skip verification on the other regions of the +flash chip which are not being written. ### Externally @@ -57,6 +57,10 @@ Please note that SPI voltage on this board is standard 3.3V, despite using mobile SoC. Vendor populated this board with Winbond W25Q128JV chip in SOIC-8 package. +Flashing coreboot using an external programmer is exactly the same as +using an internal programmer, other than the `programmer` argument: +`flashprog -p <programmer> --ifd -i bios -w ./build/coreboot.rom -N` + ## Functionality ### Tested and working diff --git a/MAINTAINERS b/MAINTAINERS index 203868e252fb..98fe4f2ee852 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -329,7 +329,10 @@ M: Angel Pons <th3fanbus@gmail.com> S: Maintained F: src/mainboard/gigabyte/ga-h61m-series/ - +GOOGLE BLUEY MAINBOARDS +M: Subrata Banik <subratabanik@google.com> +M: Kapil Porwal <kapilporwal@google.com> +F: src/mainboard/google/bluey/ GOOGLE REX MAINBOARDS M: Subrata Banik <subratabanik@google.com> @@ -977,11 +980,15 @@ S: Maintained F: src/soc/mediatek/mt8192/ F: src/vendorcode/mediatek/mt8192/ +QUALCOMM SOCS +M: Subrata Banik <subratabanik@google.com> +M: Kapil Porwal <kapilporwal@google.com> +F: src/soc/qualcomm/ + ORPHANED ARM SOCS S: Orphan F: src/cpu/armltd/ F: src/soc/ti/ -F: src/soc/qualcomm/ F: src/soc/samsung/ F: util/exynos/ F: util/ipqheader/ diff --git a/spd/lp5/memory_parts.json b/spd/lp5/memory_parts.json index 1c345050561a..e13ffec9301b 100644 --- a/spd/lp5/memory_parts.json +++ b/spd/lp5/memory_parts.json @@ -284,7 +284,7 @@ "speedMbps": 8533, "lp5x": true } - }, + }, { "name": "K3KL8L80EM-MGCU", "attribs": { @@ -295,6 +295,17 @@ "speedMbps": 8533, "lp5x": true } + }, + { + "name": "K3KL9L90EM-MGCU", + "attribs": { + "densityPerDieGb": 16, + "diesPerPackage": 4, + "bitWidthPerChannel": 16, + "ranksPerChannel": 2, + "speedMbps": 8533, + "lp5x": true + } } ] } diff --git a/spd/lp5/set-0/parts_spd_manifest.generated.txt b/spd/lp5/set-0/parts_spd_manifest.generated.txt index f560ba3f1ae1..f28554c4e977 100644 --- a/spd/lp5/set-0/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-0/parts_spd_manifest.generated.txt @@ -29,3 +29,4 @@ K3KL8L80DM-MGCU,spd-11.hex MT62F2G32D4DS-020 WT:F,spd-10.hex H58G56CK8BX146,spd-11.hex K3KL8L80EM-MGCU,spd-11.hex +K3KL9L90EM-MGCU,spd-10.hex diff --git a/spd/lp5/set-1/parts_spd_manifest.generated.txt b/spd/lp5/set-1/parts_spd_manifest.generated.txt index f560ba3f1ae1..f28554c4e977 100644 --- a/spd/lp5/set-1/parts_spd_manifest.generated.txt +++ b/spd/lp5/set-1/parts_spd_manifest.generated.txt @@ -29,3 +29,4 @@ K3KL8L80DM-MGCU,spd-11.hex MT62F2G32D4DS-020 WT:F,spd-10.hex H58G56CK8BX146,spd-11.hex K3KL8L80EM-MGCU,spd-11.hex +K3KL9L90EM-MGCU,spd-10.hex diff --git a/src/arch/x86/c_start.S b/src/arch/x86/c_start.S index fd61cab44d8e..acd26a41be95 100644 --- a/src/arch/x86/c_start.S +++ b/src/arch/x86/c_start.S @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include <cpu/x86/gdt.h> #include <cpu/x86/post_code.h> -#include <arch/ram_segs.h> /* Place the stack in the bss section. It's not necessary to define it in * the linker script. */ @@ -30,9 +30,9 @@ _start: lgdt (%rax) #else lgdt %cs:gdtaddr - ljmp $RAM_CODE_SEG, $1f + ljmp $GDT_CODE_SEG, $1f #endif -1: movl $RAM_DATA_SEG, %eax +1: movl $GDT_DATA_SEG, %eax movl %eax, %ds movl %eax, %es movl %eax, %ss @@ -40,7 +40,7 @@ _start: movl %eax, %fs movl %eax, %gs /* Will be used for cpu_info */ #if ENV_X86_64 - mov $RAM_CODE_SEG64, %ecx + mov $GDT_CODE_SEG64, %ecx call SetCodeSelector #endif @@ -152,46 +152,44 @@ gdtaddr: .data - /* This is the gdt for GCC part of coreboot. + /* + * This is the gdt for coreboot's ramstage. * It is different from the gdt in ASM part of coreboot * which is defined in gdt_init.S * * When the machine is initially started, we use a very simple * gdt from ROM (that in gdt_init.S) which only contains those - * entries we need for protected mode. + * entries we need for protected mode and long mode. * * When we're executing code from RAM, we want to do more complex * stuff, like initializing PCI option ROMs in real mode, or doing - * a resume from a suspend to RAM. + * a resume from a suspend to RAM, which happens in real mode. + * + * Keep in sync with 'cpu/x86/gdt.h'. */ gdt: /* selgdt 0, unused */ .word 0x0000, 0x0000 /* dummy */ .byte 0x00, 0x00, 0x00, 0x00 - /* selgdt 8, unused */ - .word 0x0000, 0x0000 /* dummy */ - .byte 0x00, 0x00, 0x00, 0x00 - - /* selgdt 0x10, flat code segment */ + /* selgdt 0x08, flat code segment */ .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for - * limit - */ + .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes + for limit */ - /* selgdt 0x18, flat data segment */ + /* selgdt 0x10, flat data segment */ .word 0xffff, 0x0000 -#if ENV_X86_64 - .byte 0x00, 0x92, 0xcf, 0x00 -#else .byte 0x00, 0x93, 0xcf, 0x00 -#endif - /* selgdt 0x20, unused */ - .word 0x0000, 0x0000 /* dummy */ - .byte 0x00, 0x00, 0x00, 0x00 + /* selgdt 0x18, flat code segment (64-bit) */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xaf, 0x00 + + /* gdt selector 0x20 tss segment, used by STM */ + .word 0xffff, 0x0000 + .byte 0x00, 0x8b, 0x80, 0x00 - /* The next two entries are used for executing VGA option ROMs */ + /* The next two entries are used for executing ACPI S3 RESUME and VGA option ROMs */ /* selgdt 0x28 16 bit 64k code at 0x00000000 */ .word 0xffff, 0x0000 @@ -201,34 +199,25 @@ gdt: .word 0xffff, 0x0000 .byte 0, 0x92, 0, 0 - /* The next two entries are used for ACPI S3 RESUME */ + /* The next entry is used for VGA option ROMs. See x86_asm.S */ - /* selgdt 0x38, flat data segment 16 bit */ - .word 0x0000, 0x0000 /* dummy */ - .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for - * limit - */ - - /* selgdt 0x40, flat code segment 16 bit */ + /* + * selgdt 0x38, flat code segment 16 bits + * + * FIXME: It's only used in %ds (therefore used like a data segment). + * The PCI Specification doesn't enforce this. + * Is this a workaround for broken Option ROMs? + */ .word 0xffff, 0x0000 .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for * limit */ -#if ENV_X86_64 - /* selgdt 0x48, flat x64 code segment */ - .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0xaf, 0x00 -#endif per_cpu_segment_descriptors: .rept CONFIG_MAX_CPUS /* flat data segment */ .word 0xffff, 0x0000 -#if ENV_X86_64 - .byte 0x00, 0x92, 0xcf, 0x00 -#else .byte 0x00, 0x93, 0xcf, 0x00 -#endif .endr gdt_end: diff --git a/src/arch/x86/exception.c b/src/arch/x86/exception.c index 224f0e1d4164..e21cfa6de583 100644 --- a/src/arch/x86/exception.c +++ b/src/arch/x86/exception.c @@ -665,6 +665,8 @@ asmlinkage void exception_init(void) load_idt(idt, sizeof(idt)); +#if !ENV_SMM null_breakpoint_init(); stack_canary_breakpoint_init(); +#endif } diff --git a/src/arch/x86/include/arch/ram_segs.h b/src/arch/x86/include/arch/ram_segs.h deleted file mode 100644 index 3f92a1f6803a..000000000000 --- a/src/arch/x86/include/arch/ram_segs.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef RAM_SEGS_H -#define RAM_SEGS_H - -#define RAM_CODE_SEG 0x10 -#define RAM_DATA_SEG 0x18 -#define RAM_CODE16_SEG 0x28 -#define RAM_DATA16_SEG 0x30 -#define RAM_CODE_ACPI_SEG 0x38 -#define RAM_DATA_ACPI_SEG 0x40 -#define RAM_CODE_SEG64 0x48 - -#endif /* RAM_SEGS_H */ diff --git a/src/arch/x86/include/arch/rom_segs.h b/src/arch/x86/include/arch/rom_segs.h deleted file mode 100644 index a7e31d29511d..000000000000 --- a/src/arch/x86/include/arch/rom_segs.h +++ /dev/null @@ -1,17 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef ROM_SEGS_H -#define ROM_SEGS_H - -#define ROM_CODE_SEG 0x08 -#define ROM_DATA_SEG 0x10 -#define ROM_CODE_SEG64 0x18 - -/* - * This define is placed here to make sure future romstage programmers - * know about it. - * It is used for STM setup code. - */ -#define SMM_TASK_STATE_SEG 0x20 - -#endif /* ROM_SEGS_H */ diff --git a/src/arch/x86/wakeup.S b/src/arch/x86/wakeup.S index 7bff006d14bc..1afc31173553 100644 --- a/src/arch/x86/wakeup.S +++ b/src/arch/x86/wakeup.S @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include <arch/ram_segs.h> +#include <cpu/x86/gdt.h> #define WAKEUP_BASE 0x600 #define RELOCATED(x) (x - __wakeup + WAKEUP_BASE) @@ -31,7 +31,7 @@ __wakeup: add $8, %rax push %rax pushfq - push $RAM_CODE_SEG + push $GDT_CODE_SEG lea 3(%rip), %rax push %rax iretq @@ -60,7 +60,7 @@ __wakeup: movw %ax, (__wakeup_segment) /* Activate the right segment descriptor real mode. */ - ljmp $RAM_CODE16_SEG, $RELOCATED(1f) + ljmp $GDT_CODE16_SEG, $RELOCATED(1f) 1: .code16 /* 16 bit code from here on... */ @@ -70,7 +70,7 @@ __wakeup: * configurations (limits, writability, etc.) once * protected mode is turned off. */ - mov $RAM_DATA16_SEG, %ax + mov $GDT_DATA16_SEG, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 78dbe8ef4c51..7860a413ce07 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -539,11 +539,17 @@ struct lb_smmstorev2 { uint32_t size; uint32_t num_blocks; /* Number of writable blocks in SMM */ uint32_t block_size; /* Size of a block in byte. Default: 64 KiB */ - uint32_t mmap_addr; /* MMIO address of the store for read only access */ + uint32_t mmap_addr_deprecated; /* 32-bit MMIO address of the store for read only access. + Prefer 'mmap_addr' for new software. + Zero when the address won't fit into 32-bits. */ uint32_t com_buffer; /* Physical address of the communication buffer */ uint32_t com_buffer_size; /* Size of the communication buffer in bytes */ uint8_t apm_cmd; /* The command byte to write to the APM I/O port */ uint8_t unused[3]; /* Set to zero */ + uint64_t mmap_addr; /* 64-bit MMIO address of the store for read only access. + Introduced after the initial implementation. Users of + this table must check the 'size' field to detect if its + written out by coreboot. */ }; enum lb_tpm_ppi_tpm_version { diff --git a/src/cpu/x86/64bit/entry64.inc b/src/cpu/x86/64bit/entry64.inc index 52da6037d554..a9f7ba49a8e2 100644 --- a/src/cpu/x86/64bit/entry64.inc +++ b/src/cpu/x86/64bit/entry64.inc @@ -17,12 +17,8 @@ #endif #endif +#include <cpu/x86/gdt.h> #include <cpu/x86/msr.h> -#if defined(__RAMSTAGE__) -#include <arch/ram_segs.h> -#else -#include <arch/rom_segs.h> -#endif .macro setup_longmode page_table /* Get page table address */ @@ -48,12 +44,8 @@ movl %eax, %cr0 /* use long jump to switch to 64-bit code segment */ -#if defined(__RAMSTAGE__) - ljmp $RAM_CODE_SEG64, $jmp_addr\@ -#else - ljmp $ROM_CODE_SEG64, $jmp_addr\@ + ljmp $GDT_CODE_SEG64, $jmp_addr\@ -#endif .code64 jmp_addr\@: .endm diff --git a/src/cpu/x86/64bit/exit32.inc b/src/cpu/x86/64bit/exit32.inc index 3ac86a9df101..a3d215e785b6 100644 --- a/src/cpu/x86/64bit/exit32.inc +++ b/src/cpu/x86/64bit/exit32.inc @@ -10,17 +10,9 @@ */ .code64 +#include <cpu/x86/gdt.h> #include <cpu/x86/msr.h> #include <cpu/x86/cr.h> -#if defined(__RAMSTAGE__) -#include <arch/ram_segs.h> -#define CODE_SEG RAM_CODE_SEG -#define DATA_SEG RAM_DATA_SEG -#else -#include <arch/rom_segs.h> -#define CODE_SEG ROM_CODE_SEG -#define DATA_SEG ROM_DATA_SEG -#endif drop_longmode: #if !ENV_CACHE_AS_RAM @@ -28,7 +20,7 @@ drop_longmode: wbinvd #endif /* Set 32-bit code segment and ss */ - mov $CODE_SEG, %rcx + mov $GDT_CODE_SEG, %rcx /* SetCodeSelector32 will drop us to protected mode on return */ call SetCodeSelector32 @@ -63,7 +55,7 @@ __longmode_compatibility: /* Running in 32-bit compatibility mode */ /* Use flat data segment */ - movl $DATA_SEG, %eax + movl $GDT_DATA_SEG, %eax movl %eax, %ds movl %eax, %es movl %eax, %ss diff --git a/src/cpu/x86/entry16.S b/src/cpu/x86/entry16.S index ff4f1a26d04f..b19ffa5d6aff 100644 --- a/src/cpu/x86/entry16.S +++ b/src/cpu/x86/entry16.S @@ -27,7 +27,7 @@ /* Start code to put an i386 or later processor into 32-bit protected mode. */ -#include <arch/rom_segs.h> +#include <cpu/x86/gdt.h> #include <cpu/x86/post_code.h> .section .init._start, "ax", @progbits @@ -136,7 +136,7 @@ _start16bit: movl %ebp, %eax /* Now that we are in protected mode jump to a 32 bit code segment. */ - ljmpl $ROM_CODE_SEG, $bootblock_protected_mode_entry + ljmpl $GDT_CODE_SEG, $bootblock_protected_mode_entry /** * The gdt is defined in gdt_init.S, it has a 4 Gb code segment diff --git a/src/cpu/x86/entry32.S b/src/cpu/x86/entry32.S index 5c29581090a8..d013cbaf602a 100644 --- a/src/cpu/x86/entry32.S +++ b/src/cpu/x86/entry32.S @@ -11,7 +11,7 @@ * */ -#include <arch/rom_segs.h> +#include <cpu/x86/gdt.h> #include <cpu/x86/cr.h> #include <cpu/x86/post_code.h> @@ -33,7 +33,7 @@ bootblock_protected_mode_entry: post_code(POSTCODE_ENTER_PROTECTED_MODE) - movw $ROM_DATA_SEG, %ax + movw $GDT_DATA_SEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss diff --git a/src/cpu/x86/mtrr/Makefile.mk b/src/cpu/x86/mtrr/Makefile.mk index c74f014531d5..2846280d258f 100644 --- a/src/cpu/x86/mtrr/Makefile.mk +++ b/src/cpu/x86/mtrr/Makefile.mk @@ -1,5 +1,11 @@ ## SPDX-License-Identifier: GPL-2.0-only +bootblock-y += mtrrlib.c +verstage_x86-y += mtrrlib.c +romstage-y += mtrrlib.c +postcar-y += mtrrlib.c +ramstage-y += mtrrlib.c + ramstage-y += mtrr.c romstage-y += earlymtrr.c diff --git a/src/cpu/x86/mtrr/earlymtrr.c b/src/cpu/x86/mtrr/earlymtrr.c index 6c819a8c46f3..4ca7a0a5a4dc 100644 --- a/src/cpu/x86/mtrr/earlymtrr.c +++ b/src/cpu/x86/mtrr/earlymtrr.c @@ -7,67 +7,14 @@ #include <commonlib/bsd/helpers.h> #include <types.h> -/* Get first available variable MTRR. - * Returns var# if available, else returns -1. - */ -int get_free_var_mtrr(void) -{ - msr_t maskm; - int vcnt; - int i; - - vcnt = get_var_mtrr_count(); - - /* Identify the first var mtrr which is not valid. */ - for (i = 0; i < vcnt; i++) { - maskm = rdmsr(MTRR_PHYS_MASK(i)); - if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0) - return i; - } - - /* No free var mtrr. */ - return -1; -} - -void set_var_mtrr( - unsigned int reg, unsigned int base, unsigned int size, - unsigned int type) -{ - /* Bit 32-35 of MTRRphysMask should be set to 1 */ - /* FIXME: It only support 4G less range */ - msr_t basem, maskm; - - if (type == MTRR_TYPE_WRBACK && !is_cache_sets_power_of_two() && ENV_CACHE_AS_RAM) - printk(BIOS_ERR, "MTRR Error: Type %x may not be supported due to NEM limitation\n", - type); - if (!IS_POWER_OF_2(size)) - printk(BIOS_ERR, "MTRR Error: size %#x is not a power of two\n", size); - if (size < 4 * KiB) - printk(BIOS_ERR, "MTRR Error: size %#x smaller than 4KiB\n", size); - if (base % size != 0) - printk(BIOS_ERR, "MTRR Error: base %#x must be aligned to size %#x\n", base, - size); - - basem.lo = base | type; - basem.hi = 0; - wrmsr(MTRR_PHYS_BASE(reg), basem); - maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; - maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1; - wrmsr(MTRR_PHYS_MASK(reg), maskm); -} - void clear_all_var_mtrr(void) { - msr_t mtrr = { .raw = 0 }; int vcnt; - int i; vcnt = get_var_mtrr_count(); - for (i = 0; i < vcnt; i++) { - wrmsr(MTRR_PHYS_MASK(i), mtrr); - wrmsr(MTRR_PHYS_BASE(i), mtrr); - } + for (int i = 0; i < vcnt; i++) + clear_var_mtrr(i); } void var_mtrr_context_init(struct var_mtrr_context *ctx) diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index 0d31cab769e6..33fc46e362de 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -369,14 +369,6 @@ struct var_mtrr_state { struct var_mtrr_regs *regs; }; -static void clear_var_mtrr(int index) -{ - msr_t msr = { .lo = 0, .hi = 0 }; - - wrmsr(MTRR_PHYS_BASE(index), msr); - wrmsr(MTRR_PHYS_MASK(index), msr); -} - static int get_os_reserved_mtrrs(void) { return CONFIG(RESERVE_MTRRS_FOR_OS) ? 2 : 0; diff --git a/src/cpu/x86/mtrr/mtrrlib.c b/src/cpu/x86/mtrr/mtrrlib.c new file mode 100644 index 000000000000..fe6bd6aef51e --- /dev/null +++ b/src/cpu/x86/mtrr/mtrrlib.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <cpu/cpu.h> +#include <cpu/x86/mtrr.h> +#include <cpu/x86/msr.h> +#include <console/console.h> +#include <commonlib/bsd/helpers.h> +#include <types.h> + +/* + * Get first available variable MTRR. + * Returns var# if available, else returns -1. + */ +int get_free_var_mtrr(void) +{ + msr_t maskm; + int vcnt; + int i; + + vcnt = get_var_mtrr_count(); + + /* Identify the first var mtrr which is not valid. */ + for (i = 0; i < vcnt; i++) { + maskm = rdmsr(MTRR_PHYS_MASK(i)); + if ((maskm.lo & MTRR_PHYS_MASK_VALID) == 0) + return i; + } + + /* No free var mtrr. */ + return -1; +} + +/* + * Sets the specified variable MTRR (as per index) with the + * given base, size, and memory type. + */ +void set_var_mtrr( + unsigned int index, unsigned int base, unsigned int size, + unsigned int type) +{ + /* Bit 32-35 of MTRRphysMask should be set to 1 */ + /* FIXME: It only support 4G less range */ + msr_t basem, maskm; + + if (type == MTRR_TYPE_WRBACK && !is_cache_sets_power_of_two() && ENV_CACHE_AS_RAM) + printk(BIOS_ERR, "MTRR Error: Type %x may not be supported due to NEM limitation\n", + type); + if (!IS_POWER_OF_2(size)) + printk(BIOS_ERR, "MTRR Error: size %#x is not a power of two\n", size); + if (size < 4 * KiB) + printk(BIOS_ERR, "MTRR Error: size %#x smaller than 4KiB\n", size); + if (base % size != 0) + printk(BIOS_ERR, "MTRR Error: base %#x must be aligned to size %#x\n", base, + size); + + basem.lo = base | type; + basem.hi = 0; + wrmsr(MTRR_PHYS_BASE(index), basem); + maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; + maskm.hi = (1 << (cpu_phys_address_size() - 32)) - 1; + wrmsr(MTRR_PHYS_MASK(index), maskm); +} + +/* Disables the variable MTRR at the given index by clearing its base and mask MSRs. */ +void clear_var_mtrr(int index) +{ + msr_t msr = { .lo = 0, .hi = 0 }; + + wrmsr(MTRR_PHYS_BASE(index), msr); + wrmsr(MTRR_PHYS_MASK(index), msr); +} + +/* + * Acquires a free variable MTRR, configures it with the given base, size, and type. + * Returns the MTRR index if successful (>=0), or an error code (<0) if acquisition failed. + */ +int acquire_and_configure_mtrr(unsigned int base, unsigned int size, unsigned int type) +{ + int index = get_free_var_mtrr(); + + if (index >= 0) + set_var_mtrr(index, base, size, type); + + return index; +} diff --git a/src/cpu/x86/sipi_vector.S b/src/cpu/x86/sipi_vector.S index b7d700fb3946..6057282d765d 100644 --- a/src/cpu/x86/sipi_vector.S +++ b/src/cpu/x86/sipi_vector.S @@ -1,9 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include <cpu/x86/cr.h> +#include <cpu/x86/gdt.h> #include <cpu/amd/mtrr.h> #include <cpu/x86/msr.h> -#include <arch/ram_segs.h> #define __RAMSTAGE__ #include <cpu/x86/64bit/entry64.inc> @@ -77,10 +77,10 @@ _start: orl $CR0_SET_FLAGS, %eax movl %eax, %cr0 - ljmpl $RAM_CODE_SEG, $1f + ljmpl $GDT_CODE_SEG, $1f 1: .code32 - movw $RAM_DATA_SEG, %ax + movw $GDT_DATA_SEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss diff --git a/src/cpu/x86/smm/smm_module_handler.c b/src/cpu/x86/smm/smm_module_handler.c index d25b5f47cf4f..d9f64204d6da 100644 --- a/src/cpu/x86/smm/smm_module_handler.c +++ b/src/cpu/x86/smm/smm_module_handler.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include <arch/io.h> +#include <arch/exception.h> #include <commonlib/region.h> #include <console/cbmem_console.h> #include <console/console.h> @@ -169,6 +170,9 @@ asmlinkage void smm_handler_start(void *arg) printk(BIOS_SPEW, "\nSMI# #%d\n", cpu); + if (CONFIG(DEBUG_SMI) && CONFIG(CONSOLE_SERIAL)) + exception_init(); + /* Allow drivers to initialize variables in SMM context. */ if (do_driver_init) { #if CONFIG(SPI_FLASH_SMM) diff --git a/src/cpu/x86/smm/smm_stub.S b/src/cpu/x86/smm/smm_stub.S index ae8e047f4efe..dcfbcba5909c 100644 --- a/src/cpu/x86/smm/smm_stub.S +++ b/src/cpu/x86/smm/smm_stub.S @@ -9,8 +9,8 @@ * found in smm.h. */ -#include <arch/rom_segs.h> #include <cpu/x86/cr.h> +#include <cpu/x86/gdt.h> #include <cpu/x86/msr.h> #include <cpu/x86/lapic_def.h> #include <cpu/x86/64bit/entry64.inc> @@ -48,7 +48,6 @@ fallback_stack_top: .code16 .global _start _start: -smm_handler_start: #if CONFIG(SMM_LAPIC_REMAP_MITIGATION) /* Check if the LAPIC register block overlaps with the stub. * This block needs to work without data accesses because they @@ -94,7 +93,7 @@ untampered_lapic: movl %eax, %cr0 /* Enable protected mode */ - ljmpl $ROM_CODE_SEG, $smm_trampoline32 + ljmpl $GDT_CODE_SEG, $smm_trampoline32 .align 4 smm_relocate_gdt: @@ -125,7 +124,7 @@ smm_relocate_gdt_end: .global smm_trampoline32 smm_trampoline32: /* Use flat data segment */ - movw $ROM_DATA_SEG, %ax + movw $GDT_DATA_SEG, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss diff --git a/src/device/oprom/realmode/x86_asm.S b/src/device/oprom/realmode/x86_asm.S index ff33c0f4ba9d..39c504bad7d9 100644 --- a/src/device/oprom/realmode/x86_asm.S +++ b/src/device/oprom/realmode/x86_asm.S @@ -3,7 +3,7 @@ #define REALMODE_BASE 0x600 #define RELOCATED(x) (x - __realmode_code + REALMODE_BASE) -#include <arch/ram_segs.h> +#include <cpu/x86/gdt.h> /* CR0 bits */ #define PE (1 << 0) @@ -97,7 +97,7 @@ __realmode_call: movl %eax, __registers + 20 /* edi */ /* Activate the right segment descriptor real mode. */ - ljmp $RAM_CODE16_SEG, $RELOCATED(1f) + ljmp $GDT_CODE16_SEG, $RELOCATED(1f) 1: .code16 /* 16 bit code from here on... */ @@ -107,7 +107,7 @@ __realmode_call: * configurations (limits, writability, etc.) once * protected mode is turned off. */ - mov $RAM_DATA16_SEG, %ax + mov $GDT_DATA16_SEG, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs @@ -144,13 +144,13 @@ __realmode_call: movl __registers + 16, %esi movl __registers + 20, %edi - /* Set all segments to 0x0000, ds to 0x0040 */ + /* Set all segments to 0x0000, ds to 0x0038 */ push %ax xor %ax, %ax mov %ax, %es mov %ax, %fs mov %ax, %gs - mov $RAM_DATA_ACPI_SEG, %ax + mov $GDT_DATA_ACPI_SEG, %ax mov %ax, %ds pop %ax @@ -177,10 +177,10 @@ __lcall_instr = RELOCATED(.) /* Now that we are in protected mode * jump to a 32 bit code segment. */ - ljmpl $RAM_CODE_SEG, $RELOCATED(1f) + ljmpl $GDT_CODE_SEG, $RELOCATED(1f) 1: .code32 - mov $RAM_DATA_SEG, %ax + mov $GDT_DATA_SEG, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs @@ -233,7 +233,7 @@ __realmode_interrupt: movl %eax, __registers + 20 /* edi */ /* This configures CS properly for real mode. */ - ljmp $RAM_CODE16_SEG, $RELOCATED(1f) + ljmp $GDT_CODE16_SEG, $RELOCATED(1f) 1: .code16 /* 16 bit code from here on... */ @@ -241,7 +241,7 @@ __realmode_interrupt: * descriptors. They will retain these configurations (limits, * writability, etc.) once protected mode is turned off. */ - mov $RAM_DATA16_SEG, %ax + mov $GDT_DATA16_SEG, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs @@ -305,10 +305,10 @@ __intXX_instr = RELOCATED(.) movl %eax, %cr0 /* Now that we are in protected mode jump to a 32-bit code segment. */ - ljmpl $RAM_CODE_SEG, $RELOCATED(1f) + ljmpl $GDT_CODE_SEG, $RELOCATED(1f) 1: .code32 - mov $RAM_DATA_SEG, %ax + mov $GDT_DATA_SEG, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs @@ -354,10 +354,10 @@ __interrupt_handler_16bit = RELOCATED(.) movl %eax, %cr0 /* ... and jump to a 32 bit code segment. */ - ljmpl $RAM_CODE_SEG, $RELOCATED(1f) + ljmpl $GDT_CODE_SEG, $RELOCATED(1f) 1: .code32 - mov $RAM_DATA_SEG, %ax + mov $GDT_DATA_SEG, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs @@ -371,14 +371,14 @@ __interrupt_handler_16bit = RELOCATED(.) call *%eax /* Now return to real mode ... */ - ljmp $RAM_CODE16_SEG, $RELOCATED(1f) + ljmp $GDT_CODE16_SEG, $RELOCATED(1f) 1: .code16 /* Load the segment registers with properly configured segment * descriptors. They will retain these configurations (limits, * writability, etc.) once protected mode is turned off. */ - mov $RAM_DATA16_SEG, %ax + mov $GDT_DATA16_SEG, %ax mov %ax, %ds mov %ax, %es mov %ax, %fs diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig index 942591585d8e..715ec2a759bd 100644 --- a/src/drivers/intel/fsp2_0/Kconfig +++ b/src/drivers/intel/fsp2_0/Kconfig @@ -475,4 +475,22 @@ config BUILDING_WITH_DEBUG_FSP Enable this option if you are using a debug build of the FSP (Firmware Support Package) in your project. +config USE_COREBOOT_FOR_BMP_RENDERING + bool + default n + help + This option forces coreboot to use its native bitmap (BMP) image rendering + and skip using the FSP for this purpose during the boot process. + + If this option is selected (y), the platform will rely on the + coreboot native implementation for rendering BMP images. This might be + chosen if there are issues with FSP rendering or if native rendering + is preferred for specific reasons. + + If this option is not selected (n), the FSP's capabilities for BMP rendering + will be utilized. + + Platforms can choose to override this Kconfig option based on their + specific graphics requirements and FSP capabilities. + endif diff --git a/src/drivers/intel/fsp2_0/Makefile.mk b/src/drivers/intel/fsp2_0/Makefile.mk index 18a62e3b5796..16905ca3734b 100644 --- a/src/drivers/intel/fsp2_0/Makefile.mk +++ b/src/drivers/intel/fsp2_0/Makefile.mk @@ -35,6 +35,7 @@ ramstage-$(CONFIG_FSP_NVS_DATA_POST_SILICON_INIT) += save_mrc_data.c ramstage-$(CONFIG_MMA) += mma_core.c ramstage-$(CONFIG_ENABLE_FSP_ERROR_INFO) += fsp_error_info_hob.c ramstage-$(CONFIG_BMP_LOGO) += fsp_gop_blt.c +ramstage-$(CONFIG_USE_COREBOOT_FOR_BMP_RENDERING) += cb_logo.c ifneq ($(CONFIG_NO_FSP_TEMP_RAM_EXIT),y) postcar-$(CONFIG_FSP_CAR) += temp_ram_exit.c diff --git a/src/drivers/intel/fsp2_0/cb_logo.c b/src/drivers/intel/fsp2_0/cb_logo.c new file mode 100644 index 000000000000..cc62a1c55339 --- /dev/null +++ b/src/drivers/intel/fsp2_0/cb_logo.c @@ -0,0 +1,175 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define __SIMPLE_DEVICE__ + +#include <bootmode.h> +#include <console/console.h> +#include <cpu/x86/mtrr.h> +#include <device/pci_ops.h> +#include <fsp/api.h> +#include <fsp/fsp_gop_blt.h> +#include <fsp/graphics.h> +#include <fsp/util.h> +#include <intelblocks/graphics.h> +#include <soc/iomap.h> +#include <soc/soc_chip.h> +#include <stdlib.h> +#include <string.h> + +struct logo_coordinates { + uint32_t x; + uint32_t y; +}; + +/* + * Programs the Local Memory BAR (LMEMBAR) for the IGD. + * + * This function disables PCI command bits related to I/O, memory, and bus mastering + * for the IGD, programs the LMEMBAR with the provided base address, and then + * re-enables the PCI command bits. + */ +static void program_igd_lmembar(uint32_t base) +{ + const uint16_t disable_mask = ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + const uint16_t enable_mask = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + + /* Disable response in IO, MMIO space and Bus Master. */ + pci_and_config16(SA_DEV_IGD, PCI_COMMAND, disable_mask); + + /* Program IGD Base Address Register 2 aka LMEMBAR */ + pci_write_config32(SA_DEV_IGD, PCI_BASE_ADDRESS_2, base); + + /* Enable response in IO, MMIO space and Bus Master. */ + pci_or_config16(SA_DEV_IGD, PCI_COMMAND, enable_mask); +} + +/* + * Calculates the destination coordinates for the logo based on alignment settings. + * + * horizontal_resolution: The horizontal resolution of the display panel. + * vertical_resolution: The vertical resolution of the display panel. + * logo_width: The width of the logo bitmap. + * logo_height: The height of the logo bitmap. + * valignment: The vertical alignment setting. + * + * Returning `struct logo_coordinates` that contains the calculated x and y coordinates + * for rendering the logo. + */ +static struct logo_coordinates calculate_logo_coordinates( + uint32_t horizontal_resolution, uint32_t vertical_resolution, + uint32_t logo_width, uint32_t logo_height, enum fw_splash_vertical_alignment valignment) +{ + struct logo_coordinates coords; + /* Always horizontally centered */ + coords.x = (horizontal_resolution - logo_width) / 2; + + switch (valignment) { + case FW_SPLASH_VALIGNMENT_MIDDLE: + coords.y = vertical_resolution / 2; + break; + case FW_SPLASH_VALIGNMENT_TOP: + coords.y = 0; + break; + case FW_SPLASH_VALIGNMENT_BOTTOM: + coords.y = vertical_resolution - logo_height; + break; + default: /* FW_SPLASH_VALIGNMENT_CENTER (default) */ + coords.y = (vertical_resolution - logo_height) / 2; + break; + } + + return coords; +} + +/* + * Copies the logo to the framebuffer. + * + * framebuffer_base: The base address of the framebuffer. + * bytes_per_scanline: The number of bytes per scanline in the framebuffer. + * logo_buffer_addr: The address of the logo data in BLT format. + * logo_width: The width of the logo bitmap. + * logo_height: The height of the logo bitmap. + * dest_x: The destination x-coordinate in the framebuffer for rendering the logo. + * dest_y: The destination y-coordinate in the framebuffer for rendering the logo. + */ +static void copy_logo_to_framebuffer( + uintptr_t framebuffer_base, uint32_t bytes_per_scanline, + efi_uintn_t logo_buffer_addr, uint32_t logo_width, uint32_t logo_height, + efi_uintn_t dest_x, efi_uintn_t dest_y) +{ + size_t pixel_size = sizeof(efi_graphics_output_blt_pixel); + size_t logo_line_bytes = logo_width * pixel_size; + efi_uintn_t framebuffer_offset = framebuffer_base + dest_y * bytes_per_scanline + + dest_x * pixel_size; + uint8_t *dst_row_address = (uint8_t *)framebuffer_offset; + uint8_t *src_row_address = (uint8_t *)(uintptr_t)logo_buffer_addr; + for (uint32_t i = 0; i < logo_height; i++) { + memcpy(dst_row_address, src_row_address, logo_line_bytes); + dst_row_address += bytes_per_scanline; + src_row_address += logo_line_bytes; + } +} + +void soc_load_logo_by_coreboot(void) +{ + size_t size; + const struct hob_graphics_info *ginfo; + struct soc_intel_common_config *config = chip_get_common_soc_structure(); + efi_uintn_t logo, blt_size; + efi_uintn_t blt_buffer_addr; + uint32_t logo_size, logo_height, logo_width; + int temp_mtrr_index = -1; + + /* Find the graphics information HOB */ + ginfo = fsp_find_extension_hob_by_guid(fsp_graphics_info_guid, &size); + if (!ginfo || ginfo->framebuffer_base == 0) { + printk(BIOS_ERR, "Graphics information HOB not found or invalid framebuffer base.\n"); + return; + } + + /* Program the IGD LMEMBAR */ + program_igd_lmembar(GMADR_BASE); + + /* Set up a temporary Write Combine (WC) MTRR for the GMADR range */ + temp_mtrr_index = acquire_and_configure_mtrr(GMADR_BASE, GMADR_SIZE, MTRR_TYPE_WRCOMB); + if (temp_mtrr_index < 0) { + printk(BIOS_ERR, "Failed to configure WC MTRR for GMADR.\n"); + return; + } + + uintptr_t framebuffer_bar = ginfo->framebuffer_base; + uint32_t horizontal_resolution = ginfo->horizontal_resolution; + uint32_t vertical_resolution = ginfo->vertical_resolution; + uint32_t bytes_per_scanline = ginfo->pixels_per_scanline * + sizeof(efi_graphics_output_blt_pixel); + + /* + * Adjusts panel orientation for external display when the lid is closed. + * + * When the lid is closed, indicating the onboard display is inactive, + * below logic forces the panel orientation to normal. This ensures proper display + * on an external monitor, as rotated orientations are typically not suitable in + * such state. + */ + if (CONFIG(VBOOT_LID_SWITCH) ? !get_lid_switch() : !CONFIG(RUN_FSP_GOP)) + config->panel_orientation = LB_FB_ORIENTATION_NORMAL; + + /* Convert BMP logo to GOP BLT format */ + fsp_convert_bmp_to_gop_blt(&logo, &logo_size, &blt_buffer_addr, &blt_size, + &logo_height, &logo_width, config->panel_orientation); + + /* Override logo alignment if the default screen orientation is not normal */ + if (config->panel_orientation != LB_FB_ORIENTATION_NORMAL) + config->logo_valignment = FW_SPLASH_VALIGNMENT_CENTER; + + /* Calculate logo destination coordinates */ + struct logo_coordinates logo_coords = calculate_logo_coordinates(horizontal_resolution, + vertical_resolution, logo_width, logo_height, config->logo_valignment); + + /* Copy the logo to the framebuffer */ + copy_logo_to_framebuffer(framebuffer_bar, bytes_per_scanline, blt_buffer_addr, logo_width, + logo_height, logo_coords.x, logo_coords.y); + + /* Clear temporary Write Combine (WC) MTRR */ + clear_var_mtrr(temp_mtrr_index); +} diff --git a/src/drivers/intel/fsp2_0/fsp_gop_blt.c b/src/drivers/intel/fsp2_0/fsp_gop_blt.c index 087fb02df0e1..2ab716c4b764 100644 --- a/src/drivers/intel/fsp2_0/fsp_gop_blt.c +++ b/src/drivers/intel/fsp2_0/fsp_gop_blt.c @@ -100,12 +100,12 @@ static uint32_t calculate_blt_buffer_size(efi_bmp_image_header *header) return blt_buffer_size; } -static uint32_t get_color_map_num(efi_bmp_image_header *header) +static int get_color_map_num(efi_bmp_image_header *header) { - uint32_t col_map_number = 0; + int col_map_number; if (header == NULL) - return 0; + return -1; switch (header->BitPerPixel) { case 1: @@ -118,6 +118,11 @@ static uint32_t get_color_map_num(efi_bmp_image_header *header) col_map_number = 256; break; default: + /* + * For other bit depths (e.g., 24-bit and 32-bit) that doesn't have + * a standard palette, col_map_number remains 0. + */ + col_map_number = 0; break; } @@ -127,7 +132,7 @@ static uint32_t get_color_map_num(efi_bmp_image_header *header) */ if (header->ImageOffset - sizeof(efi_bmp_image_header) < sizeof(efi_bmp_color_map) * col_map_number) - return 0; + return -1; return col_map_number; } @@ -450,7 +455,7 @@ void fsp_convert_bmp_to_gop_blt(efi_uintn_t *logo, uint32_t *logo_size, if (!blt_buffer_size) return; - if (!get_color_map_num(bmp_header)) + if (get_color_map_num(bmp_header) < 0) return; bool is_standard_orientation = (orientation == LB_FB_ORIENTATION_NORMAL || diff --git a/src/drivers/intel/fsp2_0/graphics.c b/src/drivers/intel/fsp2_0/graphics.c index b7466a55ab5e..08609b67c183 100644 --- a/src/drivers/intel/fsp2_0/graphics.c +++ b/src/drivers/intel/fsp2_0/graphics.c @@ -15,25 +15,6 @@ enum pixel_format { pixel_bitmask = 2, /* defined by <rgb>_mask values */ }; -static const uint8_t fsp_graphics_info_guid[16] = { - 0xce, 0x2c, 0xf6, 0x39, 0x25, 0x68, 0x69, 0x46, - 0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07 -}; - -struct hob_graphics_info { - uint64_t framebuffer_base; - uint32_t framebuffer_size; - uint32_t version; - uint32_t horizontal_resolution; - uint32_t vertical_resolution; - uint32_t pixel_format; /* See enum pixel_format */ - uint32_t red_mask; - uint32_t green_mask; - uint32_t blue_mask; - uint32_t reserved_mask; - uint32_t pixels_per_scanline; -} __packed; - struct pixel { uint8_t pos; uint8_t size; diff --git a/src/drivers/intel/fsp2_0/include/fsp/api.h b/src/drivers/intel/fsp2_0/include/fsp/api.h index 0cbefbe9ae41..9ff32be6fcf3 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/api.h +++ b/src/drivers/intel/fsp2_0/include/fsp/api.h @@ -85,8 +85,33 @@ void platform_fsp_notify_status(enum fsp_notify_phase phase); /* Initialize memory margin analysis settings. */ void setup_mma(FSP_M_CONFIG *memory_cfg); -/* Update the SOC specific logo param and load the logo. */ -void soc_load_logo(FSPS_UPD *supd); +/* + * Populate UPD entries for the logo if the platform utilizes + * the FSP's capability for rendering bitmap (BMP) images. + */ +void soc_load_logo_by_fsp(FSPS_UPD *supd); +/* + * API that allows coreboot to perform native logo rendering after FSP display initialization. + * + * This implementation handles rendering the boot logo directly within coreboot. + * It depends on the FSP to initialize the display panel. + * Once the FSP completes display initialization and transfers control, coreboot + * renders the logo. + * + * Note: This native approach may introduce a ~10-30ms delay in displaying + * BMP images compared to rendering via FSP (when `USE_COREBOOT_FOR_BMP_RENDERING` + * Kconfig is not enable). + * + * coreboot native logo rendering provides greater flexibility for platform-specific + * logo customizations (e.g., alignment) that are not feasible or practical to implement + * within the FSP (silicon firmware) depending upon the OEM device need. + */ +#if CONFIG(USE_COREBOOT_FOR_BMP_RENDERING) +void soc_load_logo_by_coreboot(void); +#else +static inline void soc_load_logo_by_coreboot(void) { /* nop */ } +#endif + /* Update the SOC specific memory config param for mma. */ void soc_update_memory_params_for_mma(FSP_M_CONFIG *memory_cfg, struct mma_config_param *mma_cfg); diff --git a/src/drivers/intel/fsp2_0/include/fsp/graphics.h b/src/drivers/intel/fsp2_0/include/fsp/graphics.h index a5f781f87fc6..7348237f1b09 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/graphics.h +++ b/src/drivers/intel/fsp2_0/include/fsp/graphics.h @@ -5,6 +5,25 @@ #include <types.h> +static const uint8_t fsp_graphics_info_guid[16] = { + 0xce, 0x2c, 0xf6, 0x39, 0x25, 0x68, 0x69, 0x46, + 0xbb, 0x56, 0x54, 0x1a, 0xba, 0x75, 0x3a, 0x07 +}; + +struct hob_graphics_info { + uint64_t framebuffer_base; + uint32_t framebuffer_size; + uint32_t version; + uint32_t horizontal_resolution; + uint32_t vertical_resolution; + uint32_t pixel_format; /* See enum pixel_format */ + uint32_t red_mask; + uint32_t green_mask; + uint32_t blue_mask; + uint32_t reserved_mask; + uint32_t pixels_per_scanline; +} __packed; + /* * Report the fsp_graphics_info_guid HOB to framebuffer info. * diff --git a/src/drivers/intel/fsp2_0/silicon_init.c b/src/drivers/intel/fsp2_0/silicon_init.c index f3472420bc6f..76636dd7a89e 100644 --- a/src/drivers/intel/fsp2_0/silicon_init.c +++ b/src/drivers/intel/fsp2_0/silicon_init.c @@ -124,9 +124,12 @@ static void do_silicon_init(struct fsp_header *hdr) /* Give SoC/mainboard a chance to populate entries */ platform_fsp_silicon_init_params_cb(upd); - /* Populate logo related entries */ - if (CONFIG(BMP_LOGO)) - soc_load_logo(upd); + /* + * Populate UPD entries for the logo if the platform utilizes + * the FSP's capability for rendering bitmap (BMP) images. + */ + if (CONFIG(BMP_LOGO) && !CONFIG(USE_COREBOOT_FOR_BMP_RENDERING)) + soc_load_logo_by_fsp(upd); /* Call SiliconInit */ silicon_init = (void *)(uintptr_t)(hdr->image_base + @@ -154,6 +157,17 @@ static void do_silicon_init(struct fsp_header *hdr) fsp_debug_after_silicon_init(status); fsps_return_value_handler(FSP_SILICON_INIT_API, status); + /* + * Only applies for SoC platforms prior to FSP 2.2 specification: + * If a BMP logo is enabled (`BMP_LOGO`) and the platform is + * configured to skip the FSP for rendering logo bitmap + * (`USE_COREBOOT_FOR_BMP_RENDERING`), then call the coreboot + * native function to handle BMP logo loading and display. + */ + if (!CONFIG(PLATFORM_USES_FSP2_2) && CONFIG(BMP_LOGO) && + CONFIG(USE_COREBOOT_FOR_BMP_RENDERING)) + soc_load_logo_by_coreboot(); + /* Reinitialize CPUs if FSP-S has done MP Init */ if (CONFIG(USE_INTEL_FSP_MP_INIT) && !fsp_is_multi_phase_init_enabled()) do_mpinit_after_fsp(); @@ -202,6 +216,15 @@ static void do_silicon_init(struct fsp_header *hdr) timestamp_add_now(TS_FSP_MULTI_PHASE_SI_INIT_END); post_code(POSTCODE_FSP_MULTI_PHASE_SI_INIT_EXIT); + /* + * If a BMP logo is enabled (`BMP_LOGO`) and the platform is + * configured to skip the FSP for rendering logo bitmap + * (`USE_COREBOOT_FOR_BMP_RENDERING`), then call the coreboot + * native function to handle BMP logo loading and display. + */ + if (CONFIG(BMP_LOGO) && CONFIG(USE_COREBOOT_FOR_BMP_RENDERING)) + soc_load_logo_by_coreboot(); + /* Reinitialize CPUs if FSP-S has done MP Init */ if (CONFIG(USE_INTEL_FSP_MP_INIT)) do_mpinit_after_fsp(); @@ -269,7 +292,7 @@ void fsp_silicon_init(void) fsp_display_timestamp(); } -__weak void soc_load_logo(FSPS_UPD *supd) { } +__weak void soc_load_logo_by_fsp(FSPS_UPD *supd) { } static void release_logo(void *arg_unused) { diff --git a/src/drivers/mrc_cache/mrc_cache.c b/src/drivers/mrc_cache/mrc_cache.c index 17f5fee72753..a066fa8f3a6e 100644 --- a/src/drivers/mrc_cache/mrc_cache.c +++ b/src/drivers/mrc_cache/mrc_cache.c @@ -9,6 +9,7 @@ #include <elog.h> #include <fmap.h> #include <region_file.h> +#include <security/tpm/tspi.h> #include <security/vboot/antirollback.h> #include <security/vboot/mrc_cache_hash_tpm.h> #include <security/vboot/vboot_common.h> @@ -248,6 +249,19 @@ static int mrc_data_valid(int type, const struct mrc_metadata *md, return 0; } +static tpm_result_t mrc_measure_cache(int type, struct region_device *cache_region) +{ + tpm_result_t rc = TPM_SUCCESS; + char rname[TPM_CB_LOG_PCR_HASH_NAME]; + snprintf(rname, sizeof(rname), "MRC: %s cache", + (type == MRC_VARIABLE_DATA) ? "variable" : "training"); + rc = tpm_measure_region(cache_region, CONFIG_PCR_RUNTIME_DATA, rname); + if (rc) + printk(BIOS_ERR, "MRC: Couldn't measure %s! rc %#x\n", rname, rc); + + return rc; +} + static int mrc_cache_get_latest_slot_info(const char *name, const struct region_device *backing_rdev, struct mrc_metadata *md, @@ -346,6 +360,9 @@ ssize_t mrc_cache_load_current(int type, uint32_t version, void *buffer, if (mrc_data_valid(type, &md, buffer, data_size) < 0) return -1; + if (CONFIG(TPM_MEASURE_MRC_CACHE)) + mrc_measure_cache(type, &rdev); + return data_size; } @@ -373,6 +390,9 @@ void *mrc_cache_current_mmap_leak(int type, uint32_t version, if (mrc_data_valid(type, &md, data, region_device_size) < 0) return NULL; + if (CONFIG(TPM_MEASURE_MRC_CACHE)) + mrc_measure_cache(type, &rdev); + return data; } @@ -509,6 +529,9 @@ static void update_mrc_cache_by_type(int type, hash_idx = cr->tpm_hash_index; if (hash_idx && CONFIG(MRC_SAVE_HASH_IN_TPM)) mrc_cache_update_hash(hash_idx, new_data, new_data_size); + if (CONFIG(TPM_MEASURE_MRC_CACHE) && + !rdev_chain_mem(&read_rdev, new_data, new_data_size)) + mrc_measure_cache(type, &read_rdev); } } diff --git a/src/drivers/smmstore/ramstage.c b/src/drivers/smmstore/ramstage.c index 1cbf9fb28a5f..507678754c94 100644 --- a/src/drivers/smmstore/ramstage.c +++ b/src/drivers/smmstore/ramstage.c @@ -28,6 +28,10 @@ void lb_smmstorev2(struct lb_header *header) store->size = sizeof(*store); store->com_buffer = (uintptr_t)cbmem_entry_start(e); store->com_buffer_size = cbmem_entry_size(e); + if (info.mmap_addr < 4ULL * GiB) + store->mmap_addr_deprecated = info.mmap_addr; + else + store->mmap_addr_deprecated = 0; store->mmap_addr = info.mmap_addr; store->num_blocks = info.num_blocks; store->block_size = info.block_size; diff --git a/src/include/cpu/x86/gdt.h b/src/include/cpu/x86/gdt.h index 27a863ee3308..767e79467fee 100644 --- a/src/include/cpu/x86/gdt.h +++ b/src/include/cpu/x86/gdt.h @@ -3,16 +3,28 @@ #ifndef CPU_X86_GDT #define CPU_X86_GDT +#ifndef __ASSEMBLER__ /* These symbols are defined in c_start.S. */ extern char gdt[]; extern char per_cpu_segment_descriptors[]; extern uint32_t per_cpu_segment_selector; extern char gdt_end[]; extern char idtarg[]; +#endif -/* These symbols are defined in secondary.S. */ -extern char _secondary_gdt_addr[]; -extern char _secondary_start[]; -extern char _secondary_start_end[]; +/* Offset to GDT's segment descriptors: */ +#define GDT_CODE_SEG 0x08 +#define GDT_DATA_SEG 0x10 +#define GDT_CODE_SEG64 0x18 +/* + * This define is placed here to make sure future romstage programmers + * know about it. + * It is used only in SMM for STM setup code. + */ +#define GDT_TASK_STATE_SEG 0x20 + +#define GDT_CODE16_SEG 0x28 +#define GDT_DATA16_SEG 0x30 +#define GDT_DATA_ACPI_SEG 0x38 #endif /* CPU_X86_GDT */ diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h index 930edfdef7d6..87aee95c67f4 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -124,9 +124,11 @@ static inline int get_var_mtrr_count(void) return rdmsr(MTRR_CAP_MSR).lo & MTRR_CAP_VCNT; } -void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size, +int acquire_and_configure_mtrr(unsigned int base, unsigned int size, unsigned int type); +void set_var_mtrr(unsigned int index, unsigned int base, unsigned int size, unsigned int type); int get_free_var_mtrr(void); +void clear_var_mtrr(int index); void clear_all_var_mtrr(void); asmlinkage void display_mtrrs(void); diff --git a/src/include/smmstore.h b/src/include/smmstore.h index 595fe8b29bd5..4ee4c55c750b 100644 --- a/src/include/smmstore.h +++ b/src/include/smmstore.h @@ -69,7 +69,7 @@ struct smmstore_params_init { struct smmstore_params_info { uint32_t num_blocks; uint32_t block_size; - uint32_t mmap_addr; + uint64_t mmap_addr; } __packed; /* diff --git a/src/mainboard/amd/birman/Kconfig b/src/mainboard/amd/birman/Kconfig index 9fafae15e394..3a9ffc77f1d7 100644 --- a/src/mainboard/amd/birman/Kconfig +++ b/src/mainboard/amd/birman/Kconfig @@ -2,7 +2,7 @@ config BOARD_AMD_BIRMAN_COMMON def_bool n - select BOARD_ROMSIZE_KB_16384 # Birman actually has a 32MiB ROM + select BOARD_ROMSIZE_KB_32768 select EC_ACPI select SOC_AMD_COMMON_BLOCK_USE_ESPI if !SOC_AMD_COMMON_BLOCK_SIMNOW_BUILD select DRIVERS_PCIE_RTD3_DEVICE diff --git a/src/mainboard/amd/birman_plus/Kconfig b/src/mainboard/amd/birman_plus/Kconfig index 91e39bf26008..62d5c2914110 100644 --- a/src/mainboard/amd/birman_plus/Kconfig +++ b/src/mainboard/amd/birman_plus/Kconfig @@ -2,7 +2,7 @@ config BOARD_AMD_BIRMANPLUS_COMMON def_bool n - select BOARD_ROMSIZE_KB_16384 # Birman+ actually has a 64MiB ROM + select BOARD_ROMSIZE_KB_65536 select EC_ACPI select SOC_AMD_COMMON_BLOCK_USE_ESPI if !SOC_AMD_COMMON_BLOCK_SIMNOW_BUILD select DRIVERS_PCIE_RTD3_DEVICE diff --git a/src/mainboard/amd/crater/Kconfig b/src/mainboard/amd/crater/Kconfig index 620bc3d084a8..11bd6b9cf72c 100644 --- a/src/mainboard/amd/crater/Kconfig +++ b/src/mainboard/amd/crater/Kconfig @@ -2,7 +2,7 @@ config BOARD_AMD_CRATER_COMMON def_bool n - select BOARD_ROMSIZE_KB_16384 # Birman actually has a 32MiB ROM + select BOARD_ROMSIZE_KB_32768 select EC_ACPI select SOC_AMD_COMMON_BLOCK_USE_ESPI if !SOC_AMD_COMMON_BLOCK_SIMNOW_BUILD select DRIVERS_PCIE_RTD3_DEVICE diff --git a/src/mainboard/amd/mayan/Kconfig b/src/mainboard/amd/mayan/Kconfig index 327599d78c72..1af2d1838bee 100644 --- a/src/mainboard/amd/mayan/Kconfig +++ b/src/mainboard/amd/mayan/Kconfig @@ -4,7 +4,7 @@ if BOARD_AMD_MAYAN_PHOENIX config BOARD_SPECIFIC_OPTIONS def_bool y - select BOARD_ROMSIZE_KB_16384 # Mayan actually has a 32MiB ROM + select BOARD_ROMSIZE_KB_32768 select EC_ACPI select SOC_AMD_COMMON_BLOCK_USE_ESPI select AMD_SOC_CONSOLE_UART diff --git a/src/mainboard/asus/h61-series/Kconfig b/src/mainboard/asus/h61-series/Kconfig index 4c4fd7e2be8c..d09ed1e244ab 100644 --- a/src/mainboard/asus/h61-series/Kconfig +++ b/src/mainboard/asus/h61-series/Kconfig @@ -12,6 +12,16 @@ config BOARD_ASUS_H61_SERIES select SOUTHBRIDGE_INTEL_BD82X6X select USE_NATIVE_RAMINIT +config BOARD_ASUS_H61M_A_USB3 + select BOARD_ASUS_H61_SERIES + select BOARD_ROMSIZE_KB_8192 + select HAVE_CMOS_DEFAULT + select HAVE_OPTION_TABLE + select NO_UART_ON_SUPERIO + select REALTEK_8168_RESET + select RT8168_SET_LED_MODE + select SUPERIO_NUVOTON_NCT6779D + config BOARD_ASUS_H61M_CS select BOARD_ASUS_H61_SERIES select BOARD_ROMSIZE_KB_8192 @@ -75,12 +85,13 @@ config MAINBOARD_DIR default "asus/h61-series" config VARIANT_DIR - default "h61m-cs" if BOARD_ASUS_H61M_CS - default "p8h61-m_lx" if BOARD_ASUS_P8H61_M_LX - default "p8h61-m_lx3_r2_0" if BOARD_ASUS_P8H61_M_LX3_R2_0 - default "p8h61-m_pro" if BOARD_ASUS_P8H61_M_PRO + default "h61m-a_usb3" if BOARD_ASUS_H61M_A_USB3 + default "h61m-cs" if BOARD_ASUS_H61M_CS + default "p8h61-m_lx" if BOARD_ASUS_P8H61_M_LX + default "p8h61-m_lx3_r2_0" if BOARD_ASUS_P8H61_M_LX3_R2_0 + default "p8h61-m_pro" if BOARD_ASUS_P8H61_M_PRO default "p8h61-m_pro_cm6630" if BOARD_ASUS_P8H61_M_PRO_CM6630 - default "p8h67-i_deluxe" if BOARD_ASUS_P8H67_I_DELUXE + default "p8h67-i_deluxe" if BOARD_ASUS_P8H67_I_DELUXE config MAINBOARD_PART_NUMBER default "H61M-CS" if BOARD_ASUS_H61M_CS diff --git a/src/mainboard/asus/h61-series/Kconfig.name b/src/mainboard/asus/h61-series/Kconfig.name index eee48c0f91c7..e1e2317f093d 100644 --- a/src/mainboard/asus/h61-series/Kconfig.name +++ b/src/mainboard/asus/h61-series/Kconfig.name @@ -1,5 +1,8 @@ ## SPDX-License-Identifier: GPL-2.0-only +config BOARD_ASUS_H61M_A_USB3 + bool "H61M-A/USB3" + config BOARD_ASUS_H61M_CS bool "H61M-CS" diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/board_info.txt b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/board_info.txt new file mode 100644 index 000000000000..9008bcc862cc --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/board_info.txt @@ -0,0 +1,6 @@ +Category: desktop +Board URL: https://www.asus.com/supportonly/h61mausb3/helpdesk_knowledge/ +ROM package: DIP-8 +ROM protocol: SPI +ROM socketed: y +Flashrom support: y diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/cmos.default b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/cmos.default new file mode 100644 index 000000000000..76c0b2d6ce33 --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/cmos.default @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +boot_option=Fallback +debug_level=Debug +power_on_after_fail=Enable +sata_mode=AHCI +gfx_uma_size=32M diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/cmos.layout b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/cmos.layout new file mode 100644 index 000000000000..227711afa286 --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/cmos.layout @@ -0,0 +1,65 @@ +## SPDX-License-Identifier: GPL-2.0-only + +# ----------------------------------------------------------------- +entries + +# ----------------------------------------------------------------- +0 120 r 0 reserved_memory + +# ----------------------------------------------------------------- +# RTC_BOOT_BYTE (coreboot hardcoded) +384 1 e 4 boot_option +388 4 h 0 reboot_counter + +# ----------------------------------------------------------------- +# coreboot config options: console +395 4 e 6 debug_level + +# coreboot config options: southbridge +409 2 e 7 power_on_after_fail + +421 1 e 9 sata_mode + +# coreboot config options: cpu + +# coreboot config options: northbridge +432 3 e 11 gfx_uma_size + +# coreboot config options: check sums +984 16 h 0 check_sum + +# ----------------------------------------------------------------- + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +4 0 Fallback +4 1 Normal +6 0 Emergency +6 1 Alert +6 2 Critical +6 3 Error +6 4 Warning +6 5 Notice +6 6 Info +6 7 Debug +6 8 Spew +7 0 Disable +7 1 Enable +7 2 Keep +9 0 AHCI +9 1 IDE +11 0 32M +11 1 64M +11 2 96M +11 3 128M +11 4 160M +11 5 192M +11 6 224M + +# ----------------------------------------------------------------- +checksums + +checksum 392 439 984 diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/data.vbt b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/data.vbt Binary files differnew file mode 100644 index 000000000000..7739a7fb36d2 --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/data.vbt diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/early_init.c b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/early_init.c new file mode 100644 index 000000000000..37da16c471b6 --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/early_init.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <bootblock_common.h> +#include <device/pnp_ops.h> +#include <superio/nuvoton/common/nuvoton.h> +#include <superio/nuvoton/nct6779d/nct6779d.h> + +#define GLOBAL_DEV PNP_DEV(0x2e, 0) +#define ACPI_DEV PNP_DEV(0x2e, NCT6779D_ACPI) + +void bootblock_mainboard_early_init(void) +{ + nuvoton_pnp_enter_conf_state(GLOBAL_DEV); + + /* Select SIO pin states. */ + pnp_write_config(GLOBAL_DEV, 0x1c, 0x71); + pnp_write_config(GLOBAL_DEV, 0x1d, 0x0e); + pnp_write_config(GLOBAL_DEV, 0x22, 0xd7); + pnp_write_config(GLOBAL_DEV, 0x24, 0x00); + pnp_write_config(GLOBAL_DEV, 0x2a, 0x48); + pnp_write_config(GLOBAL_DEV, 0x2c, 0x00); + pnp_write_config(GLOBAL_DEV, 0x2f, 0x01); + + /* Power RAM in S3. */ + pnp_set_logical_device(ACPI_DEV); + pnp_write_config(ACPI_DEV, 0xe4, 0x10); + + nuvoton_pnp_exit_conf_state(GLOBAL_DEV); +} diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/gma-mainboard.ads b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/gma-mainboard.ads new file mode 100644 index 000000000000..20c53ef0f44b --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/gma-mainboard.ads @@ -0,0 +1,21 @@ +-- SPDX-License-Identifier: GPL-2.0-or-later + +with HW.GFX.GMA; +with HW.GFX.GMA.Display_Probing; + +use HW.GFX.GMA; +use HW.GFX.GMA.Display_Probing; + +private package GMA.Mainboard is + + -- For a three-pipe setup, bandwidth is shared between the 2nd and + -- the 3rd pipe. Thus, probe ports that likely have a high-resolution + -- display attached first. + + ports : constant Port_List := + (HDMI2, -- mainboard HDMI port + HDMI1, -- mainboard DVI-D port + Analog, + others => Disabled); + +end GMA.Mainboard; diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/gpio.c b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/gpio.c new file mode 100644 index 000000000000..66fc05a68059 --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/gpio.c @@ -0,0 +1,211 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <southbridge/intel/common/gpio.h> + +static const struct pch_gpio_set1 pch_gpio_set1_mode = { + .gpio0 = GPIO_MODE_GPIO, + .gpio1 = GPIO_MODE_GPIO, + .gpio2 = GPIO_MODE_GPIO, + .gpio3 = GPIO_MODE_GPIO, + .gpio4 = GPIO_MODE_GPIO, + .gpio5 = GPIO_MODE_GPIO, + .gpio6 = GPIO_MODE_GPIO, + .gpio7 = GPIO_MODE_GPIO, + .gpio8 = GPIO_MODE_GPIO, + .gpio9 = GPIO_MODE_NATIVE, + .gpio10 = GPIO_MODE_GPIO, + .gpio11 = GPIO_MODE_GPIO, + .gpio12 = GPIO_MODE_GPIO, + .gpio13 = GPIO_MODE_GPIO, + .gpio14 = GPIO_MODE_GPIO, + .gpio15 = GPIO_MODE_GPIO, + .gpio16 = GPIO_MODE_GPIO, + .gpio17 = GPIO_MODE_GPIO, + .gpio18 = GPIO_MODE_NATIVE, + .gpio19 = GPIO_MODE_GPIO, + .gpio20 = GPIO_MODE_GPIO, + .gpio21 = GPIO_MODE_GPIO, + .gpio22 = GPIO_MODE_GPIO, + .gpio23 = GPIO_MODE_GPIO, + .gpio24 = GPIO_MODE_GPIO, + .gpio25 = GPIO_MODE_NATIVE, + .gpio26 = GPIO_MODE_NATIVE, + .gpio27 = GPIO_MODE_GPIO, + .gpio28 = GPIO_MODE_GPIO, + .gpio29 = GPIO_MODE_GPIO, + .gpio30 = GPIO_MODE_GPIO, + .gpio31 = GPIO_MODE_GPIO, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_direction = { + .gpio0 = GPIO_DIR_OUTPUT, + .gpio1 = GPIO_DIR_INPUT, + .gpio2 = GPIO_DIR_INPUT, + .gpio3 = GPIO_DIR_INPUT, + .gpio4 = GPIO_DIR_INPUT, + .gpio5 = GPIO_DIR_INPUT, + .gpio6 = GPIO_DIR_INPUT, + .gpio7 = GPIO_DIR_INPUT, + .gpio8 = GPIO_DIR_INPUT, + .gpio10 = GPIO_DIR_INPUT, + .gpio11 = GPIO_DIR_INPUT, + .gpio12 = GPIO_DIR_INPUT, + .gpio13 = GPIO_DIR_INPUT, + .gpio14 = GPIO_DIR_INPUT, + .gpio15 = GPIO_DIR_INPUT, + .gpio16 = GPIO_DIR_INPUT, + .gpio17 = GPIO_DIR_INPUT, + .gpio19 = GPIO_DIR_INPUT, + .gpio20 = GPIO_DIR_INPUT, + .gpio21 = GPIO_DIR_INPUT, + .gpio22 = GPIO_DIR_INPUT, + .gpio23 = GPIO_DIR_INPUT, + .gpio24 = GPIO_DIR_INPUT, + .gpio27 = GPIO_DIR_INPUT, + .gpio28 = GPIO_DIR_INPUT, + .gpio29 = GPIO_DIR_INPUT, + .gpio30 = GPIO_DIR_INPUT, + .gpio31 = GPIO_DIR_INPUT, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_level = { + .gpio0 = GPIO_LEVEL_LOW, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_reset = { +}; + +static const struct pch_gpio_set1 pch_gpio_set1_invert = { + .gpio1 = GPIO_INVERT, + .gpio13 = GPIO_INVERT, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_blink = { +}; + +static const struct pch_gpio_set2 pch_gpio_set2_mode = { + .gpio32 = GPIO_MODE_GPIO, + .gpio33 = GPIO_MODE_GPIO, + .gpio34 = GPIO_MODE_GPIO, + .gpio35 = GPIO_MODE_GPIO, + .gpio36 = GPIO_MODE_GPIO, + .gpio37 = GPIO_MODE_GPIO, + .gpio38 = GPIO_MODE_GPIO, + .gpio39 = GPIO_MODE_GPIO, + .gpio40 = GPIO_MODE_NATIVE, + .gpio41 = GPIO_MODE_NATIVE, + .gpio42 = GPIO_MODE_GPIO, + .gpio43 = GPIO_MODE_NATIVE, + .gpio44 = GPIO_MODE_GPIO, + .gpio45 = GPIO_MODE_GPIO, + .gpio46 = GPIO_MODE_GPIO, + .gpio47 = GPIO_MODE_NATIVE, + .gpio48 = GPIO_MODE_GPIO, + .gpio49 = GPIO_MODE_GPIO, + .gpio50 = GPIO_MODE_GPIO, + .gpio51 = GPIO_MODE_GPIO, + .gpio52 = GPIO_MODE_GPIO, + .gpio53 = GPIO_MODE_GPIO, + .gpio54 = GPIO_MODE_GPIO, + .gpio55 = GPIO_MODE_GPIO, + .gpio56 = GPIO_MODE_NATIVE, + .gpio57 = GPIO_MODE_GPIO, + .gpio58 = GPIO_MODE_GPIO, + .gpio59 = GPIO_MODE_NATIVE, + .gpio60 = GPIO_MODE_GPIO, + .gpio61 = GPIO_MODE_GPIO, + .gpio62 = GPIO_MODE_NATIVE, + .gpio63 = GPIO_MODE_GPIO, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_direction = { + .gpio32 = GPIO_DIR_INPUT, + .gpio33 = GPIO_DIR_INPUT, + .gpio34 = GPIO_DIR_INPUT, + .gpio35 = GPIO_DIR_INPUT, + .gpio36 = GPIO_DIR_INPUT, + .gpio37 = GPIO_DIR_INPUT, + .gpio38 = GPIO_DIR_INPUT, + .gpio39 = GPIO_DIR_INPUT, + .gpio42 = GPIO_DIR_INPUT, + .gpio44 = GPIO_DIR_INPUT, + .gpio45 = GPIO_DIR_INPUT, + .gpio46 = GPIO_DIR_INPUT, + .gpio48 = GPIO_DIR_INPUT, + .gpio49 = GPIO_DIR_INPUT, + .gpio50 = GPIO_DIR_INPUT, + .gpio51 = GPIO_DIR_INPUT, + .gpio52 = GPIO_DIR_INPUT, + .gpio53 = GPIO_DIR_INPUT, + .gpio54 = GPIO_DIR_INPUT, + .gpio55 = GPIO_DIR_INPUT, + .gpio57 = GPIO_DIR_INPUT, + .gpio58 = GPIO_DIR_INPUT, + .gpio60 = GPIO_DIR_INPUT, + .gpio61 = GPIO_DIR_INPUT, + .gpio63 = GPIO_DIR_OUTPUT, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_level = { + .gpio63 = GPIO_LEVEL_HIGH, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_reset = { + .gpio57 = GPIO_RESET_RSMRST, + .gpio63 = GPIO_RESET_RSMRST, +}; + +static const struct pch_gpio_set3 pch_gpio_set3_mode = { + .gpio64 = GPIO_MODE_GPIO, + .gpio65 = GPIO_MODE_NATIVE, + .gpio66 = GPIO_MODE_GPIO, + .gpio67 = GPIO_MODE_NATIVE, + .gpio68 = GPIO_MODE_GPIO, + .gpio69 = GPIO_MODE_GPIO, + .gpio70 = GPIO_MODE_GPIO, + .gpio71 = GPIO_MODE_GPIO, + .gpio72 = GPIO_MODE_GPIO, + .gpio73 = GPIO_MODE_NATIVE, + .gpio74 = GPIO_MODE_GPIO, + .gpio75 = GPIO_MODE_NATIVE, +}; + +static const struct pch_gpio_set3 pch_gpio_set3_direction = { + .gpio64 = GPIO_DIR_INPUT, + .gpio66 = GPIO_DIR_INPUT, + .gpio68 = GPIO_DIR_INPUT, + .gpio69 = GPIO_DIR_INPUT, + .gpio70 = GPIO_DIR_INPUT, + .gpio71 = GPIO_DIR_INPUT, + .gpio72 = GPIO_DIR_INPUT, + .gpio74 = GPIO_DIR_INPUT, +}; + +static const struct pch_gpio_set3 pch_gpio_set3_level = { +}; + +static const struct pch_gpio_set3 pch_gpio_set3_reset = { +}; + +const struct pch_gpio_map mainboard_gpio_map = { + .set1 = { + .mode = &pch_gpio_set1_mode, + .direction = &pch_gpio_set1_direction, + .level = &pch_gpio_set1_level, + .blink = &pch_gpio_set1_blink, + .invert = &pch_gpio_set1_invert, + .reset = &pch_gpio_set1_reset, + }, + .set2 = { + .mode = &pch_gpio_set2_mode, + .direction = &pch_gpio_set2_direction, + .level = &pch_gpio_set2_level, + .reset = &pch_gpio_set2_reset, + }, + .set3 = { + .mode = &pch_gpio_set3_mode, + .direction = &pch_gpio_set3_direction, + .level = &pch_gpio_set3_level, + .reset = &pch_gpio_set3_reset, + }, +}; diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/hda_verb.c b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/hda_verb.c new file mode 100644 index 000000000000..1af52eb94e7e --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/hda_verb.c @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/azalia_device.h> + +const u32 cim_verb_data[] = { + 0x10ec0887, /* Codec Vendor / Device ID: Realtek */ + 0x10438445, /* Subsystem ID */ + 15, /* Number of 4 dword sets */ + AZALIA_SUBVENDOR(0, 0x10438445), + AZALIA_PIN_CFG(0, 0x11, 0x40330000), + AZALIA_PIN_CFG(0, 0x12, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x14, 0x01014010), + AZALIA_PIN_CFG(0, 0x15, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x16, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x17, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x18, 0x01a19030), + AZALIA_PIN_CFG(0, 0x19, 0x02a19040), + AZALIA_PIN_CFG(0, 0x1a, 0x0181303f), + AZALIA_PIN_CFG(0, 0x1b, 0x02214020), + AZALIA_PIN_CFG(0, 0x1c, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1d, 0x4024c601), + AZALIA_PIN_CFG(0, 0x1e, AZALIA_PIN_CFG_NC(0)), + AZALIA_PIN_CFG(0, 0x1f, AZALIA_PIN_CFG_NC(0)), + + 0x8086281c, /* Codec Vendor / Device ID: Intel */ + 0x80860101, /* Subsystem ID */ + 10, /* Number of 4 dword sets */ + AZALIA_SUBVENDOR(2, 0x80860101), + AZALIA_PIN_CFG(2, 0x04, 0x18560010), + AZALIA_PIN_CFG(2, 0x06, 0x18560010), + AZALIA_PIN_CFG(2, 0x08, 0x18560010), + AZALIA_PIN_CFG(2, 0x0a, 0x18560010), + AZALIA_PIN_CFG(2, 0x0b, 0x18560010), + AZALIA_PIN_CFG(2, 0x0c, 0x18560010), + AZALIA_PIN_CFG(2, 0x0d, 0x18560010), + AZALIA_PIN_CFG(2, 0x0e, 0x18560010), + AZALIA_PIN_CFG(2, 0x0f, 0x18560010), + + 0x80862805, /* Codec Vendor / Device ID: Intel */ + 0x80860101, /* Subsystem ID */ + 4, /* Number of 4 dword sets */ + AZALIA_SUBVENDOR(3, 0x80860101), + AZALIA_PIN_CFG(3, 0x05, 0x58560010), + AZALIA_PIN_CFG(3, 0x06, 0x58560020), + AZALIA_PIN_CFG(3, 0x07, 0x18560030), + +}; + +const u32 pc_beep_verbs[0] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/asus/h61-series/variants/h61m-a_usb3/overridetree.cb b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/overridetree.cb new file mode 100644 index 000000000000..be9667a328d9 --- /dev/null +++ b/src/mainboard/asus/h61-series/variants/h61m-a_usb3/overridetree.cb @@ -0,0 +1,82 @@ +## SPDX-License-Identifier: GPL-2.0-or-later + +chip northbridge/intel/sandybridge + register "gpu_dp_b_hotplug" = "4" + register "gpu_dp_d_hotplug" = "4" + device domain 0 on + subsystemid 0x1043 0x844d inherit + chip southbridge/intel/bd82x6x + register "usb_port_config" = "{ + { 1, 0x95f, 0 }, + { 1, 0x95f, 0 }, + { 1, 0x9df, 1 }, + { 1, 0xfff, 1 }, + { 1, 0x95f, 2 }, + { 1, 0xfbf, 2 }, + { 1, 0xb57, 3 }, + { 1, 0xb57, 3 }, + { 1, 0x353, 4 }, + { 1, 0x353, 4 }, + { 1, 0xb5f, 6 }, + { 1, 0xb5f, 5 }, + { 1, 0xb57, 5 }, + { 1, 0xb57, 6 }, + }" + register "pcie_port_coalesce" = "1" + register "gen1_dec" = "0x000c0291" + device ref hda on + subsystemid 0x1043 0x8445 + end + device ref pcie_rp1 off end + device ref pcie_rp2 on end # ASM1042 USB 3.0 controller + device ref pcie_rp3 off end + device ref pcie_rp4 on end # PCIEX1_1 slot + device ref pcie_rp5 on end # PCIEX1_2 slot + device ref pcie_rp6 on # Realtek Gigabit NIC + device pci 00.0 on end + end + device ref pcie_rp7 off end + device ref pcie_rp8 off end + + device ref lpc on + chip superio/nuvoton/nct6779d + device pnp 2e.1 off end # Parallel + device pnp 2e.2 off end # UART A + device pnp 2e.3 off end # UART B, IR + device pnp 2e.5 on # Keyboard + io 0x60 = 0x0060 + io 0x62 = 0x0064 + irq 0x70 = 1 + irq 0x72 = 12 + end + device pnp 2e.6 off end # CIR + device pnp 2e.7 off end # GPIO6-8 + device pnp 2e.8 off end # WDT1, GPIO0, GPIO1 + device pnp 2e.108 on end # GPIO0 + device pnp 2e.9 off end # GPIO1-8 + device pnp 2e.109 off end # GPIO1 + device pnp 2e.209 off end # GPIO2 + device pnp 2e.309 off end # GPIO3 + device pnp 2e.409 off end # GPIO4 + device pnp 2e.509 off end # GPIO5 + device pnp 2e.609 off end # GPIO6 + device pnp 2e.709 off end # GPIO7 + device pnp 2e.a on # ACPI + irq 0xe7 = 0x11 + irq 0xf2 = 0x5d + end + device pnp 2e.b on # H/W Monitor, FP LED + io 0x60 = 0x0290 + io 0x62 = 0 + irq 0x70 = 0 + end + device pnp 2e.d off end # WDT1 + device pnp 2e.e off end # CIR WAKE-UP + device pnp 2e.f off end # GPIO Push-pull/Open-drain selection + device pnp 2e.14 off end # PORT80 UART + device pnp 2e.16 off end # Deep Sleep + end + end + end + end +end diff --git a/src/mainboard/dell/e7240/Makefile.mk b/src/mainboard/dell/e7240/Makefile.mk deleted file mode 100644 index c3dd6194218d..000000000000 --- a/src/mainboard/dell/e7240/Makefile.mk +++ /dev/null @@ -1,5 +0,0 @@ -## SPDX-License-Identifier: GPL-2.0-only - -bootblock-y += bootblock.c -romstage-y += gpio.c -ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads diff --git a/src/mainboard/dell/e7240/Kconfig b/src/mainboard/dell/haswell_latitude/Kconfig index 4f24cf93ed3a..c01735d35d76 100644 --- a/src/mainboard/dell/e7240/Kconfig +++ b/src/mainboard/dell/haswell_latitude/Kconfig @@ -1,26 +1,38 @@ ## SPDX-License-Identifier: GPL-2.0-only -if BOARD_DELL_LATITUDE_E7240 - -config BOARD_SPECIFIC_OPTIONS - def_bool y - select BOARD_ROMSIZE_KB_8192 +config BOARD_DELL_HASWELL_LATITUDE_COMMON + def_bool n select EC_DELL_MEC5035 select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select INTEL_LYNXPOINT_LP select MAINBOARD_HAS_LIBGFXINIT - select MAINBOARD_USES_IFD_GBE_REGION select NORTHBRIDGE_INTEL_HASWELL select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_LYNXPOINT select SYSTEM_TYPE_LAPTOP +config BOARD_DELL_LATITUDE_E7240 + select BOARD_DELL_HASWELL_LATITUDE_COMMON + select BOARD_ROMSIZE_KB_8192 + select INTEL_LYNXPOINT_LP + select MAINBOARD_USES_IFD_GBE_REGION + +if BOARD_DELL_HASWELL_LATITUDE_COMMON + config MAINBOARD_DIR - default "dell/e7240" + default "dell/haswell_latitude" config MAINBOARD_PART_NUMBER - default "Latitude E7240" + default "Latitude E7240" if BOARD_DELL_LATITUDE_E7240 + +config DEVICETREE + default "devicetree_lp.cb" if INTEL_LYNXPOINT_LP + +config VARIANT_DIR + default "e7240" if BOARD_DELL_LATITUDE_E7240 + +config OVERRIDE_DEVICETREE + default "variants/\$(CONFIG_VARIANT_DIR)/overridetree.cb" config VGA_BIOS_ID default "8086,0a16" diff --git a/src/mainboard/dell/e7240/Kconfig.name b/src/mainboard/dell/haswell_latitude/Kconfig.name index 499f783a101d..499f783a101d 100644 --- a/src/mainboard/dell/e7240/Kconfig.name +++ b/src/mainboard/dell/haswell_latitude/Kconfig.name diff --git a/src/mainboard/dell/haswell_latitude/Makefile.mk b/src/mainboard/dell/haswell_latitude/Makefile.mk new file mode 100644 index 000000000000..38679fffac34 --- /dev/null +++ b/src/mainboard/dell/haswell_latitude/Makefile.mk @@ -0,0 +1,7 @@ +## SPDX-License-Identifier: GPL-2.0-only + +bootblock-y += bootblock.c +romstage-y += variants/$(VARIANT_DIR)/gpio.c +romstage-y += variants/$(VARIANT_DIR)/romstage.c +ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads +ramstage-y += variants/$(VARIANT_DIR)/hda_verb.c diff --git a/src/mainboard/dell/e7240/acpi/ec.asl b/src/mainboard/dell/haswell_latitude/acpi/ec.asl index 24915c22ef27..24915c22ef27 100644 --- a/src/mainboard/dell/e7240/acpi/ec.asl +++ b/src/mainboard/dell/haswell_latitude/acpi/ec.asl diff --git a/src/mainboard/dell/e7240/acpi/platform.asl b/src/mainboard/dell/haswell_latitude/acpi/platform.asl index 2d24bbd9b9a8..2d24bbd9b9a8 100644 --- a/src/mainboard/dell/e7240/acpi/platform.asl +++ b/src/mainboard/dell/haswell_latitude/acpi/platform.asl diff --git a/src/mainboard/dell/e7240/acpi/superio.asl b/src/mainboard/dell/haswell_latitude/acpi/superio.asl index 55b1db5b1137..55b1db5b1137 100644 --- a/src/mainboard/dell/e7240/acpi/superio.asl +++ b/src/mainboard/dell/haswell_latitude/acpi/superio.asl diff --git a/src/mainboard/dell/e7240/board_info.txt b/src/mainboard/dell/haswell_latitude/board_info.txt index accdf52791d6..accdf52791d6 100644 --- a/src/mainboard/dell/e7240/board_info.txt +++ b/src/mainboard/dell/haswell_latitude/board_info.txt diff --git a/src/mainboard/dell/e7240/bootblock.c b/src/mainboard/dell/haswell_latitude/bootblock.c index 2f6090a40fcc..a9223d33720b 100644 --- a/src/mainboard/dell/e7240/bootblock.c +++ b/src/mainboard/dell/haswell_latitude/bootblock.c @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include <device/pci_ops.h> #include <ec/dell/mec5035/mec5035.h> #include <southbridge/intel/lynxpoint/pch.h> diff --git a/src/mainboard/dell/e7240/devicetree.cb b/src/mainboard/dell/haswell_latitude/devicetree_lp.cb index 07d7cd1d5b47..d9537886c033 100644 --- a/src/mainboard/dell/e7240/devicetree.cb +++ b/src/mainboard/dell/haswell_latitude/devicetree_lp.cb @@ -10,7 +10,6 @@ chip northbridge/intel/haswell device domain 0x0 on ops haswell_pci_domain_ops - subsystemid 0x1028 0x05ca inherit device pci 00.0 on end # Host bridge device pci 02.0 on # Internal graphics VGA controller @@ -30,7 +29,7 @@ chip northbridge/intel/haswell end device pci 03.0 on end # Mini-HD audio - chip southbridge/intel/lynxpoint # Intel Series 8 Lynx Point PCH + chip southbridge/intel/lynxpoint # Intel Series 8 Lynx Point LP PCH register "docking_supported" = "true" register "alt_gp_smi_en" = "0x00002000" register "gpe0_en_1" = "0x00000100" @@ -53,13 +52,12 @@ chip northbridge/intel/haswell device pci 17.0 off end # SDIO device pci 19.0 on end # Intel Gigabit Ethernet device pci 1b.0 on end # High Definition Audio - device pci 1c.0 on end # PCIe Port #1 + device pci 1c.0 off end # PCIe Port #1 device pci 1c.1 off end # PCIe Port #2 device pci 1c.2 off end # PCIe Port #3 - device pci 1c.3 on end # PCIe Port #4, WLAN - device pci 1c.4 on end # PCIe Port #5, SD/MMC Card Reader - # PCIe Port #6 Can be muxed between PCIe and SATA - device pci 1c.5 on end # PCIe Port #6 + device pci 1c.3 off end # PCIe Port #4 + device pci 1c.4 off end # PCIe Port #5 + device pci 1c.5 off end # PCIe Port #6 device pci 1d.0 on end # USB2 EHCI #1 device pci 1f.0 on # LPC bridge register "gen1_dec" = "0x007c0681" @@ -72,10 +70,7 @@ chip northbridge/intel/haswell device pnp ff.0 on end end end - device pci 1f.2 on # SATA Controller (AHCI) - # 0(eSATA on dock), 1(mSATA near the fan), 3(mSATA near WLAN) - register "sata_port_map" = "0x0b" - end + device pci 1f.2 on end # SATA Controller (AHCI) device pci 1f.3 on end # SMBus device pci 1f.6 off end # Thermal end diff --git a/src/mainboard/dell/e7240/dsdt.asl b/src/mainboard/dell/haswell_latitude/dsdt.asl index b1d4c7912780..b1d4c7912780 100644 --- a/src/mainboard/dell/e7240/dsdt.asl +++ b/src/mainboard/dell/haswell_latitude/dsdt.asl diff --git a/src/mainboard/dell/e7240/gma-mainboard.ads b/src/mainboard/dell/haswell_latitude/gma-mainboard.ads index cdc7f1868015..cdc7f1868015 100644 --- a/src/mainboard/dell/e7240/gma-mainboard.ads +++ b/src/mainboard/dell/haswell_latitude/gma-mainboard.ads diff --git a/src/mainboard/dell/e7240/gpio.c b/src/mainboard/dell/haswell_latitude/variants/e7240/gpio.c index 166502505f4d..166502505f4d 100644 --- a/src/mainboard/dell/e7240/gpio.c +++ b/src/mainboard/dell/haswell_latitude/variants/e7240/gpio.c diff --git a/src/mainboard/dell/e7240/hda_verb.c b/src/mainboard/dell/haswell_latitude/variants/e7240/hda_verb.c index b052e15ead80..b052e15ead80 100644 --- a/src/mainboard/dell/e7240/hda_verb.c +++ b/src/mainboard/dell/haswell_latitude/variants/e7240/hda_verb.c diff --git a/src/mainboard/dell/haswell_latitude/variants/e7240/overridetree.cb b/src/mainboard/dell/haswell_latitude/variants/e7240/overridetree.cb new file mode 100644 index 000000000000..a29e184fde25 --- /dev/null +++ b/src/mainboard/dell/haswell_latitude/variants/e7240/overridetree.cb @@ -0,0 +1,21 @@ +## SPDX-License-Identifier: GPL-2.0-or-later + +chip northbridge/intel/haswell + device domain 0 on + subsystemid 0x1028 0x05ca inherit + + chip southbridge/intel/lynxpoint # Intel Series 8 Lynx Point PCH + device pci 1c.0 on end # PCIe Port #1 + device pci 1c.1 off end # PCIe Port #2 + device pci 1c.2 off end # PCIe Port #3 + device pci 1c.3 on end # PCIe Port #4, WLAN + device pci 1c.4 on end # PCIe Port #5, SD/MMC Card Reader + # PCIe Port #6 Can be muxed between PCIe and SATA + device pci 1c.5 on end # PCIe Port #6 + device pci 1f.2 on # SATA Controller (AHCI) + # 0(eSATA on dock), 1(mSATA near the fan), 3(mSATA near WLAN) + register "sata_port_map" = "0x0b" + end + end + end +end diff --git a/src/mainboard/dell/e7240/romstage.c b/src/mainboard/dell/haswell_latitude/variants/e7240/romstage.c index c439bfcf151e..c439bfcf151e 100644 --- a/src/mainboard/dell/e7240/romstage.c +++ b/src/mainboard/dell/haswell_latitude/variants/e7240/romstage.c diff --git a/src/mainboard/google/beltino/Kconfig b/src/mainboard/google/beltino/Kconfig index 8bde8e6d1c7e..2d5c3e96378c 100644 --- a/src/mainboard/google/beltino/Kconfig +++ b/src/mainboard/google/beltino/Kconfig @@ -3,6 +3,7 @@ config BOARD_GOOGLE_BASEBOARD_BELTINO def_bool n select BOARD_ROMSIZE_KB_8192 + select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE diff --git a/src/mainboard/google/beltino/Makefile.mk b/src/mainboard/google/beltino/Makefile.mk index 77edc30b8e8b..00255b834e84 100644 --- a/src/mainboard/google/beltino/Makefile.mk +++ b/src/mainboard/google/beltino/Makefile.mk @@ -1,19 +1,19 @@ ## SPDX-License-Identifier: GPL-2.0-only bootblock-y += bootblock.c +bootblock-y += variants/$(VARIANT_DIR)/led.c romstage-$(CONFIG_CHROMEOS) += chromeos.c +romstage-y += variants/$(VARIANT_DIR)/gpio.c + +ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c -verstage-y += chromeos.c +ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads ramstage-y += lan.c -smm-y += variants/$(VARIANT_DIR)/led.c - -romstage-y += variants/$(VARIANT_DIR)/gpio.c - -bootblock-y += variants/$(VARIANT_DIR)/led.c +verstage-y += chromeos.c -ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads +smm-y += variants/$(VARIANT_DIR)/led.c subdirs-y += variants/$(VARIANT_DIR) CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include diff --git a/src/mainboard/google/beltino/cfr.c b/src/mainboard/google/beltino/cfr.c new file mode 100644 index 000000000000..0ff1433e5760 --- /dev/null +++ b/src/mainboard/google/beltino/cfr.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boot/coreboot_tables.h> +#include <drivers/option/cfr_frontend.h> +#include <southbridge/intel/lynxpoint/cfr.h> + +static struct sm_obj_form system = { + .ui_name = "System", + .obj_list = (const struct sm_object *[]) { + &me_disable, + &nmi, + NULL + }, +}; + +static struct sm_obj_form power = { + .ui_name = "Power", + .obj_list = (const struct sm_object *[]) { + &power_on_after_fail, + NULL + }, +}; + +static struct sm_obj_form *sm_root[] = { + &system, + &power, + NULL +}; + +void mb_cfr_setup_menu(struct lb_cfr *cfr_root) +{ + cfr_write_setup_menu(cfr_root, sm_root); +} diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index c633e8dfb1f0..db44fe7972f1 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -1,7 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include <bootmode.h> +#include <console/console.h> #include <device/device.h> +#include <gpio.h> #include <soc/pcie.h> +#include <soc/qupv3_config_common.h> +#include <soc/qup_se_handlers_common.h> +#include "board.h" bool mainboard_needs_pcie_init(void) { @@ -9,9 +15,43 @@ bool mainboard_needs_pcie_init(void) return false; } +static void display_startup(void) +{ + if (!display_init_required()) { + printk(BIOS_INFO, "Skipping display init.\n"); + return; + } + + /* TODO: add logic for display init */ +} + static void mainboard_init(struct device *dev) { - /* Placeholder */ + gpi_firmware_load(QUP_0_GSI_BASE); + gpi_firmware_load(QUP_1_GSI_BASE); + gpi_firmware_load(QUP_2_GSI_BASE); + + /* + * Load console UART QUP firmware. + * This is required even if coreboot's serial output is disabled. + */ + if (!CONFIG(CONSOLE_SERIAL)) + qupv3_se_fw_load_and_init(QUPV3_2_SE5, SE_PROTOCOL_UART, FIFO); + + qupv3_se_fw_load_and_init(QUPV3_1_SE0, SE_PROTOCOL_I2C, MIXED); /* Touch I2C */ + qupv3_se_fw_load_and_init(QUPV3_1_SE6, SE_PROTOCOL_UART, FIFO); /* BT UART */ + qupv3_se_fw_load_and_init(QUPV3_0_SE0, SE_PROTOCOL_I2C, MIXED); /* Trackpad I2C */ + if (CONFIG(MAINBOARD_HAS_FINGERPRINT_VIA_SPI)) + qupv3_se_fw_load_and_init(QUPV3_2_SE2, SE_PROTOCOL_SPI, MIXED); /* Fingerprint SPI */ + + /* + * Deassert FPMCU reset. Power applied in romstage + * has now stabilized. + */ + if (CONFIG(MAINBOARD_HAS_FINGERPRINT)) + gpio_output(GPIO_FP_RST_L, 1); + + display_startup(); } static void mainboard_enable(struct device *dev) diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index 8d15157e70ec..f6932fefdc1d 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -1,8 +1,19 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include <arch/stages.h> +#include <gpio.h> +#include "board.h" void platform_romstage_main(void) { /* Placeholder */ + + /* + * Enable this power rail now for FPMCU stability prior to + * its reset being deasserted in ramstage. This applies + * when MAINBOARD_HAS_FINGERPRINT_VIA_SPI Kconfig is enabled. + * Requires >=200ms delay after its pin was driven low in bootblock. + */ + if (CONFIG(MAINBOARD_HAS_FINGERPRINT_VIA_SPI)) + gpio_output(GPIO_EN_FP_RAILS, 1); } diff --git a/src/mainboard/google/brya/dsdt.asl b/src/mainboard/google/brya/dsdt.asl index 4c1574e55f4e..4f824095653d 100644 --- a/src/mainboard/google/brya/dsdt.asl +++ b/src/mainboard/google/brya/dsdt.asl @@ -27,6 +27,7 @@ DefinitionBlock( #include <soc/intel/alderlake/acpi/southbridge.asl> #include <soc/intel/alderlake/acpi/tcss.asl> #include <drivers/intel/gma/acpi/default_brightness_levels.asl> + #include <soc/intel/common/block/acpi/acpi/gna.asl> } } diff --git a/src/mainboard/google/brya/variants/baseboard/brask/devicetree.cb b/src/mainboard/google/brya/variants/baseboard/brask/devicetree.cb index 3009f6570331..d54c68d866e8 100644 --- a/src/mainboard/google/brya/variants/baseboard/brask/devicetree.cb +++ b/src/mainboard/google/brya/variants/baseboard/brask/devicetree.cb @@ -111,6 +111,7 @@ chip soc/intel/alderlake device ref tbt_pcie_rp0 on end device ref tbt_pcie_rp1 on end device ref tbt_pcie_rp2 on end + device ref gna on end device ref tcss_xhci on end device ref tcss_dma0 on end device ref tcss_dma1 on end diff --git a/src/mainboard/google/brya/variants/baseboard/brya/devicetree.cb b/src/mainboard/google/brya/variants/baseboard/brya/devicetree.cb index 6160ebf0848b..71dfb54b46cb 100644 --- a/src/mainboard/google/brya/variants/baseboard/brya/devicetree.cb +++ b/src/mainboard/google/brya/variants/baseboard/brya/devicetree.cb @@ -162,6 +162,7 @@ chip soc/intel/alderlake device ref tbt_pcie_rp0 on end device ref tbt_pcie_rp1 on end device ref tbt_pcie_rp2 on end + device ref gna on end device ref tcss_xhci on end device ref tcss_dma0 on end device ref tcss_dma1 on end diff --git a/src/mainboard/google/brya/variants/baseboard/hades/devicetree.cb b/src/mainboard/google/brya/variants/baseboard/hades/devicetree.cb index 6bd659dbce2e..54046b904b9f 100644 --- a/src/mainboard/google/brya/variants/baseboard/hades/devicetree.cb +++ b/src/mainboard/google/brya/variants/baseboard/hades/devicetree.cb @@ -100,6 +100,7 @@ chip soc/intel/alderlake }" end device ref dtt on end + device ref gna on end device ref tcss_xhci on end device ref xhci on end device ref shared_sram on end diff --git a/src/mainboard/google/brya/variants/baseboard/nissa/devicetree.cb b/src/mainboard/google/brya/variants/baseboard/nissa/devicetree.cb index 65d3518b7be6..8b1cebd1a519 100644 --- a/src/mainboard/google/brya/variants/baseboard/nissa/devicetree.cb +++ b/src/mainboard/google/brya/variants/baseboard/nissa/devicetree.cb @@ -192,6 +192,7 @@ chip soc/intel/alderlake register "gfx" = "GMA_DEFAULT_PANEL(0)" end device ref dtt on end + device ref gna on end device ref tcss_xhci on end device ref xhci on end device ref shared_sram on end diff --git a/src/mainboard/google/brya/variants/meliks/overridetree.cb b/src/mainboard/google/brya/variants/meliks/overridetree.cb index 913ccb889711..c98d31e6d606 100644 --- a/src/mainboard/google/brya/variants/meliks/overridetree.cb +++ b/src/mainboard/google/brya/variants/meliks/overridetree.cb @@ -77,26 +77,6 @@ chip soc/intel/alderlake [PchSerialIoIndexI2C5] = PchSerialIoPci, }" - # VR Settings - register "domain_vr_config[VR_DOMAIN_IA]" = "{ - .vr_config_enable = 1, - .tdc_timewindow = 1000, - .ac_loadline = 500, - .dc_loadline = 500, - .psi1threshold = VR_CFG_AMP(20), - .psi2threshold = VR_CFG_AMP(5), - .psi3threshold = VR_CFG_AMP(1), - }" - - register "domain_vr_config[VR_DOMAIN_GT]" = "{ - .vr_config_enable = 1, - .tdc_timewindow = 1000, - .psi1threshold = VR_CFG_AMP(13), - .psi2threshold = VR_CFG_AMP(5), - .psi3threshold = VR_CFG_AMP(1), - - }" - # Enable the Cnvi BT Audio Offload register "cnvi_bt_audio_offload" = "1" diff --git a/src/mainboard/google/brya/variants/uldrenite/gpio.c b/src/mainboard/google/brya/variants/uldrenite/gpio.c index d453adb1810b..667a369604e8 100644 --- a/src/mainboard/google/brya/variants/uldrenite/gpio.c +++ b/src/mainboard/google/brya/variants/uldrenite/gpio.c @@ -143,18 +143,18 @@ static const struct pad_config gpio_table[] = { PAD_NC_LOCK(GPP_D11, NONE, LOCK_CONFIG), /* D12 : ISH_SPI_MOSI ==> GPP_D12_STRAP */ PAD_NC_LOCK(GPP_D12, NONE, LOCK_CONFIG), - /* D13 : UART0_ISH_RXD ==> NC */ - PAD_NC(GPP_D13, NONE), - /* D14 : UART0_ISH_TXD ==> LCD_CBL_DET# */ - PAD_CFG_GPO(GPP_D14, 1, DEEP), + /* D13 : UART0_ISH_RXD */ + PAD_CFG_NF(GPP_D13, NONE, DEEP, NF1), + /* D14 : UART0_ISH_TXD */ + PAD_CFG_NF(GPP_D14, NONE, DEEP, NF1), /* D15 : GPP_D15 ==> SOC_TS_I2C_RST# */ PAD_CFG_GPO_LOCK(GPP_D15, 1, LOCK_CONFIG), /* D16 : ISH_UART0_CTS# ==> SOC_TS_I2C_INT# */ PAD_CFG_GPI_APIC(GPP_D16, NONE, PLTRST, LEVEL, INVERT), - /* D17 : NC ==> UART1_ISH_RX_DBG_TX */ - PAD_CFG_NF(GPP_D17, NONE, DEEP, NF2), - /* D18 : NC ==> UART1_ISH_TX_DBG_RX */ - PAD_CFG_NF(GPP_D18, NONE, DEEP, NF2), + /* D17 : NC */ + PAD_NC(GPP_D17, NONE), + /* D18 : LCD_CBL_DET# */ + PAD_CFG_GPO(GPP_D18, 1, DEEP), /* D19 : I2S_MCLK1_OUT ==> NC */ PAD_NC(GPP_D19, NONE), diff --git a/src/mainboard/google/brya/variants/uldrenite/variant.c b/src/mainboard/google/brya/variants/uldrenite/variant.c index 532752837f34..75809e233f94 100644 --- a/src/mainboard/google/brya/variants/uldrenite/variant.c +++ b/src/mainboard/google/brya/variants/uldrenite/variant.c @@ -8,6 +8,7 @@ #include <fw_config.h> #include <sar.h> #include <soc/bootblock.h> +#include <stdlib.h> const char *get_wifi_sar_cbfs_filename(void) { @@ -40,7 +41,7 @@ static const struct pad_config lte_disable_pads[] = { PAD_NC(GPP_H23, NONE), }; -static const struct pad_config ish_disable_pads[] = { +static const struct pad_config ish_uart0_disable_pads[] = { /* A16 : ISH_GP5 ==> NC */ PAD_NC_LOCK(GPP_A16, NONE, LOCK_CONFIG), /* B5 : GPP_B5 ==> NC */ @@ -49,12 +50,46 @@ static const struct pad_config ish_disable_pads[] = { PAD_NC(GPP_B6, NONE), /* D1 : ISH_GP1 ==> NC */ PAD_NC(GPP_D1, NONE), + /* D13 : UART0_ISH_RXD ==> NC */ + PAD_NC(GPP_D13, NONE), + /* D14 : UART0_ISH_TXD ==> NC */ + PAD_NC(GPP_D14, NONE), + /* E9 : SOC_ACC2_INT ==> NC */ + PAD_NC_LOCK(GPP_E9, NONE, LOCK_CONFIG), +}; + +static const struct pad_config switch_ish_uart1_pads[] = { + /* D13 : UART0_ISH_RXD ==> NC */ + PAD_NC(GPP_D13, NONE), + /* D14 : UART0_ISH_TXD ==> LCD_CBL_DET# */ + PAD_CFG_GPO(GPP_D14, 1, DEEP), + /* D17 : NC ==> UART1_ISH_RDX */ + PAD_CFG_NF(GPP_D17, NONE, DEEP, NF2), + /* D18 : LCD_CBL_DET# ==> UART1_ISH_TDX */ + PAD_CFG_NF(GPP_D18, NONE, DEEP, NF2), +}; + +static const struct pad_config ish_uart1_disable_pads[] = { + /* A16 : ISH_GP5 ==> NC */ + PAD_NC_LOCK(GPP_A16, NONE, LOCK_CONFIG), + /* B5 : GPP_B5 ==> NC */ + PAD_NC(GPP_B5, NONE), + /* B6 : GPP_B6 ==> NC */ + PAD_NC(GPP_B6, NONE), + /* D1 : ISH_GP1 ==> NC */ + PAD_NC(GPP_D1, NONE), + /* D17 : UART1_ISH_RDX ==> NC */ + PAD_NC(GPP_D17, NONE), + /* D18 : UART1_ISH_TDX ==> NC*/ + PAD_NC(GPP_D18, NONE), /* E9 : SOC_ACC2_INT ==> NC */ PAD_NC_LOCK(GPP_E9, NONE, LOCK_CONFIG), }; void fw_config_gpio_padbased_override(struct pad_config *padbased_table) { + uint32_t board_version = board_id(); + if (fw_config_probe(FW_CONFIG(TOUCHSCREEN, TOUCHSCREEN_NONE))) { printk(BIOS_INFO, "Disable touchscreen GPIO pins.\n"); gpio_padbased_override(padbased_table, touchscreen_disable_pads, @@ -65,10 +100,24 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table) gpio_padbased_override(padbased_table, lte_disable_pads, ARRAY_SIZE(lte_disable_pads)); } - if (!fw_config_probe(FW_CONFIG(ISH, ISH_ENABLE))) { - printk(BIOS_INFO, "Disable ISH GPIO pins.\n"); - gpio_padbased_override(padbased_table, ish_disable_pads, - ARRAY_SIZE(ish_disable_pads)); + + /* b/415605630: Support different ISH UART mappings according the board id */ + if (board_version < 2) { + /* Override ISH UART0 to ISH UART1 */ + gpio_padbased_override(padbased_table, switch_ish_uart1_pads, + ARRAY_SIZE(switch_ish_uart1_pads)); + + if (!fw_config_probe(FW_CONFIG(ISH, ISH_ENABLE))) { + printk(BIOS_INFO, "Disable ISH GPIO pins is based on ISH UART1.\n"); + gpio_padbased_override(padbased_table, ish_uart1_disable_pads, + ARRAY_SIZE(ish_uart1_disable_pads)); + } + } else { + if (!fw_config_probe(FW_CONFIG(ISH, ISH_ENABLE))) { + printk(BIOS_INFO, "Disable ISH GPIO pins is based on ISH UART0.\n"); + gpio_padbased_override(padbased_table, ish_uart0_disable_pads, + ARRAY_SIZE(ish_uart0_disable_pads)); + } } } @@ -122,3 +171,17 @@ void variant_update_descriptor(void) configure_descriptor(fivr_bytes, ARRAY_SIZE(fivr_bytes)); } } + +void variant_configure_pads(void) +{ + const struct pad_config *base_pads; + struct pad_config *padbased_table; + size_t base_num; + + padbased_table = new_padbased_table(); + base_pads = variant_gpio_table(&base_num); + gpio_padbased_override(padbased_table, base_pads, base_num); + fw_config_gpio_padbased_override(padbased_table); + gpio_configure_pads_with_padbased(padbased_table); + free(padbased_table); +} diff --git a/src/mainboard/google/drallion/Kconfig b/src/mainboard/google/drallion/Kconfig index 484fd027cadf..cd14d2c10e54 100644 --- a/src/mainboard/google/drallion/Kconfig +++ b/src/mainboard/google/drallion/Kconfig @@ -22,6 +22,7 @@ config BOARD_GOOGLE_BASEBOARD_DRALLION select MAINBOARD_USES_IFD_EC_REGION select SMBIOS_SERIAL_FROM_VPD if VPD select SOC_INTEL_COMETLAKE_1 + select SOC_INTEL_COMMON_BLOCK_DTT_STATIC_ASL select SOC_INTEL_COMMON_BLOCK_HDA_VERB select SOC_INTEL_COMMON_BLOCK_SMM_ESPI_DISABLE select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb index 565aad6f98a5..858205902d6a 100644 --- a/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/fatcat/overridetree.cb @@ -128,6 +128,7 @@ chip soc/intel/pantherlake #| I2C5 | Touchpad | #+-------------------+---------------------------+ register "common_soc_config" = "{ + .logo_valignment = FW_SPLASH_VALIGNMENT_MIDDLE, .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, .i2c[1] = { .speed = I2C_SPEED_FAST, diff --git a/src/mainboard/google/fatcat/variants/felino/overridetree.cb b/src/mainboard/google/fatcat/variants/felino/overridetree.cb index ff7d07a2c2d5..979583d67f96 100644 --- a/src/mainboard/google/fatcat/variants/felino/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/felino/overridetree.cb @@ -102,6 +102,7 @@ chip soc/intel/pantherlake #| I2C4 | CLICK PAD | #+-------------------+---------------------------+ register "common_soc_config" = "{ + .logo_valignment = FW_SPLASH_VALIGNMENT_MIDDLE, .i2c[1] = { .early_init=1, .speed = I2C_SPEED_FAST, diff --git a/src/mainboard/google/fatcat/variants/francka/overridetree.cb b/src/mainboard/google/fatcat/variants/francka/overridetree.cb index b44cdc629168..d11ff4ab622e 100644 --- a/src/mainboard/google/fatcat/variants/francka/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/francka/overridetree.cb @@ -78,6 +78,7 @@ chip soc/intel/pantherlake #| I2C4 | Touchscreen, Touchpad | #+-------------------+---------------------------+ register "common_soc_config" = "{ + .logo_valignment = FW_SPLASH_VALIGNMENT_MIDDLE, .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, .i2c[1] = { .early_init = 1, @@ -206,7 +207,7 @@ chip soc/intel/pantherlake register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_E01_IRQ)" register "generic.detect" = "1" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B08)" - register "generic.reset_delay_ms" = "200" + register "generic.reset_delay_ms" = "10" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_B18)" register "generic.enable_delay_ms" = "12" register "generic.has_power_resource" = "1" diff --git a/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb b/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb index bfd637ae5086..b012da987288 100644 --- a/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb +++ b/src/mainboard/google/fatcat/variants/kinmen/overridetree.cb @@ -1,4 +1,7 @@ chip soc/intel/pantherlake + register "common_soc_config" = "{ + .logo_valignment = FW_SPLASH_VALIGNMENT_MIDDLE, + }" device domain 0 on end diff --git a/src/mainboard/google/fizz/Kconfig b/src/mainboard/google/fizz/Kconfig index 84a514566ee4..635170cc4cfd 100644 --- a/src/mainboard/google/fizz/Kconfig +++ b/src/mainboard/google/fizz/Kconfig @@ -4,6 +4,7 @@ config BOARD_GOOGLE_BASEBOARD_FIZZ def_bool n select BOARD_ROMSIZE_KB_16384 select DRIVERS_I2C_GENERIC + select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select DRIVERS_SPI_ACPI select DRIVERS_USB_ACPI select EC_GOOGLE_CHROMEEC diff --git a/src/mainboard/google/fizz/Makefile.mk b/src/mainboard/google/fizz/Makefile.mk index 6c20356bb67e..a99eb95ec14a 100644 --- a/src/mainboard/google/fizz/Makefile.mk +++ b/src/mainboard/google/fizz/Makefile.mk @@ -7,6 +7,7 @@ verstage-$(CONFIG_CHROMEOS) += chromeos.c romstage-$(CONFIG_CHROMEOS) += chromeos.c +ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC) += ec.c ramstage-y += mainboard.c diff --git a/src/mainboard/google/fizz/cfr.c b/src/mainboard/google/fizz/cfr.c new file mode 100644 index 000000000000..c775136d54c3 --- /dev/null +++ b/src/mainboard/google/fizz/cfr.c @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boot/coreboot_tables.h> +#include <drivers/option/cfr_frontend.h> +#include <intelblocks/cfr.h> +#include <soc/cfr.h> + +static struct sm_obj_form system = { + .ui_name = "System", + .obj_list = (const struct sm_object *[]) { + &hyper_threading, + &igd_dvmt, + &igd_aperture, + &legacy_8254_timer, + &me_state, + &me_state_counter, + &pciexp_aspm, + &pciexp_clk_pm, + &pciexp_l1ss, + &pciexp_speed, + &s0ix_enable, + &vtd, + NULL + }, +}; + +static struct sm_obj_form power = { + .ui_name = "Power", + .obj_list = (const struct sm_object *[]) { + &power_on_after_fail, + NULL + }, +}; + +static struct sm_obj_form *sm_root[] = { + &system, + &power, + NULL +}; + +void mb_cfr_setup_menu(struct lb_cfr *cfr_root) +{ + cfr_write_setup_menu(cfr_root, sm_root); +} diff --git a/src/mainboard/google/hatch/Kconfig b/src/mainboard/google/hatch/Kconfig index 82a632692abe..850234153f98 100644 --- a/src/mainboard/google/hatch/Kconfig +++ b/src/mainboard/google/hatch/Kconfig @@ -26,6 +26,7 @@ config BOARD_GOOGLE_BASEBOARD_HATCH select MAINBOARD_HAS_TPM2 select MB_HAS_ACTIVE_HIGH_SD_PWR_ENABLE select SOC_INTEL_COMETLAKE_1 + select SOC_INTEL_COMMON_BLOCK_DTT_STATIC_ASL select SPI_TPM select SYSTEM_TYPE_LAPTOP select TPM_GOOGLE_CR50 diff --git a/src/mainboard/google/jecht/Kconfig b/src/mainboard/google/jecht/Kconfig index eb3b985e5ad1..9122e8750f85 100644 --- a/src/mainboard/google/jecht/Kconfig +++ b/src/mainboard/google/jecht/Kconfig @@ -3,6 +3,7 @@ config BOARD_GOOGLE_BASEBOARD_JECHT def_bool n select BOARD_ROMSIZE_KB_8192 + select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select HAVE_OPTION_TABLE diff --git a/src/mainboard/google/jecht/Makefile.mk b/src/mainboard/google/jecht/Makefile.mk index ed74d751095a..66ffb865552d 100644 --- a/src/mainboard/google/jecht/Makefile.mk +++ b/src/mainboard/google/jecht/Makefile.mk @@ -1,23 +1,22 @@ ## SPDX-License-Identifier: GPL-2.0-only -subdirs-y += spd +bootblock-y += bootblock.c +bootblock-y += led.c + romstage-$(CONFIG_CHROMEOS) += chromeos.c +romstage-y += variants/$(VARIANT_DIR)/gpio.c +romstage-y += variants/$(VARIANT_DIR)/pei_data.c + +ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c -verstage-$(CONFIG_CHROMEOS) += chromeos.c +ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads ramstage-y += lan.c - -smm-y += led.c - -romstage-y += variants/$(VARIANT_DIR)/pei_data.c ramstage-y += variants/$(VARIANT_DIR)/pei_data.c -bootblock-y += led.c - -bootblock-y += bootblock.c +verstage-$(CONFIG_CHROMEOS) += chromeos.c -ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads +smm-y += led.c +subdirs-y += spd subdirs-y += variants/$(VARIANT_DIR) CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include - -romstage-y += variants/$(VARIANT_DIR)/gpio.c diff --git a/src/mainboard/google/jecht/cfr.c b/src/mainboard/google/jecht/cfr.c new file mode 100644 index 000000000000..9f4d19088e7a --- /dev/null +++ b/src/mainboard/google/jecht/cfr.c @@ -0,0 +1,33 @@ + +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boot/coreboot_tables.h> +#include <drivers/option/cfr_frontend.h> +#include <soc/cfr.h> + +static struct sm_obj_form system = { + .ui_name = "System", + .obj_list = (const struct sm_object *[]) { + &me_disable, + NULL + }, +}; + +static struct sm_obj_form power = { + .ui_name = "Power", + .obj_list = (const struct sm_object *[]) { + &power_on_after_fail, + NULL + }, +}; + +static struct sm_obj_form *sm_root[] = { + &system, + &power, + NULL +}; + +void mb_cfr_setup_menu(struct lb_cfr *cfr_root) +{ + cfr_write_setup_menu(cfr_root, sm_root); +} diff --git a/src/mainboard/google/puff/Kconfig b/src/mainboard/google/puff/Kconfig index d5786a5e62a9..c35cf6b1882f 100644 --- a/src/mainboard/google/puff/Kconfig +++ b/src/mainboard/google/puff/Kconfig @@ -11,6 +11,7 @@ config BOARD_GOOGLE_BASEBOARD_PUFF select DRIVERS_I2C_HID select DRIVERS_I2C_SX9310 select DRIVERS_INTEL_DPTF + select DRIVERS_OPTION_CFR_ENABLED if PAYLOAD_EDK2 && SMMSTORE select DRIVERS_SPI_ACPI select DRIVERS_USB_ACPI select EC_GOOGLE_CHROMEEC diff --git a/src/mainboard/google/puff/Makefile.mk b/src/mainboard/google/puff/Makefile.mk index b26f1d20e563..bbe2f38e1834 100644 --- a/src/mainboard/google/puff/Makefile.mk +++ b/src/mainboard/google/puff/Makefile.mk @@ -6,6 +6,7 @@ bootblock-$(CONFIG_CHROMEOS) += chromeos.c ramstage-y += ramstage.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC) += ec.c +ramstage-$(CONFIG_DRIVERS_OPTION_CFR) += cfr.c romstage-y += romstage.c romstage-$(CONFIG_CHROMEOS) += chromeos.c diff --git a/src/mainboard/google/puff/cfr.c b/src/mainboard/google/puff/cfr.c new file mode 100644 index 000000000000..8a60ed7d5317 --- /dev/null +++ b/src/mainboard/google/puff/cfr.c @@ -0,0 +1,45 @@ + +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boot/coreboot_tables.h> +#include <drivers/option/cfr_frontend.h> +#include <intelblocks/cfr.h> +#include <soc/cfr.h> + +static struct sm_obj_form system = { + .ui_name = "System", + .obj_list = (const struct sm_object *[]) { + &hyper_threading, + &igd_dvmt, + &igd_aperture, + &legacy_8254_timer, + &me_state, + &me_state_counter, + &pciexp_aspm, + &pciexp_clk_pm, + &pciexp_l1ss, + &pciexp_speed, + &s0ix_enable, + &vtd, + NULL + }, +}; + +static struct sm_obj_form power = { + .ui_name = "Power", + .obj_list = (const struct sm_object *[]) { + &power_on_after_fail, + NULL + }, +}; + +static struct sm_obj_form *sm_root[] = { + &system, + &power, + NULL +}; + +void mb_cfr_setup_menu(struct lb_cfr *cfr_root) +{ + cfr_write_setup_menu(cfr_root, sm_root); +} diff --git a/src/mainboard/google/rex/variants/screebo/memory/Makefile.mk b/src/mainboard/google/rex/variants/screebo/memory/Makefile.mk index d633b43bef5e..d0dfec1db097 100644 --- a/src/mainboard/google/rex/variants/screebo/memory/Makefile.mk +++ b/src/mainboard/google/rex/variants/screebo/memory/Makefile.mk @@ -9,3 +9,4 @@ SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 1(0b0001) Parts = MT62F1G32D SPD_SOURCES += spd/lp5/set-0/spd-8.hex # ID = 2(0b0010) Parts = K3KL9L90CM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-9.hex # ID = 3(0b0011) Parts = K3KL6L60GM-MGCT SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 4(0b0100) Parts = K3KL8L80EM-MGCU +SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 5(0b0101) Parts = K3KL9L90EM-MGCU diff --git a/src/mainboard/google/rex/variants/screebo/memory/dram_id.generated.txt b/src/mainboard/google/rex/variants/screebo/memory/dram_id.generated.txt index a7e4fe684f12..6498a2b97e58 100644 --- a/src/mainboard/google/rex/variants/screebo/memory/dram_id.generated.txt +++ b/src/mainboard/google/rex/variants/screebo/memory/dram_id.generated.txt @@ -12,3 +12,4 @@ K3KL9L90CM-MGCT 2 (0010) K3KL6L60GM-MGCT 3 (0011) K3KL8L80CM-MGCT 1 (0001) K3KL8L80EM-MGCU 4 (0100) +K3KL9L90EM-MGCU 5 (0101) diff --git a/src/mainboard/google/rex/variants/screebo/memory/mem_parts_used.txt b/src/mainboard/google/rex/variants/screebo/memory/mem_parts_used.txt index 7d8cfba3d14c..76e077f98c5c 100644 --- a/src/mainboard/google/rex/variants/screebo/memory/mem_parts_used.txt +++ b/src/mainboard/google/rex/variants/screebo/memory/mem_parts_used.txt @@ -17,3 +17,4 @@ K3KL9L90CM-MGCT K3KL6L60GM-MGCT K3KL8L80CM-MGCT K3KL8L80EM-MGCU +K3KL9L90EM-MGCU diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index 5f678aa4befc..666fb8f7f070 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -20,6 +20,7 @@ config BOARD_GOOGLE_BASEBOARD_SARIEN select MAINBOARD_HAS_TPM2 select MAINBOARD_USES_IFD_EC_REGION select SMBIOS_SERIAL_FROM_VPD if VPD + select SOC_INTEL_COMMON_BLOCK_DTT_STATIC_ASL select SOC_INTEL_COMMON_BLOCK_HDA_VERB select SOC_INTEL_COMMON_BLOCK_SMM_ESPI_DISABLE select SOC_INTEL_WHISKEYLAKE diff --git a/src/mainboard/google/skywalker/Kconfig b/src/mainboard/google/skywalker/Kconfig index fcf37dda1404..cf9c69f9b5b8 100644 --- a/src/mainboard/google/skywalker/Kconfig +++ b/src/mainboard/google/skywalker/Kconfig @@ -3,7 +3,8 @@ # Umbrella option to be selected by variant boards. config BOARD_GOOGLE_SKYWALKER_COMMON def_bool BOARD_GOOGLE_OBIWAN || \ - BOARD_GOOGLE_SKYWALKER + BOARD_GOOGLE_SKYWALKER || \ + BOARD_GOOGLE_YODA if BOARD_GOOGLE_SKYWALKER_COMMON @@ -29,6 +30,7 @@ config MAINBOARD_PART_NUMBER string default "Obiwan" if BOARD_GOOGLE_OBIWAN default "Skywalker" if BOARD_GOOGLE_SKYWALKER + default "Yoda" if BOARD_GOOGLE_YODA config BOOT_DEVICE_SPI_FLASH_BUS int diff --git a/src/mainboard/google/skywalker/Kconfig.name b/src/mainboard/google/skywalker/Kconfig.name index eb0e7c0c9ede..1bef303a1204 100644 --- a/src/mainboard/google/skywalker/Kconfig.name +++ b/src/mainboard/google/skywalker/Kconfig.name @@ -7,3 +7,6 @@ config BOARD_GOOGLE_OBIWAN config BOARD_GOOGLE_SKYWALKER bool "-> Skywalker" + +config BOARD_GOOGLE_YODA + bool "-> Yoda" diff --git a/src/mainboard/google/volteer/variants/elemi/ramstage.c b/src/mainboard/google/volteer/variants/elemi/ramstage.c index f7a174d88865..16261b7d45d7 100644 --- a/src/mainboard/google/volteer/variants/elemi/ramstage.c +++ b/src/mainboard/google/volteer/variants/elemi/ramstage.c @@ -3,17 +3,31 @@ #include <delay.h> #include <gpio.h> #include <baseboard/variants.h> +#include <ec/google/chromeec/ec.h> void variant_ramstage_init(void) { - /* - * Assert FPMCU reset and enable power to FPMCU, - * wait for power rail to stabilize, - * and then deassert FPMCU reset. - * Waiting for the power rail to stabilize can take a while. - */ - gpio_output(GPP_C23, 0); - gpio_output(GPP_A21, 1); - mdelay(1); - gpio_output(GPP_C23, 1); + uint32_t sku_id = google_chromeec_get_board_sku(); + + switch (sku_id) { + case 102: + case 104: + case 107: + case 109: + case 115: + /* + * Assert FPMCU reset and enable power to FPMCU, + * wait for power rail to stabilize, + * and then deassert FPMCU reset. + * Waiting for the power rail to stabilize can take a while. + */ + gpio_output(GPP_C23, 0); + gpio_output(GPP_A21, 1); + mdelay(1); + gpio_output(GPP_C23, 1); + break; + default: + /* SKU does not have FP Sensor, do not enable FPMCU */ + break; + } } diff --git a/src/mainboard/intel/coffeelake_rvp/variants/baseboard/devicetree.cb b/src/mainboard/intel/coffeelake_rvp/variants/baseboard/devicetree.cb index 16c68cd1a3c0..476e4f78dba1 100644 --- a/src/mainboard/intel/coffeelake_rvp/variants/baseboard/devicetree.cb +++ b/src/mainboard/intel/coffeelake_rvp/variants/baseboard/devicetree.cb @@ -43,33 +43,18 @@ chip soc/intel/cannonlake register "s0ix_enable" = "false" device domain 0 on - device pci 00.0 on end # Host Bridge - device pci 02.0 on end # Integrated Graphics Device - device pci 04.0 on end # SA Thermal device - device pci 12.0 on end # Thermal Subsystem - device pci 12.5 off end # UFS SCS - device pci 12.6 off end # GSPI #2 - device pci 14.0 on end # USB xHCI - device pci 14.1 off end # USB xDCI (OTG) - device pci 14.5 on end # SDCard - device pci 16.0 on end # Management Engine Interface 1 - device pci 16.1 off end # Management Engine Interface 2 - device pci 16.2 off end # Management Engine IDE-R - device pci 16.3 off end # Management Engine KT Redirection - device pci 16.4 off end # Management Engine Interface 3 - device pci 16.5 off end # Management Engine Interface 4 - device pci 1e.0 on end # UART #0 - device pci 1e.2 off end # GSPI #0 - device pci 1e.3 off end # GSPI #1 - device pci 1f.0 on + device ref igpu on end + device ref dptf on end + device ref thermal on end + device ref xhci on end + device ref sdxc on end + device ref uart0 on end + device ref lpc_espi on chip drivers/pc80/tpm device pnp 0c31.0 on end end - end # LPC Interface - device pci 1f.1 on end # P2SB - device pci 1f.2 hidden end # Power Management Controller - device pci 1f.3 on end # Intel HDA - device pci 1f.4 on end # SMBus - device pci 1f.5 on end # PCH SPI + end + device ref hda on end + device ref smbus on end end end diff --git a/src/mainboard/intel/coffeelake_rvp/variants/cfl_h/overridetree.cb b/src/mainboard/intel/coffeelake_rvp/variants/cfl_h/overridetree.cb index a10d271610d5..d36f9e22a412 100644 --- a/src/mainboard/intel/coffeelake_rvp/variants/cfl_h/overridetree.cb +++ b/src/mainboard/intel/coffeelake_rvp/variants/cfl_h/overridetree.cb @@ -61,15 +61,11 @@ chip soc/intel/cannonlake register "PcieClkSrcClkReq[9]" = "9" device domain 0 on - device pci 15.0 on end # I2C #0 - device pci 15.1 on end # I2C #1 - device pci 15.2 off end # I2C #2 - device pci 15.3 off end # I2C #3 - device pci 17.0 on end # SATA - device pci 19.0 off end # I2C #4 (Not available on PCH-H) - device pci 19.1 off end # I2C #5 (Not available on PCH-H) - device pci 19.2 on end # UART #2 - device pci 1a.0 on end # eMMC + device ref i2c0 on end + device ref i2c1 on end + device ref sata on end + device ref uart2 on end + device ref emmc on end device ref pcie_rp1 on # x4 SLOT1 register "PcieRpSlotImplemented[0]" = "1" end @@ -79,9 +75,6 @@ chip soc/intel/cannonlake device ref pcie_rp9 on register "PcieRpSlotImplemented[8]" = "1" end - device pci 1e.1 off end # UART #1 - device pci 1e.2 off end # GSPI #0 - device pci 1e.3 off end # GSPI #1 - device pci 1f.6 on end # GbE + device ref gbe on end end end diff --git a/src/mainboard/intel/coffeelake_rvp/variants/cfl_s/overridetree.cb b/src/mainboard/intel/coffeelake_rvp/variants/cfl_s/overridetree.cb index c8c443486fc7..607eb6a37155 100644 --- a/src/mainboard/intel/coffeelake_rvp/variants/cfl_s/overridetree.cb +++ b/src/mainboard/intel/coffeelake_rvp/variants/cfl_s/overridetree.cb @@ -63,21 +63,19 @@ chip soc/intel/cannonlake register "PcieClkSrcClkReq[10]" = "10" device domain 0 on - device pci 14.3 on + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "PME_B0_EN_BIT" device generic 0 on end end - end # CNVi wifi - device pci 15.0 on end # I2C #0 - device pci 15.1 on end # I2C #1 - device pci 15.2 on end # I2C #2 - device pci 15.3 on end # I2C #3 - device pci 17.0 on end # SATA - device pci 19.0 off end # I2C #4 (Not available on PCH-H) - device pci 19.1 off end # I2C #5 (Not available on PCH-H) - device pci 19.2 on end # UART #2 - device pci 1a.0 on end # eMMC + end + device ref i2c0 on end + device ref i2c1 on end + device ref i2c2 on end + device ref i2c3 on end + device ref sata on end + device ref uart2 on end + device ref emmc on end device ref pcie_rp1 on register "PcieRpSlotImplemented[0]" = "1" end @@ -102,7 +100,6 @@ chip soc/intel/cannonlake device ref pcie_rp21 on # x4 SLOT 2 register "PcieRpSlotImplemented[20]" = "1" end - device pci 1e.1 off end # UART #1 - device pci 1f.6 on end # GbE + device ref gbe on end end end diff --git a/src/mainboard/intel/coffeelake_rvp/variants/cfl_u/overridetree.cb b/src/mainboard/intel/coffeelake_rvp/variants/cfl_u/overridetree.cb index 25d084ac163b..908632093c3e 100644 --- a/src/mainboard/intel/coffeelake_rvp/variants/cfl_u/overridetree.cb +++ b/src/mainboard/intel/coffeelake_rvp/variants/cfl_u/overridetree.cb @@ -38,16 +38,15 @@ chip soc/intel/cannonlake }" device domain 0 on - device pci 14.3 on + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "PME_B0_EN_BIT" device generic 0 on end end - end # CNVi wifi - device pci 15.0 on end # I2C #0 - device pci 15.1 on end # I2C #1 - device pci 15.2 off end # I2C #2 - device pci 15.3 on + end + device ref i2c0 on end + device ref i2c1 on end + device ref i2c3 on chip drivers/i2c/max98373 register "interleave_mode" = "1" register "vmon_slot_no" = "4" @@ -57,12 +56,10 @@ chip soc/intel/cannonlake register "name" = ""MAXR"" device i2c 32 on end end - end # I2C #3 - device pci 17.0 off end # SATA - device pci 19.0 on end # I2C #4 - device pci 19.1 off end # I2C #5 - device pci 19.2 on end # UART #2 - device pci 1a.0 on end # eMMC + end + device ref i2c4 on end + device ref uart2 on end + device ref emmc on end device ref pcie_rp1 on # x4 SLOT1 register "PcieRpSlotImplemented[0]" = "1" end @@ -72,9 +69,5 @@ chip soc/intel/cannonlake device ref pcie_rp9 on register "PcieRpSlotImplemented[8]" = "1" end - device pci 1e.1 off end # UART #1 - device pci 1e.2 off end # GSPI #0 - device pci 1e.3 off end # GSPI #1 - device pci 1f.6 off end # GbE end end diff --git a/src/mainboard/intel/coffeelake_rvp/variants/cml_u/overridetree.cb b/src/mainboard/intel/coffeelake_rvp/variants/cml_u/overridetree.cb index 1f3bf9074bce..a14e9910c1ff 100644 --- a/src/mainboard/intel/coffeelake_rvp/variants/cml_u/overridetree.cb +++ b/src/mainboard/intel/coffeelake_rvp/variants/cml_u/overridetree.cb @@ -59,22 +59,19 @@ chip soc/intel/cannonlake register "sdcard_cd_gpio" = "GPP_G5" device domain 0 on - device pci 14.3 on + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "PME_B0_EN_BIT" device generic 0 on end end - end # CNVi wifi - device pci 14.5 on end # SDCard - device pci 15.0 on end # I2C #0 - device pci 15.1 on end # I2C #1 - device pci 15.2 off end # I2C #2 - device pci 15.3 off end # I2C #3 - device pci 17.0 on end # SATA - device pci 19.0 on end # I2C #4 - device pci 19.1 off end # I2C #5 - device pci 19.2 on end # UART #2 - device pci 1a.0 on end # eMMC + end + device ref sdxc on end + device ref i2c0 on end + device ref i2c1 on end + device ref sata on end + device ref i2c4 on end + device ref uart2 on end + device ref emmc on end device ref pcie_rp1 on # x4 SLOT1 register "PcieRpSlotImplemented[0]" = "1" end @@ -84,7 +81,6 @@ chip soc/intel/cannonlake device ref pcie_rp9 on register "PcieRpSlotImplemented[8]" = "1" end - device pci 1e.1 off end # UART #1 - device pci 1f.6 on end # GbE + device ref gbe on end end end diff --git a/src/mainboard/intel/coffeelake_rvp/variants/whl_u/overridetree.cb b/src/mainboard/intel/coffeelake_rvp/variants/whl_u/overridetree.cb index 309082ed4d3b..ded8e72c2391 100644 --- a/src/mainboard/intel/coffeelake_rvp/variants/whl_u/overridetree.cb +++ b/src/mainboard/intel/coffeelake_rvp/variants/whl_u/overridetree.cb @@ -44,21 +44,18 @@ chip soc/intel/cannonlake register "sdcard_cd_gpio" = "GPP_G5" device domain 0 on - device pci 14.3 on + device ref cnvi_wifi on chip drivers/wifi/generic register "wake" = "PME_B0_EN_BIT" device generic 0 on end end - end # CNVi wifi - device pci 15.0 on end # I2C #0 - device pci 15.1 on end # I2C #1 - device pci 15.2 off end # I2C #2 - device pci 15.3 off end # I2C #3 - device pci 17.0 on end # SATA - device pci 19.0 on end # I2C #4 - device pci 19.1 off end # I2C #5 - device pci 19.2 on end # UART #2 - device pci 1a.0 on end # eMMC + end + device ref i2c0 on end + device ref i2c1 on end + device ref sata on end + device ref i2c4 on end + device ref uart2 on end + device ref emmc on end device ref pcie_rp1 on # x4 SLOT1 register "PcieRpSlotImplemented[0]" = "1" end @@ -68,7 +65,6 @@ chip soc/intel/cannonlake device ref pcie_rp9 on register "PcieRpSlotImplemented[8]" = "1" end - device pci 1e.1 off end # UART #1 - device pci 1f.6 on end # GbE + device ref gbe on end end end diff --git a/src/mainboard/intel/ptlrvp/mainboard.c b/src/mainboard/intel/ptlrvp/mainboard.c index e14c5ace797c..5b80d9d650af 100644 --- a/src/mainboard/intel/ptlrvp/mainboard.c +++ b/src/mainboard/intel/ptlrvp/mainboard.c @@ -28,12 +28,15 @@ void __weak variant_update_soc_chip_config(struct soc_intel_pantherlake_config * static void mainboard_init(void *chip_info) { struct pad_config *padbased_table; - const struct pad_config *base_pads; - size_t base_num; + const struct pad_config *base_pads, *variant_diff_pads; + size_t base_num, variant_diff_num; padbased_table = new_padbased_table(); base_pads = variant_gpio_table(&base_num); gpio_padbased_override(padbased_table, base_pads, base_num); + variant_diff_pads = variant_board_gpio_diff_table(&variant_diff_num); + if (variant_diff_pads) + gpio_padbased_override(padbased_table, variant_diff_pads, variant_diff_num); fw_config_gpio_padbased_override(padbased_table); gpio_configure_pads_with_padbased(padbased_table); free(padbased_table); diff --git a/src/mainboard/intel/ptlrvp/variants/baseboard/include/baseboard/variants.h b/src/mainboard/intel/ptlrvp/variants/baseboard/include/baseboard/variants.h index 0ee09a5835ba..05ddf5bb5f27 100644 --- a/src/mainboard/intel/ptlrvp/variants/baseboard/include/baseboard/variants.h +++ b/src/mainboard/intel/ptlrvp/variants/baseboard/include/baseboard/variants.h @@ -23,6 +23,7 @@ enum ptl_boardid { */ const struct pad_config *variant_gpio_table(size_t *num); +const struct pad_config *variant_board_gpio_diff_table(size_t *num); const struct pad_config *variant_early_gpio_table(size_t *num); const struct pad_config *variant_romstage_gpio_table(size_t *num); void fw_config_configure_pre_mem_gpio(void); diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/Makefile.mk b/src/mainboard/intel/ptlrvp/variants/ptlrvp/Makefile.mk index b9f1fd15dd42..598167cbe49d 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/Makefile.mk +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/Makefile.mk @@ -7,3 +7,4 @@ romstage-$(CONFIG_FW_CONFIG) += fw_config.c ramstage-y += gpio.c romstage-$(CONFIG_FW_CONFIG) += variant.c ramstage-$(CONFIG_FW_CONFIG) += fw_config.c +ramstage-$(CONFIG_FW_CONFIG) += variant.c diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/gpio.c b/src/mainboard/intel/ptlrvp/variants/ptlrvp/gpio.c index 9531065689c7..7b4dbe3c9f6b 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/gpio.c +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/gpio.c @@ -3,10 +3,11 @@ #include <baseboard/gpio.h> #include <baseboard/variants.h> #include <boardid.h> +#include <ec/intel/board_id.h> #include <soc/gpio.h> /* Pad configuration in ramstage*/ -static const struct pad_config gpio_table[] = { +static const struct pad_config t3_gpio_table[] = { /* GPP_A00: ESPI_IO0_EC_R */ /* GPP_A00 : GPP_A00 ==> ESPI_IO0_EC_R configured on reset, do not touch */ @@ -391,10 +392,48 @@ static const struct pad_config romstage_gpio_table[] = { PAD_CFG_NF(GPP_C01, NONE, DEEP, NF1), }; +/* Pad difference in ramstage for LP5 T4 RVP */ +static const struct pad_config t4_gpio_diff_table[] = { + /* GPP_B09: MOD_TCSS2_DISP_HPD1 */ + PAD_CFG_NF(GPP_B09, NONE, DEEP, NF2), + /* GPP_B10: MOD_TCSS1_DISP_HPD2 */ + PAD_CFG_NF(GPP_B10, NONE, DEEP, NF2), + /* GPP_B11: GEN4_SSD_PWREN */ + PAD_CFG_GPO(GPP_B11, 1, PLTRST), + + /* GPP_B14: Not used */ + PAD_NC(GPP_B14, NONE), + + /* GPP_B17: MOD_TCSS2_LSX_DIR_SEL_EDP_VDD_EN */ + PAD_CFG_NF(GPP_B17, NONE, DEEP, NF2), + + /* GPP_C06: X4_PCIE_SLOT_PWR_EN_N */ + PAD_CFG_GPO(GPP_C06, 0, DEEP), + /* GPP_C07: X4_DT_PCIE_RST_N */ + PAD_CFG_GPO(GPP_C07, 1, DEEP), + + /* GPP_D01: MOD_TCSS2_TYP_A_VBUS_EN_EDP_BKLT_EN */ + PAD_CFG_NF(GPP_D01, NONE, DEEP, NF2), + /* GPP_D02: MOD_TCSS2_EDP_BKLT_CTRL */ + PAD_CFG_NF(GPP_D02, NONE, DEEP, NF2), + + /* GPP_D20: CLKREQ7_X4_GEN5_DT_CEM_SLOT_N */ + PAD_CFG_NF(GPP_D20, NONE, DEEP, NF1), + + /* GPP_E08: M2_GEN4_SSD_RESET_N */ + PAD_CFG_GPO(GPP_E08, 1, PLTRST), + + /* GPP_F23: SMC_LID */ + PAD_CFG_GPI_TRIG_OWN(GPP_F23, NONE, DEEP, LEVEL, ACPI), + + /* GPP_V17: TCP_RT_S0IX_ENTRY_EXIT_N */ + PAD_CFG_GPO(GPP_V17, 1, PLTRST), +}; + const struct pad_config *variant_gpio_table(size_t *num) { - *num = ARRAY_SIZE(gpio_table); - return gpio_table; + *num = ARRAY_SIZE(t3_gpio_table); + return t3_gpio_table; } const struct pad_config *variant_early_gpio_table(size_t *num) @@ -410,6 +449,24 @@ const struct pad_config *variant_romstage_gpio_table(size_t *num) return romstage_gpio_table; } +const struct pad_config *variant_board_gpio_diff_table(size_t *num) +{ + int board_id = get_rvp_board_id(); + + switch (board_id) { + case PTLP_LP5_T3_RVP: + return NULL; + case PTLP_LP5_T4_RVP: + *num = ARRAY_SIZE(t4_gpio_diff_table); + return t4_gpio_diff_table; + case GCS_32GB: + case GCS_64GB: + return NULL; + default: + die("Unknown board ID = 0x%x\n", board_id); + } +} + static const struct cros_gpio cros_gpios[] = { CROS_GPIO_REC_AL(CROS_GPIO_VIRTUAL, CROS_GPIO_DEVICE0_NAME), CROS_GPIO_REC_AL(CROS_GPIO_VIRTUAL, CROS_GPIO_DEVICE1_NAME), diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory.c b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory.c index 6a1706fe9fe1..350405dc2920 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory.c +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory.c @@ -65,7 +65,7 @@ static const struct mb_cfg gcs_mem_config = { }, }; -static const struct mb_cfg lp5_mem_config = { +static const struct mb_cfg lp5_t3_mem_config = { .type = MEM_TYPE_LP5X, .lpx_dq_map = { @@ -125,6 +125,66 @@ static const struct mb_cfg lp5_mem_config = { }, }; +static const struct mb_cfg lp5_t4_mem_config = { + .type = MEM_TYPE_LP5X, + + .lpx_dq_map = { + .ddr0 = { + .dq0 = { 10, 8, 11, 9, 15, 12, 14, 13 }, + .dq1 = { 6, 7, 5, 4, 3, 1, 0, 2 }, + }, + .ddr1 = { + .dq0 = { 1, 0, 3, 2, 7, 6, 5, 4 }, + .dq1 = { 14, 13, 12, 15, 11, 9, 8, 10 }, + }, + .ddr2 = { + .dq0 = { 13, 14, 12, 15, 8, 10, 9, 11 }, + .dq1 = { 6, 7, 5, 4, 1, 3, 2, 0 }, + }, + .ddr3 = { + .dq0 = { 6, 5, 7, 4, 3, 2, 0, 1 }, + .dq1 = { 14, 13, 12, 15, 11, 9, 8, 10 }, + }, + .ddr4 = { + .dq0 = { 10, 8, 9, 11, 13, 12, 14, 15 }, + .dq1 = { 1, 3, 0, 2, 4, 7, 5, 6 }, + }, + .ddr5 = { + .dq0 = { 1, 0, 2, 3, 7, 6, 5, 4 }, + .dq1 = { 10, 8, 11, 9, 13, 12, 14, 15 }, + }, + .ddr6 = { + .dq0 = { 10, 8, 11, 9, 13, 12, 14, 15 }, + .dq1 = { 6, 5, 7, 4, 0, 1, 2, 3 }, + }, + .ddr7 = { + .dq0 = { 1, 0, 2, 3, 7, 4, 6, 5 }, + .dq1 = { 14, 13, 15, 12, 10, 11, 9, 8 }, + }, + }, + + .lpx_dqs_map = { + .ddr0 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr1 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr2 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr3 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr4 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr5 = { .dqs0 = 0, .dqs1 = 1 }, + .ddr6 = { .dqs0 = 1, .dqs1 = 0 }, + .ddr7 = { .dqs0 = 0, .dqs1 = 1 } + }, + + .ect = true, /* Early Command Training */ + + .lp_ddr_dq_dqs_re_training = 1, + + .user_bd = BOARD_TYPE_ULT_ULX, + + .lp5x_config = { + .ccc_config = 0xFF, + }, +}; + static const struct mb_cfg ddr5_mem_config = { .type = MEM_TYPE_DDR5, @@ -149,8 +209,9 @@ const struct mb_cfg *variant_memory_params(void) switch (board_id) { case PTLP_LP5_T3_RVP: + return &lp5_t3_mem_config; case PTLP_LP5_T4_RVP: - return &lp5_mem_config; + return &lp5_t4_mem_config; case GCS_32GB: case GCS_64GB: return &gcs_mem_config; diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/Makefile.mk b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/Makefile.mk index 1a93597f4e47..5575815d1b21 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/Makefile.mk +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/Makefile.mk @@ -6,3 +6,4 @@ SPD_SOURCES = SPD_SOURCES += spd/lp5/set-0/spd-7.hex # ID = 0(0b0000) Parts = H58G56BK7BX068 SPD_SOURCES += spd/lp5/set-0/spd-10.hex # ID = 1(0b0001) Parts = H58G66BK8BX067 +SPD_SOURCES += spd/lp5/set-0/spd-11.hex # ID = 2(0b0010) Parts = H58G56BK8BX068 diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/dram_id.generated.txt b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/dram_id.generated.txt index 7f7236d0eca2..244c063804ef 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/dram_id.generated.txt +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/dram_id.generated.txt @@ -6,3 +6,4 @@ DRAM Part Name ID to assign H58G56BK7BX068 0 (0000) H58G66BK8BX067 1 (0001) +H58G56BK8BX068 2 (0010) diff --git a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/mem_parts_used.txt b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/mem_parts_used.txt index 86a6e201d78f..98255ad4d3b3 100644 --- a/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/mem_parts_used.txt +++ b/src/mainboard/intel/ptlrvp/variants/ptlrvp/memory/mem_parts_used.txt @@ -11,3 +11,4 @@ # Part Name H58G56BK7BX068 H58G66BK8BX067 +H58G56BK8BX068 diff --git a/src/mainboard/lenovo/m900_tiny/data.vbt b/src/mainboard/lenovo/m900_tiny/data.vbt Binary files differindex 7e6fe3dc1399..4c26ae512bd8 100644 --- a/src/mainboard/lenovo/m900_tiny/data.vbt +++ b/src/mainboard/lenovo/m900_tiny/data.vbt diff --git a/src/mainboard/starlabs/byte_adl/cfr.c b/src/mainboard/starlabs/byte_adl/cfr.c index e360e3b41969..7dfacd6fa371 100644 --- a/src/mainboard/starlabs/byte_adl/cfr.c +++ b/src/mainboard/starlabs/byte_adl/cfr.c @@ -2,6 +2,7 @@ #include <boot/coreboot_tables.h> #include <commonlib/coreboot_tables.h> +#include <console/cfr.h> #include <drivers/option/cfr_frontend.h> #include <inttypes.h> #include <intelblocks/pcie_rp.h> @@ -9,35 +10,6 @@ #include <types.h> #include <variants.h> -static const struct sm_object boot_option = SM_DECLARE_ENUM({ - .opt_name = "boot_option", - .ui_name = "Boot Option", - .ui_helptext = "Change the boot device in the event of a failed boot", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Fallback", 0 }, - { "Normal", 1 }, - SM_ENUM_VALUE_END }, -}); - -static const struct sm_object debug_level = SM_DECLARE_ENUM({ - .opt_name = "debug_level", - .ui_name = "Debug Level", - .ui_helptext = "Set the verbosity of the debug output.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Emergency", 0 }, - { "Alert", 1 }, - { "Critical", 2 }, - { "Error", 3 }, - { "Warning", 4 }, - { "Notice", 5 }, - { "Info", 6 }, - { "Debug", 7 }, - { "Spew", 8 }, - SM_ENUM_VALUE_END }, -}); - static const struct sm_object gna = SM_DECLARE_BOOL({ .opt_name = "gna", .ui_name = "Gaussian & Neural Accelerator", @@ -122,13 +94,6 @@ static const struct sm_object pciexp_l1ss = SM_DECLARE_ENUM({ SM_ENUM_VALUE_END }, }); -static const struct sm_object reboot_counter = SM_DECLARE_NUMBER({ - .opt_name = "reboot_counter", - .ui_name = "Reboot Counter", - .flags = CFR_OPTFLAG_SUPPRESS, - .default_value = 0, -}); - static const struct sm_object vtd = SM_DECLARE_BOOL({ .opt_name = "vtd", .ui_name = "VT-d", @@ -192,9 +157,7 @@ static struct sm_obj_form pci = { static struct sm_obj_form coreboot = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { - &boot_option, &debug_level, - &reboot_counter, NULL }, }; diff --git a/src/mainboard/starlabs/lite/cfr.c b/src/mainboard/starlabs/lite/cfr.c index 251f55c33941..8cfedf822492 100644 --- a/src/mainboard/starlabs/lite/cfr.c +++ b/src/mainboard/starlabs/lite/cfr.c @@ -2,6 +2,7 @@ #include <boot/coreboot_tables.h> #include <commonlib/coreboot_tables.h> +#include <console/cfr.h> #include <drivers/option/cfr_frontend.h> #include <ec/starlabs/merlin/cfr.h> #include <inttypes.h> @@ -10,17 +11,6 @@ #include <types.h> #include <variants.h> -static const struct sm_object boot_option = SM_DECLARE_ENUM({ - .opt_name = "boot_option", - .ui_name = "Boot Option", - .ui_helptext = "Change the boot device in the event of a failed boot", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Fallback", 0 }, - { "Normal", 1 }, - SM_ENUM_VALUE_END }, -}); - static const struct sm_object card_reader = SM_DECLARE_BOOL({ .opt_name = "card_reader", .ui_name = "Card Reader", @@ -28,24 +18,6 @@ static const struct sm_object card_reader = SM_DECLARE_BOOL({ .default_value = true, }); -static const struct sm_object debug_level = SM_DECLARE_ENUM({ - .opt_name = "debug_level", - .ui_name = "Debug Level", - .ui_helptext = "Set the verbosity of the debug output.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Emergency", 0 }, - { "Alert", 1 }, - { "Critical", 2 }, - { "Error", 3 }, - { "Warning", 4 }, - { "Notice", 5 }, - { "Info", 6 }, - { "Debug", 7 }, - { "Spew", 8 }, - SM_ENUM_VALUE_END }, -}); - #if CONFIG(EC_STARLABS_FAST_CHARGE) static const struct sm_object fast_charge = SM_DECLARE_BOOL({ .opt_name = "fast_charge", @@ -81,13 +53,6 @@ static const struct sm_object microphone = SM_DECLARE_BOOL({ .default_value = true, }); -static const struct sm_object reboot_counter = SM_DECLARE_NUMBER({ - .opt_name = "reboot_counter", - .ui_name = "Reboot Counter", - .flags = CFR_OPTFLAG_SUPPRESS, - .default_value = 0, -}); - static const struct sm_object webcam = SM_DECLARE_BOOL({ .opt_name = "webcam", .ui_name = "Webcam", @@ -171,9 +136,7 @@ static struct sm_obj_form pci = { static struct sm_obj_form coreboot = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { - &boot_option, &debug_level, - &reboot_counter, NULL }, }; diff --git a/src/mainboard/starlabs/starbook/Kconfig b/src/mainboard/starlabs/starbook/Kconfig index be0ed131772b..a948e45c767c 100644 --- a/src/mainboard/starlabs/starbook/Kconfig +++ b/src/mainboard/starlabs/starbook/Kconfig @@ -116,6 +116,7 @@ config BOARD_STARLABS_STARBOOK_MTL select MAINBOARD_HAS_TPM2 select MEMORY_MAPPED_TPM select PMC_IPC_ACPI_INTERFACE + select SKIP_SEND_CONNECT_TOPOLOGY_CMD select SOC_INTEL_COMMON_BLOCK_VTD select SOC_INTEL_METEORLAKE select SOC_INTEL_METEORLAKE_U_H diff --git a/src/mainboard/starlabs/starbook/cfr.c b/src/mainboard/starlabs/starbook/cfr.c index 5acb1a2d8d87..de8ad2eeb06e 100644 --- a/src/mainboard/starlabs/starbook/cfr.c +++ b/src/mainboard/starlabs/starbook/cfr.c @@ -2,6 +2,7 @@ #include <boot/coreboot_tables.h> #include <commonlib/coreboot_tables.h> +#include <console/cfr.h> #include <drivers/option/cfr_frontend.h> #include <ec/starlabs/merlin/cfr.h> #include <inttypes.h> @@ -100,9 +101,7 @@ static struct sm_obj_form pci = { static struct sm_obj_form coreboot = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { - &boot_option, &debug_level, - &reboot_counter, NULL }, }; diff --git a/src/mainboard/starlabs/starbook/cfr.h b/src/mainboard/starlabs/starbook/cfr.h index 6270e7a50f6e..fe1a01e93cd6 100644 --- a/src/mainboard/starlabs/starbook/cfr.h +++ b/src/mainboard/starlabs/starbook/cfr.h @@ -8,17 +8,6 @@ #include <intelblocks/pcie_rp.h> #include <variants.h> -static const struct sm_object boot_option = SM_DECLARE_ENUM({ - .opt_name = "boot_option", - .ui_name = "Boot Option", - .ui_helptext = "Change the boot device in the event of a failed boot", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Fallback", 0 }, - { "Normal", 1 }, - SM_ENUM_VALUE_END }, -}); - static const struct sm_object card_reader = SM_DECLARE_BOOL({ .opt_name = "card_reader", .ui_name = "Card Reader", @@ -26,24 +15,6 @@ static const struct sm_object card_reader = SM_DECLARE_BOOL({ .default_value = true, }); -static const struct sm_object debug_level = SM_DECLARE_ENUM({ - .opt_name = "debug_level", - .ui_name = "Debug Level", - .ui_helptext = "Set the verbosity of the debug output.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Emergency", 0 }, - { "Alert", 1 }, - { "Critical", 2 }, - { "Error", 3 }, - { "Warning", 4 }, - { "Notice", 5 }, - { "Info", 6 }, - { "Debug", 7 }, - { "Spew", 8 }, - SM_ENUM_VALUE_END }, -}); - static const struct sm_object fingerprint_reader = SM_DECLARE_BOOL({ .opt_name = "fingerprint_reader", .ui_name = "Fingerprint Reader", @@ -157,14 +128,6 @@ static const struct sm_object pciexp_l1ss = SM_DECLARE_ENUM({ SM_ENUM_VALUE_END }, }); -static const struct sm_object reboot_counter = SM_DECLARE_NUMBER({ - .opt_name = "reboot_counter", - .ui_name = "Reboot Counter", - .flags = CFR_OPTFLAG_SUPPRESS, - .default_value = 0, -}); - - static const struct sm_object thunderbolt = SM_DECLARE_BOOL({ .opt_name = "thunderbolt", .ui_name = "Thunderbolt", diff --git a/src/mainboard/starlabs/starbook/variants/mtl/devicetree.cb b/src/mainboard/starlabs/starbook/variants/mtl/devicetree.cb index b86e01bc1526..11b969fd2630 100644 --- a/src/mainboard/starlabs/starbook/variants/mtl/devicetree.cb +++ b/src/mainboard/starlabs/starbook/variants/mtl/devicetree.cb @@ -18,6 +18,12 @@ chip soc/intel/meteorlake [PchSerialIoIndexUART0] = PchSerialIoSkipInit, }" + # Power + register "pch_slp_s3_min_assertion_width" = "SLP_S3_ASSERTION_1_MS" + register "pch_slp_s4_min_assertion_width" = "SLP_S4_ASSERTION_3S" + register "pch_slp_sus_min_assertion_width" = "SLP_SUS_ASSERTION_1_S" + register "pch_slp_a_min_assertion_width" = "SLP_A_ASSERTION_98_MS" + # Device Tree device domain 0 on device ref igpu on diff --git a/src/mainboard/starlabs/starfighter/cfr.c b/src/mainboard/starlabs/starfighter/cfr.c index bbef3a7c265d..bb0c34b83fce 100644 --- a/src/mainboard/starlabs/starfighter/cfr.c +++ b/src/mainboard/starlabs/starfighter/cfr.c @@ -2,6 +2,7 @@ #include <boot/coreboot_tables.h> #include <commonlib/coreboot_tables.h> +#include <console/cfr.h> #include <drivers/option/cfr_frontend.h> #include <ec/starlabs/merlin/cfr.h> #include <inttypes.h> @@ -10,35 +11,6 @@ #include <types.h> #include <variants.h> -static const struct sm_object boot_option = SM_DECLARE_ENUM({ - .opt_name = "boot_option", - .ui_name = "Boot Option", - .ui_helptext = "Change the boot device in the event of a failed boot", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Fallback", 0 }, - { "Normal", 1 }, - SM_ENUM_VALUE_END }, -}); - -static const struct sm_object debug_level = SM_DECLARE_ENUM({ - .opt_name = "debug_level", - .ui_name = "Debug Level", - .ui_helptext = "Set the verbosity of the debug output.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Emergency", 0 }, - { "Alert", 1 }, - { "Critical", 2 }, - { "Error", 3 }, - { "Warning", 4 }, - { "Notice", 5 }, - { "Info", 6 }, - { "Debug", 7 }, - { "Spew", 8 }, - SM_ENUM_VALUE_END }, -}); - #if CONFIG(SOC_INTEL_TIGERLAKE) || CONFIG(SOC_INTEL_ALDERLAKE) || CONFIG(SOC_INTEL_RAPTORLAKE) static const struct sm_object gna = SM_DECLARE_BOOL({ .opt_name = "gna", @@ -134,13 +106,6 @@ static const struct sm_object pciexp_l1ss = SM_DECLARE_ENUM({ }); #endif -static const struct sm_object reboot_counter = SM_DECLARE_NUMBER({ - .opt_name = "reboot_counter", - .ui_name = "Reboot Counter", - .flags = CFR_OPTFLAG_SUPPRESS, - .default_value = 0, -}); - #if CONFIG(DRIVERS_INTEL_USB4_RETIMER) static const struct sm_object thunderbolt = SM_DECLARE_BOOL({ .opt_name = "thunderbolt", @@ -247,9 +212,7 @@ static struct sm_obj_form pci = { static struct sm_obj_form coreboot = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { - &boot_option, &debug_level, - &reboot_counter, NULL }, }; diff --git a/src/mainboard/starlabs/starlite_adl/cfr.c b/src/mainboard/starlabs/starlite_adl/cfr.c index cd58641e1a0d..e1c86cf17fe3 100644 --- a/src/mainboard/starlabs/starlite_adl/cfr.c +++ b/src/mainboard/starlabs/starlite_adl/cfr.c @@ -2,6 +2,7 @@ #include <boot/coreboot_tables.h> #include <commonlib/coreboot_tables.h> +#include <console/cfr.h> #include <drivers/option/cfr_frontend.h> #include <ec/starlabs/merlin/cfr.h> #include <inttypes.h> @@ -17,35 +18,6 @@ static const struct sm_object accelerometer = SM_DECLARE_BOOL({ .default_value = true, }); -static const struct sm_object boot_option = SM_DECLARE_ENUM({ - .opt_name = "boot_option", - .ui_name = "Boot Option", - .ui_helptext = "Change the boot device in the event of a failed boot", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Fallback", 0 }, - { "Normal", 1 }, - SM_ENUM_VALUE_END }, -}); - -static const struct sm_object debug_level = SM_DECLARE_ENUM({ - .opt_name = "debug_level", - .ui_name = "Debug Level", - .ui_helptext = "Set the verbosity of the debug output.", - .default_value = 0, - .values = (const struct sm_enum_value[]) { - { "Emergency", 0 }, - { "Alert", 1 }, - { "Critical", 2 }, - { "Error", 3 }, - { "Warning", 4 }, - { "Notice", 5 }, - { "Info", 6 }, - { "Debug", 7 }, - { "Spew", 8 }, - SM_ENUM_VALUE_END }, -}); - #if CONFIG(SOC_INTEL_TIGERLAKE) || CONFIG(SOC_INTEL_ALDERLAKE) || CONFIG(SOC_INTEL_RAPTORLAKE) static const struct sm_object gna = SM_DECLARE_BOOL({ .opt_name = "gna", @@ -154,13 +126,6 @@ static const struct sm_object pciexp_l1ss = SM_DECLARE_ENUM({ }); #endif -static const struct sm_object reboot_counter = SM_DECLARE_NUMBER({ - .opt_name = "reboot_counter", - .ui_name = "Reboot Counter", - .flags = CFR_OPTFLAG_SUPPRESS, - .default_value = 0, -}); - static const struct sm_object touchscreen = SM_DECLARE_BOOL({ .opt_name = "touchscreen", .ui_name = "Touchscreen", @@ -272,9 +237,7 @@ static struct sm_obj_form pci = { static struct sm_obj_form coreboot = { .ui_name = "coreboot", .obj_list = (const struct sm_object *[]) { - &boot_option, &debug_level, - &reboot_counter, NULL }, }; diff --git a/src/security/intel/stm/StmPlatformSmm.c b/src/security/intel/stm/StmPlatformSmm.c index 9c5ae5264e5b..99e62c77c032 100644 --- a/src/security/intel/stm/StmPlatformSmm.c +++ b/src/security/intel/stm/StmPlatformSmm.c @@ -4,6 +4,7 @@ #include <security/intel/stm/SmmStm.h> #include <security/intel/stm/StmPlatformResource.h> #include <security/tpm/tspi.h> +#include <cpu/x86/gdt.h> #include <cpu/x86/smm.h> #include <cpu/x86/msr.h> @@ -11,7 +12,6 @@ #include <console/console.h> #include <stdbool.h> #include <stdint.h> -#include <arch/rom_segs.h> /* * Load STM image to MSEG @@ -109,11 +109,11 @@ void setup_smm_descriptor(void *smbase, int32_t apic_id, int32_t entry32_off) psd->acpi_rsdp = 0; psd->bios_hw_resource_requirements_ptr = (uint64_t)((uintptr_t)get_stm_resource()); - psd->smm_cs = ROM_CODE_SEG; - psd->smm_ds = ROM_DATA_SEG; - psd->smm_ss = ROM_DATA_SEG; - psd->smm_other_segment = ROM_DATA_SEG; - psd->smm_tr = SMM_TASK_STATE_SEG; + psd->smm_cs = GDT_CODE_SEG; + psd->smm_ds = GDT_DATA_SEG; + psd->smm_ss = GDT_DATA_SEG; + psd->smm_other_segment = GDT_DATA_SEG; + psd->smm_tr = GDT_TASK_STATE_SEG; // At this point the coreboot smm_stub is relative to the default // smbase and not the one for the smi handler in tseg. So we have diff --git a/src/security/intel/txt/getsec_enteraccs.S b/src/security/intel/txt/getsec_enteraccs.S index ff9db05f0608..9c0f5319a3f7 100644 --- a/src/security/intel/txt/getsec_enteraccs.S +++ b/src/security/intel/txt/getsec_enteraccs.S @@ -3,7 +3,7 @@ #include <cpu/x86/mtrr.h> #include <cpu/x86/cr.h> #include <cpu/x86/msr.h> -#include <arch/ram_segs.h> +#include <cpu/x86/gdt.h> #include "getsec_mtrr_setup.inc" @@ -257,10 +257,10 @@ cond_clear_var_mtrrs: lgdt -48(%ebp) /* Set cs */ - ljmp $RAM_CODE_SEG, $1f + ljmp $GDT_CODE_SEG, $1f 1: /* Fix segment registers */ - movl $RAM_DATA_SEG, %eax + movl $GDT_DATA_SEG, %eax movl %eax, %ds movl %eax, %es movl %eax, %ss diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index 377d6dcb8879..c8eb446839f2 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -78,6 +78,17 @@ config TPM_MEASURED_BOOT help Enables measured boot (experimental) +config TPM_MEASURE_MRC_CACHE + bool "Measure MRC cache" + default n + depends on TPM_MEASURED_BOOT + depends on CACHE_MRC_SETTINGS + help + Measures MRC cache as runtime data to guarantee that a + tamper with the memory will be detected. The runtime data + measurement becomes stable after the second boot after + changing DIMM. + choice prompt "TPM event log format" depends on TPM_MEASURED_BOOT diff --git a/src/soc/amd/mendocino/fsp_s_params.c b/src/soc/amd/mendocino/fsp_s_params.c index 5393eba911f7..23b2cfe5ced3 100644 --- a/src/soc/amd/mendocino/fsp_s_params.c +++ b/src/soc/amd/mendocino/fsp_s_params.c @@ -59,7 +59,7 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) payload_preload(); } -void soc_load_logo(FSPS_UPD *supd) +void soc_load_logo_by_fsp(FSPS_UPD *supd) { size_t logo_size; supd->FspsConfig.logo_bmp_buffer = (uint32_t)(uintptr_t)bmp_load_logo(&logo_size); diff --git a/src/soc/intel/alderlake/Makefile.mk b/src/soc/intel/alderlake/Makefile.mk index 55fc83ea7c52..6262cf29993e 100644 --- a/src/soc/intel/alderlake/Makefile.mk +++ b/src/soc/intel/alderlake/Makefile.mk @@ -70,11 +70,6 @@ endif CPPFLAGS_common += -I$(src)/soc/intel/alderlake CPPFLAGS_common += -I$(src)/soc/intel/alderlake/include -# Include the missing MemInfoHob.h from vendorcode -ifeq ($(CONFIG_SOC_INTEL_RAPTORLAKE_PCH_S)$(CONFIG_FSP_TYPE_IOT),yy) -CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp2_0/iot/raptorlake_s -endif - ifeq ($(CONFIG_SOC_INTEL_ALDERLAKE_PCH_S),y) # 06-97-00, 06-97-01, 06-97-04 are ADL-S Engineering Samples # 06-97-02 are ADL-S/HX Quality Samples but also ADL-HX Engineering Samples diff --git a/src/soc/intel/alderlake/fsp_params.c b/src/soc/intel/alderlake/fsp_params.c index 380f40ba601d..a788319efc6f 100644 --- a/src/soc/intel/alderlake/fsp_params.c +++ b/src/soc/intel/alderlake/fsp_params.c @@ -1249,6 +1249,9 @@ static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg, /* Override settings per board if required. */ mainboard_update_soc_chip_config(config); + /* Runtime configuration of S0ix */ + config->s0ix_enable = get_uint_option("s0ix_enable", config->s0ix_enable); + void (*const fill_fsps_params[])(FSP_S_CONFIG *s_cfg, const struct soc_intel_alderlake_config *config) = { fill_fsps_lpss_params, @@ -1378,7 +1381,7 @@ __weak void mainboard_silicon_init_params(FSP_S_CONFIG *s_cfg) } /* Handle FSP logo params */ -void soc_load_logo(FSPS_UPD *supd) +void soc_load_logo_by_fsp(FSPS_UPD *supd) { struct soc_intel_common_config *config = chip_get_common_soc_structure(); FSP_S_CONFIG *s_cfg = &supd->FspsConfig; diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index ab5b5d884d0f..c5553780ea59 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -914,7 +914,7 @@ void mainboard_silicon_init_params(FSP_S_CONFIG *silconfig) } /* Handle FSP logo params */ -void soc_load_logo(FSPS_UPD *supd) +void soc_load_logo_by_fsp(FSPS_UPD *supd) { size_t logo_size; supd->FspsConfig.LogoPtr = (uint32_t)(uintptr_t)bmp_load_logo(&logo_size); diff --git a/src/soc/intel/cannonlake/fsp_params.c b/src/soc/intel/cannonlake/fsp_params.c index 993efbb10785..2e00018f369d 100644 --- a/src/soc/intel/cannonlake/fsp_params.c +++ b/src/soc/intel/cannonlake/fsp_params.c @@ -801,7 +801,7 @@ __weak void mainboard_silicon_init_params(FSPS_UPD *supd) } /* Handle FSP logo params */ -void soc_load_logo(FSPS_UPD *supd) +void soc_load_logo_by_fsp(FSPS_UPD *supd) { size_t logo_size; supd->FspsConfig.LogoPtr = (uintptr_t)bmp_load_logo(&logo_size); diff --git a/src/soc/intel/common/block/include/intelblocks/cfg.h b/src/soc/intel/common/block/include/intelblocks/cfg.h index 856352096147..299e923d85c4 100644 --- a/src/soc/intel/common/block/include/intelblocks/cfg.h +++ b/src/soc/intel/common/block/include/intelblocks/cfg.h @@ -14,6 +14,76 @@ enum { }; /* + * Specifies the vertical alignment for the splash screen image. + * + * Visual Guide (representing the display area and the [LOGO]): + * + * Each option dictates the vertical placement of the splash image + * within the display's height. + */ +enum fw_splash_vertical_alignment { + /* FW_SPLASH_VALIGNMENT_CENTER: + * The splash image is centered vertically `(Y-axis - logo_height)/2` on the screen. + * The center of the [LOGO] aligns with the vertical center of the screen. + * + * +---------------+ + * | | + * | | + * | [LOGO] | <-- Vertically Centered + * | | + * | | + * +---------------+ + */ + FW_SPLASH_VALIGNMENT_CENTER = 0, + + /* FW_SPLASH_VALIGNMENT_TOP: + * The splash image is aligned to the top edge of the screen. + * + * +---------------+ + * | [LOGO] | <-- Top Aligned + * | | + * | | + * | | + * | | + * +---------------+ + */ + FW_SPLASH_VALIGNMENT_TOP = 1, + + /* FW_SPLASH_VALIGNMENT_BOTTOM: + * The splash image is aligned to the bottom edge of the screen. + * + * +---------------+ + * | | + * | | + * | | + * | | + * | [LOGO] | <-- Bottom Aligned + * +---------------+ + */ + FW_SPLASH_VALIGNMENT_BOTTOM = 2, + + /* FW_SPLASH_VALIGNMENT_MIDDLE: + * The splash image is placed in the vertical middle `(Y-axis/2)` of the screen + * (without considering the `logo height`). This means the TOP EDGE of the + * [LOGO] aligns with the screen's vertical midpoint line. + * + * +---------------+ + * | (Upper Half) | + * | | + * | [LOGO] | <-- [LOGO] aligns at Middle of the Y-axis + * | | + * | (Lower Half) | + * +---------------+ + * + * Note: The distinction between CENTER and MIDDLE is relevant as in for MIDDLE + * alignment, it ignores the logo height (i.e., the logo's top edge is placed + * at the screen's Y-midpoint). CENTER alignment, by contrast, would place + * the geometrical center of the logo at the screen's Y-midpoint. + */ + FW_SPLASH_VALIGNMENT_MIDDLE = 3, +}; + +/* * This structure will hold data required by common blocks. * These are soc specific configurations which will be filled by soc. * We'll fill this structure once during init and use the data in common block. @@ -26,6 +96,7 @@ struct soc_intel_common_config { uint8_t pch_thermal_trip; struct mmc_dll_params emmc_dll; enum lb_fb_orientation panel_orientation; + enum fw_splash_vertical_alignment logo_valignment; }; /* This function to retrieve soc config structure required by common code */ diff --git a/src/soc/intel/elkhartlake/fsp_params.c b/src/soc/intel/elkhartlake/fsp_params.c index 2f2e7408c470..082acaf7ae2c 100644 --- a/src/soc/intel/elkhartlake/fsp_params.c +++ b/src/soc/intel/elkhartlake/fsp_params.c @@ -505,6 +505,9 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Override/Fill FSP Silicon Param for mainboard */ mainboard_silicon_init_params(params); + + /* Runtime configuration of S0ix */ + config->s0ix_enable = get_uint_option("s0ix_enable", config->s0ix_enable); } /* Mainboard GPIO Configuration */ diff --git a/src/soc/intel/jasperlake/fsp_params.c b/src/soc/intel/jasperlake/fsp_params.c index 3bad53342407..b01610d2fed8 100644 --- a/src/soc/intel/jasperlake/fsp_params.c +++ b/src/soc/intel/jasperlake/fsp_params.c @@ -253,6 +253,9 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Override/Fill FSP Silicon Param for mainboard */ mainboard_silicon_init_params(params); + + /* Runtime configuration of S0ix */ + config->s0ix_enable = get_uint_option("s0ix_enable", config->s0ix_enable); } /* Mainboard GPIO Configuration */ diff --git a/src/soc/intel/meteorlake/Kconfig b/src/soc/intel/meteorlake/Kconfig index 8a51abd49614..cbab6a7f7cdc 100644 --- a/src/soc/intel/meteorlake/Kconfig +++ b/src/soc/intel/meteorlake/Kconfig @@ -458,4 +458,16 @@ config SOC_PHYSICAL_ADDRESS_WIDTH int default 42 +config SKIP_SEND_CONNECT_TOPOLOGY_CMD + bool + default y if SOFTWARE_CONNECTION_MANAGER + default n + help + When selected, the FSP UPD ITbtConnectTopologyTimeoutInMs will be set to + zero, causing FSP to skip sending the Connect Topology (CNTP) command, + which by default has a 5s timeout. CNTP is not needed when using software + connection manager, and sending it will cause a 5-10s boot delay. + Mainboards which use firmware connection manager may also wish to select this + as needed. + endif diff --git a/src/soc/intel/meteorlake/chip.h b/src/soc/intel/meteorlake/chip.h index fa657733d844..2c93aac69dfc 100644 --- a/src/soc/intel/meteorlake/chip.h +++ b/src/soc/intel/meteorlake/chip.h @@ -457,6 +457,55 @@ struct soc_intel_meteorlake_config { */ bool cpu_replacement_check; + enum { + SLP_S3_ASSERTION_DEFAULT, + SLP_S3_ASSERTION_60_US, + SLP_S3_ASSERTION_1_MS, + SLP_S3_ASSERTION_50_MS, + SLP_S3_ASSERTION_2_S, + } pch_slp_s3_min_assertion_width; + + enum { + SLP_S4_ASSERTION_DEFAULT, + SLP_S4_ASSERTION_1S, + SLP_S4_ASSERTION_2S, + SLP_S4_ASSERTION_3S, + SLP_S4_ASSERTION_4S, + } pch_slp_s4_min_assertion_width; + + enum { + SLP_SUS_ASSERTION_DEFAULT, + SLP_SUS_ASSERTION_0_MS, + SLP_SUS_ASSERTION_500_MS, + SLP_SUS_ASSERTION_1_S, + SLP_SUS_ASSERTION_4_S, + } pch_slp_sus_min_assertion_width; + + enum { + SLP_A_ASSERTION_DEFAULT, + SLP_A_ASSERTION_0_MS, + SLP_A_ASSERTION_4_S, + SLP_A_ASSERTION_98_MS, + SLP_A_ASSERTION_2_S, + } pch_slp_a_min_assertion_width; + + /* + * PCH PM Reset Power Cycle Duration + * NOTE: Duration programmed in the PchPmPwrCycDur should never be smaller than the + * stretch duration programmed in the following registers: + * - GEN_PMCON_A.SLP_S3_MIN_ASST_WDTH (PchPmSlpS3MinAssert) + * - GEN_PMCON_A.S4MAW (PchPmSlpS4MinAssert) + * - PM_CFG.SLP_A_MIN_ASST_WDTH (PchPmSlpAMinAssert) + * - PM_CFG.SLP_LAN_MIN_ASST_WDTH + */ + enum { + POWER_CYCLE_DURATION_DEFAULT, + POWER_CYCLE_DURATION_1S, + POWER_CYCLE_DURATION_2S, + POWER_CYCLE_DURATION_3S, + POWER_CYCLE_DURATION_4S, + } pch_reset_power_cycle_duration; + /* ISA Serial Base selection. */ enum { ISA_SERIAL_BASE_ADDR_3F8, diff --git a/src/soc/intel/meteorlake/fsp_params.c b/src/soc/intel/meteorlake/fsp_params.c index ad85702dbeb7..9adee42f7f33 100644 --- a/src/soc/intel/meteorlake/fsp_params.c +++ b/src/soc/intel/meteorlake/fsp_params.c @@ -22,6 +22,7 @@ #include <intelblocks/irq.h> #include <intelblocks/lpss.h> #include <intelblocks/mp_init.h> +#include <intelblocks/pmclib.h> #include <intelblocks/systemagent.h> #include <intelblocks/xdci.h> #include <intelpch/lockdown.h> @@ -396,6 +397,13 @@ static void fill_fsps_tcss_params(FSP_S_CONFIG *s_cfg, /* Explicitly clear this field to avoid using defaults */ memset(s_cfg->IomTypeCPortPadCfg, 0, sizeof(s_cfg->IomTypeCPortPadCfg)); + /* + * Set ITbtConnectTopologyTimeoutInMs to 0 if config selected, + * in order to skip sending the connect toplogy (CNTP) command. + */ + if (CONFIG(SKIP_SEND_CONNECT_TOPOLOGY_CMD)) + s_cfg->ITbtConnectTopologyTimeoutInMs = 0; + /* D3Hot and D3Cold for TCSS */ s_cfg->D3HotEnable = !config->tcss_d3_hot_disable; s_cfg->D3ColdEnable = CONFIG(D3COLD_SUPPORT); @@ -651,6 +659,24 @@ static void fill_fsps_misc_power_params(FSP_S_CONFIG *s_cfg, /* Enable the energy efficient turbo mode */ s_cfg->EnergyEfficientTurbo = 1; s_cfg->PmcLpmS0ixSubStateEnableMask = get_supported_lpm_mask(); + + /* Apply minimum assertion width settings if non-zero */ + if (config->pch_slp_s3_min_assertion_width) + s_cfg->PchPmSlpS3MinAssert = config->pch_slp_s3_min_assertion_width; + if (config->pch_slp_s4_min_assertion_width) + s_cfg->PchPmSlpS4MinAssert = config->pch_slp_s4_min_assertion_width; + if (config->pch_slp_sus_min_assertion_width) + s_cfg->PchPmSlpSusMinAssert = config->pch_slp_sus_min_assertion_width; + if (config->pch_slp_a_min_assertion_width) + s_cfg->PchPmSlpAMinAssert = config->pch_slp_a_min_assertion_width; + + /* Set Power Cycle Duration */ + if (config->pch_reset_power_cycle_duration) + s_cfg->PchPmPwrCycDur = get_pm_pwr_cyc_dur(config->pch_slp_s4_min_assertion_width, + config->pch_slp_s3_min_assertion_width, + config->pch_slp_a_min_assertion_width, + config->pch_reset_power_cycle_duration); + /* Un-Demotion from Demoted C1 need to be disable when * C1 auto demotion is disabled */ s_cfg->C1StateUnDemotion = !config->disable_c1_state_auto_demotion; @@ -784,6 +810,9 @@ static void soc_silicon_init_params(FSP_S_CONFIG *s_cfg, /* Override settings per board if required. */ mainboard_update_soc_chip_config(config); + /* Runtime configuration of S0ix */ + config->s0ix_enable = get_uint_option("s0ix_enable", config->s0ix_enable); + void (*fill_fsps_params[])(FSP_S_CONFIG *s_cfg, const struct soc_intel_meteorlake_config *config) = { fill_fsps_lpss_params, @@ -868,7 +897,7 @@ __weak void mainboard_silicon_init_params(FSP_S_CONFIG *s_cfg) } /* Handle FSP logo params */ -void soc_load_logo(FSPS_UPD *supd) +void soc_load_logo_by_fsp(FSPS_UPD *supd) { struct soc_intel_common_config *config = chip_get_common_soc_structure(); FSP_S_CONFIG *s_cfg = &supd->FspsConfig; diff --git a/src/soc/intel/pantherlake/Kconfig b/src/soc/intel/pantherlake/Kconfig index df14a2fe9127..6787642f24e4 100644 --- a/src/soc/intel/pantherlake/Kconfig +++ b/src/soc/intel/pantherlake/Kconfig @@ -104,6 +104,7 @@ config SOC_INTEL_PANTHERLAKE_BASE select TSC_MONOTONIC_TIMER select UDELAY_TSC select UDK_202302_BINDING + select USE_COREBOOT_FOR_BMP_RENDERING select USE_X86_64_SUPPORT select X86_INIT_NEED_1_SIPI help diff --git a/src/soc/intel/pantherlake/fsp_params.c b/src/soc/intel/pantherlake/fsp_params.c index 32be2852db1f..f45d333032e7 100644 --- a/src/soc/intel/pantherlake/fsp_params.c +++ b/src/soc/intel/pantherlake/fsp_params.c @@ -800,7 +800,7 @@ __weak void mainboard_silicon_init_params(FSP_S_CONFIG *s_cfg) } /* Handle FSP logo params */ -void soc_load_logo(FSPS_UPD *supd) +void soc_load_logo_by_fsp(FSPS_UPD *supd) { efi_uintn_t logo, blt_size; uint32_t logo_size; diff --git a/src/soc/intel/pantherlake/include/soc/iomap.h b/src/soc/intel/pantherlake/include/soc/iomap.h index 0bd56975a902..fac9c03f1cde 100644 --- a/src/soc/intel/pantherlake/include/soc/iomap.h +++ b/src/soc/intel/pantherlake/include/soc/iomap.h @@ -86,6 +86,10 @@ #define IOM_BASE_SIZE 0x10000 #define IOM_BASE_ADDR_MAX 0x401080ffff /* ((IOM_BASE_ADDR + IOM_BASE_SIZE) - 1) */ +/* Temporary MMIO address for GMADR (aka LMEMBAR) with 256MB */ +#define GMADR_BASE 0xB0000000 +#define GMADR_SIZE 0x10000000 + /* I/O port address space */ #define ACPI_BASE_ADDRESS 0x1800 #define ACPI_BASE_SIZE 0x100 diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index 0356c3e8ddf9..0061c10ae810 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -511,7 +511,7 @@ __weak void mainboard_silicon_init_params(FSP_S_CONFIG *params) } /* Handle FSP logo params */ -void soc_load_logo(FSPS_UPD *supd) +void soc_load_logo_by_fsp(FSPS_UPD *supd) { size_t logo_size; supd->FspsConfig.LogoPtr = (uint32_t)(uintptr_t)bmp_load_logo(&logo_size); diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 8f294f7c8f06..853ad6840e3f 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -199,8 +199,7 @@ static void post_mp_init(void) global_smi_enable_no_pwrbtn(); /* Lock down the SMRAM space. */ - if (CONFIG(HAVE_SMI_HANDLER)) - smm_lock(); + smm_lock(); if (mp_run_on_all_cpus(vmx_configure, NULL) != CB_SUCCESS) failure = true; diff --git a/src/soc/intel/tigerlake/fsp_params.c b/src/soc/intel/tigerlake/fsp_params.c index c3400b45c93f..35562d1a697b 100644 --- a/src/soc/intel/tigerlake/fsp_params.c +++ b/src/soc/intel/tigerlake/fsp_params.c @@ -682,6 +682,9 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) params->SiSkipSsidProgramming = 0; mainboard_silicon_init_params(params); + + /* Runtime configuration of S0ix */ + config->s0ix_enable = get_uint_option("s0ix_enable", config->s0ix_enable); } /* diff --git a/src/soc/mediatek/common/include/soc/mtcmos.h b/src/soc/mediatek/common/include/soc/mtcmos.h index 75f1c3818aea..15b4367fc4ae 100644 --- a/src/soc/mediatek/common/include/soc/mtcmos.h +++ b/src/soc/mediatek/common/include/soc/mtcmos.h @@ -1,15 +1,25 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __SOC_MEDIATEK_COMMON_MTCMOS_H__ -#define __SOC_MEDIATEK_COMMON_MTCMOS_H__ +#ifndef __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTCMOS_H__ +#define __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTCMOS_H__ + +struct bus_protect { + void *clr_addr; + u32 mask; +}; struct power_domain_data { void *pwr_con; + void *pwr_status; + void *pwr_status_2nd; u32 pwr_sta_mask; u32 sram_pdn_mask; u32 sram_ack_mask; u32 ext_buck_iso_bits; u32 caps; + size_t bp_steps; + /* Bus protection */ + const struct bus_protect *bp_table; }; #define SCPD_SRAM_ISO BIT(0) @@ -26,4 +36,4 @@ void mtcmos_protect_adsp_bus(void); void mtcmos_protect_audio_bus(void); void mtcmos_protect_display_bus(void); -#endif /* __SOC_MEDIATEK_COMMON_MTCMOS_H__ */ +#endif /* __SOC_MEDIATEK_COMMON_INCLUDE_SOC_MTCMOS_H__ */ diff --git a/src/soc/mediatek/common/include/soc/pmif_spi.h b/src/soc/mediatek/common/include/soc/pmif_spi.h index ead1e8170564..b704ec1e128b 100644 --- a/src/soc/mediatek/common/include/soc/pmif_spi.h +++ b/src/soc/mediatek/common/include/soc/pmif_spi.h @@ -57,14 +57,6 @@ enum { PMIC_AUXADC_RQST0 = PMIC_BASE + 0x1108, }; -#define PMIF_SPI_HW_INF 0x307F -#define PMIF_SPI_MD BIT(8) -#define PMIF_SPI_AP_SECURE BIT(9) -#define PMIF_SPI_AP BIT(10) -#define PMIF_SPI_STAUPD BIT(14) -#define PMIF_SPI_TSX_HW BIT(19) -#define PMIF_SPI_DCXO_HW BIT(20) - #define DEFAULT_SLVID 0 #define PMIF_CMD_STA BIT(2) diff --git a/src/soc/mediatek/common/mtcmos.c b/src/soc/mediatek/common/mtcmos.c index 2f4bd22d54d1..f69e84fab7cd 100644 --- a/src/soc/mediatek/common/mtcmos.c +++ b/src/soc/mediatek/common/mtcmos.c @@ -19,8 +19,19 @@ __weak void mtcmos_set_scpd_ext_buck_iso(const struct power_domain_data *pd) /* do nothing */ } +static void release_bus_protection(const struct power_domain_data *pd) +{ + int i; + + for (i = 0; i < pd->bp_steps; i++) + write32(pd->bp_table[i].clr_addr, pd->bp_table[i].mask); +} + void mtcmos_power_on(const struct power_domain_data *pd) { + u32 *pwr_status; + u32 *pwr_status_2nd; + write32(&mtk_spm->poweron_config_set, (SPM_PROJECT_CODE << 16) | (1U << 0)); @@ -30,8 +41,16 @@ void mtcmos_power_on(const struct power_domain_data *pd) setbits32(pd->pwr_con, PWR_ON); setbits32(pd->pwr_con, PWR_ON_2ND); - while (!(read32(&mtk_spm->pwr_status) & pd->pwr_sta_mask) || - !(read32(&mtk_spm->pwr_status_2nd) & pd->pwr_sta_mask)) + if ((pd->pwr_status != NULL) && (pd->pwr_status_2nd != NULL)) { + pwr_status = pd->pwr_status; + pwr_status_2nd = pd->pwr_status_2nd; + } else { + pwr_status = &mtk_spm->pwr_status; + pwr_status_2nd = &mtk_spm->pwr_status_2nd; + } + + while (!(read32(pwr_status) & pd->pwr_sta_mask) || + !(read32(pwr_status_2nd) & pd->pwr_sta_mask)) continue; clrbits32(pd->pwr_con, PWR_CLK_DIS); @@ -47,6 +66,8 @@ void mtcmos_power_on(const struct power_domain_data *pd) udelay(1); clrbits32(pd->pwr_con, SRAM_CKISO); } + + release_bus_protection(pd); } void mtcmos_display_power_on(void) diff --git a/src/soc/mediatek/common/pmif_spi.c b/src/soc/mediatek/common/pmif_spi.c index ea791cb91d1b..e6ee1b7e8c86 100644 --- a/src/soc/mediatek/common/pmif_spi.c +++ b/src/soc/mediatek/common/pmif_spi.c @@ -309,11 +309,9 @@ int pmif_spi_init(struct pmif *arb) write32(&arb->mtk_pmif->timer_ctrl, 0x3); /* Enable interfaces and arbitration */ - write32(&arb->mtk_pmif->inf_en, PMIF_SPI_HW_INF | PMIF_SPI_MD | - PMIF_SPI_AP_SECURE | PMIF_SPI_AP); + write32(&arb->mtk_pmif->inf_en, PMIF_SPI_INF_EN); - write32(&arb->mtk_pmif->arb_en, PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | - PMIF_SPI_AP | PMIF_SPI_STAUPD | PMIF_SPI_TSX_HW | PMIF_SPI_DCXO_HW); + write32(&arb->mtk_pmif->arb_en, PMIF_SPI_ARB_EN); /* Enable GPS AUXADC HW 0 and 1 */ SET32_BITFIELDS(&arb->mtk_pmif->other_inf_en, INTGPSADCINF_EN, 0x3); diff --git a/src/soc/mediatek/mt8188/include/soc/pmif.h b/src/soc/mediatek/mt8188/include/soc/pmif.h index c22a77399bb4..a6cf06bcb60a 100644 --- a/src/soc/mediatek/mt8188/include/soc/pmif.h +++ b/src/soc/mediatek/mt8188/include/soc/pmif.h @@ -124,6 +124,20 @@ check_member(mtk_pmif_regs, pmic_eint_sta_addr, 0x414); check_member(mtk_pmif_regs, irq_event_en_0, 0x420); check_member(mtk_pmif_regs, swinf_0_acc, 0x800); +#define PMIF_SPI_HW_INF 0x307F +#define PMIF_SPI_MD BIT(8) +#define PMIF_SPI_AP_SECURE BIT(9) +#define PMIF_SPI_AP BIT(10) +#define PMIF_SPI_STAUPD BIT(14) +#define PMIF_SPI_TSX_HW BIT(19) +#define PMIF_SPI_DCXO_HW BIT(20) + +#define PMIF_SPI_INF_EN (PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | \ + PMIF_SPI_AP) +#define PMIF_SPI_ARB_EN (PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | \ + PMIF_SPI_AP | PMIF_SPI_STAUPD | PMIF_SPI_TSX_HW | \ + PMIF_SPI_DCXO_HW) + #define PMIF_SPMI_AP_CHAN (PMIF_SPMI_BASE + 0x880) #define PMIF_SPI_AP_CHAN (PMIF_SPI_BASE + 0x880) diff --git a/src/soc/mediatek/mt8189/Makefile.mk b/src/soc/mediatek/mt8189/Makefile.mk index 56a7033eb375..eefdae1f4133 100644 --- a/src/soc/mediatek/mt8189/Makefile.mk +++ b/src/soc/mediatek/mt8189/Makefile.mk @@ -11,6 +11,8 @@ all-y += ../common/uart.c bootblock-y += bootblock.c bootblock-y += ../common/mmu_operations.c +bootblock-y += ../common/mtcmos.c mtcmos.c +bootblock-y += ../common/pll.c pll.c bootblock-y += ../common/wdt.c ../common/wdt_req.c wdt.c romstage-y += ../common/cbmem.c @@ -19,12 +21,14 @@ romstage-y += ../common/dramc_param.c romstage-y += ../common/emi.c romstage-y += ../common/memory.c ../common/memory_test.c romstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c +romstage-y += ../common/pll.c pll.c ramstage-$(CONFIG_ARM64_USE_ARM_TRUSTED_FIRMWARE) += ../common/bl31.c ramstage-y += ../common/dramc_info.c ramstage-y += ../common/emi.c ramstage-y += ../common/memory.c ramstage-y += ../common/mmu_operations.c ../common/mmu_cmops.c +ramstage-y += ../common/mtcmos.c mtcmos.c ramstage-y += soc.c ramstage-y += ../common/usb.c usb.c diff --git a/src/soc/mediatek/mt8189/bootblock.c b/src/soc/mediatek/mt8189/bootblock.c index ed78d65354c3..8465a4974f3c 100644 --- a/src/soc/mediatek/mt8189/bootblock.c +++ b/src/soc/mediatek/mt8189/bootblock.c @@ -2,10 +2,15 @@ #include <bootblock_common.h> #include <soc/mmu_operations.h> +#include <soc/pll.h> +#include <soc/spm_mtcmos.h> #include <soc/wdt.h> void bootblock_soc_init(void) { mtk_mmu_init(); mtk_wdt_init(); + mt_pll_init(); + mtcmos_init(); + mt_pll_post_init(); } diff --git a/src/soc/mediatek/mt8189/include/soc/addressmap.h b/src/soc/mediatek/mt8189/include/soc/addressmap.h index 84006623a4ee..c02f25accd25 100644 --- a/src/soc/mediatek/mt8189/include/soc/addressmap.h +++ b/src/soc/mediatek/mt8189/include/soc/addressmap.h @@ -4,7 +4,15 @@ #define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_ADDRESSMAP_H__ enum { - IO_PHYS = 0x10000000, + MCUCFG_BASE = 0x0C530000, + DBGAO_BASE = 0x0D01A000, + DEM_BASE = 0x0D0A0000, + IO_PHYS = 0x10000000, +}; + +enum { + CPU_PLLDIV_CTRL_BASE = MCUCFG_BASE + 0x0000A2A0, + BUS_PLLDIV_CTRL_BASE = MCUCFG_BASE + 0x0000A2E0, }; enum { @@ -21,12 +29,13 @@ enum { GPIO_BASE = IO_PHYS + 0x00005000, APMIXED_BASE = IO_PHYS + 0x0000C000, DEVAPC_INFRA_SECU_AO_BASE = IO_PHYS + 0x0001C000, - BCRM_INFRA_AO_BASE = IO_PHYS + 0x00022000, + INFRA_AO_BCRM_BASE = IO_PHYS + 0x00022000, DEVAPC_INFRA_AO_BASE = IO_PHYS + 0x00030000, DEVAPC_INFRA_AO1_BASE = IO_PHYS + 0x00034000, EMI0_BASE = IO_PHYS + 0x00219000, EMI0_MPU_BASE = IO_PHYS + 0x00226000, DRAMC_CHA_AO_BASE = IO_PHYS + 0x00230000, + EMICFG_AO_MEM_BASE = IO_PHYS + 0x00270000, THERM_CTRL_BASE = IO_PHYS + 0x00315000, DPM_PM_SRAM_BASE = IO_PHYS + 0x00900000, DPM_DM_SRAM_BASE = IO_PHYS + 0x00920000, @@ -36,10 +45,14 @@ enum { DPM_CFG_BASE2 = IO_PHYS + 0x00A40000, UART0_BASE = IO_PHYS + 0x01001000, SFLASH_REG_BASE = IO_PHYS + 0x01018000, + PERI_AO_BCRM_BASE = IO_PHYS + 0x01035000, PERICFG_AO_BASE = IO_PHYS + 0x01036000, DEVAPC_PERI_PAR_AO_BASE = IO_PHYS + 0x0103C000, + AUDIO_BASE = IO_PHYS + 0x01050000, SSUSB_IPPC_BASE = IO_PHYS + 0x01263E00, UFSHCI_BASE = IO_PHYS + 0x012B0000, + UFS0_AO_CFG_BASE = IO_PHYS + 0x012B8000, + UFS0_PDN_CFG_BASE = IO_PHYS + 0x012BB000, I2C0_DMA_BASE = IO_PHYS + 0x01300200, I2C1_DMA_BASE = IO_PHYS + 0x01300300, I2C2_DMA_BASE = IO_PHYS + 0x01300400, @@ -51,6 +64,7 @@ enum { I2C8_DMA_BASE = IO_PHYS + 0x01300A00, SSUSB_SIF_BASE = IO_PHYS + 0x01B00300, I2C2_BASE = IO_PHYS + 0x01B20000, + IMP_IIC_WRAP_WS_BASE = IO_PHYS + 0x01B21000, MIPITX0_BASE = IO_PHYS + 0x01B40000, IOCFG_LM_BASE = IO_PHYS + 0x01B50000, EDP_BASE = IO_PHYS + 0x01B70000, @@ -62,24 +76,49 @@ enum { I2C6_BASE = IO_PHYS + 0x01D73000, I2C7_BASE = IO_PHYS + 0x01F30000, I2C8_BASE = IO_PHYS + 0x01F31000, + IMP_IIC_WRAP_E_BASE = IO_PHYS + 0x01C22000, IOCFG_RB0_BASE = IO_PHYS + 0x01C50000, IOCFG_RB1_BASE = IO_PHYS + 0x01C60000, IOCFG_BM0_BASE = IO_PHYS + 0x01D20000, IOCFG_BM1_BASE = IO_PHYS + 0x01D30000, IOCFG_BM2_BASE = IO_PHYS + 0x01D40000, + IMP_IIC_WRAP_S_BASE = IO_PHYS + 0x01D74000, IOCFG_LT0_BASE = IO_PHYS + 0x01E20000, IOCFG_LT1_BASE = IO_PHYS + 0x01E30000, IOCFG_RT_BASE = IO_PHYS + 0x01F20000, + IMP_IIC_WRAP_EN_BASE = IO_PHYS + 0x01F32000, + MFGCFG_BASE = IO_PHYS + 0x03FBF000, + MMSYS_CONFIG_BASE = IO_PHYS + 0x04000000, DSI0_BASE = IO_PHYS + 0x04016000, DISP_DVO0 = IO_PHYS + 0x04019000, + IMGSYS1_BASE = IO_PHYS + 0x05020000, + IMGSYS2_BASE = IO_PHYS + 0x05820000, + VDEC_CORE_BASE = IO_PHYS + 0x0602F000, + VENC_GCON_BASE = IO_PHYS + 0x07000000, + CAMSYS_MAIN_BASE = IO_PHYS + 0x0A000000, + CAMSYS_RAWA_BASE = IO_PHYS + 0x0A04F000, + CAMSYS_RAWB_BASE = IO_PHYS + 0x0A06F000, + IPE_BASE = IO_PHYS + 0x0B000000, + VLPCFG_AO_REG_BASE = IO_PHYS + 0x0C000000, + SPM_BASE = IO_PHYS + 0x0C001000, RGU_BASE = IO_PHYS + 0x0C00A000, + VLPCFG_REG_BASE = IO_PHYS + 0x0C00C000, + DVFSRC_TOP_BASE = IO_PHYS + 0x0C00F000, + VLP_CK_BASE = IO_PHYS + 0x0C012000, SPMI_MST_BASE = IO_PHYS + 0x0C013000, DEVAPC_VLP_AO_BASE = IO_PHYS + 0x0C018000, + SCP_IIC_BASE = IO_PHYS + 0x0C80A000, + SCP_BASE = IO_PHYS + 0x0CB21000, SPMI_MST_P_BASE = IO_PHYS + 0x0CC00000, PMIF_SPMI_BASE = IO_PHYS + 0x0CC04000, PMIF_SPMI_P_BASE = IO_PHYS + 0x0CC06000, SYSTIMER_BASE = IO_PHYS + 0x0CC10000, + VAD_BASE = IO_PHYS + 0x0E010000, DEVAPC_MM_AO_BASE = IO_PHYS + 0x0E820000, + MMINFRA_CONFIG_BASE = IO_PHYS + 0x0E800000, + GCE_BASE = IO_PHYS + 0x0E980000, + MDP_GCE_BASE = IO_PHYS + 0x0E990000, + MDPSYS_CONFIG_BASE = IO_PHYS + 0x0F000000, }; #endif /* __SOC_MEDIATEK_MT8189_INCLUDE_SOC_ADDRESSMAP_H__ */ diff --git a/src/soc/mediatek/mt8189/include/soc/pll.h b/src/soc/mediatek/mt8189/include/soc/pll.h index 8d6de12dd113..fb8069c01005 100644 --- a/src/soc/mediatek/mt8189/include/soc/pll.h +++ b/src/soc/mediatek/mt8189/include/soc/pll.h @@ -8,16 +8,548 @@ #ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_PLL_H__ #define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_PLL_H__ +#include <soc/addressmap.h> #include <soc/pll_common.h> -/* top_div rate */ +static struct mtk_infra_ao_bcrm_regs *const + mtk_infra_ao_bcrm = (void *)INFRA_AO_BCRM_BASE; +static struct mtk_cpu_plldiv_cfg_regs *const + mtk_cpu_plldiv_cfg = (void *)CPU_PLLDIV_CTRL_BASE; +static struct mtk_bus_plldiv_cfg_regs *const + mtk_bus_plldiv_cfg = (void *)BUS_PLLDIV_CTRL_BASE; +static struct mtk_peri_ao_bcrm_regs *const + mtk_peri_ao_bcrm = (void *)PERI_AO_BCRM_BASE; +static struct mtk_vlp_regs *const + mtk_vlpsys = (void *)VLP_CK_BASE; +static struct mtk_pericfg_ao_regs *const + mtk_pericfg_ao = (void *)PERICFG_AO_BASE; +static struct mtk_afe_regs *const + mtk_afe = (void *)AUDIO_BASE; +static struct mtk_ufscfg_ao_regs *const + mtk_ufscfg_ao = (void *)UFS0_AO_CFG_BASE; +static struct mtk_ufscfg_pdn_regs *const + mtk_ufscfg_pdn = (void *)UFS0_PDN_CFG_BASE; +static struct mtk_imp_iic_wrap_ws_regs *const + mtk_imp_iic_wrap_ws = (void *)IMP_IIC_WRAP_WS_BASE; +static struct mtk_imp_iic_wrap_e_regs *const + mtk_imp_iic_wrap_e = (void *)IMP_IIC_WRAP_E_BASE; +static struct mtk_imp_iic_wrap_s_regs *const + mtk_imp_iic_wrap_s = (void *)IMP_IIC_WRAP_S_BASE; +static struct mtk_imp_iic_wrap_en_regs *const + mtk_imp_iic_wrap_en = (void *)IMP_IIC_WRAP_EN_BASE; +static struct mtk_mfg_regs *const + mtk_mfg = (void *)MFGCFG_BASE; +static struct mtk_mmsys_config_regs *const + mtk_mmsys_config = (void *)MMSYS_CONFIG_BASE; +static struct mtk_imgsys1_regs *const + mtk_imgsys1 = (void *)IMGSYS1_BASE; +static struct mtk_imgsys2_regs *const + mtk_imgsys2 = (void *)IMGSYS2_BASE; +static struct mtk_vdec_core_regs *const + mtk_vdec_core = (void *)VDEC_CORE_BASE; +static struct mtk_venc_gcon_regs *const + mtk_venc_gcon = (void *)VENC_GCON_BASE; +static struct mtk_scp_iic_regs *const + mtk_scp_iic = (void *)SCP_IIC_BASE; +static struct mtk_scp_regs *const + mtk_scp = (void *)SCP_BASE; +static struct mtk_vadsys_regs *const + mtk_vadsys = (void *)VAD_BASE; +static struct mtk_camsys_main_regs *const + mtk_camsys_main = (void *)CAMSYS_MAIN_BASE; +static struct mtk_camsys_rawa_regs *const + mtk_camsys_rawa = (void *)CAMSYS_RAWA_BASE; +static struct mtk_camsys_rawb_regs *const + mtk_camsys_rawb = (void *)CAMSYS_RAWB_BASE; +static struct mtk_ipesys_regs *const + mtk_ipesys = (void *)IPE_BASE; +static struct mtk_vlpcfg_ao_regs *const + mtk_vlpcfg_ao = (void *)VLPCFG_AO_REG_BASE; +static struct mtk_dvfsrc_top_regs *const + mtk_dvfsrc_top = (void *)DVFSRC_TOP_BASE; +static struct mtk_mminfra_config_regs *const + mtk_mminfra_config = (void *)MMINFRA_CONFIG_BASE; +static struct mtk_gce_d_regs *const + mtk_gce_d = (void *)GCE_BASE; +static struct mtk_gce_m_regs *const + mtk_gce_m = (void *)MDP_GCE_BASE; +static struct mtk_mdpsys_config_regs *const + mtk_mdpsys_config = (void *)MDPSYS_CONFIG_BASE; +static struct mtk_dbgao_regs *const + mtk_dbgao = (void *)DBGAO_BASE; +static struct mtk_dem_regs *const + mtk_dem = (void *)DEM_BASE; + +struct mtk_infra_ao_bcrm_regs { + u32 reserved[14]; + u32 vdnr_dcm_infra_par_bus_ctrl_0; +}; +check_member(mtk_infra_ao_bcrm_regs, vdnr_dcm_infra_par_bus_ctrl_0, 0x0038); + +struct mtk_cpu_plldiv_cfg_regs { + u32 cpu_plldiv_0_cfg0; + u32 cpu_plldiv_1_cfg0; +}; + +struct mtk_bus_plldiv_cfg_regs { + u32 bus_plldiv_cfg0; +}; + +struct mtk_peri_ao_bcrm_regs { + u32 reserved1[8]; + u32 vdnr_dcm_peri_par_bus_ctrl_0; + u32 reserved2[8]; +}; +check_member(mtk_peri_ao_bcrm_regs, vdnr_dcm_peri_par_bus_ctrl_0, 0x0020); + +struct mtk_clk_cfg { + u32 cfg; + u32 set; + u32 clr; + u32 reserved; +}; + +struct mtk_vlp_clk_cfg { + u32 cfg; + u32 set; + u32 clr; +}; + +struct mtk_vlp_regs { + u32 reserved1; + u32 vlp_clk_cfg_update; + struct mtk_vlp_clk_cfg vlp_clk_cfg[6]; + u32 reserved2[104]; + u32 vlp_clk_cfg_30; + u32 vlp_clk_cfg_30_set; + u32 vlp_clk_cfg_30_clr; + u32 reserved3[13]; + u32 vlp_fqmtr_con[2]; +}; + +check_member(mtk_vlp_regs, vlp_clk_cfg_update, 0x0004); +check_member(mtk_vlp_regs, vlp_clk_cfg[0].set, 0x000C); +check_member(mtk_vlp_regs, vlp_clk_cfg[0].clr, 0x0010); +check_member(mtk_vlp_regs, vlp_clk_cfg[5].set, 0x0048); +check_member(mtk_vlp_regs, vlp_clk_cfg[5].clr, 0x004C); +check_member(mtk_vlp_regs, vlp_clk_cfg_30, 0x01F0); +check_member(mtk_vlp_regs, vlp_fqmtr_con[0], 0x0230); + +struct mtk_topckgen_regs { + u32 reserved1; + u32 clk_cfg_update[3]; + struct mtk_clk_cfg clk_cfg[17]; + u32 reserved2[8]; + u32 clk_misc_cfg_0; + u32 reserved3[7]; + u32 clk_mem_dfs_cfg; + u32 reserved4[6]; + u32 clk_dbg_cfg; + struct mtk_clk_cfg clk_cfg_17; + struct mtk_clk_cfg clk_cfg_18; + u32 reserved5[24]; + u32 clk_scp_cfg_0; + u32 reserved6[7]; + u32 clk26cali[2]; + u32 reserved7[6]; + struct mtk_clk_cfg clk_cfg_19; + u32 reserved8[176]; + struct mtk_clk_cfg clk_misc_cfg_3; +}; +check_member(mtk_topckgen_regs, clk_cfg_update[0], 0x0004); +check_member(mtk_topckgen_regs, clk_cfg[0].set, 0x0014); +check_member(mtk_topckgen_regs, clk_cfg[0].clr, 0x0018); +check_member(mtk_topckgen_regs, clk_cfg[16].set, 0x0114); +check_member(mtk_topckgen_regs, clk_cfg[16].clr, 0x0118); +check_member(mtk_topckgen_regs, clk_misc_cfg_0, 0x0140); +check_member(mtk_topckgen_regs, clk_mem_dfs_cfg, 0x0160); +check_member(mtk_topckgen_regs, clk_dbg_cfg, 0x017C); +check_member(mtk_topckgen_regs, clk_cfg_17.set, 0x0184); +check_member(mtk_topckgen_regs, clk_cfg_17.clr, 0x0188); +check_member(mtk_topckgen_regs, clk_cfg_18.set, 0x0194); +check_member(mtk_topckgen_regs, clk_cfg_18.clr, 0x0198); +check_member(mtk_topckgen_regs, clk_scp_cfg_0, 0x0200); +check_member(mtk_topckgen_regs, clk26cali, 0x0220); +check_member(mtk_topckgen_regs, clk_cfg_19.set, 0x0244); +check_member(mtk_topckgen_regs, clk_cfg_19.clr, 0x0248); +check_member(mtk_topckgen_regs, clk_misc_cfg_3.cfg, 0x0510); +check_member(mtk_topckgen_regs, clk_misc_cfg_3.set, 0x0514); +check_member(mtk_topckgen_regs, clk_misc_cfg_3.clr, 0x0518); + +struct mtk_apmixed_regs { + u32 reserved1[16]; + u32 apll1_tuner_con0; /* 0x0040 */ + u32 apll2_tuner_con0; + u32 reserved2[11]; + u32 pllen_all_set; /* 0x0074 */ + u32 pllen_all_clr; + u32 reserved3[2]; + u32 pll_div_rstb_all_set; /* 0x0084 */ + u32 reserved4[95]; + u32 armpll_ll_con[2]; /* 0x0204 */ + u32 reserved5[2]; + u32 armpll_bl_con[2]; /* 0x0214 */ + u32 reserved6[2]; + u32 ccipll_con[2]; /* 0x0224 */ + u32 reserved7[54]; + u32 mainpll_con[2]; /* 0x0304 */ + u32 reserved8[2]; + u32 univpll_con[2]; /* 0x0314 */ + u32 reserved9[2]; + u32 mmpll_con[2]; /* 0x0324 */ + u32 reserved10[2]; + u32 emipll_con[2]; /* 0x0334 */ + u32 reserved11[50]; + u32 apll1_con[3]; /* 0x0404 */ + u32 reserved12[2]; + u32 apll2_con[3]; /* 0x0418 */ + u32 reserved13[2]; + u32 tvdpll1_con[2]; /* 0x042c */ + u32 reserved14[2]; + u32 tvdpll2_con[2]; /* 0x043c */ + u32 reserved15[48]; + u32 mfgpll_con[2]; /* 0x0504 */ + u32 reserved16[2]; + u32 ethpll_con[2]; /* 0x0514 */ + u32 reserved17[2]; + u32 msdcpll_con[2]; /* 0x0524 */ + u32 reserved18[2]; + u32 ufspll_con[2]; /* 0x0534 */ + u32 reserved19[50]; + u32 apupll_con[2]; /* 0x0604 */ + u32 reserved20[2]; + u32 apupll2_con[2]; /* 0x0614 */ + u32 reserved21[57]; + u32 ap_clksq_con0; /* 0x0700 */ +}; +check_member(mtk_apmixed_regs, apll1_tuner_con0, 0x0040); +check_member(mtk_apmixed_regs, pllen_all_set, 0x0074); +check_member(mtk_apmixed_regs, pll_div_rstb_all_set, 0x0084); +check_member(mtk_apmixed_regs, armpll_ll_con[0], 0x0204); +check_member(mtk_apmixed_regs, armpll_bl_con[0], 0x0214); +check_member(mtk_apmixed_regs, ccipll_con[0], 0x0224); +check_member(mtk_apmixed_regs, mainpll_con[0], 0x0304); +check_member(mtk_apmixed_regs, univpll_con[0], 0x0314); +check_member(mtk_apmixed_regs, mmpll_con[0], 0x0324); +check_member(mtk_apmixed_regs, emipll_con[0], 0x0334); +check_member(mtk_apmixed_regs, apll1_con[0], 0x0404); +check_member(mtk_apmixed_regs, apll2_con[0], 0x0418); +check_member(mtk_apmixed_regs, tvdpll1_con[0], 0x042C); +check_member(mtk_apmixed_regs, tvdpll2_con[0], 0x043C); +check_member(mtk_apmixed_regs, mfgpll_con[0], 0x0504); +check_member(mtk_apmixed_regs, ethpll_con[0], 0x0514); +check_member(mtk_apmixed_regs, msdcpll_con[0], 0x0524); +check_member(mtk_apmixed_regs, ufspll_con[0], 0x0534); +check_member(mtk_apmixed_regs, apupll_con[0], 0x0604); +check_member(mtk_apmixed_regs, apupll2_con[0], 0x0614); +check_member(mtk_apmixed_regs, ap_clksq_con0, 0x0700); + +struct mtk_pericfg_ao_regs { + u32 reserved1[4]; + u32 pericfg_ao_peri_cg_0; + u32 pericfg_ao_peri_cg_1; + u32 pericfg_ao_peri_cg_2; + u32 reserved2[2]; + u32 pericfg_ao_peri_cg_0_set; + u32 pericfg_ao_peri_cg_0_clr; + u32 pericfg_ao_peri_cg_1_set; + u32 pericfg_ao_peri_cg_1_clr; + u32 pericfg_ao_peri_cg_2_set; + u32 pericfg_ao_peri_cg_2_clr; +}; +check_member(mtk_pericfg_ao_regs, pericfg_ao_peri_cg_0, 0x0010); +check_member(mtk_pericfg_ao_regs, pericfg_ao_peri_cg_0_set, 0x0024); + +struct mtk_afe_regs { + u32 audio_audio_top[5]; +}; + +struct mtk_ufscfg_ao_regs { + u32 reserved1; + u32 ufscfg_ao_reg_ufs_ao_cg_0; + u32 ufscfg_ao_reg_ufs_ao_cg_0_set; + u32 ufscfg_ao_reg_ufs_ao_cg_0_clr; +}; + +struct mtk_ufscfg_pdn_regs { + u32 reserved1; + u32 ufscfg_pdn_reg_ufs_pdn_cg_0; + u32 ufscfg_pdn_reg_ufs_pdn_cg_0_set; + u32 ufscfg_pdn_reg_ufs_pdn_cg_0_clr; +}; + +struct mtk_imp_iic_wrap_ws_regs { + u32 reserved1[896]; + u32 imp_iic_wrap_ws_ap_clock_cg; + u32 imp_iic_wrap_ws_ap_clock_cg_clr; + u32 imp_iic_wrap_ws_ap_clock_cg_set; +}; +check_member(mtk_imp_iic_wrap_ws_regs, imp_iic_wrap_ws_ap_clock_cg, 0x0E00); + +struct mtk_imp_iic_wrap_e_regs { + u32 reserved1[896]; + u32 imp_iic_wrap_e_ap_clock_cg; + u32 imp_iic_wrap_e_ap_clock_cg_clr; + u32 imp_iic_wrap_e_ap_clock_cg_set; +}; +check_member(mtk_imp_iic_wrap_e_regs, imp_iic_wrap_e_ap_clock_cg, 0x0E00); + +struct mtk_imp_iic_wrap_s_regs { + u32 reserved1[896]; + u32 imp_iic_wrap_s_ap_clock_cg; + u32 imp_iic_wrap_s_ap_clock_cg_clr; + u32 imp_iic_wrap_s_ap_clock_cg_set; +}; +check_member(mtk_imp_iic_wrap_s_regs, imp_iic_wrap_s_ap_clock_cg, 0x0E00); + +struct mtk_imp_iic_wrap_en_regs { + u32 reserved1[896]; + u32 imp_iic_wrap_en_ap_clock_cg; + u32 imp_iic_wrap_en_ap_clock_cg_clr; + u32 imp_iic_wrap_en_ap_clock_cg_set; +}; +check_member(mtk_imp_iic_wrap_en_regs, imp_iic_wrap_en_ap_clock_cg, 0x0E00); + +struct mtk_mfg_regs { + u32 mfg_mfg_cg_con; + u32 mfg_mfg_cg_con_set; + u32 mfg_mfg_cg_con_clr; +}; + +struct mtk_mmsys_config_regs { + u32 reserved1[64]; + u32 mmsys_config_mmsys_cg_0; + u32 mmsys_config_mmsys_cg_0_set; + u32 mmsys_config_mmsys_cg_0_clr; + u32 reserved2[1]; + u32 mmsys_config_mmsys_cg_1; + u32 mmsys_config_mmsys_cg_1_set; + u32 mmsys_config_mmsys_cg_1_clr; +}; +check_member(mtk_mmsys_config_regs, mmsys_config_mmsys_cg_0, 0x0100); +check_member(mtk_mmsys_config_regs, mmsys_config_mmsys_cg_1, 0x0110); + +struct mtk_imgsys1_regs { + u32 imgsys1_img_cg; + u32 imgsys1_img_cg_set; + u32 imgsys1_img_cg_clr; +}; + +struct mtk_imgsys2_regs { + u32 imgsys2_img_cg; + u32 imgsys2_img_cg_set; + u32 imgsys2_img_cg_clr; +}; + +struct mtk_vdec_core_regs { + u32 vdec_core_vdec_cken; + u32 vdec_core_vdec_cken_clr; + u32 vdec_core_larb_cken_con; + u32 vdec_core_larb_cken_con_clr; +}; + +struct mtk_venc_gcon_regs { + u32 venc_gcon_vencsys_cg; + u32 venc_gcon_vencsys_cg_set; + u32 venc_gcon_vencsys_cg_clr; +}; + +struct mtk_scp_iic_regs { + u32 reserved[900]; + u32 scp_iic_ccu_clock_cg; + u32 scp_iic_ccu_clock_cg_clr; + u32 scp_iic_ccu_clock_cg_set; +}; +check_member(mtk_scp_iic_regs, scp_iic_ccu_clock_cg, 0x0E10); + +struct mtk_scp_regs { + u32 reserved[85]; + u32 scp_ap_spi_cg; + u32 scp_ap_spi_cg_clr; +}; +check_member(mtk_scp_regs, scp_ap_spi_cg, 0x0154); + +struct mtk_vadsys_regs { + u32 vad_vadsys_ck_en; + u32 reserved1[95]; + u32 vad_vow_audiodsp_sw_cg; +}; +check_member(mtk_vadsys_regs, vad_vow_audiodsp_sw_cg, 0x0180); + +struct mtk_camsys_main_regs { + u32 camsys_main_camsys_cg; + u32 camsys_main_camsys_cg_set; + u32 camsys_main_camsys_cg_clr; +}; + +struct mtk_camsys_rawa_regs { + u32 camsys_rawa_camsys_cg; + u32 camsys_rawa_camsys_cg_set; + u32 camsys_rawa_camsys_cg_clr; +}; + +struct mtk_camsys_rawb_regs { + u32 camsys_rawb_camsys_cg; + u32 camsys_rawb_camsys_cg_set; + u32 camsys_rawb_camsys_cg_clr; +}; + +struct mtk_ipesys_regs { + u32 ipe_img_cg; + u32 ipe_img_cg_set; + u32 ipe_img_cg_clr; +}; + +struct mtk_vlpcfg_ao_regs { + u32 reserved[512]; + u32 vlpcfg_ao_reg_debugtop_vlpao_ctrl; +}; +check_member(mtk_vlpcfg_ao_regs, vlpcfg_ao_reg_debugtop_vlpao_ctrl, 0x0800); + +struct mtk_dvfsrc_top_regs { + u32 dvfsrc_top_dvfsrc_basic_control; +}; + +struct mtk_mminfra_config_regs { + u32 reserved1[64]; + u32 mminfra_config_mminfra_cg_0; + u32 mminfra_config_mminfra_cg_0_set; + u32 mminfra_config_mminfra_cg_0_clr; + u32 reserved2[1]; + u32 mminfra_config_mminfra_cg_1; + u32 mminfra_config_mminfra_cg_1_set; + u32 mminfra_config_mminfra_cg_1_clr; +}; +check_member(mtk_mminfra_config_regs, mminfra_config_mminfra_cg_0, 0x0100); +check_member(mtk_mminfra_config_regs, mminfra_config_mminfra_cg_1, 0x0110); + +struct mtk_gce_d_regs { + u32 reserved[60]; + u32 gce_gce_ctl_int0; +}; +check_member(mtk_gce_d_regs, gce_gce_ctl_int0, 0x00F0); + +struct mtk_gce_m_regs { + u32 reserved[60]; + u32 mdp_gce_gce_ctl_int0; +}; +check_member(mtk_gce_m_regs, mdp_gce_gce_ctl_int0, 0x00F0); + +struct mtk_mdpsys_config_regs { + u32 reserved1[64]; + u32 mdpsys_config_mdpsys_cg_0; + u32 mdpsys_config_mdpsys_cg_0_set; + u32 mdpsys_config_mdpsys_cg_0_clr; + u32 reserved2[1]; + u32 mdpsys_config_mdpsys_cg_1; + u32 mdpsys_config_mdpsys_cg_1_set; + u32 mdpsys_config_mdpsys_cg_1_clr; +}; +check_member(mtk_mdpsys_config_regs, mdpsys_config_mdpsys_cg_0, 0x0100); +check_member(mtk_mdpsys_config_regs, mdpsys_config_mdpsys_cg_1, 0x0110); + +struct mtk_dbgao_regs { + u32 reserved[28]; + u32 dbgao_atb; +}; +check_member(mtk_dbgao_regs, dbgao_atb, 0x0070); + +struct mtk_dem_regs { + u32 reserved1[11]; + u32 dem_dbgbusclk_en; + u32 dem_dbgsysclk_en; + u32 reserved2[15]; + u32 dem_atb; +}; +check_member(mtk_dem_regs, dem_dbgbusclk_en, 0x002C); +check_member(mtk_dem_regs, dem_atb, 0x0070); + +/* Fmeter Type */ +enum fmeter_id { + APLL1_CTRL, + APLL2_CTRL, + ARMPLL_BL_CTRL, + ARMPLL_LL_CTRL, + CCIPLL_CTRL, + MAINPLL_CTRL, + MMPLL_CTRL, + MSDCPLL_CTRL, + UFSPLL_CTRL, + UNIVPLL_CTRL, + EMIPLL_CTRL, + TVDPLL1_CTRL, + TVDPLL2_CTRL, + MFGPLL_CTRL, + ETHPLL_CTRL, + APUPLL_CTRL, + APUPLL2_CTRL, + VLP_CKSYS_TOP_CTRL, +}; + +/* PLL set rate list */ +enum pll_rate_type { + ARMPLL_LL_RATE = 0, + ARMPLL_BL_RATE, + CCIPLL_RATE, + PLL_RATE_NUM, +}; + +#define ARMPLL_BL_ID 6 +#define ARMPLL_LL_ID 8 +#define CCIPLL_ID 10 + +enum { + ARMPLL_LL_HZ = 1600UL * MHz, + ARMPLL_BL_HZ = 1700UL * MHz, + CCIPLL_HZ = 1140UL * MHz, + MAINPLL_HZ = 2184UL * MHz, + UNIVPLL_HZ = 2496UL * MHz, + MMPLL_HZ = 2750UL * MHz, + MFGPLL_HZ = 390 * MHz, + APLL1_HZ = 180633600UL, + APLL2_HZ = 196608UL * KHz, + EMIPLL_HZ = 387 * MHz, + APUPLL2_HZ = 230 * MHz, + APUPLL_HZ = 330 * MHz, + TVDPLL1_HZ = 594 * MHz, + TVDPLL2_HZ = 594 * MHz, + ETHPLL_HZ = 500 * MHz, + MSDCPLL_HZ = 416 * MHz, + UFSPLL_HZ = 594 * MHz, +}; + +enum { + CLK26M_HZ = 26 * MHz, + UNIVPLL_D6_D2_HZ = UNIVPLL_HZ / 6 / 2, +}; + +enum { + PCW_INTEGER_BITS = 8, +}; + +enum { + SPI_HZ = UNIVPLL_D6_D2_HZ, + UART_HZ = CLK26M_HZ, +}; + enum { - CLK26M_HZ = 26 * MHz, + PLL_EN_DELAY = 20, }; -/* top_mux rate */ enum { - UART_HZ = CLK26M_HZ, + MCU_DIV_MASK = 0x1f << 17, + MCU_DIV_1 = 0x8 << 17, + + MCU_MUX_MASK = 0x3 << 9, + MCU_MUX_SRC_PLL = 0x1 << 9, + MCU_MUX_SRC_26M = 0x0 << 9, }; +/* + * Clock manager functions + */ +void mt_pll_post_init(void); +u32 mt_get_vlpck_freq(u32 id); +void mt_set_topck_default(void); + #endif /* __SOC_MEDIATEK_MT8189_INCLUDE_SOC_PLL_H__ */ diff --git a/src/soc/mediatek/mt8189/include/soc/spm.h b/src/soc/mediatek/mt8189/include/soc/spm.h new file mode 100644 index 000000000000..c504672b2a5d --- /dev/null +++ b/src/soc/mediatek/mt8189/include/soc/spm.h @@ -0,0 +1,1028 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_H__ +#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_H__ + +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <soc/mtcmos.h> +#include <soc/pll.h> +#include <soc/spm_common.h> +#include <types.h> + +/* SPM READ/WRITE CFG */ +#define SPM_PROJECT_CODE 0xB16 +#define SPM_REGWR_CFG_KEY (SPM_PROJECT_CODE << 16) + +/* POWERON_CONFIG_EN (0x1C001000 + 0x000) */ +#define BCLK_CG_EN_LSB BIT(0) +#define PROJECT_CODE_LSB BIT(16) + +/* SPM_CLK_CON (0x1C001000 + 0x024) */ +#define REG_SPM_LOCK_INFRA_DCM_LSB BIT(0) +#define REG_CXO32K_REMOVE_EN_LSB BIT(1) +#define REG_SPM_LEAVE_SUSPEND_MERGE_MASK_LSB BIT(4) +#define REG_SRCLKENO0_SRC_MASK_B_LSB BIT(8) +#define REG_SRCLKENO1_SRC_MASK_B_LSB BIT(16) +#define REG_SRCLKENO2_SRC_MASK_B_LSB BIT(24) + +/* PCM_CON0 (0x1C001000 + 0x018) */ +#define PCM_CK_EN_LSB BIT(2) +#define PCM_SW_RESET_LSB BIT(15) +#define PCM_CON0_PROJECT_CODE_LSB BIT(16) + +/* PCM_CON1 (0x1C001000 + 0x01C) */ +#define REG_SPM_APB_INTERNAL_EN_LSB BIT(3) +#define REG_PCM_TIMER_EN_LSB BIT(5) +#define REG_PCM_WDT_EN_LSB BIT(8) +#define REG_PCM_WDT_WAKE_LSB BIT(9) +#define REG_SSPM_APB_P2P_EN_LSB BIT(10) +#define REG_MCUPM_APB_P2P_EN_LSB BIT(11) +#define REG_RSV_APB_P2P_EN_LSB BIT(12) +#define RG_PCM_IRQ_MSK_LSB BIT(15) +#define PCM_CON1_PROJECT_CODE_LSB BIT(16) + +/* SPM_WAKEUP_EVENT_MASK (0x1C001000 + 0x808) */ +#define REG_WAKEUP_EVENT_MASK_LSB BIT(0) + +/* DDREN_DBC_CON (0x1C001000 + 0x890) */ +#define REG_DDREN_DBC_LEN_LSB BIT(0) +#define REG_DDREN_DBC_EN_LSB BIT(16) + +/* SPM_DVFS_CON (0x1C001000 + 0x3AC) */ +#define SPM_DVFS_FORCE_ENABLE_LSB BIT(2) +#define FORCE_DVFS_WAKE_LSB BIT(3) +#define SPM_DVFSRC_ENABLE_LSB BIT(4) +#define DVFSRC_WAKEUP_EVENT_MASK_LSB BIT(6) +#define SPM2RC_EVENT_ABORT_LSB BIT(7) +#define DVFSRC_LEVEL_ACK_LSB BIT(8) + +/* SPM_SW_FLAG_0 (0x1C001000 + 0x600) */ +#define SPM_SW_FLAG_LSB BIT(0) + +/* SYS_TIMER_CON (0x1C001000 + 0x500) */ +#define SYS_TIMER_START_EN_LSB BIT(0) +#define SYS_TIMER_LATCH_EN_LSB BIT(1) +#define SYS_TIMER_ID_LSB BIT(8) +#define SYS_TIMER_VALID_LSB BIT(31) + +/************************************** + * Config and Parameter + **************************************/ +#define POWER_ON_VAL0_DEF 0x0000F100 +#define POWER_ON_VAL1_DEF 0x003FFE20 +#define SPM_WAKEUP_EVENT_MASK_DEF 0xF97FFCFF +#define SPM_BUS_PROTECT_MASK_B_DEF 0xFFFFFFFF +#define SPM_BUS_PROTECT2_MASK_B_DEF 0xFFFFFFFF +#define MD32PCM_DMA0_CON_VAL 0x0003820E +#define MD32PCM_DMA0_START_VAL 0x00008000 +#define SPM_DVFS_LEVEL_DEF 0x00000001 +#define SPM_DVS_DFS_LEVEL_DEF 0x00010001 +#define SPM_RESOURCE_ACK_CON0_DEF 0xCC4E4ECC +#define SPM_RESOURCE_ACK_CON1_DEF 0x00CCCCCC +#define SPM_SYSCLK_SETTLE 0x60FE /* 1685us */ +#define SPM_INIT_DONE_US 20 +#define PCM_WDT_TIMEOUT (30 * 32768) +#define PCM_TIMER_MAX ((5400 - 30) * 32768) /* 90min - 30sec */ + +/************************************** + * Definition and Declaration + **************************************/ +/* SPM_IRQ_MASK */ +#define ISRM_TWAM BIT(2) +#define ISRM_RET_IRQ1 BIT(9) +#define ISRM_RET_IRQ2 BIT(10) +#define ISRM_RET_IRQ3 BIT(11) +#define ISRM_RET_IRQ4 BIT(12) +#define ISRM_RET_IRQ5 BIT(13) +#define ISRM_RET_IRQ6 BIT(14) +#define ISRM_RET_IRQ7 BIT(15) +#define ISRM_RET_IRQ8 BIT(16) +#define ISRM_RET_IRQ9 BIT(17) +#define ISRM_RET_IRQ_AUX (ISRM_RET_IRQ9 | ISRM_RET_IRQ8 | \ + ISRM_RET_IRQ7 | ISRM_RET_IRQ6 | \ + ISRM_RET_IRQ5 | ISRM_RET_IRQ4 | \ + ISRM_RET_IRQ3 | ISRM_RET_IRQ2 | \ + ISRM_RET_IRQ1) + +#define ISRM_ALL_EXC_TWAM ISRM_RET_IRQ_AUX +#define ISRM_ALL (ISRM_ALL_EXC_TWAM | ISRM_TWAM) + +/* SPM_IRQ_STA */ +#define ISRS_TWAM BIT(2) +#define ISRS_PCM_RETURN BIT(3) +#define ISRC_TWAM ISRS_TWAM +#define ISRC_ALL_EXC_TWAM ISRS_PCM_RETURN +#define ISRC_ALL (ISRC_ALL_EXC_TWAM | ISRC_TWAM) + +/* PCM_PWR_IO_EN */ +#define PCM_PWRIO_EN_R0 BIT(0) +#define PCM_PWRIO_EN_R7 BIT(7) +#define PCM_RF_SYNC_R0 BIT(16) +#define PCM_RF_SYNC_R6 BIT(22) +#define PCM_RF_SYNC_R7 BIT(23) + +/* SPM_SWINT */ +#define PCM_SW_INT0 BIT(0) +#define PCM_SW_INT1 BIT(1) +#define PCM_SW_INT2 BIT(2) +#define PCM_SW_INT3 BIT(3) +#define PCM_SW_INT4 BIT(4) +#define PCM_SW_INT5 BIT(5) +#define PCM_SW_INT6 BIT(6) +#define PCM_SW_INT7 BIT(7) +#define PCM_SW_INT8 BIT(8) +#define PCM_SW_INT9 BIT(9) +#define PCM_SW_INT_ALL (PCM_SW_INT9 | PCM_SW_INT8 | PCM_SW_INT7 | \ + PCM_SW_INT6 | PCM_SW_INT5 | PCM_SW_INT4 | \ + PCM_SW_INT3 | PCM_SW_INT2 | PCM_SW_INT1 | \ + PCM_SW_INT0) + +#define SPM_ACK_CHK_3_SEL_HW_S1 0x00350098 +#define SPM_ACK_CHK_3_HW_S1_CNT 1 + +DEFINE_BIT(SPM_ACK_CHK_3_CON_CLR_ALL, 1) +DEFINE_BIT(SPM_ACK_CHK_3_CON_EN_0, 4) +DEFINE_BIT(SPM_ACK_CHK_3_CON_EN_1, 8) +DEFINE_BIT(SPM_ACK_CHK_3_CON_HW_MODE_TRIG, 11) + +struct pwr_ctrl { + /* for SPM */ + u32 pcm_flags; + /* can override pcm_flags */ + u32 pcm_flags_cust; + /* set bit of pcm_flags, after pcm_flags_cust */ + u32 pcm_flags_cust_set; + /* clr bit of pcm_flags, after pcm_flags_cust */ + u32 pcm_flags_cust_clr; + u32 pcm_flags1; + /* can override pcm_flags1 */ + u32 pcm_flags1_cust; + /* set bit of pcm_flags1, after pcm_flags1_cust */ + u32 pcm_flags1_cust_set; + /* clr bit of pcm_flags1, after pcm_flags1_cust */ + u32 pcm_flags1_cust_clr; + /* @ 1T 32K */ + u32 timer_val; + /* @ 1T 32K, can override timer_val */ + u32 timer_val_cust; + /* stress for dpidle */ + u32 timer_val_ramp_en; + /* stress for suspend */ + u32 timer_val_ramp_en_sec; + u32 wake_src; + /* can override wake_src */ + u32 wake_src_cust; + u32 wakelock_timer_val; + /* disable wdt in suspend */ + u8 wdt_disable; + + /* SPM_CLK_CON */ + u8 reg_spm_lock_infra_dcm_lsb; + u8 reg_cxo32k_remove_en_lsb; + u8 reg_spm_leave_suspend_merge_mask_lsb; + u8 reg_sysclk0_src_mask_b_lsb; + u8 reg_sysclk1_src_mask_b_lsb; + u8 reg_sysclk2_src_mask_b_lsb; + + /* SPM_AP_STANDBY_CON */ + u8 reg_wfi_op; + u8 reg_wfi_type; + u8 reg_mp0_cputop_idle_mask; + u8 reg_mp1_cputop_idle_mask; + u8 reg_mcusys_idle_mask; + u8 reg_csyspwrup_req_mask_lsb; + u8 reg_wfi_af_sel; + u8 reg_cpu_sleep_wfi; + + /* SPM_SRC_REQ */ + u8 reg_spm_adsp_mailbox_req; + u8 reg_spm_apsrc_req; + u8 reg_spm_ddren_req; + u8 reg_spm_dvfs_req; + u8 reg_spm_emi_req; + u8 reg_spm_f26m_req; + u8 reg_spm_infra_req; + u8 reg_spm_pmic_req; + u8 reg_spm_scp_mailbox_req; + u8 reg_spm_sspm_mailbox_req; + u8 reg_spm_sw_mailbox_req; + u8 reg_spm_vcore_req; + u8 reg_spm_vrf18_req; + u8 adsp_mailbox_state; + u8 apsrc_state; + u8 ddren_state; + u8 dvfs_state; + u8 emi_state; + u8 f26m_state; + u8 infra_state; + u8 pmic_state; + u8 scp_mailbox_state; + u8 sspm_mailbox_state; + u8 sw_mailbox_state; + u8 vcore_state; + u8 vrf18_state; + + /* SPM_SRC_MASK_0 */ + u8 reg_apu_apsrc_req_mask_b; + u8 reg_apu_ddren_req_mask_b; + u8 reg_apu_emi_req_mask_b; + u8 reg_apu_infra_req_mask_b; + u8 reg_apu_pmic_req_mask_b; + u8 reg_apu_srcclkena_mask_b; + u8 reg_apu_vrf18_req_mask_b; + u8 reg_audio_dsp_apsrc_req_mask_b; + u8 reg_audio_dsp_ddren_req_mask_b; + u8 reg_audio_dsp_emi_req_mask_b; + u8 reg_audio_dsp_infra_req_mask_b; + u8 reg_audio_dsp_pmic_req_mask_b; + u8 reg_audio_dsp_srcclkena_mask_b; + u8 reg_audio_dsp_vcore_req_mask_b; + u8 reg_audio_dsp_vrf18_req_mask_b; + u8 reg_cam_apsrc_req_mask_b; + u8 reg_cam_ddren_req_mask_b; + u8 reg_cam_emi_req_mask_b; + u8 reg_cam_infra_req_mask_b; + u8 reg_cam_pmic_req_mask_b; + u8 reg_cam_srcclkena_mask_b; + u8 reg_cam_vrf18_req_mask_b; + u8 reg_mdp_emi_req_mask_b; + + /* SPM_SRC_MASK_1 */ + u32 reg_ccif_apsrc_req_mask_b; + u32 reg_ccif_emi_req_mask_b; + + /* SPM_SRC_MASK_2 */ + u32 reg_ccif_infra_req_mask_b; + u32 reg_ccif_pmic_req_mask_b; + + /* SPM_SRC_MASK_3 */ + u32 reg_ccif_srcclkena_mask_b; + u32 reg_ccif_vrf18_req_mask_b; + u8 reg_ccu_apsrc_req_mask_b; + u8 reg_ccu_ddren_req_mask_b; + u8 reg_ccu_emi_req_mask_b; + u8 reg_ccu_infra_req_mask_b; + u8 reg_ccu_pmic_req_mask_b; + u8 reg_ccu_srcclkena_mask_b; + u8 reg_ccu_vrf18_req_mask_b; + u8 reg_cg_check_apsrc_req_mask_b; + + /* SPM_SRC_MASK_4 */ + u8 reg_cg_check_ddren_req_mask_b; + u8 reg_cg_check_emi_req_mask_b; + u8 reg_cg_check_infra_req_mask_b; + u8 reg_cg_check_pmic_req_mask_b; + u8 reg_cg_check_srcclkena_mask_b; + u8 reg_cg_check_vcore_req_mask_b; + u8 reg_cg_check_vrf18_req_mask_b; + u8 reg_conn_apsrc_req_mask_b; + u8 reg_conn_ddren_req_mask_b; + u8 reg_conn_emi_req_mask_b; + u8 reg_conn_infra_req_mask_b; + u8 reg_conn_pmic_req_mask_b; + u8 reg_conn_srcclkena_mask_b; + u8 reg_conn_srcclkenb_mask_b; + u8 reg_conn_vcore_req_mask_b; + u8 reg_conn_vrf18_req_mask_b; + u8 reg_cpueb_apsrc_req_mask_b; + u8 reg_cpueb_ddren_req_mask_b; + u8 reg_cpueb_emi_req_mask_b; + u8 reg_cpueb_infra_req_mask_b; + u8 reg_cpueb_pmic_req_mask_b; + u8 reg_cpueb_srcclkena_mask_b; + u8 reg_cpueb_vrf18_req_mask_b; + u8 reg_disp0_apsrc_req_mask_b; + u8 reg_disp0_ddren_req_mask_b; + u8 reg_disp0_emi_req_mask_b; + u8 reg_disp0_infra_req_mask_b; + u8 reg_disp0_pmic_req_mask_b; + u8 reg_disp0_srcclkena_mask_b; + u8 reg_disp0_vrf18_req_mask_b; + u8 reg_disp1_apsrc_req_mask_b; + u8 reg_disp1_ddren_req_mask_b; + + /* SPM_SRC_MASK_5 */ + u8 reg_disp1_emi_req_mask_b; + u8 reg_disp1_infra_req_mask_b; + u8 reg_disp1_pmic_req_mask_b; + u8 reg_disp1_srcclkena_mask_b; + u8 reg_disp1_vrf18_req_mask_b; + u8 reg_dpm_apsrc_req_mask_b; + u8 reg_dpm_ddren_req_mask_b; + u8 reg_dpm_emi_req_mask_b; + u8 reg_dpm_infra_req_mask_b; + u8 reg_dpm_pmic_req_mask_b; + u8 reg_dpm_srcclkena_mask_b; + + /* SPM_SRC_MASK_6 */ + u8 reg_dpm_vcore_req_mask_b; + u8 reg_dpm_vrf18_req_mask_b; + u8 reg_dpmaif_apsrc_req_mask_b; + u8 reg_dpmaif_ddren_req_mask_b; + u8 reg_dpmaif_emi_req_mask_b; + u8 reg_dpmaif_infra_req_mask_b; + u8 reg_dpmaif_pmic_req_mask_b; + u8 reg_dpmaif_srcclkena_mask_b; + u8 reg_dpmaif_vrf18_req_mask_b; + u8 reg_dvfsrc_level_req_mask_b; + u8 reg_emisys_apsrc_req_mask_b; + u8 reg_emisys_ddren_req_mask_b; + u8 reg_emisys_emi_req_mask_b; + u8 reg_gce_d_apsrc_req_mask_b; + u8 reg_gce_d_ddren_req_mask_b; + u8 reg_gce_d_emi_req_mask_b; + u8 reg_gce_d_infra_req_mask_b; + u8 reg_gce_d_pmic_req_mask_b; + u8 reg_gce_d_srcclkena_mask_b; + u8 reg_gce_d_vrf18_req_mask_b; + u8 reg_gce_m_apsrc_req_mask_b; + u8 reg_gce_m_ddren_req_mask_b; + u8 reg_gce_m_emi_req_mask_b; + u8 reg_gce_m_infra_req_mask_b; + u8 reg_gce_m_pmic_req_mask_b; + u8 reg_gce_m_srcclkena_mask_b; + + /* SPM_SRC_MASK_7 */ + u8 reg_gce_m_vrf18_req_mask_b; + u8 reg_gpueb_apsrc_req_mask_b; + u8 reg_gpueb_ddren_req_mask_b; + u8 reg_gpueb_emi_req_mask_b; + u8 reg_gpueb_infra_req_mask_b; + u8 reg_gpueb_pmic_req_mask_b; + u8 reg_gpueb_srcclkena_mask_b; + u8 reg_gpueb_vrf18_req_mask_b; + u8 reg_hwccf_apsrc_req_mask_b; + u8 reg_hwccf_ddren_req_mask_b; + u8 reg_hwccf_emi_req_mask_b; + u8 reg_hwccf_infra_req_mask_b; + u8 reg_hwccf_pmic_req_mask_b; + u8 reg_hwccf_srcclkena_mask_b; + u8 reg_hwccf_vcore_req_mask_b; + u8 reg_hwccf_vrf18_req_mask_b; + u8 reg_img_apsrc_req_mask_b; + u8 reg_img_ddren_req_mask_b; + u8 reg_img_emi_req_mask_b; + u8 reg_img_infra_req_mask_b; + u8 reg_img_pmic_req_mask_b; + u8 reg_img_srcclkena_mask_b; + u8 reg_img_vrf18_req_mask_b; + u8 reg_infrasys_apsrc_req_mask_b; + u8 reg_infrasys_ddren_req_mask_b; + u8 reg_infrasys_emi_req_mask_b; + u8 reg_ipic_infra_req_mask_b; + u8 reg_ipic_vrf18_req_mask_b; + u8 reg_mcu_apsrc_req_mask_b; + u8 reg_mcu_ddren_req_mask_b; + u8 reg_mcu_emi_req_mask_b; + + /* SPM_SRC_MASK_8 */ + u8 reg_mcusys_apsrc_req_mask_b; + u8 reg_mcusys_ddren_req_mask_b; + u8 reg_mcusys_emi_req_mask_b; + u8 reg_mcusys_infra_req_mask_b; + + /* SPM_SRC_MASK_9 */ + u8 reg_mcusys_pmic_req_mask_b; + u8 reg_mcusys_srcclkena_mask_b; + u8 reg_mcusys_vrf18_req_mask_b; + u8 reg_md_apsrc_req_mask_b; + u8 reg_md_ddren_req_mask_b; + u8 reg_md_emi_req_mask_b; + u8 reg_md_infra_req_mask_b; + u8 reg_md_pmic_req_mask_b; + u8 reg_md_srcclkena_mask_b; + u8 reg_md_srcclkena1_mask_b; + u8 reg_md_vcore_req_mask_b; + + /* SPM_SRC_MASK_10 */ + u8 reg_md_vrf18_req_mask_b; + u8 reg_mdp_apsrc_req_mask_b; + u8 reg_mdp_ddren_req_mask_b; + u8 reg_mm_proc_apsrc_req_mask_b; + u8 reg_mm_proc_ddren_req_mask_b; + u8 reg_mm_proc_emi_req_mask_b; + u8 reg_mm_proc_infra_req_mask_b; + u8 reg_mm_proc_pmic_req_mask_b; + u8 reg_mm_proc_srcclkena_mask_b; + u8 reg_mm_proc_vrf18_req_mask_b; + u8 reg_mmsys_apsrc_req_mask_b; + u8 reg_mmsys_ddren_req_mask_b; + u8 reg_mmsys_vrf18_req_mask_b; + u8 reg_pcie0_apsrc_req_mask_b; + u8 reg_pcie0_ddren_req_mask_b; + u8 reg_pcie0_infra_req_mask_b; + u8 reg_pcie0_srcclkena_mask_b; + u8 reg_pcie0_vrf18_req_mask_b; + u8 reg_pcie1_apsrc_req_mask_b; + u8 reg_pcie1_ddren_req_mask_b; + u8 reg_pcie1_infra_req_mask_b; + u8 reg_pcie1_srcclkena_mask_b; + u8 reg_pcie1_vrf18_req_mask_b; + u8 reg_perisys_apsrc_req_mask_b; + u8 reg_perisys_ddren_req_mask_b; + u8 reg_perisys_emi_req_mask_b; + u8 reg_perisys_infra_req_mask_b; + u8 reg_perisys_pmic_req_mask_b; + u8 reg_perisys_srcclkena_mask_b; + u8 reg_perisys_vcore_req_mask_b; + u8 reg_perisys_vrf18_req_mask_b; + u8 reg_scp_apsrc_req_mask_b; + + /* SPM_SRC_MASK_11 */ + u8 reg_scp_ddren_req_mask_b; + u8 reg_scp_emi_req_mask_b; + u8 reg_scp_infra_req_mask_b; + u8 reg_scp_pmic_req_mask_b; + u8 reg_scp_srcclkena_mask_b; + u8 reg_scp_vcore_req_mask_b; + u8 reg_scp_vrf18_req_mask_b; + u8 reg_srcclkeni_infra_req_mask_b; + u8 reg_srcclkeni_pmic_req_mask_b; + u8 reg_srcclkeni_srcclkena_mask_b; + u8 reg_sspm_apsrc_req_mask_b; + u8 reg_sspm_ddren_req_mask_b; + u8 reg_sspm_emi_req_mask_b; + u8 reg_sspm_infra_req_mask_b; + u8 reg_sspm_pmic_req_mask_b; + u8 reg_sspm_srcclkena_mask_b; + u8 reg_sspm_vrf18_req_mask_b; + u8 reg_ssr_apsrc_req_mask_b; + u8 reg_ssr_ddren_req_mask_b; + u8 reg_ssr_emi_req_mask_b; + u8 reg_ssr_infra_req_mask_b; + u8 reg_ssr_pmic_req_mask_b; + u8 reg_ssr_srcclkena_mask_b; + u8 reg_ssr_vrf18_req_mask_b; + u8 reg_ufs_apsrc_req_mask_b; + u8 reg_ufs_ddren_req_mask_b; + u8 reg_ufs_emi_req_mask_b; + u8 reg_ufs_infra_req_mask_b; + u8 reg_ufs_pmic_req_mask_b; + + /* SPM_SRC_MASK_12 */ + u8 reg_ufs_srcclkena_mask_b; + u8 reg_ufs_vrf18_req_mask_b; + u8 reg_vdec_apsrc_req_mask_b; + u8 reg_vdec_ddren_req_mask_b; + u8 reg_vdec_emi_req_mask_b; + u8 reg_vdec_infra_req_mask_b; + u8 reg_vdec_pmic_req_mask_b; + u8 reg_vdec_srcclkena_mask_b; + u8 reg_vdec_vrf18_req_mask_b; + u8 reg_venc_apsrc_req_mask_b; + u8 reg_venc_ddren_req_mask_b; + u8 reg_venc_emi_req_mask_b; + u8 reg_venc_infra_req_mask_b; + u8 reg_venc_pmic_req_mask_b; + u8 reg_venc_srcclkena_mask_b; + u8 reg_venc_vrf18_req_mask_b; + u8 reg_ipe_apsrc_req_mask_b; + u8 reg_ipe_ddren_req_mask_b; + u8 reg_ipe_emi_req_mask_b; + u8 reg_ipe_infra_req_mask_b; + u8 reg_ipe_pmic_req_mask_b; + u8 reg_ipe_srcclkena_mask_b; + u8 reg_ipe_vrf18_req_mask_b; + u8 reg_ufs_vcore_req_mask_b; + + /* SPM_EVENT_CON_MISC */ + u8 reg_srcclken_fast_resp; + u8 reg_csyspwrup_ack_mask; + + /* SPM_WAKEUP_EVENT_MASK */ + u32 reg_wakeup_event_mask; + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + u32 reg_ext_wakeup_event_mask; +}; + +struct mtk_spm_regs { + u32 poweron_config_set; + u32 spm_power_on_val[4]; + u32 pcm_pwr_io_en; + u32 pcm_con0; + u32 pcm_con1; + u32 spm_sram_sleep_ctrl; + u32 spm_clk_con; + u32 spm_clk_settle; + u32 spm_clk_con1; + u8 reserved0[16]; + u32 spm_sw_rst_con; + u32 spm_sw_rst_con_set; + u32 spm_sw_rst_con_clr; + u8 reserved1[4]; + u32 spm_sec_read_mask; + u32 spm_one_time_lock_l; + u32 spm_one_time_lock_m; + u32 spm_one_time_lock_h; + u8 reserved2[36]; + u32 sspm_clk_con; + u32 scp_clk_con; + u8 reserved3[4]; + u32 spm_swint; + u32 spm_swint_set; + u32 spm_swint_clr; + u8 reserved4[20]; + u32 spm_cpu_wakeup_event; + u32 spm_irq_mask; + u8 reserved5[72]; + u32 md32pcm_scu_ctrl[4]; + u32 md32pcm_scu_sta0; + u8 reserved6[20]; + u32 spm_irq_sta; + u8 reserved7[4]; + u32 md32pcm_wakeup_sta; + u32 md32pcm_event_sta; + u8 reserved8[8]; + u32 spm_wakeup_misc; + u8 reserved9[32]; + u32 spm_ck_sta; + u8 reserved10[40]; + u32 md32pcm_sta; + u32 md32pcm_pc; + u8 reserved11[104]; + u32 spm_ap_standby_con; + u32 cpu_wfi_en; + u32 cpu_wfi_en_set; + u32 cpu_wfi_en_clr; + u32 ext_int_wakeup_req; + u32 ext_int_wakeup_req_set; + u32 ext_int_wakeup_req_clr; + u32 mcusys_idle_sta; + u32 cpu_pwr_status; + u32 sw2spm_wakeup; + u32 sw2spm_wakeup_set; + u32 sw2spm_wakeup_clr; + u32 sw2spm_mailbox[4]; + u32 spm2sw_mailbox[4]; + u32 spm2mcupm_con; + u8 reserved12[12]; + u32 spm_mcusys_pwr_con; + u32 spm_cputop_pwr_con; + u32 spm_cpu0_pwr_con; + u32 spm_cpu1_pwr_con; + u32 spm_cpu2_pwr_con; + u32 spm_cpu3_pwr_con; + u32 spm_cpu4_pwr_con; + u32 spm_cpu5_pwr_con; + u32 spm_cpu6_pwr_con; + u32 spm_cpu7_pwr_con; + u32 spm_mcupm_spmc_con; + u8 reserved13[20]; + u32 spm_dpm_p2p_sta; + u32 spm_dpm_p2p_con; + u32 spm_dpm_intf_sta; + u32 spm_dpm_wb_con; + u32 spm_ack_chk_timer_3; + u32 spm_ack_chk_sta_3; + u8 reserved14[72]; + u32 spm_pwrap_con; + u32 spm_pwrap_con_sta; + u32 spm_pmic_spmi_con; + u8 reserved15[4]; + u32 spm_pwrap_cmd[32]; + u32 dvfsrc_event_sta; + u32 spm_force_dvfs; + u32 spm_dvfs_sta; + u32 spm_dvs_dfs_level; + u32 spm_dvfs_level; + u32 spm_dvfs_opp; + u32 spm_ultra_req; + u32 spm_dvfs_con; + u32 spm_sramrc_con; + u32 spm_srclkenrc_con; + u32 spm_dpsw_con; + u8 reserved16[68]; + u32 ulposc_con; + u32 ap_mdsrc_req; + u32 spm2md_switch_ctrl; + u32 rc_spm_ctrl; + u32 spm2gpupm_con; + u32 spm2apu_con; + u32 spm2efuse_con; + u32 spm2dfd_con; + u32 rsv_pll_con; + u32 emi_slb_con; + u32 spm_suspend_flag_con; + u32 spm2pmsr_con; + u32 spm_topck_rtff_con; + u32 emi_shf_con; + u32 cirq_byoass_con; + u32 aoc_vcore_sram_con; + u8 reserved17[32]; + u32 reg_module_sw_cg_ddren_req_mask_0; + u32 reg_module_sw_cg_ddren_req_mask_1; + u32 reg_module_sw_cg_ddren_req_mask_2; + u32 reg_module_sw_cg_ddren_req_mask_3; + u32 reg_module_sw_cg_vrf18_req_mask_0; + u32 reg_module_sw_cg_vrf18_req_mask_1; + u32 reg_module_sw_cg_vrf18_req_mask_2; + u32 reg_module_sw_cg_vrf18_req_mask_3; + u32 reg_module_sw_cg_infra_req_mask_0; + u32 reg_module_sw_cg_infra_req_mask_1; + u32 reg_module_sw_cg_infra_req_mask_2; + u32 reg_module_sw_cg_infra_req_mask_3; + u32 reg_module_sw_cg_f26m_req_mask_0; + u32 reg_module_sw_cg_f26m_req_mask_1; + u32 reg_module_sw_cg_f26m_req_mask_2; + u32 reg_module_sw_cg_f26m_req_mask_3; + u32 reg_module_sw_cg_vcore_req_mask_0; + u32 reg_module_sw_cg_vcore_req_mask_1; + u32 reg_module_sw_cg_vcore_req_mask_2; + u32 reg_module_sw_cg_vcore_req_mask_3; + u32 reg_pwr_status_ddren_req_mask; + u32 reg_pwr_status_vrf18_req_mask; + u32 reg_pwr_status_infra_req_mask; + u32 reg_pwr_status_f26m_req_mask; + u32 reg_pwr_status_pmic_req_mask; + u32 reg_pwr_status_vcore_req_mask; + u32 reg_pwr_status_msb_ddren_req_mask; + u32 reg_pwr_status_msb_vrf18_req_mask; + u32 reg_pwr_status_msb_infra_req_mask; + u32 reg_pwr_status_msb_f26m_req_mask; + u32 reg_pwr_status_msb_pmic_req_mask; + u32 reg_pwr_status_msb_vcore_req_mask; + u32 reg_module_busy_msb_ddren_req_mask; + u32 reg_module_busy_msb_vrf18_req_mask; + u32 reg_module_busy_msb_infra_req_mask; + u32 reg_module_busy_msb_f26m_req_mask; + u32 reg_module_busy_msb_pmic_req_mask; + u32 reg_module_busy_msb_vcore_req_mask; + u8 reserved18[8]; + u32 sys_timer_con; + u32 sys_timer_value_l; + u32 sys_timer_value_h; + u32 sys_timer_start_l; + u32 sys_timer_start_h; + struct { + u32 latch_l; + u32 latch_h; + } sys_timer_latch[16]; + u32 pcm_timer_val; + u32 pcm_timer_out; + u32 spm_counter_0; + u32 spm_counter_1; + u32 spm_counter_2; + u32 pcm_wdt_val; + u32 pcm_wdt_out; + u8 reserved19[80]; + u32 spm_sw_flag_0; + u32 spm_sw_debug_0; + u32 spm_sw_flag_1; + u32 spm_sw_debug_1; + u32 spm_sw_rsv[9]; + u32 spm_bk_wake_event; + u32 spm_bk_vtcxo_dur; + u32 spm_bk_wake_misc; + u32 spm_bk_pcm_timer; + u8 reserved20[12]; + u32 spm_rsv_con_0; + u32 spm_rsv_con_1; + u32 spm_rsv_sta_0; + u32 spm_rsv_sta_1; + u32 spm_spare_con; + u32 spm_spare_con_set; + u32 spm_spare_con_clr; + u32 spm_cross_wake_m00_req; + u32 spm_cross_wake_m01_req; + u32 spm_cross_wake_m02_req; + u32 spm_cross_wake_m03_req; + u32 scp_vcore_level; + u32 spm_ddren_ack_sel_con; + u32 spm_sw_flag_2; + u32 spm_sw_debug_2; + u32 spm_dv_con_0; + u32 spm_dv_con_1; + u8 reserved21[8]; + u32 spm_sema_m0; + u32 spm_sema_m1; + u32 spm_sema_m2; + u32 spm_sema_m3; + u32 spm_sema_m4; + u32 spm_sema_m5; + u32 spm_sema_m6; + u32 spm_sema_m7; + u32 spm2adsp_mailbox; + u32 adsp2spm_mailbox; + u32 vcore_rtff_ctrl_mask_set; + u32 vcore_rtff_ctrl_mask_clr; + u32 spm2pmcu_mailbox_0; + u32 spm2pmcu_mailbox_1; + u32 spm2pmcu_mailbox_2; + u32 spm2pmcu_mailbox_3; + u32 pmcu2spm_mailbox_0; + u32 pmcu2spm_mailbox_1; + u32 pmcu2spm_mailbox_2; + u32 pmcu2spm_mailbox_3; + u32 spm2scp_mailbox; + u32 scp2spm_mailbox; + u32 scp_aov_bus_con; + u32 vcore_rtff_ctrl_mask; + u32 spm_sram_srclkeno_mask; + u32 emi_pdn_req; + u32 emi_busy_req; + u32 emi_reserved_sta; + u32 sc_univpll_div_rst_b; + u32 eco_armpll_div_clock_off; + u32 spm_mcdsr_cg_check_x1; + u32 spm_sodi2_cg_check_x1; + u8 reserved22[228]; + u32 spm_wakeup_sta; + u32 spm_wakeup_ext_sta; + u32 spm_wakeup_event_mask; + u32 spm_wakeup_event_ext_mask; + u32 spm_wakeup_event_sens; + u32 spm_wakeup_event_clear; + u32 spm_src_req; + u32 spm_src_mask_0; + u32 spm_src_mask_1; + u32 spm_src_mask_2; + u32 spm_src_mask_3; + u32 spm_src_mask_4; + u32 spm_src_mask_5; + u32 spm_src_mask_6; + u32 spm_src_mask_7; + u32 spm_src_mask_8; + u32 spm_src_mask_9; + u32 spm_src_mask_10; + u32 spm_src_mask_11; + u32 spm_src_mask_12; + u32 src_req_sta_0; + u32 src_req_sta_1; + u32 src_req_sta_2; + u32 src_req_sta_3; + u32 src_req_sta_4; + u32 src_req_sta_5; + u32 src_req_sta_6; + u32 src_req_sta_7; + u32 src_req_sta_8; + u32 src_req_sta_9; + u32 src_req_sta_10; + u32 src_req_sta_11; + u32 src_req_sta_12; + u32 spm_ipc_wakeup_req; + u32 ipc_wakeup_req_mask_sta; + u32 spm_event_con_misc; + u32 ddren_dbc_con; + u32 spm_resource_ack_con0; + u32 spm_resource_ack_con1; + u32 spm_resource_ack_mask0; + u32 spm_resource_ack_mask1; + u32 spm_resource_ack_mask2; + u32 spm_resource_ack_mask3; + u32 spm_resource_ack_mask4; + u32 spm_resource_ack_mask5; + u32 spm_resource_ack_mask6; + u32 spm_event_counter_clear; + u32 spm_vcore_event_count_sta; + u32 spm_pmic_event_count_sta; + u32 spm_srcclkena_event_count_sta; + u32 spm_infra_event_count_sta; + u32 spm_vrf18_event_count_sta; + u32 spm_emi_event_count_sta; + u32 spm_apsrc_event_count_sta; + u32 spm_ddren_event_count_sta; + u32 pcm_wdt_latch_0; + u32 pcm_wdt_latch_1; + u32 pcm_wdt_latch_2; + u32 pcm_wdt_latch_3; + u32 pcm_wdt_latch_4; + u32 pcm_wdt_latch_5; + u32 pcm_wdt_latch_6; + u32 pcm_wdt_latch_7; + u32 pcm_wdt_latch_8; + u32 pcm_wdt_latch_9; + u32 pcm_wdt_latch_10; + u32 pcm_wdt_latch_11; + u32 pcm_wdt_latch_12; + u32 pcm_wdt_latch_13; + u32 pcm_wdt_latch_14; + u32 pcm_wdt_latch_15; + u32 pcm_wdt_latch_16; + u32 pcm_wdt_latch_17; + u32 pcm_wdt_latch_18; + u32 pcm_wdt_latch_19; + u32 pcm_wdt_latch_20; + u32 pcm_wdt_latch_21; + u32 pcm_wdt_latch_22; + u32 pcm_wdt_latch_23; + u32 pcm_wdt_latch_24; + u32 pcm_wdt_latch_25; + u32 pcm_wdt_latch_26; + u32 pcm_wdt_latch_27; + u32 pcm_wdt_latch_28; + u32 pcm_wdt_latch_29; + u32 pcm_wdt_latch_30; + u32 pcm_wdt_latch_31; + u32 pcm_wdt_latch_32; + u32 pcm_wdt_latch_33; + u32 pcm_wdt_latch_34; + u32 pcm_wdt_latch_35; + u32 pcm_wdt_latch_36; + u32 pcm_wdt_latch_37; + u32 pcm_wdt_latch_38; + u32 pcm_wdt_latch_39; + u32 pcm_wdt_latch_40; + u32 pcm_wdt_latch_spare_0; + u32 pcm_wdt_latch_spare_1; + u32 pcm_wdt_latch_spare_2; + u32 pcm_wdt_latch_spare_3; + u32 pcm_wdt_latch_spare_4; + u32 pcm_wdt_latch_spare_5; + u32 pcm_wdt_latch_spare_6; + u32 pcm_wdt_latch_spare_7; + u32 pcm_wdt_latch_spare_8; + u32 pcm_wdt_latch_spare_9; + u32 dramc_gating_err_latch_0; + u32 dramc_gating_err_latch_1; + u32 dramc_gating_err_latch_2; + u32 dramc_gating_err_latch_3; + u32 dramc_gating_err_latch_4; + u32 dramc_gating_err_latch_5; + u32 dramc_gating_err_latch_spare_0; + u32 spm_debug_con; + u32 spm_ack_chk_con_0; + u32 spm_ack_chk_sel_0; + u32 spm_ack_chk_timer_0; + u32 spm_ack_chk_sta_0; + u32 spm_ack_chk_con_1; + u32 spm_ack_chk_sel_1; + u32 spm_ack_chk_timer_1; + u32 spm_ack_chk_sta_1; + u32 spm_ack_chk_con_2; + u32 spm_ack_chk_sel_2; + u32 spm_ack_chk_timer_2; + u32 spm_ack_chk_sta_2; + u32 spm_ack_chk_con_3; + u32 spm_ack_chk_sel_3; + u8 reserved23[1024]; + u32 md1_pwr_con; + u32 conn_pwr_con; + u32 ifr_pwr_con; + u32 peri_pwr_con; + u32 ufs0_pwr_con; + u32 ufs0_phy_pwr_con; + u32 audio_pwr_con; + u32 adsp_top_pwr_con; + u32 adsp_infra_pwr_con; + u32 adsp_ao_pwr_con; + u32 isp_img1_pwr_con; + u32 isp_img2_pwr_con; + u32 isp_ipe_pwr_con; + u32 isp_vcore_pwr_con; + u32 vde0_pwr_con; + u32 vde1_pwr_con; + u32 ven0_pwr_con; + u32 ven1_pwr_con; + u32 cam_main_pwr_con; + u32 cam_mraw_pwr_con; + u32 cam_suba_pwr_con; + u32 cam_subb_pwr_con; + u32 cam_subc_pwr_con; + u32 cam_vcore_pwr_con; + u32 cam_ccu_pwr_con; + u32 cam_ccu_ao_pwr_con; + u32 mdp0_pwr_con; + u32 mdp1_pwr_con; + u32 dis0_pwr_con; + u32 dis1_pwr_con; + u32 mm_infra_pwr_con; + u32 mm_proc_pwr_con; + u32 dp_tx_pwr_con; + u32 scp_core_pwr_con; + u32 scp_peri_pwr_con; + u32 dpm0_pwr_con; + u32 dpm1_pwr_con; + u32 emi0_pwr_con; + u32 emi1_pwr_con; + u32 csi_rx_pwr_con; + u32 ssrsys_pwr_con; + u32 sspm_pwr_con; + u32 ssusb_pwr_con; + u32 ssusb_phy_pwr_con; + u32 cpueb_pwr_con; + u32 mfg0_pwr_con; + u32 mfg1_pwr_con; + u32 mfg2_pwr_con; + u32 mfg3_pwr_con; + u32 mfg4_pwr_con; + u32 mfg5_pwr_con; + u32 mfg6_pwr_con; + u32 mfg7_pwr_con; + u32 adsp_hre_sram_con; + u32 ccu_sleep_sram_con; + u32 efuse_sram_con; + u32 emi_hre_sram_con; + u32 emi_slb_sram_con; + u32 infra_hre_sram_con; + u32 infra_sleep_sram_con; + u32 mm_hre_sram_con; + u32 nth_emi_slb_sram_con; + u32 nth_emi_slb_sram_ack; + u32 peri_sleep_sram_con; + u32 spm_sram_con; + u32 sspm_sram_con; + u32 ssr_sleep_sram_con; + u32 sth_emi_slb_sram_con; + u32 sth_emi_slb_sram_ack; + u32 ufs_pdn_sram_con; + u32 ufs_sleep_sram_con; + u32 unipro_pdn_sram_con; + u32 cpu_buck_iso_con; + u32 md_buck_iso_con; + u32 soc_buck_iso_con; + u32 soc_buck_iso_con_set; + u32 soc_buck_iso_con_clr; + u32 soc_buck_iso_con_2; + u32 soc_buck_iso_con_2_set; + u32 soc_buck_iso_con_2_clr; + u32 pwr_status; + u32 pwr_status_2nd; + u32 pwr_status_msb; + u32 pwr_status_msb_2nd; + u32 xpu_pwr_status; + u32 xpu_pwr_status_2nd; + u32 dfd_soc_pwr_latch; + u32 subsys_pm_bypass; + u32 vadsp_hre_sram_con; + u32 vadsp_hre_sram_ack; + u32 gcpu_sram_con; + u32 gcpu_sram_ack; + u32 edp_tx_pwr_con; + u32 pcie_pwr_con; + u32 pcie_phy_pwr_con; + u8 reserved24[4]; + u32 spm_twam_con; + u32 spm_twam_window_len; + u32 spm_twam_idle_sel; + u32 spm_twam_last_sta0; + u32 spm_twam_last_sta1; + u32 spm_twam_last_sta2; + u32 spm_twam_last_sta3; + u32 spm_twam_curr_sta0; + u32 spm_twam_curr_sta1; + u32 spm_twam_curr_sta2; + u32 spm_twam_curr_sta3; + u32 spm_twam_timer_out; +}; + +check_member(mtk_spm_regs, ap_mdsrc_req, 0x404); +check_member(mtk_spm_regs, ulposc_con, 0x400); +check_member(mtk_spm_regs, conn_pwr_con, 0x0E04); +check_member(mtk_spm_regs, ufs0_pwr_con, 0x0E10); +check_member(mtk_spm_regs, audio_pwr_con, 0xe18); +check_member(mtk_spm_regs, vde0_pwr_con, 0x0E38); +check_member(mtk_spm_regs, ven0_pwr_con, 0x0E40); +check_member(mtk_spm_regs, cam_main_pwr_con, 0x0E48); +check_member(mtk_spm_regs, cam_suba_pwr_con, 0x0E50); +check_member(mtk_spm_regs, mdp0_pwr_con, 0x0E68); +check_member(mtk_spm_regs, dis0_pwr_con, 0x0E70); +check_member(mtk_spm_regs, mm_infra_pwr_con, 0x0E78); +check_member(mtk_spm_regs, dp_tx_pwr_con, 0x0E80); +check_member(mtk_spm_regs, scp_peri_pwr_con, 0x0E88); +check_member(mtk_spm_regs, csi_rx_pwr_con, 0x0E9C); +check_member(mtk_spm_regs, ssusb_pwr_con, 0x0EA8); +check_member(mtk_spm_regs, mfg0_pwr_con, 0x0EB4); +check_member(mtk_spm_regs, mfg3_pwr_con, 0x0EC0); +check_member(mtk_spm_regs, pwr_status, 0x0F40); +check_member(mtk_spm_regs, edp_tx_pwr_con, 0x0F70); + +static struct mtk_spm_regs *const mtk_spm = (void *)SPM_BASE; + +static const struct power_domain_data disp[] = { + { + /* dis0 */ + .pwr_con = &mtk_spm->dis0_pwr_con, + .pwr_sta_mask = BIT(28), + .sram_pdn_mask = BIT(8), + .sram_ack_mask = BIT(12), + }, + { + /* edp_tx */ + .pwr_con = &mtk_spm->edp_tx_pwr_con, + .pwr_status = &mtk_spm->pwr_status_msb, + .pwr_status_2nd = &mtk_spm->pwr_status_msb_2nd, + .pwr_sta_mask = BIT(12), + .sram_pdn_mask = BIT(8), + .sram_ack_mask = BIT(12), + .caps = SCPD_SRAM_ISO, + }, +}; + +static const struct power_domain_data audio[] = { + { + /* adsp_ao */ + .pwr_con = &mtk_spm->adsp_ao_pwr_con, + .pwr_sta_mask = BIT(9), + }, + { + /* audio */ + .pwr_con = &mtk_spm->audio_pwr_con, + .pwr_sta_mask = BIT(6), + .sram_pdn_mask = BIT(8), + .sram_ack_mask = BIT(12), + }, +}; + +#endif /* __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_H__ */ diff --git a/src/soc/mediatek/mt8189/include/soc/spm_mtcmos.h b/src/soc/mediatek/mt8189/include/soc/spm_mtcmos.h new file mode 100644 index 000000000000..f9b9f473a654 --- /dev/null +++ b/src/soc/mediatek/mt8189/include/soc/spm_mtcmos.h @@ -0,0 +1,91 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +#ifndef __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_MTCMOS_H__ +#define __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_MTCMOS_H__ + +#include <device/mmio.h> +#include <soc/addressmap.h> +#include <types.h> + +struct mtk_reg_cfg { + u32 status; + u32 set; + u32 clr; + u32 ready; +}; + +struct mtk_vlpcfg_regs { + u32 reserved1; + u32 vlp_test_ck_ctrl; + u32 reserved2[130]; + u32 bus_vlp_topaxi_protecten; + u32 bus_vlp_topaxi_protecten_set; + u32 bus_vlp_topaxi_protecten_clr; + u32 bus_vlp_topaxi_protecten_sta1; +}; +check_member(mtk_vlpcfg_regs, vlp_test_ck_ctrl, 0x0004); +check_member(mtk_vlpcfg_regs, bus_vlp_topaxi_protecten, 0x0210); + +struct mtk_infracfg_ao_regs { + u32 reserved1[28]; + u32 infra_bus_dcm_ctrl; + u32 reserved2[3]; + u32 infracfg_ao_module_cg_0_set; + u32 infracfg_ao_module_cg_0_clr; + u32 infracfg_ao_module_cg_1_set; + u32 infracfg_ao_module_cg_1_clr; + u32 infracfg_ao_module_cg_0; + u32 infracfg_ao_module_cg_1; + u32 reserved3[3]; + u32 infracfg_ao_module_cg_2_set; + u32 infracfg_ao_module_cg_2_clr; + u32 infracfg_ao_module_cg_2; + u32 reserved4[4]; + u32 infracfg_ao_module_cg_3_set; + u32 infracfg_ao_module_cg_3_clr; + u32 infracfg_ao_module_cg_3; + u32 reserved5[721]; + struct mtk_reg_cfg mmsys_protect[2]; + u32 reserved6[4]; + struct mtk_reg_cfg infrasys_protect[2]; + struct mtk_reg_cfg emisys_protect; + u32 reserved7[4]; + struct mtk_reg_cfg perisys_protect; + struct mtk_reg_cfg mcu_connsys_protect; + struct mtk_reg_cfg md_mfgsys_protect; +}; +check_member(mtk_infracfg_ao_regs, infra_bus_dcm_ctrl, 0x0070); +check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_0_set, 0x0080); +check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_1, 0x0094); +check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_2_set, 0x00A4); +check_member(mtk_infracfg_ao_regs, infracfg_ao_module_cg_3_set, 0x00C0); +check_member(mtk_infracfg_ao_regs, mmsys_protect[0].status, 0x0C10); +check_member(mtk_infracfg_ao_regs, mmsys_protect[0].set, 0x0C14); +check_member(mtk_infracfg_ao_regs, mmsys_protect[0].clr, 0x0C18); +check_member(mtk_infracfg_ao_regs, mmsys_protect[0].ready, 0x0C1C); +check_member(mtk_infracfg_ao_regs, infrasys_protect[0].status, 0x0C40); +check_member(mtk_infracfg_ao_regs, infrasys_protect[0].set, 0x0C44); +check_member(mtk_infracfg_ao_regs, infrasys_protect[0].clr, 0x0C48); +check_member(mtk_infracfg_ao_regs, infrasys_protect[0].ready, 0x0C4C); +check_member(mtk_infracfg_ao_regs, perisys_protect.status, 0x0C80); +check_member(mtk_infracfg_ao_regs, perisys_protect.set, 0x0C84); +check_member(mtk_infracfg_ao_regs, perisys_protect.clr, 0x0C88); +check_member(mtk_infracfg_ao_regs, perisys_protect.ready, 0x0C8C); + +struct mtk_emicfg_ao_mem_regs { + u32 reserved[32]; + struct mtk_reg_cfg gals_slp_prot; +}; +check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.status, 0x0080); +check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.set, 0x0084); +check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.clr, 0x0088); +check_member(mtk_emicfg_ao_mem_regs, gals_slp_prot.ready, 0x008C); + +static struct mtk_vlpcfg_regs *const mtk_vlpcfg = (void *)VLPCFG_REG_BASE; +static struct mtk_infracfg_ao_regs *const mtk_infracfg_ao = (void *)INFRACFG_AO_BASE; +static struct mtk_emicfg_ao_mem_regs *const mtk_emicfg_ao_mem = (void *)EMICFG_AO_MEM_BASE; + +void spm_power_on(void); +void mtcmos_init(void); + +#endif /* __SOC_MEDIATEK_MT8189_INCLUDE_SOC_SPM_MTCMOS_H__ */ diff --git a/src/soc/mediatek/mt8189/mtcmos.c b/src/soc/mediatek/mt8189/mtcmos.c new file mode 100644 index 000000000000..8b89e58ad2be --- /dev/null +++ b/src/soc/mediatek/mt8189/mtcmos.c @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +/* + * This file is created based on MT8189 Functional Specification + * Chapter number: 8.1 + */ + +#include <console/console.h> +#include <soc/mtcmos.h> +#include <soc/spm.h> +#include <soc/spm_mtcmos.h> + +static const struct bus_protect bp_ufs[] = { + {&mtk_vlpcfg->bus_vlp_topaxi_protecten_clr, BIT(6)}, + {&mtk_infracfg_ao->perisys_protect.clr, BIT(4)}, + {&mtk_vlpcfg->bus_vlp_topaxi_protecten_clr, BIT(5)}, +}; + +static const struct bus_protect bp_mminfra[] = { + {&mtk_infracfg_ao->emisys_protect.clr, BIT(20) | BIT(21)}, + {&mtk_infracfg_ao->infrasys_protect[0].clr, BIT(16)}, + {&mtk_infracfg_ao->mmsys_protect[1].clr, + BIT(0) | BIT(7) | BIT(8) | BIT(9) | BIT(10) | + BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15)}, + {&mtk_infracfg_ao->infrasys_protect[1].clr, BIT(11)}, + {&mtk_infracfg_ao->mmsys_protect[1].clr, + BIT(1) | BIT(2) | BIT(3)}, +}; + +static const struct bus_protect bp_ssusb[] = { + {&mtk_infracfg_ao->perisys_protect.clr, BIT(7)}, +}; + +static const struct power_domain_data pd_plat[] = { + { + /* ufs0 */ + .pwr_con = &mtk_spm->ufs0_pwr_con, + .pwr_sta_mask = BIT(4), + .sram_pdn_mask = BIT(8), + .sram_ack_mask = BIT(12), + .bp_steps = ARRAY_SIZE(bp_ufs), + .bp_table = bp_ufs, + }, + { + /* ufs0_phy */ + .pwr_con = &mtk_spm->ufs0_phy_pwr_con, + .pwr_sta_mask = BIT(5), + }, + { + /* mm_infra */ + .pwr_con = &mtk_spm->mm_infra_pwr_con, + .pwr_sta_mask = BIT(30), + .sram_pdn_mask = BIT(8), + .sram_ack_mask = BIT(12), + .bp_steps = ARRAY_SIZE(bp_mminfra), + .bp_table = bp_mminfra, + }, + { + /* ssusb */ + .pwr_con = &mtk_spm->ssusb_pwr_con, + .pwr_status = &mtk_spm->pwr_status_msb, + .pwr_status_2nd = &mtk_spm->pwr_status_msb_2nd, + .pwr_sta_mask = BIT(10), + .sram_pdn_mask = BIT(8), + .sram_ack_mask = BIT(12), + .bp_steps = ARRAY_SIZE(bp_ssusb), + .bp_table = bp_ssusb, + }, +}; + +void spm_power_on(void) +{ + write32(&mtk_spm->poweron_config_set, SPM_REGWR_CFG_KEY | (0x1 << 0)); +} + +void mtcmos_init(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(pd_plat); i++) + mtcmos_power_on(&pd_plat[i]); +} + +void mtcmos_protect_audio_bus(void) +{ + write32(&mtk_infracfg_ao->perisys_protect.clr, BIT(6)); + + /* AUDIO CG Clear */ + clrbits32(&mtk_afe->audio_audio_top[0], 0x03364F80); + clrbits32(&mtk_afe->audio_audio_top[1], 0x00F000FF); + clrbits32(&mtk_afe->audio_audio_top[2], 0x01323000); + clrbits32(&mtk_afe->audio_audio_top[3], 0x03F00000); + clrbits32(&mtk_afe->audio_audio_top[4], 0x0000301F); +} + +void mtcmos_protect_display_bus(void) +{ + write32(&mtk_infracfg_ao->mmsys_protect[0].clr, BIT(1) | BIT(0)); + + /* MMSYS_CONFIG CG Clear */ + write32(&mtk_mmsys_config->mmsys_config_mmsys_cg_0_clr, 0xFF7FFFFF); + write32(&mtk_mmsys_config->mmsys_config_mmsys_cg_1_clr, 0x0000007B); +} diff --git a/src/soc/mediatek/mt8189/pll.c b/src/soc/mediatek/mt8189/pll.c new file mode 100644 index 000000000000..24c7cc59e98f --- /dev/null +++ b/src/soc/mediatek/mt8189/pll.c @@ -0,0 +1,727 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ + +/* + * This file is created based on MT8189 Functional Specification + * Chapter number: 8.1 + */ + +#include <console/console.h> +#include <delay.h> +#include <device/mmio.h> +#include <timer.h> +#include <soc/addressmap.h> +#include <soc/mtcmos.h> +#include <soc/pll.h> +#include <soc/spm.h> +#include <soc/spm_mtcmos.h> + +#define VLP_FM_WAIT_TIME 40 + +enum mux_id { + CLK_TOP_AXI_SEL, + CLK_TOP_AXI_PERI_SEL, + CLK_TOP_AXI_U_SEL, + CLK_TOP_BUS_AXIMEM_SEL, + CLK_TOP_DISP0_SEL, + CLK_TOP_MMINFRA_SEL, + CLK_TOP_UART_SEL, + CLK_TOP_SPI0_SEL, + CLK_TOP_SPI1_SEL, + CLK_TOP_SPI2_SEL, + CLK_TOP_SPI3_SEL, + CLK_TOP_SPI4_SEL, + CLK_TOP_SPI5_SEL, + CLK_TOP_MSDC_MACRO_0P_SEL, + CLK_TOP_MSDC50_0_HCLK_SEL, + CLK_TOP_MSDC50_0_SEL, + CLK_TOP_AES_MSDCFDE_SEL, + CLK_TOP_MSDC_MACRO_1P_SEL, + CLK_TOP_MSDC30_1_SEL, + CLK_TOP_MSDC30_1_HCLK_SEL, + CLK_TOP_MSDC_MACRO_2P_SEL, + CLK_TOP_MSDC30_2_SEL, + CLK_TOP_MSDC30_2_HCLK_SEL, + CLK_TOP_AUD_INTBUS_SEL, + CLK_TOP_ATB_SEL, + CLK_TOP_DISP_PWM_SEL, + CLK_TOP_USB_TOP_P0_SEL, + CLK_TOP_USB_XHCI_P0_SEL, + CLK_TOP_USB_TOP_P1_SEL, + CLK_TOP_USB_XHCI_P1_SEL, + CLK_TOP_USB_TOP_P2_SEL, + CLK_TOP_USB_XHCI_P2_SEL, + CLK_TOP_USB_TOP_P3_SEL, + CLK_TOP_USB_XHCI_P3_SEL, + CLK_TOP_USB_TOP_P4_SEL, + CLK_TOP_USB_XHCI_P4_SEL, + CLK_TOP_I2C_SEL, + CLK_TOP_AUD_ENGEN1_SEL, + CLK_TOP_AUD_ENGEN2_SEL, + CLK_TOP_AES_UFSFDE_SEL, + CLK_TOP_U_SEL, + CLK_TOP_U_MBIST_SEL, + CLK_TOP_AUD_1_SEL, + CLK_TOP_AUD_2_SEL, + CLK_TOP_PWM_SEL, + CLK_TOP_AUDIO_H_SEL, + CLK_TOP_MCUPM_SEL, + CLK_TOP_MEM_SUB_SEL, + CLK_TOP_MEM_SUB_U_SEL, + CLK_TOP_DXCC_SEL, + CLK_TOP_DP_SEL, + CLK_TOP_EDP_SEL, + CLK_TOP_EDP_FAVT_SEL, + CLK_TOP_SFLASH_SEL, + CLK_TOP_ECC_SEL, + CLK_TOP_APLL_I2SIN0_MCK_SEL, + CLK_TOP_APLL_I2SIN1_MCK_SEL, + CLK_TOP_APLL_I2SIN4_MCK_SEL, + CLK_TOP_APLL_I2SOUT0_MCK_SEL, + CLK_TOP_APLL_I2SOUT1_MCK_SEL, + CLK_TOP_APLL_I2SOUT4_MCK_SEL, + CLK_TOP_APLL_TDMOUT_MCK_SEL, +}; + +enum vlp_mux_id { + CLK_VLP_CK_SCP_SEL, + CLK_VLP_CK_PWRAP_ULPOSC_SEL, + CLK_VLP_CK_SPMI_P_MST_SEL, + CLK_VLP_CK_DVFSRC_SEL, + CLK_VLP_CK_PWM_VLP_SEL, + CLK_VLP_CK_AXI_VLP_SEL, + CLK_VLP_CK_SYSTIMER_26M_SEL, + CLK_VLP_CK_SSPM_SEL, + CLK_VLP_CK_SSPM_F26M_SEL, + CLK_VLP_CK_SRCK_SEL, + CLK_VLP_CK_SCP_SPI_SEL, + CLK_VLP_CK_SCP_IIC_SEL, + CLK_VLP_CK_SCP_SPI_HIGH_SPD_SEL, + CLK_VLP_CK_SCP_IIC_HIGH_SPD_SEL, + CLK_VLP_CK_SSPM_ULPOSC_SEL, + CLK_VLP_CK_APXGPT_26M_SEL, + CLK_VLP_CK_AUD_ADC_SEL, + CLK_VLP_CK_KP_IRQ_GEN_SEL +}; + +struct mux_sel { + u8 id; + u8 sel; +}; + +struct vlp_mux_sel { + u8 id; + u8 sel; +}; + +#define MUX(_id, _sys, _clk_cfg, _mux_shift, _mux_width)\ + [_id] = { \ + .reg = &_sys->_clk_cfg.cfg, \ + .set_reg = &_sys->_clk_cfg.set, \ + .clr_reg = &_sys->_clk_cfg.clr, \ + .mux_shift = _mux_shift, \ + .mux_width = _mux_width, \ + } + +#define MUX_UPD(_id, _sys, _clk_cfg, _mux_shift, _mux_width, _upd_reg, _upd_shift)\ + [_id] = { \ + .reg = &_sys->_clk_cfg.cfg, \ + .set_reg = &_sys->_clk_cfg.set, \ + .clr_reg = &_sys->_clk_cfg.clr, \ + .mux_shift = _mux_shift, \ + .mux_width = _mux_width, \ + .upd_reg = &_sys->_upd_reg, \ + .upd_shift = _upd_shift, \ + } + +#define CKSYS_MUX(_id, _clk_cfg, _mux_shift, _mux_width)\ + MUX(_id, mtk_topckgen, _clk_cfg, _mux_shift, _mux_width) + +#define CKSYS_MUX_UPD(_id, _clk_cfg, _mux_shift, _mux_width, _upd_reg, _upd_shift)\ + MUX_UPD(_id, mtk_topckgen, _clk_cfg, _mux_shift, _mux_width, _upd_reg, _upd_shift) + +#define VLP_MUX_UPD(_id, _clk_cfg, _mux_shift, _mux_width, _upd_shift)\ + MUX_UPD(_id, mtk_vlpsys, _clk_cfg, _mux_shift, _mux_width, vlp_clk_cfg_update, \ + _upd_shift) + +static const struct mux muxes[] = { + CKSYS_MUX_UPD(CLK_TOP_AXI_SEL, clk_cfg[0], 0, 3, clk_cfg_update[0], 0), + CKSYS_MUX_UPD(CLK_TOP_AXI_PERI_SEL, clk_cfg[0], 8, 2, clk_cfg_update[0], 1), + CKSYS_MUX_UPD(CLK_TOP_AXI_U_SEL, clk_cfg[0], 16, 2, clk_cfg_update[0], 2), + CKSYS_MUX_UPD(CLK_TOP_BUS_AXIMEM_SEL, clk_cfg[0], 24, 3, clk_cfg_update[0], 3), + CKSYS_MUX_UPD(CLK_TOP_DISP0_SEL, clk_cfg[1], 0, 4, clk_cfg_update[0], 4), + CKSYS_MUX_UPD(CLK_TOP_MMINFRA_SEL, clk_cfg[1], 8, 4, clk_cfg_update[0], 5), + CKSYS_MUX_UPD(CLK_TOP_UART_SEL, clk_cfg[1], 16, 1, clk_cfg_update[0], 6), + CKSYS_MUX_UPD(CLK_TOP_SPI0_SEL, clk_cfg[1], 24, 3, clk_cfg_update[0], 7), + CKSYS_MUX_UPD(CLK_TOP_SPI1_SEL, clk_cfg[2], 0, 3, clk_cfg_update[0], 8), + CKSYS_MUX_UPD(CLK_TOP_SPI2_SEL, clk_cfg[2], 8, 3, clk_cfg_update[0], 9), + CKSYS_MUX_UPD(CLK_TOP_SPI3_SEL, clk_cfg[2], 16, 3, clk_cfg_update[0], 10), + CKSYS_MUX_UPD(CLK_TOP_SPI4_SEL, clk_cfg[2], 24, 3, clk_cfg_update[0], 11), + CKSYS_MUX_UPD(CLK_TOP_SPI5_SEL, clk_cfg[3], 0, 3, clk_cfg_update[0], 12), + CKSYS_MUX_UPD(CLK_TOP_MSDC_MACRO_0P_SEL, clk_cfg[3], 8, 2, clk_cfg_update[0], 13), + CKSYS_MUX_UPD(CLK_TOP_MSDC50_0_HCLK_SEL, clk_cfg[3], 16, 2, clk_cfg_update[0], 14), + CKSYS_MUX_UPD(CLK_TOP_MSDC50_0_SEL, clk_cfg[3], 24, 3, clk_cfg_update[0], 15), + CKSYS_MUX_UPD(CLK_TOP_AES_MSDCFDE_SEL, clk_cfg[4], 0, 3, clk_cfg_update[0], 16), + CKSYS_MUX_UPD(CLK_TOP_MSDC_MACRO_1P_SEL, clk_cfg[4], 8, 2, clk_cfg_update[0], 17), + CKSYS_MUX_UPD(CLK_TOP_MSDC30_1_SEL, clk_cfg[4], 16, 3, clk_cfg_update[0], 18), + CKSYS_MUX_UPD(CLK_TOP_MSDC30_1_HCLK_SEL, clk_cfg[4], 24, 2, clk_cfg_update[0], 19), + CKSYS_MUX_UPD(CLK_TOP_MSDC_MACRO_2P_SEL, clk_cfg[5], 0, 2, clk_cfg_update[0], 20), + CKSYS_MUX_UPD(CLK_TOP_MSDC30_2_SEL, clk_cfg[5], 8, 3, clk_cfg_update[0], 21), + CKSYS_MUX_UPD(CLK_TOP_MSDC30_2_HCLK_SEL, clk_cfg[5], 16, 2, clk_cfg_update[0], 22), + CKSYS_MUX_UPD(CLK_TOP_AUD_INTBUS_SEL, clk_cfg[5], 24, 2, clk_cfg_update[0], 23), + CKSYS_MUX_UPD(CLK_TOP_ATB_SEL, clk_cfg[6], 0, 2, clk_cfg_update[0], 24), + CKSYS_MUX_UPD(CLK_TOP_DISP_PWM_SEL, clk_cfg[6], 8, 3, clk_cfg_update[0], 25), + CKSYS_MUX_UPD(CLK_TOP_USB_TOP_P0_SEL, clk_cfg[6], 16, 2, clk_cfg_update[0], 26), + CKSYS_MUX_UPD(CLK_TOP_USB_XHCI_P0_SEL, clk_cfg[6], 24, 2, clk_cfg_update[0], 27), + CKSYS_MUX_UPD(CLK_TOP_USB_TOP_P1_SEL, clk_cfg[7], 0, 2, clk_cfg_update[0], 28), + CKSYS_MUX_UPD(CLK_TOP_USB_XHCI_P1_SEL, clk_cfg[7], 8, 2, clk_cfg_update[0], 29), + CKSYS_MUX_UPD(CLK_TOP_USB_TOP_P2_SEL, clk_cfg[7], 16, 2, clk_cfg_update[0], 30), + CKSYS_MUX_UPD(CLK_TOP_USB_XHCI_P2_SEL, clk_cfg[7], 24, 2, clk_cfg_update[1], 0), + CKSYS_MUX_UPD(CLK_TOP_USB_TOP_P3_SEL, clk_cfg[8], 0, 2, clk_cfg_update[1], 1), + CKSYS_MUX_UPD(CLK_TOP_USB_XHCI_P3_SEL, clk_cfg[8], 8, 2, clk_cfg_update[1], 2), + CKSYS_MUX_UPD(CLK_TOP_USB_TOP_P4_SEL, clk_cfg[8], 16, 2, clk_cfg_update[1], 3), + CKSYS_MUX_UPD(CLK_TOP_USB_XHCI_P4_SEL, clk_cfg[8], 24, 2, clk_cfg_update[1], 4), + CKSYS_MUX_UPD(CLK_TOP_I2C_SEL, clk_cfg[9], 0, 2, clk_cfg_update[1], 5), + CKSYS_MUX_UPD(CLK_TOP_AUD_ENGEN1_SEL, clk_cfg[9], 24, 2, clk_cfg_update[1], 8), + CKSYS_MUX_UPD(CLK_TOP_AUD_ENGEN2_SEL, clk_cfg[10], 0, 2, clk_cfg_update[1], 9), + CKSYS_MUX_UPD(CLK_TOP_AES_UFSFDE_SEL, clk_cfg[10], 8, 3, clk_cfg_update[1], 10), + CKSYS_MUX_UPD(CLK_TOP_U_SEL, clk_cfg[10], 16, 3, clk_cfg_update[1], 11), + CKSYS_MUX_UPD(CLK_TOP_U_MBIST_SEL, clk_cfg[10], 24, 2, clk_cfg_update[1], 12), + CKSYS_MUX_UPD(CLK_TOP_AUD_1_SEL, clk_cfg[11], 0, 1, clk_cfg_update[1], 13), + CKSYS_MUX_UPD(CLK_TOP_AUD_2_SEL, clk_cfg[11], 8, 1, clk_cfg_update[1], 14), + CKSYS_MUX_UPD(CLK_TOP_PWM_SEL, clk_cfg[12], 0, 1, clk_cfg_update[1], 17), + CKSYS_MUX_UPD(CLK_TOP_AUDIO_H_SEL, clk_cfg[12], 8, 2, clk_cfg_update[1], 18), + CKSYS_MUX_UPD(CLK_TOP_MCUPM_SEL, clk_cfg[12], 16, 2, clk_cfg_update[1], 19), + CKSYS_MUX_UPD(CLK_TOP_MEM_SUB_SEL, clk_cfg[12], 24, 4, clk_cfg_update[1], 20), + CKSYS_MUX_UPD(CLK_TOP_MEM_SUB_U_SEL, clk_cfg[13], 8, 3, clk_cfg_update[1], 22), + CKSYS_MUX_UPD(CLK_TOP_DXCC_SEL, clk_cfg[15], 24, 2, clk_cfg_update[2], 1), + CKSYS_MUX_UPD(CLK_TOP_DP_SEL, clk_cfg[16], 16, 3, clk_cfg_update[2], 4), + CKSYS_MUX_UPD(CLK_TOP_EDP_SEL, clk_cfg[16], 24, 3, clk_cfg_update[2], 5), + CKSYS_MUX_UPD(CLK_TOP_EDP_FAVT_SEL, clk_cfg_17, 0, 3, clk_cfg_update[2], 6), + CKSYS_MUX_UPD(CLK_TOP_SFLASH_SEL, clk_cfg_18, 0, 3, clk_cfg_update[2], 10), + CKSYS_MUX_UPD(CLK_TOP_ECC_SEL, clk_cfg_19, 8, 3, clk_cfg_update[2], 15), +}; + +static const struct mux_sel mux_sels[] = { + { .id = CLK_TOP_AXI_SEL, .sel = 2 }, + { .id = CLK_TOP_AXI_PERI_SEL, .sel = 2 }, + { .id = CLK_TOP_AXI_U_SEL, .sel = 2 }, + { .id = CLK_TOP_BUS_AXIMEM_SEL, .sel = 2 }, + { .id = CLK_TOP_DISP0_SEL, .sel = 11 }, + { .id = CLK_TOP_MMINFRA_SEL, .sel = 14 }, + { .id = CLK_TOP_UART_SEL, .sel = 1 }, + { .id = CLK_TOP_SPI0_SEL, .sel = 1 }, + { .id = CLK_TOP_SPI1_SEL, .sel = 1 }, + { .id = CLK_TOP_SPI2_SEL, .sel = 1 }, + { .id = CLK_TOP_SPI3_SEL, .sel = 1 }, + { .id = CLK_TOP_SPI4_SEL, .sel = 1 }, + { .id = CLK_TOP_SPI5_SEL, .sel = 1 }, + { .id = CLK_TOP_MSDC_MACRO_0P_SEL, .sel = 1 }, + { .id = CLK_TOP_MSDC50_0_HCLK_SEL, .sel = 1 }, + { .id = CLK_TOP_MSDC50_0_SEL, .sel = 1 }, + { .id = CLK_TOP_AES_MSDCFDE_SEL, .sel = 4 }, + { .id = CLK_TOP_MSDC_MACRO_1P_SEL, .sel = 1 }, + { .id = CLK_TOP_MSDC30_1_SEL, .sel = 4 }, + { .id = CLK_TOP_MSDC30_1_HCLK_SEL, .sel = 1 }, + { .id = CLK_TOP_MSDC_MACRO_2P_SEL, .sel = 1 }, + { .id = CLK_TOP_MSDC30_2_SEL, .sel = 4 }, + { .id = CLK_TOP_MSDC30_2_HCLK_SEL, .sel = 1 }, + { .id = CLK_TOP_AUD_INTBUS_SEL, .sel = 1 }, + { .id = CLK_TOP_ATB_SEL, .sel = 1 }, + { .id = CLK_TOP_DISP_PWM_SEL, .sel = 6 }, + { .id = CLK_TOP_USB_TOP_P0_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_XHCI_P0_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_TOP_P1_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_XHCI_P1_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_TOP_P2_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_XHCI_P2_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_TOP_P3_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_XHCI_P3_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_TOP_P4_SEL, .sel = 1 }, + { .id = CLK_TOP_USB_XHCI_P4_SEL, .sel = 1 }, + { .id = CLK_TOP_I2C_SEL, .sel = 2 }, + { .id = CLK_TOP_AUD_ENGEN1_SEL, .sel = 2 }, + { .id = CLK_TOP_AUD_ENGEN2_SEL, .sel = 2 }, + { .id = CLK_TOP_AES_UFSFDE_SEL, .sel = 1 }, + { .id = CLK_TOP_U_SEL, .sel = 5 }, + { .id = CLK_TOP_U_MBIST_SEL, .sel = 3 }, + { .id = CLK_TOP_AUD_1_SEL, .sel = 1 }, + { .id = CLK_TOP_AUD_2_SEL, .sel = 1 }, + { .id = CLK_TOP_PWM_SEL, .sel = 0 }, + { .id = CLK_TOP_AUDIO_H_SEL, .sel = 3 }, + { .id = CLK_TOP_MCUPM_SEL, .sel = 2 }, + { .id = CLK_TOP_MEM_SUB_SEL, .sel = 9 }, + { .id = CLK_TOP_MEM_SUB_U_SEL, .sel = 7 }, + { .id = CLK_TOP_DXCC_SEL, .sel = 1 }, + { .id = CLK_TOP_DP_SEL, .sel = 4 }, + { .id = CLK_TOP_EDP_SEL, .sel = 4 }, + { .id = CLK_TOP_EDP_FAVT_SEL, .sel = 4 }, + { .id = CLK_TOP_SFLASH_SEL, .sel = 0 }, + { .id = CLK_TOP_ECC_SEL, .sel = 5 }, +}; + +static const struct mux vlp_muxes[] = { + VLP_MUX_UPD(CLK_VLP_CK_SCP_SEL, vlp_clk_cfg[0], 0, 4, 0), + VLP_MUX_UPD(CLK_VLP_CK_PWRAP_ULPOSC_SEL, vlp_clk_cfg[0], 8, 3, 1), + VLP_MUX_UPD(CLK_VLP_CK_SPMI_P_MST_SEL, vlp_clk_cfg[0], 16, 4, 2), + VLP_MUX_UPD(CLK_VLP_CK_DVFSRC_SEL, vlp_clk_cfg[0], 24, 1, 3), + VLP_MUX_UPD(CLK_VLP_CK_PWM_VLP_SEL, vlp_clk_cfg[1], 0, 3, 4), + VLP_MUX_UPD(CLK_VLP_CK_AXI_VLP_SEL, vlp_clk_cfg[1], 8, 3, 5), + VLP_MUX_UPD(CLK_VLP_CK_SYSTIMER_26M_SEL, vlp_clk_cfg[1], 16, 1, 6), + VLP_MUX_UPD(CLK_VLP_CK_SSPM_SEL, vlp_clk_cfg[1], 24, 3, 7), + VLP_MUX_UPD(CLK_VLP_CK_SSPM_F26M_SEL, vlp_clk_cfg[2], 0, 1, 8), + VLP_MUX_UPD(CLK_VLP_CK_SRCK_SEL, vlp_clk_cfg[2], 8, 1, 9), + VLP_MUX_UPD(CLK_VLP_CK_SCP_SPI_SEL, vlp_clk_cfg[2], 16, 2, 10), + VLP_MUX_UPD(CLK_VLP_CK_SCP_IIC_SEL, vlp_clk_cfg[2], 24, 2, 11), + VLP_MUX_UPD(CLK_VLP_CK_SCP_SPI_HIGH_SPD_SEL, vlp_clk_cfg[3], 0, 2, 12), + VLP_MUX_UPD(CLK_VLP_CK_SCP_IIC_HIGH_SPD_SEL, vlp_clk_cfg[3], 8, 2, 13), + VLP_MUX_UPD(CLK_VLP_CK_SSPM_ULPOSC_SEL, vlp_clk_cfg[3], 16, 2, 14), + VLP_MUX_UPD(CLK_VLP_CK_APXGPT_26M_SEL, vlp_clk_cfg[3], 24, 1, 15), + VLP_MUX_UPD(CLK_VLP_CK_AUD_ADC_SEL, vlp_clk_cfg[5], 16, 2, 22), + VLP_MUX_UPD(CLK_VLP_CK_KP_IRQ_GEN_SEL, vlp_clk_cfg[5], 24, 3, 23), +}; + +static const struct vlp_mux_sel vlp_mux_sels[] = { + { .id = CLK_VLP_CK_SCP_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_PWRAP_ULPOSC_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SPMI_P_MST_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_DVFSRC_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_PWM_VLP_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_AXI_VLP_SEL, .sel = 4 }, + { .id = CLK_VLP_CK_SYSTIMER_26M_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SSPM_SEL, .sel = 4 }, + { .id = CLK_VLP_CK_SSPM_F26M_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SRCK_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SCP_SPI_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SCP_IIC_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SCP_SPI_HIGH_SPD_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SCP_IIC_HIGH_SPD_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_SSPM_ULPOSC_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_APXGPT_26M_SEL, .sel = 0 }, + { .id = CLK_VLP_CK_AUD_ADC_SEL, .sel = 1 }, + { .id = CLK_VLP_CK_KP_IRQ_GEN_SEL, .sel = 4 } +}; + +enum pll_id { + CLK_APMIXED_ARMPLL_LL, + CLK_APMIXED_ARMPLL_BL, + CLK_APMIXED_CCIPLL, + CLK_APMIXED_MAINPLL, + CLK_APMIXED_UNIVPLL, + CLK_APMIXED_MMPLL, + CLK_APMIXED_MFGPLL, + CLK_APMIXED_APLL1, + CLK_APMIXED_APLL2, + CLK_APMIXED_EMIPLL, + CLK_APMIXED_APUPLL2, + CLK_APMIXED_APUPLL, + CLK_APMIXED_TVDPLL1, + CLK_APMIXED_TVDPLL2, + CLK_APMIXED_ETHPLL, + CLK_APMIXED_MSDCPLL, + CLK_APMIXED_UFSPLL +}; + +struct rate { + u8 id; /* enum pll_id */ + u32 rate; +}; + +static const struct rate pll_rates[] = { + { CLK_APMIXED_ARMPLL_LL, ARMPLL_LL_HZ }, + { CLK_APMIXED_ARMPLL_BL, ARMPLL_BL_HZ }, + { CLK_APMIXED_CCIPLL, CCIPLL_HZ }, + { CLK_APMIXED_MAINPLL, MAINPLL_HZ }, + { CLK_APMIXED_UNIVPLL, UNIVPLL_HZ }, + { CLK_APMIXED_MMPLL, MMPLL_HZ }, + { CLK_APMIXED_MFGPLL, MFGPLL_HZ }, + { CLK_APMIXED_APLL1, APLL1_HZ }, + { CLK_APMIXED_APLL2, APLL2_HZ }, + { CLK_APMIXED_EMIPLL, EMIPLL_HZ }, + { CLK_APMIXED_APUPLL2, APUPLL2_HZ }, + { CLK_APMIXED_APUPLL, APUPLL_HZ }, + { CLK_APMIXED_TVDPLL1, TVDPLL1_HZ }, + { CLK_APMIXED_TVDPLL2, TVDPLL2_HZ }, + { CLK_APMIXED_ETHPLL, ETHPLL_HZ }, + { CLK_APMIXED_MSDCPLL, MSDCPLL_HZ }, + { CLK_APMIXED_UFSPLL, UFSPLL_HZ } +}; + +static const u32 pll_div_rate[] = { + 3800UL * MHz, + 1900 * MHz, + 950 * MHz, + 475 * MHz, + 237500 * KHz, + 0, +}; + +#define PLL_SYS(_id, _reg, _rstb, _pcwbits, _div_reg, _div_shift, \ + _pcw_reg, _pcw_shift, _div_rate) \ + [_id] = { \ + .reg = &mtk_apmixed->_reg, \ + .rstb_shift = _rstb, \ + .pcwbits = _pcwbits, \ + .div_reg = &mtk_apmixed->_div_reg, \ + .div_shift = _div_shift, \ + .pcw_reg = &mtk_apmixed->_pcw_reg, \ + .pcw_shift = _pcw_shift, \ + .div_rate = _div_rate, \ + } + +static const struct pll plls[] = { + PLL_SYS(CLK_APMIXED_ARMPLL_LL, armpll_ll_con[0], NO_RSTB_SHIFT, 22, + armpll_ll_con[1], 24, armpll_ll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_ARMPLL_BL, armpll_bl_con[0], NO_RSTB_SHIFT, 22, + armpll_bl_con[1], 24, armpll_bl_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_CCIPLL, ccipll_con[0], NO_RSTB_SHIFT, 22, + ccipll_con[1], 24, ccipll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_MAINPLL, mainpll_con[0], 23, 22, + mainpll_con[1], 24, mainpll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_UNIVPLL, univpll_con[0], 23, 22, + univpll_con[1], 24, univpll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_MMPLL, mmpll_con[0], 23, 22, + mmpll_con[1], 24, mmpll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_MFGPLL, mfgpll_con[0], NO_RSTB_SHIFT, 22, + mfgpll_con[1], 24, mfgpll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_APLL1, apll1_con[0], NO_RSTB_SHIFT, 32, + apll1_con[1], 24, apll1_con[2], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_APLL2, apll2_con[0], NO_RSTB_SHIFT, 32, + apll2_con[1], 24, apll2_con[2], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_EMIPLL, emipll_con[0], NO_RSTB_SHIFT, 22, + emipll_con[1], 24, emipll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_APUPLL2, apupll2_con[0], NO_RSTB_SHIFT, 22, + apupll2_con[1], 24, apupll2_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_APUPLL, apupll_con[0], NO_RSTB_SHIFT, 22, + apupll_con[1], 24, apupll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_TVDPLL1, tvdpll1_con[0], NO_RSTB_SHIFT, 22, + tvdpll1_con[1], 24, tvdpll1_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_TVDPLL2, tvdpll2_con[0], NO_RSTB_SHIFT, 22, + tvdpll2_con[1], 24, tvdpll2_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_ETHPLL, ethpll_con[0], NO_RSTB_SHIFT, 22, + ethpll_con[1], 24, ethpll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_MSDCPLL, msdcpll_con[0], NO_RSTB_SHIFT, 22, + msdcpll_con[1], 24, msdcpll_con[1], 0, pll_div_rate), + PLL_SYS(CLK_APMIXED_UFSPLL, ufspll_con[0], NO_RSTB_SHIFT, 22, + ufspll_con[1], 24, ufspll_con[1], 0, pll_div_rate), +}; + +struct pll_reg_list { + const char *name; + void *div_reg; + void *con0; + void *con1; +}; + +struct fmeter_data { + u8 id; + void *pll_con0; + void *pll_con1; + void *con0; + void *con1; +}; + +static const struct fmeter_data fmd[] = { + [APLL1_CTRL] = {APLL1_CTRL, &mtk_apmixed->apll1_con[0]}, + [APLL2_CTRL] = {APLL2_CTRL, &mtk_apmixed->apll2_con[0]}, + [ARMPLL_BL_CTRL] = {ARMPLL_BL_CTRL, &mtk_apmixed->armpll_bl_con[0]}, + [ARMPLL_LL_CTRL] = {ARMPLL_LL_CTRL, &mtk_apmixed->armpll_ll_con[0]}, + [CCIPLL_CTRL] = {CCIPLL_CTRL, &mtk_apmixed->ccipll_con[0]}, + [MAINPLL_CTRL] = {MAINPLL_CTRL, &mtk_apmixed->mainpll_con[0]}, + [MMPLL_CTRL] = {MMPLL_CTRL, &mtk_apmixed->mmpll_con[0]}, + [MSDCPLL_CTRL] = {MSDCPLL_CTRL, &mtk_apmixed->msdcpll_con[0]}, + [UFSPLL_CTRL] = {UFSPLL_CTRL, &mtk_apmixed->ufspll_con[0]}, + [UNIVPLL_CTRL] = {UNIVPLL_CTRL, &mtk_apmixed->univpll_con[0]}, + [EMIPLL_CTRL] = {EMIPLL_CTRL, &mtk_apmixed->emipll_con[0]}, + [TVDPLL1_CTRL] = {TVDPLL1_CTRL, &mtk_apmixed->tvdpll1_con[0]}, + [TVDPLL2_CTRL] = {TVDPLL2_CTRL, &mtk_apmixed->tvdpll2_con[0]}, + [MFGPLL_CTRL] = {MFGPLL_CTRL, &mtk_apmixed->mfgpll_con[0]}, + [ETHPLL_CTRL] = {ETHPLL_CTRL, &mtk_apmixed->ethpll_con[0]}, + [APUPLL_CTRL] = {APUPLL_CTRL, &mtk_apmixed->apupll_con[0]}, + [APUPLL2_CTRL] = {APUPLL2_CTRL, &mtk_apmixed->apupll2_con[0]}, + [VLP_CKSYS_TOP_CTRL] = {VLP_CKSYS_TOP_CTRL, 0, 0, + &mtk_vlpsys->vlp_fqmtr_con[0], + &mtk_vlpsys->vlp_fqmtr_con[1]}, +}; + +static u32 mt_get_subsys_freq(const struct fmeter_data fm_data, u32 id) +{ + u32 output = 0, ckdiv_en = 0; + u32 temp; + + if (fm_data.pll_con0 != 0) { + /* check ckdiv_en */ + if (read32(fm_data.pll_con0) & 0x00010000) + ckdiv_en = 1; + /* pll con0[19] = 1, pll con0[16] = 1, pll con0[12] = 1 */ + /* select pll_ckdiv, enable pll_ckdiv, enable test clk */ + setbits32(fm_data.pll_con0, BIT(19) | BIT(16) | BIT(12)); + } + + /* CLK26CALI_0[15]: rst 1 -> 0 */ + write32(fm_data.con0, 0); + /* CLK26CALI_0[15]: rst 0 -> 1 */ + setbits32(fm_data.con0, BIT(15)); + + /* vlp freq meter sel ckgen[20:16] */ + /* other subsys freq meter sel ckgen[2:0] */ + if (fm_data.id == VLP_CKSYS_TOP_CTRL) + clrsetbits32(fm_data.con0, GENMASK(20, 16), id << 16); + else + clrsetbits32(fm_data.con0, GENMASK(2, 0), id); + + clrsetbits32(fm_data.con1, GENMASK(31, 16), 0x1FF << 16); + + /* select divider?dvt set zero */ + clrbits32(fm_data.con0, GENMASK(31, 24)); + + setbits32(fm_data.con0, BIT(12)); + setbits32(fm_data.con0, BIT(4)); + /* fmeter con0[1:0] = 0 */ + /* choose test clk */ + clrbits32(fm_data.con0, BIT(1) | BIT(0)); + + /* wait frequency meter finish */ + if (fm_data.id == VLP_CKSYS_TOP_CTRL) + udelay(VLP_FM_WAIT_TIME); + else + wait_us(1000, !(read32(fm_data.con0) & BIT(4))); + + temp = read32(fm_data.con1) & 0xFFFF; + output = ((temp * 26000)) / 512; /* Khz */ + + if (fm_data.pll_con0 != 0) { + /* pll con0[19] = 0, pll con0[12] = 0 */ + if (ckdiv_en) + clrbits32(fm_data.pll_con0, BIT(19) | BIT(12)); + else + clrbits32(fm_data.pll_con0, BIT(19) | BIT(16) | BIT(12)); + } + + write32(fm_data.con0, 0x8000); + + printk(BIOS_INFO, "subsys meter[%d:%d] = %d Khz\n", fm_data.id, id, output); + + return output; +} + +u32 mt_get_vlpck_freq(u32 id) +{ + return mt_get_subsys_freq(fmd[VLP_CKSYS_TOP_CTRL], id); +} + +void mt_set_topck_default(void) +{ + int i; + + write32(&mtk_topckgen->clk_cfg[0].clr, 0xFFFFFFF0); + for (i = 1; i <= 16; i++) + write32(&mtk_topckgen->clk_cfg[i].clr, 0xFFFFFFFF); + write32(&mtk_topckgen->clk_cfg_17.clr, 0xFFFFFFFF); + write32(&mtk_topckgen->clk_cfg_18.clr, 0xFFFFFFFF); + write32(&mtk_topckgen->clk_cfg_19.clr, 0xFFFFFFFF); + write32(&mtk_topckgen->clk_cfg_update[0], 0x7FFFFFFE); + write32(&mtk_topckgen->clk_cfg_update[1], 0x7FFFFFFF); + write32(&mtk_topckgen->clk_cfg_update[2], 0x0000FFFF); +} + +void pll_set_pcw_change(const struct pll *pll) +{ + setbits32(pll->div_reg, PLL_PCW_CHG); +} + +void mt_pll_init(void) +{ + int i; + + printk(BIOS_INFO, "Pll init start...\n"); + + spm_power_on(); + + printk(BIOS_INFO, "pll control start...\n"); + /* [0]=1 (CLKSQ_EN) + Default Value to avoid using BootROM's setting */ + setbits32(&mtk_apmixed->ap_clksq_con0, BIT(0)); + + /* Wait 100us */ + udelay(100); + + /* [2]=1 (CLKSQ_LPF_EN) */ + setbits32(&mtk_apmixed->ap_clksq_con0, BIT(2)); + + for (i = 0; i < ARRAY_SIZE(pll_rates); i++) + pll_set_rate(&plls[pll_rates[i].id], pll_rates[i].rate); + + write32(&mtk_apmixed->apll1_tuner_con0, 0x6F28BD4D); + write32(&mtk_apmixed->apll2_tuner_con0, 0x78FD5266); + setbits32(&mtk_apmixed->emipll_con[0], BIT(8)); + + /* PLL all enable */ + write32(&mtk_apmixed->pllen_all_set, 0x0007FFFC); + + /* Wait PLL stable (20us) */ + udelay(20); + + /* turn on pll div en */ + setbits32(&mtk_apmixed->mainpll_con[0], GENMASK(31, 24)); + setbits32(&mtk_apmixed->univpll_con[0], GENMASK(31, 24)); + udelay(20); + + /* pll all rstb */ + write32(&mtk_apmixed->pll_div_rstb_all_set, 0x00000007); + + printk(BIOS_INFO, "pll control done...\n"); + + /* [10:9] muxsel: switch to PLL speed */ + clrsetbits32(&mtk_cpu_plldiv_cfg->cpu_plldiv_0_cfg0, GENMASK(10, 9), BIT(9)); + + /* [10:9] muxsel: switch to PLL speed */ + clrsetbits32(&mtk_cpu_plldiv_cfg->cpu_plldiv_1_cfg0, GENMASK(10, 9), BIT(9)); + + /* [10:9] muxsel: switch to PLL speed */ + clrsetbits32(&mtk_bus_plldiv_cfg->bus_plldiv_cfg0, GENMASK(10, 9), BIT(9)); + + /* Infra DCM divider */ + setbits32(&mtk_infra_ao_bcrm->vdnr_dcm_infra_par_bus_ctrl_0, BIT(6) | BIT(3)); + + /* Peri DCM divider */ + setbits32(&mtk_peri_ao_bcrm->vdnr_dcm_peri_par_bus_ctrl_0, BIT(10) | BIT(7) | BIT(4)); + + printk(BIOS_INFO, "mux switch control start...\n"); + + for (i = 0; i < ARRAY_SIZE(mux_sels); i++) + pll_mux_set_sel(&muxes[mux_sels[i].id], mux_sels[i].sel); + + /* update mux */ + write32(&mtk_topckgen->clk_cfg_update[0], 0x7FFFFFFF); + write32(&mtk_topckgen->clk_cfg_update[1], 0x7FFFFFFF); + write32(&mtk_topckgen->clk_cfg_update[2], 0x0000FFFF); + + /* femisys_dvfs_ck_gfmux_sel = 1(emipll_ck) */ + write32(&mtk_topckgen->clk_mem_dfs_cfg, 0x1); + + for (i = 0; i < ARRAY_SIZE(vlp_mux_sels); i++) + pll_mux_set_sel(&vlp_muxes[vlp_mux_sels[i].id], vlp_mux_sels[i].sel); + + /* update mux */ + write32(&mtk_vlpsys->vlp_clk_cfg_update, 0x00FFFFFF); + + printk(BIOS_INFO, "mux switch control done...\n"); + + printk(BIOS_INFO, "Pll init Done!!\n"); +} + +void mt_pll_post_init(void) +{ + /* for CG */ + printk(BIOS_INFO, "subsysCG enable start...\n"); + + /* TOPCKGEN CG Clear */ + write32(&mtk_topckgen->clk_misc_cfg_3.clr, 0x00010000); + write32(&mtk_topckgen->clk_misc_cfg_3.set, 0xDF3CFCFF); + /* INFRACFG_AO CG Clear */ + write32(&mtk_infracfg_ao->infracfg_ao_module_cg_0_clr, 0x10000000); + write32(&mtk_infracfg_ao->infracfg_ao_module_cg_1_clr, 0x21000000); + write32(&mtk_infracfg_ao->infracfg_ao_module_cg_2_clr, 0x08000000); + write32(&mtk_infracfg_ao->infracfg_ao_module_cg_3_clr, 0x02000000); + /* PERICFG_AO CG Clear */ + write32(&mtk_pericfg_ao->pericfg_ao_peri_cg_0_clr, 0x3FFFFFFF); + write32(&mtk_pericfg_ao->pericfg_ao_peri_cg_1_clr, 0x3DBDFBF6); + write32(&mtk_pericfg_ao->pericfg_ao_peri_cg_2_clr, 0x0FFFFFFB); + /* UFSCFG_AO_REG CG Clear */ + write32(&mtk_ufscfg_ao->ufscfg_ao_reg_ufs_ao_cg_0_clr, 0x0000007F); + /* IMP_IIC_WRAP_WS CG Clear */ + write32(&mtk_imp_iic_wrap_ws->imp_iic_wrap_ws_ap_clock_cg_clr, 0x00000001); + /* IMP_IIC_WRAP_E CG Clear */ + write32(&mtk_imp_iic_wrap_e->imp_iic_wrap_e_ap_clock_cg_clr, 0x00000003); + /* IMP_IIC_WRAP_S CG Clear */ + write32(&mtk_imp_iic_wrap_s->imp_iic_wrap_s_ap_clock_cg_clr, 0x0000000F); + /* IMP_IIC_WRAP_EN CG Clear */ + write32(&mtk_imp_iic_wrap_en->imp_iic_wrap_en_ap_clock_cg_clr, 0x00000003); + /* VLP_CK CG Clear */ + write32(&mtk_vlpsys->vlp_clk_cfg_30_set, 0x00000832); + /* SCP_IIC CG Clear */ + write32(&mtk_scp_iic->scp_iic_ccu_clock_cg_set, 0x00000003); + /* SCP CG Clear */ + setbits32(&mtk_scp->scp_ap_spi_cg, BIT(1) | BIT(0)); + /* VLPCFG_AO_REG CG Clear */ + clrbits32(&mtk_vlpcfg_ao->vlpcfg_ao_reg_debugtop_vlpao_ctrl, BIT(8)); + /* VLPCFG_REG CG Clear */ + setbits32(&mtk_vlpcfg->vlp_test_ck_ctrl, + BIT(28) | BIT(24) | BIT(23) | BIT(22) | BIT(21) | BIT(20) | + BIT(18) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | + BIT(8) | BIT(7) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); + /* DVFSRC_TOP CG Clear */ + setbits32(&mtk_dvfsrc_top->dvfsrc_top_dvfsrc_basic_control, BIT(0)); + + /* DBGAO CG Clear */ + setbits32(&mtk_dbgao->dbgao_atb, BIT(0)); + /* DEM CG Clear*/ + setbits32(&mtk_dem->dem_atb, BIT(0)); + setbits32(&mtk_dem->dem_dbgbusclk_en, BIT(0)); + setbits32(&mtk_dem->dem_dbgsysclk_en, BIT(0)); + /* UFSCFG_PDN_REG CG Clear */ + write32(&mtk_ufscfg_pdn->ufscfg_pdn_reg_ufs_pdn_cg_0_clr, 0x0000002B); + + /* MMINFRA_CONFIG CG Clear */ + write32(&mtk_mminfra_config->mminfra_config_mminfra_cg_0_clr, 0x00000007); + write32(&mtk_mminfra_config->mminfra_config_mminfra_cg_1_clr, 0x00020000); + /* GCE CG Clear */ + clrbits32(&mtk_gce_d->gce_gce_ctl_int0, BIT(16)); + + printk(BIOS_INFO, "subsysCG enable done...\n"); +} + +void mt_pll_raise_little_cpu_freq(u32 freq) +{ + /* switch clock source to intermediate clock */ + clrsetbits32(&mtk_cpu_plldiv_cfg->cpu_plldiv_0_cfg0, MCU_MUX_MASK, MCU_MUX_SRC_26M); + + /* disable armpll_ll frequency output */ + write32(&mtk_apmixed->pllen_all_clr, 0x40000); + + /* raise armpll_ll frequency */ + pll_set_rate(&plls[CLK_APMIXED_ARMPLL_LL], freq); + + /* enable armpll_ll frequency output */ + write32(&mtk_apmixed->pllen_all_set, 0x40000); + udelay(PLL_EN_DELAY); + + /* switch clock source back to armpll_ll */ + clrsetbits32(&mtk_cpu_plldiv_cfg->cpu_plldiv_0_cfg0, MCU_MUX_MASK, MCU_MUX_SRC_PLL); +} + +void mt_pll_raise_cci_freq(u32 freq) +{ + /* switch clock source to intermediate clock */ + clrsetbits32(&mtk_bus_plldiv_cfg->bus_plldiv_cfg0, MCU_MUX_MASK, MCU_MUX_SRC_26M); + + /* disable ccipll frequency output */ + write32(&mtk_apmixed->pllen_all_clr, 0x10000); + + /* raise ccipll frequency */ + pll_set_rate(&plls[CLK_APMIXED_CCIPLL], freq); + + /* enable ccipll frequency output */ + write32(&mtk_apmixed->pllen_all_set, 0x10000); + udelay(PLL_EN_DELAY); + + /* switch clock source back to ccipll */ + clrsetbits32(&mtk_bus_plldiv_cfg->bus_plldiv_cfg0, MCU_MUX_MASK, MCU_MUX_SRC_PLL); +} + +void mt_pll_set_tvd_pll1_freq(u32 freq) +{ + /* disable tvdpll frequency output */ + write32(&mtk_apmixed->pllen_all_clr, 0x200); + + /* set tvdpll frequency */ + pll_set_rate(&plls[CLK_APMIXED_TVDPLL2], freq); + + /* enable tvdpll frequency output */ + write32(&mtk_apmixed->pllen_all_set, 0x200); + udelay(PLL_EN_DELAY); +} + +void mt_pll_edp_mux_set_sel(u32 sel) +{ + pll_mux_set_sel(&muxes[CLK_TOP_EDP_SEL], sel); +} diff --git a/src/soc/mediatek/mt8192/include/soc/pmif.h b/src/soc/mediatek/mt8192/include/soc/pmif.h index 30432d935b96..d532616d9185 100644 --- a/src/soc/mediatek/mt8192/include/soc/pmif.h +++ b/src/soc/mediatek/mt8192/include/soc/pmif.h @@ -123,6 +123,20 @@ check_member(mtk_pmif_regs, pmic_eint_sta_addr, 0x40C); check_member(mtk_pmif_regs, irq_event_en_0, 0x418); check_member(mtk_pmif_regs, swinf_0_acc, 0xC00); +#define PMIF_SPI_HW_INF 0x307F +#define PMIF_SPI_MD BIT(8) +#define PMIF_SPI_AP_SECURE BIT(9) +#define PMIF_SPI_AP BIT(10) +#define PMIF_SPI_STAUPD BIT(14) +#define PMIF_SPI_TSX_HW BIT(19) +#define PMIF_SPI_DCXO_HW BIT(20) + +#define PMIF_SPI_INF_EN (PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | \ + PMIF_SPI_AP) +#define PMIF_SPI_ARB_EN (PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | \ + PMIF_SPI_AP | PMIF_SPI_STAUPD | PMIF_SPI_TSX_HW | \ + PMIF_SPI_DCXO_HW) + #define PMIF_SPMI_AP_CHAN (PMIF_SPMI_BASE + 0xC80) #define PMIF_SPI_AP_CHAN (PMIF_SPI_BASE + 0xC80) diff --git a/src/soc/mediatek/mt8195/include/soc/pmif.h b/src/soc/mediatek/mt8195/include/soc/pmif.h index 530b31ea6276..1a386dcf5265 100644 --- a/src/soc/mediatek/mt8195/include/soc/pmif.h +++ b/src/soc/mediatek/mt8195/include/soc/pmif.h @@ -124,6 +124,20 @@ check_member(mtk_pmif_regs, pmic_eint_sta_addr, 0x414); check_member(mtk_pmif_regs, irq_event_en_0, 0x420); check_member(mtk_pmif_regs, swinf_0_acc, 0x800); +#define PMIF_SPI_HW_INF 0x307F +#define PMIF_SPI_MD BIT(8) +#define PMIF_SPI_AP_SECURE BIT(9) +#define PMIF_SPI_AP BIT(10) +#define PMIF_SPI_STAUPD BIT(14) +#define PMIF_SPI_TSX_HW BIT(19) +#define PMIF_SPI_DCXO_HW BIT(20) + +#define PMIF_SPI_INF_EN (PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | \ + PMIF_SPI_AP) +#define PMIF_SPI_ARB_EN (PMIF_SPI_HW_INF | PMIF_SPI_MD | PMIF_SPI_AP_SECURE | \ + PMIF_SPI_AP | PMIF_SPI_STAUPD | PMIF_SPI_TSX_HW | \ + PMIF_SPI_DCXO_HW) + #define PMIF_SPMI_AP_CHAN (PMIF_SPMI_BASE + 0x880) #define PMIF_SPI_AP_CHAN (PMIF_SPI_BASE + 0x880) diff --git a/src/soc/mediatek/mt8196/include/soc/mt6685_rtc.h b/src/soc/mediatek/mt8196/include/soc/mt6685_rtc.h index e46fd90ff683..612d2d424e31 100644 --- a/src/soc/mediatek/mt8196/include/soc/mt6685_rtc.h +++ b/src/soc/mediatek/mt8196/include/soc/mt6685_rtc.h @@ -49,6 +49,11 @@ #define RG_FQMTR_DATA 0x54a +#define RTC_SPAR_MACRO 0x5d8 +#define RTC_SPAR_PROT_STAT_SHIFT 6 +#define RTC_SPAR_PROT_STAT_MASK 0x3 +#define RTC_PROT_UNLOCK_SUCCESS 0x3 + #define RG_FQMTR_CLK_CK_PDN_SET 0x10c #define RG_FQMTR_CLK_CK_PDN_MASK 0x1 #define RG_FQMTR_CLK_CK_PDN_SHIFT 5 diff --git a/src/soc/mediatek/mt8196/include/soc/rtc.h b/src/soc/mediatek/mt8196/include/soc/rtc.h index b31599871325..f45e4384cec1 100644 --- a/src/soc/mediatek/mt8196/include/soc/rtc.h +++ b/src/soc/mediatek/mt8196/include/soc/rtc.h @@ -12,6 +12,7 @@ #include <soc/rtc_common.h> #include <soc/rtc_reg_common.h> #include <stdbool.h> +#include <timer.h> #include <types.h> /* RTC registers */ @@ -21,7 +22,7 @@ enum { RTC_BBPU_RELOAD = BIT(5), RTC_BBPU_CBUSY = BIT(6), - RTC_CBUSY_TIMEOUT_US = 8000, + RTC_CBUSY_TIMEOUT_US = USECS_PER_SEC, }; enum { @@ -59,6 +60,7 @@ enum { #define BBPU_RELOAD_TIMEOUT_US 100000 #define EOSC_CHECK_CLK_TIMEOUT_US 1000000 #define RECOVERY_RETRY_COUNT 3 +#define PROT_UNLOCK_RETRY_COUNT 3 struct rtc_clk_freq { u16 fqm26m_ck; diff --git a/src/soc/mediatek/mt8196/mt6685_rtc.c b/src/soc/mediatek/mt8196/mt6685_rtc.c index 95e8dd690737..36e29f5a2a20 100644 --- a/src/soc/mediatek/mt8196/mt6685_rtc.c +++ b/src/soc/mediatek/mt8196/mt6685_rtc.c @@ -33,6 +33,34 @@ void rtc_write(u16 addr, u16 wdata) mt6685_write16(addr, wdata); } +static u16 rtc_get_prot_stat(void) +{ + u16 val; + u16 state = 0; + + udelay(100); + + rtc_read(RTC_SPAR_MACRO, &val); + + state = (val >> RTC_SPAR_PROT_STAT_SHIFT) & RTC_SPAR_PROT_STAT_MASK; + + return state; +} + +static bool mt6685_writeif_unlock(void) +{ + if (!retry(PROT_UNLOCK_RETRY_COUNT, + rtc_writeif_unlock() && + rtc_get_prot_stat() == RTC_PROT_UNLOCK_SUCCESS)) { + + printk(BIOS_ERR, "%s: retry failed!!\n", __func__); + + return false; + } + + return true; +} + static bool rtc_eosc_check_clock(const struct rtc_clk_freq *result) { if ((result->fqm26m_ck >= 3 && result->fqm26m_ck <= 7) && @@ -319,7 +347,7 @@ static bool rtc_init_after_recovery(void) /* write powerkeys */ if (!rtc_powerkey_init()) return false; - if (!rtc_writeif_unlock()) + if (!mt6685_writeif_unlock()) return false; if (!rtc_gpio_init()) return false; @@ -332,7 +360,7 @@ static bool rtc_init_after_recovery(void) if (!rtc_powerkey_init()) return false; - if (!rtc_writeif_unlock()) + if (!mt6685_writeif_unlock()) return false; secure_rtc_init(); @@ -366,9 +394,9 @@ static bool rtc_first_boot_init(void) if (!rtc_write_trigger()) return false; - if (!rtc_writeif_unlock()) { + if (!mt6685_writeif_unlock()) { printk(BIOS_ERR, - "%s: rtc_writeif_unlock failed after BBPU written\n", __func__); + "%s: mt6685_writeif_unlock failed after BBPU written\n", __func__); return false; } @@ -387,9 +415,9 @@ static bool rtc_first_boot_init(void) return false; } - if (!rtc_writeif_unlock()) { + if (!mt6685_writeif_unlock()) { printk(BIOS_ERR, - "%s: rtc_writeif_unlock failed after POWERKEY written\n", __func__); + "%s: mt6685_writeif_unlock failed after POWERKEY written\n", __func__); return false; } @@ -402,9 +430,9 @@ static bool rtc_first_boot_init(void) return false; } - if (!rtc_writeif_unlock()) { + if (!mt6685_writeif_unlock()) { printk(BIOS_ERR, - "%s rtc_writeif_unlock failed after BBPU written\n", __func__); + "%s mt6685_writeif_unlock failed after BBPU written\n", __func__); return false; } @@ -418,9 +446,9 @@ static bool rtc_first_boot_init(void) return false; } - if (!rtc_writeif_unlock()) { + if (!mt6685_writeif_unlock()) { printk(BIOS_ERR, - "%s rtc_writeif_unlock failed after POWERKEY written\n", __func__); + "%s mt6685_writeif_unlock failed after POWERKEY written\n", __func__); return false; } @@ -444,8 +472,8 @@ static void rtc_enable_dcxo(void) u16 con, osc32con, sec; /* Unlock for reload */ - if (!rtc_writeif_unlock()) - printk(BIOS_ERR, "rtc_writeif_unlock() failed\n"); + if (!mt6685_writeif_unlock()) + printk(BIOS_ERR, "mt6685_writeif_unlock() failed\n"); rtc_read(RTC_BBPU, &rdata); rtc_write(RTC_BBPU, rdata | RTC_BBPU_KEY | RTC_BBPU_RELOAD); @@ -525,7 +553,7 @@ void rtc_boot(void) rtc_read(RTC_BBPU, &rtc_bbpu); rtc_write(RTC_BBPU, rtc_bbpu | RTC_BBPU_KEY | RTC_BBPU_RELOAD); - if (!rtc_write_trigger() || !rtc_writeif_unlock()) { + if (!rtc_write_trigger() || !mt6685_writeif_unlock()) { rtc_recovery_flow(); } else { rtc_read(RTC_POWERKEY1, &rtc_pwrkey1); diff --git a/src/soc/qualcomm/x1p42100/bootblock.c b/src/soc/qualcomm/x1p42100/bootblock.c index a4cedfa69fe6..32a958b68768 100644 --- a/src/soc/qualcomm/x1p42100/bootblock.c +++ b/src/soc/qualcomm/x1p42100/bootblock.c @@ -2,9 +2,16 @@ #include <bootblock_common.h> #include <soc/mmu.h> +#include <soc/qspi_common.h> +#include <soc/qupv3_config_common.h> + +#define SPI_BUS_CLOCK_FREQ (50 * MHz) void bootblock_soc_init(void) { if (!CONFIG(COMPRESS_BOOTBLOCK)) soc_mmu_init(); + + quadspi_init(SPI_BUS_CLOCK_FREQ); + qupv3_fw_init(); } diff --git a/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h b/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h index bbc67bf5fac8..76f165d061f9 100644 --- a/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/cezanne/soc_dmi_info.h @@ -10,6 +10,7 @@ #define AGESA_STRUCT_SOCKET_COUNT 2 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 8 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_3_3_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/common/dmi_info.h b/src/vendorcode/amd/fsp/common/dmi_info.h index 390732df6f01..5593d760f5e5 100644 --- a/src/vendorcode/amd/fsp/common/dmi_info.h +++ b/src/vendorcode/amd/fsp/common/dmi_info.h @@ -157,7 +157,7 @@ typedef struct { OUT UINT16 Speed; ///< Identifies the speed of the device, in megahertz (MHz). OUT UINT64 ManufacturerIdCode; ///< Manufacturer ID code. OUT CHAR8 SerialNumber[9]; ///< Serial Number. - OUT CHAR8 PartNumber[21]; ///< Part Number. + OUT CHAR8 PartNumber[AGESA_STRUCT_PART_NUMBER_SIZE]; ///< Part Number. OUT UINT8 Attributes; ///< Bits 7-4: Reserved, Bits 3-0: rank. OUT UINT32 ExtSize; ///< Extended Size. OUT UINT16 ConfigSpeed; ///< Configured memory clock speed diff --git a/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h b/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h index 08f5f5cd1b4c..3f24fe9b16d0 100644 --- a/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/glinda/soc_dmi_info.h @@ -8,9 +8,10 @@ #ifndef SOC_DMI_INFO_H #define SOC_DMI_INFO_H -#define AGESA_STRUCT_SOCKET_COUNT 2 ///< Number of sockets in AGESA FSP DMI T17 table -#define AGESA_STRUCT_CHANNELS_PER_SOCKET 8 ///< Channels per socket in AGESA FSP DMI T17 table -#define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table +#define AGESA_STRUCT_CHANNELS_PER_SOCKET 16 ///< Channels per socket in AGESA FSP DMI T17 table +#define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_PART_NUMBER_SIZE 31 #define SMBIOS_3_2_3_3_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h b/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h index 12f3e8fa57d3..1c3cb1a0b18d 100644 --- a/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/mendocino/soc_dmi_info.h @@ -10,6 +10,7 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 12 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_3_3_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h b/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h index 12f3e8fa57d3..1c3cb1a0b18d 100644 --- a/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/phoenix/soc_dmi_info.h @@ -10,6 +10,7 @@ #define AGESA_STRUCT_SOCKET_COUNT 4 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 12 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 2 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_PART_NUMBER_SIZE 21 #define SMBIOS_3_2_3_3_SUPPORT 1 diff --git a/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h b/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h index 109a01a6e0f1..94a43f55b069 100644 --- a/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h +++ b/src/vendorcode/amd/fsp/picasso/soc_dmi_info.h @@ -10,5 +10,6 @@ #define AGESA_STRUCT_SOCKET_COUNT 1 ///< Number of sockets in AGESA FSP DMI T17 table #define AGESA_STRUCT_CHANNELS_PER_SOCKET 4 ///< Channels per socket in AGESA FSP DMI T17 table #define AGESA_STRUCT_DIMMS_PER_CHANNEL 4 ///< DIMMs per channel in AGESA FSP DMI T17 table +#define AGESA_STRUCT_PART_NUMBER_SIZE 21 #endif /* SOC_DMI_INFO_H */ diff --git a/src/vendorcode/intel/fsp/fsp2_0/iot/raptorlake_s/MemInfoHob.h b/src/vendorcode/intel/fsp/fsp2_0/iot/raptorlake_s/MemInfoHob.h deleted file mode 100644 index 989bfb1a954a..000000000000 --- a/src/vendorcode/intel/fsp/fsp2_0/iot/raptorlake_s/MemInfoHob.h +++ /dev/null @@ -1,315 +0,0 @@ -/** @file - This file contains definitions required for creation of - Memory S3 Save data, Memory Info data and Memory Platform - data hobs. - -@copyright - Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> - - SPDX-License-Identifier: BSD-2-Clause-Patent - -@par Specification Reference: -**/ -#ifndef _MEM_INFO_HOB_H_ -#define _MEM_INFO_HOB_H_ - - -#pragma pack (push, 1) - -extern EFI_GUID gSiMemoryS3DataGuid; -extern EFI_GUID gSiMemoryInfoDataGuid; -extern EFI_GUID gSiMemoryPlatformDataGuid; - -#define MAX_NODE 2 -#define MAX_CH 4 -#define MAX_DIMM 2 -// Must match definitions in -// Intel\ClientOneSiliconPkg\IpBlock\MemoryInit\Mtl\Include\MrcInterface.h -#define HOB_MAX_SAGV_POINTS 4 - -/// -/// Host reset states from MRC. -/// -#define WARM_BOOT 2 - -#define R_MC_CHNL_RANK_PRESENT 0x7C -#define B_RANK0_PRS BIT0 -#define B_RANK1_PRS BIT1 -#define B_RANK2_PRS BIT4 -#define B_RANK3_PRS BIT5 - -// @todo remove and use the MdePkg\Include\Pi\PiHob.h -#if !defined(_PEI_HOB_H_) && !defined(__PI_HOB_H__) -#ifndef __HOB__H__ -typedef struct _EFI_HOB_GENERIC_HEADER { - UINT16 HobType; - UINT16 HobLength; - UINT32 Reserved; -} EFI_HOB_GENERIC_HEADER; - -typedef struct _EFI_HOB_GUID_TYPE { - EFI_HOB_GENERIC_HEADER Header; - EFI_GUID Name; - /// - /// Guid specific data goes here - /// -} EFI_HOB_GUID_TYPE; -#endif -#endif - -/// -/// Defines taken from MRC so avoid having to include MrcInterface.h -/// - -// -// Matches MAX_SPD_SAVE define in MRC -// -#ifndef MAX_SPD_SAVE -#define MAX_SPD_SAVE 29 -#endif - -// -// MRC version description. -// -typedef struct { - UINT8 Major; ///< Major version number - UINT8 Minor; ///< Minor version number - UINT8 Rev; ///< Revision number - UINT8 Build; ///< Build number -} SiMrcVersion; - -// -// Matches MrcChannelSts enum in MRC -// -#ifndef CHANNEL_NOT_PRESENT -#define CHANNEL_NOT_PRESENT 0 // There is no channel present on the controller. -#endif -#ifndef CHANNEL_DISABLED -#define CHANNEL_DISABLED 1 // There is a channel present but it is disabled. -#endif -#ifndef CHANNEL_PRESENT -#define CHANNEL_PRESENT 2 // There is a channel present and it is enabled. -#endif - -// -// Matches MrcDimmSts enum in MRC -// -#ifndef DIMM_ENABLED -#define DIMM_ENABLED 0 // DIMM/rank Pair is enabled, presence will be detected. -#endif -#ifndef DIMM_DISABLED -#define DIMM_DISABLED 1 // DIMM/rank Pair is disabled, regardless of presence. -#endif -#ifndef DIMM_PRESENT -#define DIMM_PRESENT 2 // There is a DIMM present in the slot/rank pair and it will be used. -#endif -#ifndef DIMM_NOT_PRESENT -#define DIMM_NOT_PRESENT 3 // There is no DIMM present in the slot/rank pair. -#endif - -// -// Matches MrcBootMode enum in MRC -// -#ifndef __MRC_BOOT_MODE__ -#define __MRC_BOOT_MODE__ //The below values are originated from MrcCommonTypes.h - #ifndef INT32_MAX - #define INT32_MAX (0x7FFFFFFF) - #endif //INT32_MAX -typedef enum { - bmCold, ///< Cold boot - bmWarm, ///< Warm boot - bmS3, ///< S3 resume - bmFast, ///< Fast boot - MrcBootModeMax, ///< MRC_BOOT_MODE enumeration maximum value. - MrcBootModeDelim = INT32_MAX ///< This value ensures the enum size is consistent on both sides of the PPI. -} MRC_BOOT_MODE; -#endif //__MRC_BOOT_MODE__ - -// -// Matches MrcDdrType enum in MRC -// -#ifndef MRC_DDR_TYPE_DDR5 -#define MRC_DDR_TYPE_DDR5 1 -#endif -#ifndef MRC_DDR_TYPE_LPDDR5 -#define MRC_DDR_TYPE_LPDDR5 2 -#endif -#ifndef MRC_DDR_TYPE_LPDDR4 -#define MRC_DDR_TYPE_LPDDR4 3 -#endif -#ifndef MRC_DDR_TYPE_UNKNOWN -#define MRC_DDR_TYPE_UNKNOWN 4 -#endif - -#define MAX_PROFILE_NUM 7 // number of memory profiles supported -#define MAX_XMP_PROFILE_NUM 5 // number of XMP profiles supported - -#define MAX_TRACE_REGION 5 -#define MAX_TRACE_CACHE_TYPE 2 - -// -// DIMM timings -// -typedef struct { - UINT32 tCK; ///< Memory cycle time, in femtoseconds. - UINT16 NMode; ///< Number of tCK cycles for the channel DIMM's command rate mode. - UINT16 tCL; ///< Number of tCK cycles for the channel DIMM's CAS latency. - UINT16 tCWL; ///< Number of tCK cycles for the channel DIMM's minimum CAS write latency time. - UINT16 tFAW; ///< Number of tCK cycles for the channel DIMM's minimum four activate window delay time. - UINT16 tRAS; ///< Number of tCK cycles for the channel DIMM's minimum active to precharge delay time. - UINT16 tRCDtRP; ///< Number of tCK cycles for the channel DIMM's minimum RAS# to CAS# delay time and Row Precharge delay time. - UINT16 tREFI; ///< Number of tCK cycles for the channel DIMM's minimum Average Periodic Refresh Interval. - UINT16 tRFC; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time. - UINT16 tRFCpb; ///< Number of tCK cycles for the channel DIMM's minimum per bank refresh recovery delay time. - UINT16 tRFC2; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time. - UINT16 tRFC4; ///< Number of tCK cycles for the channel DIMM's minimum refresh recovery delay time. - UINT16 tRPab; ///< Number of tCK cycles for the channel DIMM's minimum row precharge delay time for all banks. - UINT16 tRRD; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time. - UINT16 tRRD_L; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for same bank groups. - UINT16 tRRD_S; ///< Number of tCK cycles for the channel DIMM's minimum row active to row active delay time for different bank groups. - UINT16 tRTP; ///< Number of tCK cycles for the channel DIMM's minimum internal read to precharge command delay time. - UINT16 tWR; ///< Number of tCK cycles for the channel DIMM's minimum write recovery time. - UINT16 tWTR; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time. - UINT16 tWTR_L; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for same bank groups. - UINT16 tWTR_S; ///< Number of tCK cycles for the channel DIMM's minimum internal write to read command delay time for different bank groups. - UINT16 tCCD_L; ///< Number of tCK cycles for the channel DIMM's minimum CAS-to-CAS delay for same bank group. -} MRC_CH_TIMING; - -typedef struct { - UINT16 tRDPRE; ///< Read CAS to Precharge cmd delay -} MRC_IP_TIMING; - -/// -/// Memory SMBIOS & OC Memory Data Hob -/// -typedef struct { - UINT8 Status; ///< See MrcDimmStatus for the definition of this field. - UINT8 DimmId; - UINT32 DimmCapacity; ///< DIMM size in MBytes. - UINT16 MfgId; - UINT8 ModulePartNum[20]; ///< Module part number for DDR3 is 18 bytes however for DRR4 20 bytes as per JEDEC Spec, so reserving 20 bytes - UINT8 RankInDimm; ///< The number of ranks in this DIMM. - UINT8 SpdDramDeviceType; ///< Save SPD DramDeviceType information needed for SMBIOS structure creation. - UINT8 SpdModuleType; ///< Save SPD ModuleType information needed for SMBIOS structure creation. - UINT8 SpdModuleMemoryBusWidth; ///< Save SPD ModuleMemoryBusWidth information needed for SMBIOS structure creation. - UINT8 SpdSave[MAX_SPD_SAVE]; ///< Save SPD Manufacturing information needed for SMBIOS structure creation. - UINT16 Speed; ///< The maximum capable speed of the device, in MHz - UINT8 MdSocket; ///< MdSocket: 0 = Memory Down, 1 = Socketed. Needed for SMBIOS structure creation. -} DIMM_INFO; - -typedef struct { - UINT8 Status; ///< Indicates whether this channel should be used. - UINT8 ChannelId; - UINT8 DimmCount; ///< Number of valid DIMMs that exist in the channel. - MRC_CH_TIMING Timing[MAX_PROFILE_NUM]; ///< The channel timing values. - DIMM_INFO DimmInfo[MAX_DIMM]; ///< Save the DIMM output characteristics. -} CHANNEL_INFO; - -typedef struct { - UINT8 Status; ///< Indicates whether this controller should be used. - UINT16 DeviceId; ///< The PCI device id of this memory controller. - UINT8 RevisionId; ///< The PCI revision id of this memory controller. - UINT8 ChannelCount; ///< Number of valid channels that exist on the controller. - CHANNEL_INFO ChannelInfo[MAX_CH]; ///< The following are channel level definitions. -} CONTROLLER_INFO; - -typedef struct { - UINT64 BaseAddress; ///< Trace Base Address - UINT64 TotalSize; ///< Total Trace Region of Same Cache type - UINT8 CacheType; ///< Trace Cache Type - UINT8 ErrorCode; ///< Trace Region Allocation Fail Error code - UINT8 Rsvd[2]; -} PSMI_MEM_INFO; - -/// This data structure contains per-SaGv timing values that are considered output by the MRC. -typedef struct { - UINT32 DataRate; ///< The memory rate for the current SaGv Point in units of MT/s - MRC_CH_TIMING JedecTiming; ///< Timings used for this entry's corresponding SaGv Point - derived from JEDEC SPD spec - MRC_IP_TIMING IpTiming; ///< Timings used for this entry's corresponding SaGv Point - IP specific -} HOB_SAGV_TIMING_OUT; - -/// This data structure contains SAGV config values that are considered output by the MRC. -typedef struct { - UINT32 NumSaGvPointsEnabled; ///< Count of the total number of SAGV Points enabled. - UINT32 SaGvPointMask; ///< Bit mask where each bit indicates an enabled SAGV point. - HOB_SAGV_TIMING_OUT SaGvTiming[HOB_MAX_SAGV_POINTS]; -} HOB_SAGV_INFO; - -typedef struct { - UINT8 Revision; - UINT16 DataWidth; ///< Data width, in bits, of this memory device - /** As defined in SMBIOS 3.0 spec - Section 7.18.2 and Table 75 - **/ - UINT8 MemoryType; ///< DDR type: DDR3, DDR4, or LPDDR3 - UINT16 MaximumMemoryClockSpeed;///< The maximum capable speed of the device, in megahertz (MHz) - UINT16 ConfiguredMemoryClockSpeed; ///< The configured clock speed to the memory device, in megahertz (MHz) - /** As defined in SMBIOS 3.0 spec - Section 7.17.3 and Table 72 - **/ - UINT8 ErrorCorrectionType; - - SiMrcVersion Version; - BOOLEAN EccSupport; - UINT8 MemoryProfile; - UINT8 IsDMBRunning; ///< Deprecated. - UINT32 TotalPhysicalMemorySize; - UINT32 DefaultXmptCK[MAX_XMP_PROFILE_NUM];///< Stores the tCK value read from SPD XMP profiles if they exist. - /// - /// Set of bit flags showing XMP and User Profile capability status for the DIMMs detected in system. For each bit, 1 is supported, 0 is unsupported. - /// Bit 0: XMP Profile 1 capability status - /// Bit 1: XMP Profile 2 capability status - /// Bit 2: XMP Profile 3 capability status - /// Bit 3: User Profile 4 capability status - /// Bit 4: User Profile 5 capability status - /// - UINT8 XmpProfileEnable; - UINT8 XmpConfigWarning; ///< If XMP capable DIMMs config support only 1DPC, but 2DPC is installed - UINT8 Ratio; ///< DDR Frequency Ratio, Max Value 255 - UINT8 RefClk; - UINT32 VddVoltage[MAX_PROFILE_NUM]; - UINT32 VddqVoltage[MAX_PROFILE_NUM]; - UINT32 VppVoltage[MAX_PROFILE_NUM]; - CONTROLLER_INFO Controller[MAX_NODE]; - UINT16 Ratio_UINT16; ///< DDR Frequency Ratio, used for programs that require ratios higher then 255 - UINT32 NumPopulatedChannels; ///< Total number of memory channels populated - HOB_SAGV_INFO SagvConfigInfo; ///< This data structure contains SAGV config values that are considered output by the MRC. - UINT16 TotalMemWidth; ///< Total Memory Width in bits from all populated channels - BOOLEAN MemorySpeedReducedWrongDimmSlot; ///< Can be used by OEM BIOS to display a warning on the screen that DDR speed was reduced due to wrong DIMM population - BOOLEAN MemorySpeedReducedMixedConfig; ///< Can be used by OEM BIOS to display a warning on the screen that DDR speed was reduced due to mixed DIMM config - BOOLEAN DynamicMemoryBoostTrainingFailed; ///< TRUE if Dynamic Memory Boost failed to train and was force disabled on the last full training boot. FALSE otherwise. -} MEMORY_INFO_DATA_HOB; - -/** - Memory Platform Data Hob - - <b>Revision 1:</b> - - Initial version. - <b>Revision 2:</b> - - Added TsegBase, PrmrrSize, PrmrrBase, Gttbase, MmioSize, PciEBaseAddress fields -**/ -typedef struct { - UINT8 Revision; - UINT8 Reserved[3]; - UINT32 BootMode; - UINT32 TsegSize; - UINT32 TsegBase; - UINT32 PrmrrSize; - UINT64 PrmrrBase; - UINT32 GttBase; - UINT32 MmioSize; - UINT32 PciEBaseAddress; - PSMI_MEM_INFO PsmiInfo[MAX_TRACE_CACHE_TYPE]; - PSMI_MEM_INFO PsmiRegionInfo[MAX_TRACE_REGION]; - BOOLEAN MrcBasicMemoryTestPass; -} MEMORY_PLATFORM_DATA; - -typedef struct { - EFI_HOB_GUID_TYPE EfiHobGuidType; - MEMORY_PLATFORM_DATA Data; - UINT8 *Buffer; -} MEMORY_PLATFORM_DATA_HOB; - -#pragma pack (pop) - -#endif // _MEM_INFO_HOB_H_ diff --git a/util/abuild/abuild b/util/abuild/abuild index 58f48f2b05f2..5b87cbc2e731 100755 --- a/util/abuild/abuild +++ b/util/abuild/abuild @@ -11,15 +11,15 @@ #set -x # Turn echo on.... -ABUILD_DATE="Nov 18, 2023" -ABUILD_VERSION="0.11.03" +ABUILD_DATE="Apr 20, 2025" +ABUILD_VERSION="0.11.04" -TOP=$PWD +TOP=${PWD} # Where shall we place all the build trees? TARGET_DEFAULT=coreboot-builds TARGET=${COREBOOT_BUILD_DIR:-${TARGET_DEFAULT}} -XML_DEFAULT="$TOP/abuild.xml" +XML_DEFAULT="${TOP}/abuild.xml" XMLFILE="${XML_DEFAULT}" REAL_XMLFILE="${XML_DEFAULT}" @@ -29,17 +29,20 @@ TESTRUN="${TESTRUN_DEFAULT}" export KCONFIG_OVERWRITECONFIG=1 +# Identify this as a coreboot autobuild +export COREBOOT_ABUILD=1 + # path to payload. Should be more generic PAYLOAD=/dev/null # get path to coreboot XGCC if it's not already set -if [ -z "$XGCCPATH" ]; then +if [[ -z "${XGCCPATH}" ]]; then XGCCPATH="${TOP}/util/crossgcc/xgcc/bin/" fi # Add XGCC to the path. -if [ -d "$XGCCPATH" ] && [[ ":$PATH:" != *":$XGCCPATH:"* ]]; then - PATH="$XGCCPATH:$PATH" +if [[ -d "${XGCCPATH}" ]] && [[ ":${PATH}:" != *":${XGCCPATH}:"* ]]; then + PATH="${XGCCPATH}:${PATH}" fi # Lines of error context to be printed in FAILURE case @@ -61,7 +64,7 @@ checksum_file="" cpus=1 # change with -d <directory> -configdir="$TOP/configs" +configdir="${TOP}/configs" # Timeless builds TIMELESS=0 @@ -70,8 +73,8 @@ TIMELESS=0 for i in make gmake gnumake nonexistent_make; do $i --version 2>/dev/null |grep "GNU Make" >/dev/null && break done -if [ "$i" = "nonexistent_make" ]; then - echo No GNU Make found. +if [[ "$i" = "nonexistent_make" ]]; then + printf "No GNU Make found.\n" exit 1 fi MAKE=$i @@ -100,40 +103,36 @@ ts_basetime_str=$(date -u --date=@${ts_exec_shell}) trap interrupt INT -function interrupt +# shellcheck disable=SC2317 # Disable unreacheable code warning. It's a trap! +interrupt() { printf "\n%s: execution interrupted manually.\n" "$0" - if [ "$mode" == "junit" ]; then + if [[ "$mode" == "junit" ]]; then printf "%s: deleting incomplete xml output file.\n" "$0" fi exit 1 } -function debug -{ - test "$verbose" == "true" && echo "$*" -} - -function junit +junit() { - test "$mode" == "junit" && echo "$*" >> "$XMLFILE" + [[ "${mode}" == "junit" ]] && printf "%s\n" "$*" >> "${XMLFILE}" return 0 } -function junitfile +junitfile() { - test "$mode" == "junit" && { + test "${mode}" == "junit" && { printf '<![CDATA[\n' cat "$1" printf ']]>\n' - } >> "$XMLFILE" + } >> "${XMLFILE}" } # Return mainboard descriptors. # By default all mainboards are listed, but when passing a two-level path # below src/mainboard, such as emulation/qemu-i440fx, or emulation/*, it # returns all board descriptors in that hierarchy. -function get_mainboards +get_mainboards() { local search_space=${1-*/*} # shellcheck disable=SC2086 @@ -143,7 +142,7 @@ function get_mainboards } # Given a mainboard descriptor, return its directory below src/mainboard -function mainboard_directory +mainboard_directory() { local MAINBOARD=$1 @@ -154,7 +153,7 @@ function mainboard_directory } # Given a mainboard descriptor, return its vendor (CONFIG_VENDOR_*) -function mainboard_vendor +mainboard_vendor() { local MAINBOARD=$1 local kconfig_file @@ -164,10 +163,10 @@ function mainboard_vendor grep -l "^[[:space:]]*config\>[[:space:]]*\<BOARD_${MAINBOARD}\>" \ ${ROOT}/src/mainboard/*/*/Kconfig.name | \ sed "s:^\(${ROOT}/src/mainboard/.*\)/.*/\(Kconfig.name\)$:\1/\2:" ) - if [ ! -f "$kconfig_file" ]; then + if [[ ! -f "${kconfig_file}" ]]; then exit 1 fi - grep "^[[:space:]]*config\>[[:space:]]*\<VENDOR_" "$kconfig_file" | \ + grep "^[[:space:]]*config\>[[:space:]]*\<VENDOR_" "${kconfig_file}" | \ sed "s,^.*\<VENDOR_\([A-Z0-9_]*\)\>.*$,\1," } @@ -175,68 +174,78 @@ function mainboard_vendor # descriptors (eg. EMULATION_QEMU_X86_I440F} and returns the latter # format. # If a directory contains multiple boards, returns them all. -function normalize_target +normalize_target() { - # TODO: Change 'targets' variable to an array - local targets + local target_input=$1 + local -a targets=() # Initialize as an empty array local VARIANT_UC + local i VARIANT_UC=$(echo "${variant}" | tr '[:lower:]' '[:upper:]' | tr '-' '_') - targets=$(get_mainboards "$1") - if [ -n "$targets" ]; then - # shellcheck disable=SC2086 - targets="$(grep "${VARIANT_UC}\$" <<< ${targets})" - echo "$targets" + # Read output of get_mainboards into the targets array + mapfile -t targets < <(get_mainboards "${target_input}") + if [[ ${#targets[@]} -gt 0 ]]; then + # Filter the array using grep + mapfile -t targets < <(printf '%s\n' "${targets[@]}" | grep "${VARIANT_UC}\$") + # Print the filtered targets, one per line + if [[ ${#targets[@]} -gt 0 ]]; then + printf '%s\n' "${targets[@]}" + fi return fi - targets=$(echo "$1" | tr ',' ' ') - for i in $targets; do - if [ -n "$(mainboard_directory "$i")" ]; then - echo "$i" + # Handle comma-separated input string + IFS=',' read -ra targets <<< "${target_input}" + for i in "${targets[@]}"; do + # Trim whitespace if necessary (read -ra might include it) + i=$(echo "$i" | xargs) + if [[ -n "$(mainboard_directory "${i}")" ]]; then + printf "%s\n" "${i}" else - echo "$i is not a valid target" >&2 + printf "%s is not a valid target\n" "${i}" >&2 exit 1 fi done } # shellcheck disable=SC2129 -function create_config +create_config() { local BUILD_NAME=$1 local build_dir=$2 local board_srcdir local config_file="${build_dir}/config.build" - board_srcdir="$(mainboard_directory "${BUILD_NAME}")" + board_srcdir=$(mainboard_directory "${BUILD_NAME}") mkdir -p "${build_dir}" - mkdir -p "$TARGET/sharedutils" + mkdir -p "${TARGET}/sharedutils" - if [ "$quiet" == "false" ]; then echo " Creating config file for $BUILD_NAME..."; fi - echo "CONFIG_VENDOR_$(mainboard_vendor "${BUILD_NAME}")=y" > "${config_file}" - echo "CONFIG_BOARD_${BUILD_NAME}=y" >> "${config_file}" - grep "select[\t ]*ARCH" "${ROOT}/src/mainboard/${board_srcdir}/Kconfig" | \ - sed "s,^.*\(ARCH_.*\)[^A-Z0-9_]*,CONFIG_\1=y," >> "${config_file}" - echo "CONFIG_MAINBOARD_DIR=\"${board_srcdir}\"" >> "${config_file}" + if [[ "${quiet}" == "false" ]]; then printf " Creating config file for %s...\n" "${BUILD_NAME}"; fi + { + printf "CONFIG_VENDOR_%s=y\n" "$(mainboard_vendor "${BUILD_NAME}")" + printf "CONFIG_BOARD_%s=y\n" "${BUILD_NAME}" + grep "select[\t ]*ARCH" "${ROOT}/src/mainboard/${board_srcdir}/Kconfig" | \ + sed "s,^.*\\(ARCH_.*\)[^A-Z0-9_]*,CONFIG_\\1=y," + printf "CONFIG_MAINBOARD_DIR=\\\"%s\\\"\n" "${board_srcdir}" + } > "${config_file}" - update_config "$BUILD_NAME" "$build_dir" "$config_file" + update_config "${BUILD_NAME}" "${build_dir}" "${config_file}" ret=$? - if [ $ret -eq 0 ]; then - if [ "$quiet" == "false" ]; then echo " $BUILD_NAME config created."; fi + if [[ ${ret} -eq 0 ]]; then + if [[ "${quiet}" == "false" ]]; then printf " %s config created.\n" "${BUILD_NAME}"; fi return 0 else # Does this ever happen? - if [ "$quiet" == "false" ]; then printf "%s config creation FAILED!\nLog excerpt:\n" "$BUILD_NAME"; fi - tail -n $CONTEXT "$build_dir/config.log" 2> /dev/null || tail -$CONTEXT "$build_dir/config.log" + if [[ "${quiet}" == "false" ]]; then printf "%s config creation FAILED!\nLog excerpt:\n" "${BUILD_NAME}"; fi + tail -n ${CONTEXT} "${build_dir}/config.log" 2> /dev/null || tail -${CONTEXT} "${build_dir}/config.log" return 1 fi } -function update_config +update_config() { local BUILD_NAME=$1 local build_dir=$2 @@ -252,55 +261,55 @@ function update_config # Usage: payload.sh [BOARD] # the script returns an absolute path to the payload binary. - if [ -f "$payloads/payload.sh" ]; then - PAYLOAD=$(sh "$payloads/payload.sh" "$BUILD_NAME") + if [[ -f "${payloads}/payload.sh" ]]; then + PAYLOAD=$(sh "${payloads}/payload.sh" "${BUILD_NAME}") local PAYLOAD_OK=$? - if [ $PAYLOAD_OK -gt 0 ]; then - echo "problem with payload" + if [[ ${PAYLOAD_OK} -gt 0 ]]; then + printf "Problem with payload\n" exit 1 fi - if [ "$quiet" == "false" ]; then printf "Using payload %s\n" "$PAYLOAD"; fi - elif [ "$payloads" = "none" ]; then + if [[ "${quiet}" == "false" ]]; then printf "Using payload %s\n" "${PAYLOAD}"; fi + elif [[ "${payloads}" = "none" ]]; then PAYLOAD=none fi - if [ "$PAYLOAD" = "none" ]; then + if [[ "${PAYLOAD}" = "none" ]]; then { - echo "CONFIG_PAYLOAD_NONE=y" - echo "# CONFIG_PAYLOAD_ELF is not set" + printf "CONFIG_PAYLOAD_NONE=y\n" + printf "# CONFIG_PAYLOAD_ELF is not set\n" } >> "${config_file}" - elif [ "$PAYLOAD" != "/dev/null" ]; then + elif [[ "${PAYLOAD}" != "/dev/null" ]]; then { - echo "# CONFIG_PAYLOAD_NONE is not set" - echo "CONFIG_PAYLOAD_ELF=y" - echo "CONFIG_PAYLOAD_FILE=\"$PAYLOAD\"" + printf "# CONFIG_PAYLOAD_NONE is not set\n" + printf "CONFIG_PAYLOAD_ELF=y\n" + printf "CONFIG_PAYLOAD_FILE=\"%s\"\n" "$PAYLOAD" } >> "${config_file}" fi # Disable all other payload config options { - echo "# CONFIG_PAYLOAD_SEABIOS is not set" - echo "# CONFIG_PAYLOAD_FILO is not set" - echo "# CONFIG_PAYLOAD_GRUB2 is not set" - echo "# CONFIG_PAYLOAD_DEPTHCHARGE is not set" - echo "# CONFIG_PAYLOAD_LINUXBOOT is not set" - echo "# CONFIG_PAYLOAD_UBOOT is not set" - echo "# CONFIG_PAYLOAD_EDK2 is not set" - echo "# CONFIG_PXE is not set" - echo "# CONFIG_BUILD_IPXE is not set" - echo "# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set" - echo "# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set" - echo "# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set" - echo "# CONFIG_TINT_SECONDARY_PAYLOAD is not set" + printf "# CONFIG_PAYLOAD_SEABIOS is not set\n" + printf "# CONFIG_PAYLOAD_FILO is not set\n" + printf "# CONFIG_PAYLOAD_GRUB2 is not set\n" + printf "# CONFIG_PAYLOAD_DEPTHCHARGE is not set\n" + printf "# CONFIG_PAYLOAD_LINUXBOOT is not set\n" + printf "# CONFIG_PAYLOAD_UBOOT is not set\n" + printf "# CONFIG_PAYLOAD_EDK2 is not set\n" + printf "# CONFIG_PXE is not set\n" + printf "# CONFIG_BUILD_IPXE is not set\n" + printf "# CONFIG_MEMTEST_SECONDARY_PAYLOAD is not set\n" + printf "# CONFIG_COREINFO_SECONDARY_PAYLOAD is not set\n" + printf "# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set\n" + printf "# CONFIG_TINT_SECONDARY_PAYLOAD is not set\n" } >> "${config_file}" - if [ "$quiet" == "false" ]; then echo " $MAINBOARD ($customizing)"; fi + if [[ "${quiet}" == "false" ]]; then printf " %s (%s)\n" "${MAINBOARD}" "${customizing}"; fi # shellcheck disable=SC2059 - printf "$configoptions" >> "${config_file}" + printf "${configoptions}" >> "${config_file}" - $MAKE olddefconfig "$verboseopt" "DOTCONFIG=${config_file}" "obj=${build_dir}" "objutil=$TARGET/sharedutils" &> "${build_dir}/config.log" ; \ + ${MAKE} olddefconfig "${verboseopt}" "DOTCONFIG=${config_file}" "obj=${build_dir}" "objutil=${TARGET}/sharedutils" &> "${build_dir}/config.log" ; \ CONFIG_OK=$? - if [ $CONFIG_OK -eq 0 ]; then - $MAKE savedefconfig "$verboseopt" DEFCONFIG="${defconfig_file}" DOTCONFIG="${config_file}" obj="${build_dir}" objutil="$TARGET/sharedutils" &>> "${build_dir}/config.log" + if [[ ${CONFIG_OK} -eq 0 ]]; then + ${MAKE} savedefconfig "${verboseopt}" DEFCONFIG="${defconfig_file}" DOTCONFIG="${config_file}" obj="${build_dir}" objutil="${TARGET}/sharedutils" &>> "${build_dir}/config.log" return $? else return 1 @@ -308,40 +317,40 @@ function update_config } # shellcheck disable=SC2129 -function create_buildenv +create_buildenv() { local BUILD_NAME=$1 local build_dir=$2 local config_file=$3 - if [ -z "$config_file" ]; then - create_config "$BUILD_NAME" "$build_dir" + if [[ -z "${config_file}" ]]; then + create_config "${BUILD_NAME}" "${build_dir}" else local new_config_file="${build_dir}/config.build" - cp "$config_file" "$new_config_file" - update_config "$BUILD_NAME" "$build_dir" "$new_config_file" + cp "${config_file}" "${new_config_file}" + update_config "${BUILD_NAME}" "${build_dir}" "${new_config_file}" fi local ret=$? # Allow simple "make" in the target directory - local MAKEFILE=$TARGET/${BUILD_NAME}/Makefile - echo "# autogenerated" > "$MAKEFILE" - echo "TOP=$ROOT" >> "$MAKEFILE" - echo "BUILD=$TARGET" >> "$MAKEFILE" - echo "OBJ=\$(BUILD)/${MAINBOARD}" >> "$MAKEFILE" - echo "OBJUTIL=\$(BUILD)/sharedutils" >> "$MAKEFILE" - echo "all:" >> "$MAKEFILE" - echo " @cp -a config.h config.h.bak" >> "$MAKEFILE" - echo " @cd \$(TOP); \$(MAKE) olddefconfig DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)" >> "$MAKEFILE" - echo " @tail -n+6 config.h > config.new; tail -n+6 config.h.bak > config.old" >> "$MAKEFILE" - echo " @cmp -s config.new config.old && cp -a config.h.bak config.h || echo \"Config file changed\"" >> "$MAKEFILE" - echo " @rm config.h.bak config.new config.old" >> "$MAKEFILE" - echo " @cd \$(TOP); \$(MAKE) DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)" >> "$MAKEFILE" - - return $ret + local MAKEFILE=${TARGET}/${BUILD_NAME}/Makefile + printf "# autogenerated\n" > "${MAKEFILE}" + printf "TOP=%s\n" "${ROOT}" >> "${MAKEFILE}" + printf "BUILD=%s\n" "${TARGET}" >> "${MAKEFILE}" + printf "OBJ=\$(BUILD)/%s\n" "${MAINBOARD}" >> "${MAKEFILE}" + printf "OBJUTIL=\$(BUILD)/sharedutils\n" >> "${MAKEFILE}" + printf "all:\n" >> "${MAKEFILE}" + printf "\t@cp -a config.h config.h.bak\n" >> "${MAKEFILE}" + printf "\t@cd \$(TOP); \$(MAKE) olddefconfig DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)\n" >> "${MAKEFILE}" + printf "\t@tail -n+6 config.h > config.new; tail -n+6 config.h.bak > config.old\n" >> "${MAKEFILE}" + printf "\t@cmp -s config.new config.old && cp -a config.h.bak config.h || printf \"Config file changed\"\n" >> "${MAKEFILE}" + printf "\t@rm config.h.bak config.new config.old\n" >> "${MAKEFILE}" + printf "\t@cd \$(TOP); \$(MAKE) DOTCONFIG=\$(OBJ)/config.build objutil=\$(OBJUTIL) obj=\$(OBJ)\n" >> "${MAKEFILE}" + + return ${ret} } -function check_config +check_config() { local BUILD_DIR="$1" local TEST_TYPE="$2" @@ -351,16 +360,16 @@ function check_config local CONFIG_FILE="$BUILD_DIR/config.build" local CONFIG_LOG="$BUILD_DIR/config.log" - if [ -z "$NEGATE" ]; then - if ! grep -q "$TEST_STRING" "$CONFIG_FILE"; then - echo "config file: $CONFIG_FILE has incorrect $TEST_TYPE" - echo "Error: Expected '$TEST_STRING' in config file." >> "$CONFIG_LOG" + if [[ -z "${NEGATE}" ]]; then + if ! grep -q "${TEST_STRING}" "${CONFIG_FILE}"; then + printf "config file: %s has incorrect %s\n" "${CONFIG_FILE}" "${TEST_TYPE}" + printf "Error: Expected '%s' in config file.\n" "${TEST_STRING}" >> "${CONFIG_LOG}" return 1 fi else - if grep -q "$TEST_STRING" "$CONFIG_FILE"; then - echo "config file: $CONFIG_FILE has incorrect $TEST_TYPE" - echo "Error: Expected not to see '$TEST_STRING' in config file." >> "$CONFIG_LOG" + if grep -q "${TEST_STRING}" "${CONFIG_FILE}"; then + printf "config file: %s has incorrect %s\n" "${CONFIG_FILE}" "${TEST_TYPE}" + printf "Error: Expected not to see '%s' in config file.\n" "${TEST_STRING}" >> "${CONFIG_LOG}" return 1 fi fi @@ -369,23 +378,27 @@ function check_config } # Counting microseconds since start of shell -function add_timestamp +add_timestamp() { - local now=${EPOCHREALTIME} - local seconds=$(echo $now | cut -f 1 -d '.') - local usecs=$(echo $now | cut -f 2 -d '.') + local now + local seconds + local usecs + + now=${EPOCHREALTIME} + seconds=$(echo ${now} | cut -f 1 -d '.') + usecs=$(echo ${now} | cut -f 2 -d '.') seconds=$(( seconds - ts_exec_shell )) usecs=$(( seconds * 1000 * 1000 + 10#$usecs )) - printf "%s" $usecs + printf "%s" ${usecs} } -function ts_delta_seconds +ts_delta_seconds() { local delta=$(( ($2 - $1) / (1000 * 1000) )) - printf "%s" $delta + printf "%s" ${delta} } -function ts_delta_string +ts_delta_string() { local ts_minutes local ts_seconds @@ -397,23 +410,23 @@ function ts_delta_string ts_seconds=$(( delta / 1000)) delta=$(( delta % 1000 )) - if [ $ts_minutes -ne 0 ] ; then - printf "%d min %d sec" $ts_minutes $ts_seconds + if [[ ${ts_minutes} -ne 0 ]] ; then + printf "%d min %d sec" ${ts_minutes} ${ts_seconds} else - printf "%d.%03d seconds" $ts_seconds $delta + printf "%d.%03d seconds" ${ts_seconds} ${delta} fi } -function compile_target +compile_target() { local BUILD_NAME=$1 - if [ "$quiet" == "false" ]; then echo " Compiling $MAINBOARD image$cpuconfig..."; fi + if [[ "${quiet}" == "false" ]]; then printf " Compiling %s image%s...\n" "${MAINBOARD}" "${cpuconfig}"; fi CURR=$( pwd ) ts_1=$(add_timestamp) - eval "$BUILDPREFIX" "$MAKE" "$verboseopt" DOTCONFIG="${build_dir}/config.build" obj="${build_dir}" objutil="$TARGET/sharedutils" BUILD_TIMELESS=$TIMELESS \ + eval "${BUILDPREFIX}" "${MAKE}" "${verboseopt}" DOTCONFIG="${build_dir}/config.build" obj="${build_dir}" objutil="${TARGET}/sharedutils" BUILD_TIMELESS=${TIMELESS} \ &> "${build_dir}/make.log" ; \ MAKE_FAILED=$? ts_2=$(add_timestamp) @@ -421,61 +434,63 @@ function compile_target cd "${build_dir}" || return $? timestamps="abuild.timestamps" - printf "Build started %s\n" "${ts_basetime_str}" > "${timestamps}" - printf "BASETIME_SECONDS %d\n" $ts_exec_shell >> "${timestamps}" - printf "TS_0 %d\n" $ts_0 >> "${timestamps}" - printf "TS_1 %d\n" $ts_1 >> "${timestamps}" - printf "TS_2 %d\n" $ts_2 >> "${timestamps}" - - duration=$(ts_delta_seconds $ts_0 $ts_2) - duration_str=$(ts_delta_string $ts_0 $ts_2) - junit " <testcase classname='${TESTRUN}${testclass/#/.}' name='$BUILD_NAME' time='$duration' >" - - if [ $MAKE_FAILED -eq 0 ]; then + { + printf "Build started %s\n" "${ts_basetime_str}" + printf "BASETIME_SECONDS %d\n" "${ts_exec_shell}" + printf "TS_0 %d\n" "${ts_0}" + printf "TS_1 %d\n" "${ts_1}" + printf "TS_2 %d\n" "${ts_2}" + } > "${timestamps}" + + duration=$(ts_delta_seconds "${ts_0}" "${ts_2}") + duration_str=$(ts_delta_string "${ts_0}" "${ts_2}") + junit " <testcase classname='${TESTRUN}${testclass/#/.}' name='${BUILD_NAME}' time='${duration}' >" + + if [[ ${MAKE_FAILED} -eq 0 ]]; then junit "<system-out>" junitfile make.log junit "</system-out>" printf "ok\n" > compile.status - printf "%s built successfully. (took %s)\n" "$BUILD_NAME" "${duration_str}" - echo "$BUILD_NAME" >> "$PASSED_BOARDS" + printf "%s built successfully. (took %s)\n" "${BUILD_NAME}" "${duration_str}" + echo "${BUILD_NAME}" >> "${PASSED_BOARDS}" else junit "<failure type='BuildFailed'>" junitfile make.log junit "</failure>" printf "failed\n" > compile.status - printf "%s build FAILED after %s!\nLog excerpt:\n" "$BUILD_NAME" "${duration_str}" - tail -n $CONTEXT make.log 2> /dev/null || tail -$CONTEXT make.log - if [ "$clean_work" = "true" ]; then - echo "$BUILD_NAME" >> "$FAILED_BOARDS" + printf "%s build FAILED after %s!\nLog excerpt:\n" "${BUILD_NAME}" "${duration_str}" + tail -n ${CONTEXT} make.log 2> /dev/null || tail -${CONTEXT} make.log + if [[ "${clean_work}" = "true" ]]; then + echo "${BUILD_NAME}" >> "${FAILED_BOARDS}" else - echo "$BUILD_NAME - Log: ${build_dir}/make.log" >> "$FAILED_BOARDS" + echo "${BUILD_NAME} - Log: ${build_dir}/make.log" >> "${FAILED_BOARDS}" fi failed=1 fi - cd "$CURR" || return $? - if [ -n "$checksum_file" ]; then + cd "${CURR}" || return $? + if [[ -n "${checksum_file}" ]]; then sha256sum "${build_dir}/coreboot.rom" >> "${checksum_file}_platform" sort "${build_dir}/config.h" | grep CONFIG_ > "${build_dir}/config.h.sorted" sha256sum "${build_dir}/config.h.sorted" >> "${checksum_file}_config" fi stats_files="${build_dir}/${timestamps}" - if [ -f ${build_dir}/ccache.stats ]; then + if [[ -f ${build_dir}/ccache.stats ]]; then stats_files="${stats_files} ${build_dir}/ccache.stats" fi - flock -F -w 0.1 $TARGET/.statslock tar -rf ${stats_archive} ${stats_files} 2> /dev/null + flock -F -w 0.1 "${TARGET}/.statslock" tar -rf "${stats_archive}" "${stats_files}" 2> /dev/null - if [ "$clean_work" = "true" ]; then + if [[ "${clean_work}" = "true" ]]; then rm -rf "${build_dir}" fi - if [ "$clean_objs" = "true" ]; then - find ${build_dir} \! \( -name coreboot.rom -o -name config.h -o -name config.build -o -name make.log \) -type f -exec rm {} + - find ${build_dir} -type d -exec rmdir -p {} + 2>/dev/null + if [[ "${clean_objs}" = "true" ]]; then + find "${build_dir}" \! \( -name coreboot.rom -o -name config.h -o -name config.build -o -name make.log \) -type f -exec rm {} + + find "${build_dir}" -type d -exec rmdir -p {} + 2>/dev/null fi - return $MAKE_FAILED + return ${MAKE_FAILED} } -function build_config +build_config() { local MAINBOARD=$1 local build_dir=$2 @@ -486,120 +501,118 @@ function build_config board_srcdir=$(mainboard_directory "${MAINBOARD}") - if [ "$(cat "${build_dir}/compile.status" 2>/dev/null)" = "ok" ] && \ - [ "$buildall" = "false" ]; then - echo "Skipping $BUILD_NAME; (already successful)" + if [[ "$(cat "${build_dir}/compile.status" 2>/dev/null)" = "ok" ]] && \ + [[ "${buildall}" = "false" ]]; then + printf "Skipping %s; (already successful)\n" "${BUILD_NAME}" + return fi export HOSTCC='gcc' - if [ "$chromeos" = true ] && [ "$(grep -c "^[[:space:]]*select[[:space:]]*MAINBOARD_HAS_CHROMEOS\>" "${ROOT}/src/mainboard/${board_srcdir}/Kconfig")" -eq 0 ]; then - echo "${BUILD_NAME} doesn't support ChromeOS, skipping." + printf "%s doesn't support ChromeOS, skipping.\n" "${BUILD_NAME}" + if [[ "${chromeos}" = true ]] && [[ "$(grep -c "^[[:space:]]*select[[:space:]]*MAINBOARD_HAS_CHROMEOS>" "${ROOT}/src/mainboard/${board_srcdir}/Kconfig")" -eq 0 ]]; then return fi - if [ "$quiet" == "false" ]; then echo "Building $BUILD_NAME"; fi - mkdir -p "$TARGET/${BUILD_NAME}" "$TARGET/abuild" - ABSPATH="$(cd "$TARGET/abuild" && pwd)" - XMLFILE="$ABSPATH/${BUILD_NAME}.xml" + if [[ "${quiet}" == "false" ]]; then printf "Building %s\n" "${BUILD_NAME}"; fi + mkdir -p "${TARGET}/${BUILD_NAME}" "${TARGET}/abuild" + ABSPATH="$(cd "${TARGET}/abuild" && pwd)" + XMLFILE="${ABSPATH}/${BUILD_NAME}.xml" rm -f "${XMLFILE}" ts_0=$(add_timestamp) - create_buildenv "$BUILD_NAME" "$build_dir" "$config_file" + create_buildenv "${BUILD_NAME}" "${build_dir}" "${config_file}" local BUILDENV_CREATED=$? - check_config "$build_dir" "mainboard" "CONFIG_BOARD_${MAINBOARD}=y" + check_config "${build_dir}" "mainboard" "CONFIG_BOARD_${MAINBOARD}=y" local MAINBOARD_OK=$? - check_config "$build_dir" "vendor" "CONFIG_VENDOR_$(mainboard_vendor "${MAINBOARD}")=y" + check_config "${build_dir}" "vendor" "CONFIG_VENDOR_$(mainboard_vendor "${MAINBOARD}")=y" local VENDOR_OK=$? - if [ "$chromeos" = false ]; then + if [[ "${chromeos}" = false ]]; then # Skip this rule for configs created from templates that already # come with CHROMEOS enabled. - grep -q "^CONFIG_CHROMEOS=y" ${config_file:-/dev/null} || \ - check_config "$build_dir" "ChromeOS" "CONFIG_CHROMEOS=y" negate + grep -q "^CONFIG_CHROMEOS=y" "${config_file:-/dev/null}" || \ + check_config "${build_dir}" "ChromeOS" "CONFIG_CHROMEOS=y" negate local FORCE_ENABLED_CROS=$? else local FORCE_ENABLED_CROS=0 fi - if [ "$clang" = true ]; then - check_config "$build_dir" "clang" "CONFIG_COMPILER_LLVM_CLANG=y" - if [ $? -ne 0 ]; then - echo "${MAINBOARD} doesn't support clang, skipping." + if [[ "${clang}" = true ]]; then + if ! check_config "${build_dir}" "clang" "CONFIG_COMPILER_LLVM_CLANG=y"; then + printf "%s doesn't support clang, skipping.\n" "${MAINBOARD}" return fi fi - if [ -n "${skipconfig_set}" ]; then - check_config "${build_dir}" "config value" "CONFIG_${skipconfig_set}=y" negate - if [ $? -ne 0 ]; then - echo "${MAINBOARD} has ${skipconfig_set} set. Skipping at user's request." + if [[ -n "${skipconfig_set}" ]]; then + if ! check_config "${build_dir}" "config value" "CONFIG_${skipconfig_set}=y" negate; then + printf "%s has %s set. Skipping at user's request.\n" "${MAINBOARD}" "${skipconfig_set}" return fi fi - if [ -n "${skipconfig_unset}" ]; then - check_config "${build_dir}" "config value" "CONFIG_${skipconfig_unset}=y" - if [ $? -ne 0 ]; then - echo "${MAINBOARD} does not have ${skipconfig_unset} set. Skipping at user's request." + if [[ -n "${skipconfig_unset}" ]]; then + if ! check_config "${build_dir}" "config value" "CONFIG_${skipconfig_unset}=y"; then + printf "%s does not have %s set. Skipping at user's request.\n" "${MAINBOARD}" "${skipconfig_unset}" return fi fi - if [ $BUILDENV_CREATED -ne 0 ] || [ $MAINBOARD_OK -ne 0 ] || [ $VENDOR_OK -ne 0 ] || [ $FORCE_ENABLED_CROS -eq 1 ]; then - junit " <testcase classname='${TESTRUN}${testclass/#/.}' name='$BUILD_NAME' >" + if [[ ${BUILDENV_CREATED} -ne 0 ]] || [[ ${MAINBOARD_OK} -ne 0 ]] || [[ ${VENDOR_OK} -ne 0 ]] || [[ ${FORCE_ENABLED_CROS} -eq 1 ]]; then + junit " <testcase classname='${TESTRUN}${testclass/#/.}' name='${BUILD_NAME}' >" junit "<failure type='BuildFailed'>" - junitfile "$build_dir/config.log" + junitfile "${build_dir}/config.log" junit "</failure>" printf "failed\n" > compile.status - printf "%s build configuration FAILED!\nLog excerpt:\n" "$BUILD_NAME" - tail -n $CONTEXT "$build_dir/config.log" 2> /dev/null || tail -$CONTEXT "$build_dir/config.log" + printf "%s build configuration FAILED!\nLog excerpt:\n" "${BUILD_NAME}" + tail -n ${CONTEXT} "${build_dir}/config.log" 2> /dev/null || tail -${CONTEXT} "${build_dir}/config.log" junit "</testcase>" - echo "$BUILD_NAME - Log: $build_dir/config.log" >> "$FAILED_BOARDS" + printf "%s - Log: %s/config.log\n" "${BUILD_NAME}" "${build_dir}" >> "${FAILED_BOARDS}" return fi local required_arches - required_arches=$(grep -E "^CONFIG_ARCH_(BOOTBLOCK|R.MSTAGE|VERSTAGE)" "$TARGET/${BUILD_NAME}/config.build" | \ + required_arches=$(grep -E "^CONFIG_ARCH_(BOOTBLOCK|R.MSTAGE|VERSTAGE)" "${TARGET}/${BUILD_NAME}/config.build" | \ sed "s,^CONFIG_ARCH_[^_]*_\([^=]*\)=.*$,\1," |sort -u |tr 'A-Z\n\r' 'a-z ') - missing_arches="$($MAKE --no-print-directory -f - \ - REQUIRED_ARCHES="$required_arches" <<'EOF' + missing_arches="$(${MAKE} --no-print-directory -f - \ + REQUIRED_ARCHES="${required_arches}" <<'EOF' include $(xcompile) .PHONY: missing_arches missing_arches: $(if $(XCOMPILE_COMPLETE),,$(error $(xcompile) is invalid.)) - @echo $(foreach arch,$(REQUIRED_ARCHES),$(if $(filter $(arch),$(SUBARCH_SUPPORTED)),,$(arch))) + @printf "%s\n" "$(foreach arch,$(REQUIRED_ARCHES),$(if $(filter $(arch),$(SUBARCH_SUPPORTED)),,$(arch)))" EOF )" # shellcheck disable=SC2181 if [[ $? -ne 0 ]]; then - echo "Calculating missing_arches failed" >&2 + printf "Calculating missing_arches failed\n" >&2 exit 1 fi - if [ -n "$missing_arches" ]; then - printf "skipping %s because we're missing compilers for (%s)\n" "$BUILD_NAME" "$missing_arches" + if [[ -n "${missing_arches}" ]]; then + printf "skipping %s because we're missing compilers for (%s)\n" "${BUILD_NAME}" "${missing_arches}" return fi - if [ $BUILDENV_CREATED -eq 0 ] && [ $configureonly -eq 0 ]; then + if [[ ${BUILDENV_CREATED} -eq 0 ]] && [[ ${configureonly} -eq 0 ]]; then BUILDPREFIX= - if [ "$scanbuild" = "true" ]; then - scanbuild_out=$TARGET/${BUILD_NAME}-scanbuild + if [[ "${scanbuild}" = "true" ]]; then + scanbuild_out="${TARGET}/${BUILD_NAME}-scanbuild" rm -rf "${scanbuild_out}" BUILDPREFIX="scan-build ${SCANBUILD_ARGS} -o ${scanbuild_out}tmp" fi compile_target "${BUILD_NAME}" - if [ "$scanbuild" = "true" ]; then - mv "${scanbuild_out}"tmp/* "${scanbuild_out}" + if [[ "${scanbuild}" = "true" ]]; then + mv "${scanbuild_out}tmp"/* "${scanbuild_out}" rmdir "${scanbuild_out}tmp" fi fi @@ -607,74 +620,74 @@ EOF junit "</testcase>" } -function record_mainboard +record_mainboard() { local log=$1 - if test "$mode" != "text" && test -f "$TARGET/abuild/${log}.xml"; then - cat "$TARGET/abuild/${log}.xml" >> "$REAL_XMLFILE" - echo "$TARGET/abuild/${log}.xml written to $REAL_XMLFILE" >&2 + printf "%s/abuild/%s.xml written to %s\n" "${TARGET}" "${log}" "${REAL_XMLFILE}" >&2 + if test "${mode}" != "text" && test -f "${TARGET}/abuild/${log}.xml"; then + cat "${TARGET}/abuild/${log}.xml" >> "${REAL_XMLFILE}" else - echo "Warning: $TARGET/abuild/${log}.xml not found." >&2 + printf "Warning: %s/abuild/%s.xml not found.\n" "${TARGET}" "${log}" >&2 fi } # One target may build several configs -function build_target +build_target() { local MAINBOARD=$1 local MAINBOARD_LC - MAINBOARD_LC=$(echo "$MAINBOARD" | tr '[:upper:]' '[:lower:]') + MAINBOARD_LC=$(echo "${MAINBOARD}" | tr '[:upper:]' '[:lower:]') # look for config files in the config directory that match the boardname - if [ -n "$( find "$configdir" -maxdepth 1 -name "config.${MAINBOARD_LC}*" -print -quit )" ]; then - for config in "$configdir/config.${MAINBOARD_LC}"*; do + if [[ -n "$( find "${configdir}" -maxdepth 1 -name "config.${MAINBOARD_LC}*" -print -quit )" ]]; then + for config in "${configdir}/config.${MAINBOARD_LC}"*; do BUILD_NAME="${config##*/}" BUILD_NAME="${BUILD_NAME##config.}" BUILD_NAME=$(echo "${BUILD_NAME}" | tr '[:lower:]' '[:upper:]') - echo $BUILD_NAME $MAINBOARD + printf "%s %s\n" "${BUILD_NAME}" "${MAINBOARD}" # If the file in configs/ results in the same build_name as the default config # append a '_' to differentiate. Otherwise the default configuration would # override the results. - if [ "${MAINBOARD}" = "${BUILD_NAME}" ]; then + if [[ "${MAINBOARD}" = "${BUILD_NAME}" ]]; then BUILD_NAME=${BUILD_NAME}"_" fi - echo "Building config $BUILD_NAME" - build_dir=$TARGET/${BUILD_NAME} - build_config "$MAINBOARD" "$build_dir" "$BUILD_NAME" "$config" - record_mainboard "$BUILD_NAME" - remove_target "$BUILD_NAME" + printf "Building config %s\n" "${BUILD_NAME}" + build_dir="${TARGET}/${BUILD_NAME}" + build_config "${MAINBOARD}" "${build_dir}" "${BUILD_NAME}" "${config}" + record_mainboard "${BUILD_NAME}" + remove_target "${BUILD_NAME}" done fi - echo "Building board $MAINBOARD (using default config)" - build_dir=$TARGET/${MAINBOARD} - build_config "$MAINBOARD" "$build_dir" "$MAINBOARD" - record_mainboard "$MAINBOARD" - remove_target "$MAINBOARD" + printf "Building board %s (using default config)\n" "${MAINBOARD}" + build_dir="${TARGET}/${MAINBOARD}" + build_config "${MAINBOARD}" "${build_dir}" "${MAINBOARD}" + record_mainboard "${MAINBOARD}" + remove_target "${MAINBOARD}" } -function remove_target +remove_target() { - if [ "$remove" != "true" ]; then + if [[ "${remove}" != "true" ]]; then return fi local BUILD_NAME=$1 # Save the generated coreboot.rom file of each board. - if [ -r "$TARGET/${BUILD_NAME}/coreboot.rom" ]; then - cp "$TARGET/${BUILD_NAME}/coreboot.rom" \ + if [[ -r "${TARGET}/${BUILD_NAME}/coreboot.rom" ]]; then + cp "${TARGET}/${BUILD_NAME}/coreboot.rom" \ "${BUILD_NAME}_coreboot.rom" fi - echo "Removing build dir for $BUILD_NAME..." + printf "Removing build dir for %s...\n" "${BUILD_NAME}" rm -rf "${TARGET:?}/${BUILD_NAME}" return } -function myhelp +myhelp() { cat << __END_OF_HELP Usage: $0 [options] @@ -699,13 +712,13 @@ Options:\n [-n|--name] Set build name - also sets xmlfile if not already set [-o|--outdir <path>] Store build results in path - (defaults to $TARGET) + (defaults to ${TARGET}) [-p|--payloads <dir>] Use payloads in <dir> to build images [-P|--prefix <name>] File name prefix in CBFS [-q|--quiet] Print fewer messages [-r|--remove] Remove output dir after build [-R|--root <path>] Absolute path to coreboot sources - (defaults to $ROOT) + (defaults to ${ROOT}) [--scan-build] Use clang's static analyzer [--skip_set <value>] Skip building boards with this Kconfig set [--skip_unset <value>] Skip building boards with this Kconfig not set @@ -717,7 +730,7 @@ Options:\n [-x|--chromeos] Build with CHROMEOS enabled Skip boards without ChromeOS support [-X|--xmlfile <name>] Set JUnit XML log file filename - (defaults to $XMLFILE) + (defaults to ${XMLFILE}) [-y|--ccache] Use ccache [-z|--clean] Remove build results when finished [-Z|--clean-somewhat] Remove build but keep coreboot.rom + config @@ -729,11 +742,11 @@ Options:\n __END_OF_HELP } -function myversion +myversion() { cat << EOF -coreboot autobuild v$ABUILD_VERSION ($ABUILD_DATE) +coreboot autobuild v${ABUILD_VERSION} (${ABUILD_DATE}) Copyright (C) 2004 by Stefan Reinauer <stepan@openbios.org> Copyright (C) 2006-2010 by coresystems GmbH <info@coresystems.de> @@ -748,14 +761,13 @@ EOF # default options target="" buildall=false -verbose=false test -f util/sconfig/sconfig.l && ROOT=$( pwd ) test -f ../util/sconfig/sconfig.l && ROOT=$( cd .. && pwd ) -test "$ROOT" = "" && ROOT=$( cd ../.. && pwd ) +test "${ROOT}" = "" && ROOT=$( cd ../.. && pwd ) # Look if we have getopt. If not, build it. -export PATH=$PATH:util/abuild +export PATH=${PATH}:util/abuild getopt - > /dev/null 2>/dev/null || gcc -o util/abuild/getopt util/abuild/getopt.c # Save command line for xargs parallelization. @@ -765,19 +777,19 @@ cmdline=("$@") getoptbrand="$(getopt -V)" # shellcheck disable=SC2086 -if [ "${getoptbrand:0:6}" == "getopt" ]; then +if [[ "${getoptbrand:0:6}" == "getopt" ]]; then # Detected GNU getopt that supports long options. args=$(getopt -l version,verbose,quiet,help,all,target:,board-variant:,payloads:,cpus:,silent,junit,config,loglevel:,remove,prefix:,update,scan-build,ccache,blobs,clang,any-toolchain,clean,clean-somewhat,outdir:,chromeos,xmlfile:,kconfig:,dir:,root:,recursive,checksum:,timeless,exitcode,asserts,name:,skip_set:,skip_unset: -o Vvqhat:b:p:c:sJCl:rP:uyBLAzZo:xX:K:d:R:Ien: -- "$@") || exit 1 - eval set -- $args + eval set -- ${args} retval=$? else # Detected non-GNU getopt args=$(getopt Vvqhat:b:p:c:sJCl:rP:uyBLAZzo:xX:K:d:R:Ien: "$@") - set -- $args + set -- ${args} retval=$? fi -if [ $retval != 0 ]; then +if [[ ${retval} != 0 ]]; then myhelp exit 1 fi @@ -793,25 +805,25 @@ configoptions="" unset testclass while true ; do case "$1" in - -J|--junit) shift; mode=junit; rm -f "$XMLFILE" ;; + -J|--junit) shift; mode=junit; rm -f "${XMLFILE}" ;; -t|--target) shift; target="$1"; shift;; -b|--board-variant) shift; variant="$1"; shift;; -a|--all) shift; buildall=true;; -d|--dir) shift; configdir="$1"; shift;; -e|--exitcode) shift; exitcode=1;; -r|--remove) shift; remove=true;; - -v|--verbose) shift; verbose=true; verboseopt='V=1';; + -v|--verbose) shift; verboseopt='V=1';; -q|--quiet) shift; quiet=true;; -V|--version) shift; myversion; exit 0;; -h|--help) shift; myversion; myhelp; exit 0;; -p|--payloads) shift; payloads="$1"; shift;; - -R|--root) shift; ROOT="$1"; MAKE="$MAKE -C $1"; shift;; + -R|--root) shift; ROOT="$1"; MAKE="${MAKE} -C $1"; shift;; -c|--cpus) shift export MAKEFLAGS="-j $1" cpus=$1 - test "$MAKEFLAGS" == "-j max" && export MAKEFLAGS="-j" && cpuconfig=" in parallel" + test "${MAKEFLAGS}" == "-j max" && export MAKEFLAGS="-j" && cpuconfig=" in parallel" test "$1" == "1" && cpuconfig=" on 1 cpu" - expr "$1" : '-\?[0-9]\+$' > /dev/null && test "0$1" -gt 1 && cpuconfig=" on $1 cpus in parallel" + expr "$1" : '-\?[0-9]\+$' > /dev/null && test "0$1" -gt 1 && cpuconfig=" on ${1} cpus in parallel" shift;; # obsolete option -s|--silent) shift;; @@ -914,67 +926,67 @@ if [[ "${TESTRUN}" != "${TESTRUN_DEFAULT}" ]]; then fi fi -if [ -n "$1" ]; then +if [[ -n "$1" ]]; then printf "Invalid option '%s'\n\n" "$1"; myhelp; exit 1; fi -if [ -z "$TARGET" ] || [ "$TARGET" = "/" ]; then - echo "Please specify a valid, non-root build directory." + printf "Please specify a valid, non-root build directory.\n" +if [[ -z "${TARGET}" ]] || [[ "${TARGET}" = "/" ]]; then exit 1 fi -if ! mkdir -p "$TARGET"; then - echo "Unable to create build directory" +if ! mkdir -p "${TARGET}"; then + printf "Unable to create build directory\n" exit 1 fi if echo "${skipconfig_set}${skipconfig_unset}" | grep -q "CONFIG_" >/dev/null 2>&1; then - echo "Error: Do not include CONFIG_ in the Kconfig value to skip" + printf "Error: Do not include CONFIG_ in the Kconfig value to skip\n" exit 1 fi -customizing=$(echo "$customizing" | cut -c3-) -if [ -z "$customizing" ]; then +customizing=$(echo "${customizing}" | cut -c3-) +if [[ -z "${customizing}" ]]; then customizing="Default configuration" fi customizing="Config: ${customizing}" -FAILED_BOARDS="$(realpath ${TARGET}/failed_boards)" -PASSED_BOARDS="$(realpath ${TARGET}/passing_boards)" +FAILED_BOARDS="$(realpath "${TARGET}/failed_boards")" +PASSED_BOARDS="$(realpath "${TARGET}/passing_boards")" -stats_archive="$TARGET/statistics.tar" +stats_archive="${TARGET}/statistics.tar" # Generate a single xcompile for all boards export xcompile="${TARGET}/xcompile" -if [ "$recursive" = "false" ]; then +if [[ "${recursive}" = "false" ]]; then rm -f "${xcompile}" - $MAKE -C"${ROOT}" obj="$TARGET/temp" objutil="$TARGET/sharedutils" UPDATED_SUBMODULES=1 "${xcompile}" || exit 1 - rm -f "$FAILED_BOARDS" "$PASSED_BOARDS" + ${MAKE} -C"${ROOT}" obj="${TARGET}/temp" objutil="${TARGET}/sharedutils" UPDATED_SUBMODULES=1 "${xcompile}" || exit 1 + rm -f "${FAILED_BOARDS}" "${PASSED_BOARDS}" # Initialize empty statistics archive tar -cf "${stats_archive}" "${xcompile}" 2> /dev/null fi USE_XARGS=0 -if [ "$cpus" != "1" ]; then +if [[ "${cpus}" != "1" ]]; then # Limit to 32 parallel builds for now. # Thrashing all caches because we run # 160 abuilds in parallel is no fun. - if [ "$cpus" = "max" ]; then + if [[ "${cpus}" = "max" ]]; then cpus=32 fi # Test if xargs supports the non-standard -P flag - # FIXME: disabled until we managed to eliminate all the make(1) quirks - echo | xargs -P ${cpus:-0} -n 1 echo 2>/dev/null >/dev/null && USE_XARGS=1 + printf "\n" | xargs -P "${cpus:-0}" -n 1 printf "%s\n" 2>/dev/null >/dev/null && USE_XARGS=1 fi -if [ "$USE_XARGS" = "0" ]; then -test "$MAKEFLAGS" == "" && test "$cpus" != "" && export MAKEFLAGS="-j $cpus" -export MAKEFLAGS="$MAKEFLAGS UPDATED_SUBMODULES=1" # no need to re-download +if [[ "${USE_XARGS}" = "0" ]]; then +test "${MAKEFLAGS}" == "" && test "${cpus}" != "" && export MAKEFLAGS="-j ${cpus}" +export MAKEFLAGS="${MAKEFLAGS} UPDATED_SUBMODULES=1" # no need to re-download build_targets() { - local targets=${*-$(get_mainboards)} - for MAINBOARD in $targets; do + local targets + targets=${*-$(get_mainboards)} + for MAINBOARD in ${targets}; do build_target "${MAINBOARD}" done } @@ -986,109 +998,111 @@ build_targets() local etime local num_targets local cpus_per_target + local XMLFILE + local duration local targets=${*-$(get_mainboards)} # seed shared utils TMPCFG=$(mktemp) - printf "%s" "$configoptions" > "$TMPCFG" - $MAKE -j "$cpus" DOTCONFIG="$TMPCFG" obj="$TARGET/temp" objutil="$TARGET/sharedutils" olddefconfig 2>/dev/null + printf "%s" "${configoptions}" > "${TMPCFG}" + ${MAKE} -j "${cpus}" DOTCONFIG="${TMPCFG}" obj="${TARGET}/temp" objutil="${TARGET}/sharedutils" olddefconfig 2>/dev/null BUILDPREFIX= - if [ "$scanbuild" = "true" ]; then - scanbuild_out=$TARGET/sharedutils-scanbuild + if [[ "${scanbuild}" = "true" ]]; then + scanbuild_out="${TARGET}/sharedutils-scanbuild" rm -rf "${scanbuild_out}" BUILDPREFIX="scan-build -o ${scanbuild_out}tmp" fi - mkdir -p "$TARGET/abuild" - ABSPATH="$(cd "$TARGET/abuild" && pwd)" - local XMLFILE="$ABSPATH/__util.xml" + mkdir -p "${TARGET}/abuild" + ABSPATH="$(cd "${TARGET}/abuild" && pwd)" + XMLFILE="${ABSPATH}/__util.xml" rm -f "${XMLFILE}" stime=$(add_timestamp) - $BUILDPREFIX "$MAKE" -j "$cpus" DOTCONFIG="$TMPCFG" obj="$TARGET/temp" objutil="$TARGET/sharedutils" tools > "$TARGET/sharedutils/make.log" 2>&1 + ${BUILDPREFIX} "${MAKE}" -j "${cpus}" DOTCONFIG="${TMPCFG}" obj="${TARGET}/temp" objutil="${TARGET}/sharedutils" tools > "${TARGET}/sharedutils/make.log" 2>&1 local ret=$? etime=$(add_timestamp) - local duration=$(ts_delta_seconds $stime $etime) + duration=$(ts_delta_seconds "${stime}" "${etime}") - junit " <testcase classname='util' name='all' time='$duration' >" - if [ $ret -eq 0 ]; then + junit " <testcase classname='util' name='all' time='${duration}' >" + if [[ ${ret} -eq 0 ]]; then junit "<system-out>" - junitfile "$TARGET/sharedutils/make.log" + junitfile "${TARGET}/sharedutils/make.log" junit "</system-out>" junit "</testcase>" else junit "<failure type='BuildFailed'>" - junitfile "$TARGET/sharedutils/make.log" + junitfile "${TARGET}/sharedutils/make.log" junit "</failure>" junit "</testcase>" - echo "Shared Utilities - Log: $TARGET/sharedutils/make.log" >> "$FAILED_BOARDS" - rm "$TMPCFG" + echo "Shared Utilities - Log: ${TARGET}/sharedutils/make.log" >> "${FAILED_BOARDS}" + rm "${TMPCFG}" return fi - if [ "$scanbuild" = "true" ]; then + if [[ "${scanbuild}" = "true" ]]; then mv "${scanbuild_out}tmp/"* "${scanbuild_out}" rmdir "${scanbuild_out}tmp" fi - rm -rf "$TARGET/temp" "$TMPCFG" - num_targets=$(wc -w <<<"$targets") cpus_per_target=$(((${cpus:-1} + num_targets - 1) / num_targets)) - echo "$targets" | xargs -P ${cpus:-0} -n 1 "$0" "${cmdline[@]}" -I -c "$cpus_per_target" -t + printf "%s\n" "${targets}" | xargs -P "${cpus:-0}" -n 1 "$0" "${cmdline[@]}" -I -c "${cpus_per_target}" -t + rm -rf "${TARGET}/temp" "${TMPCFG}" + num_targets=$(wc -w <<<"${targets}") } fi junit '<?xml version="1.0" encoding="utf-8"?>' junit '<testsuite>' -if [ "$target" != "" ]; then +if [[ "$target" != "" ]]; then # build a single board MAINBOARD=$(normalize_target "${target}") - if [ -z "${MAINBOARD}" ]; then + if [[ -z "${MAINBOARD}" ]]; then printf "No such target: %s" "${target}" - if [ -n "${variant}" ]; then + if [[ -n "${variant}" ]]; then printf ", variant: %s" "${variant}" fi printf "\n" exit 1 fi build_srcdir="$(mainboard_directory "${MAINBOARD}")" - if [ "$(echo "${MAINBOARD}" | wc -w)" -gt 1 ]; then + if [[ "$(echo "${MAINBOARD}" | wc -w)" -gt 1 ]]; then build_targets "${MAINBOARD}" - elif [ ! -r "$ROOT/src/mainboard/${build_srcdir}" ]; then - echo "No such target: ${MAINBOARD}" + elif [[ ! -r "${ROOT}/src/mainboard/${build_srcdir}" ]]; then + printf "No such target: %s\n" "${MAINBOARD}" exit 1 else build_target "${MAINBOARD}" - XMLFILE=$REAL_XMLFILE + XMLFILE=${REAL_XMLFILE} fi else build_targets - rm -f "$REAL_XMLFILE" - XMLFILE="$REAL_XMLFILE" + rm -f "${REAL_XMLFILE}" + XMLFILE="${REAL_XMLFILE}" junit '<?xml version="1.0" encoding="utf-8"?>' junit '<testsuite>' - if [ "$mode" != "text" ]; then - for xmlfile in $TARGET/abuild/*_*.xml; do - cat "$xmlfile" >> "$REAL_XMLFILE" + if [[ "${mode}" != "text" ]]; then + for xmlfile in "${TARGET}"/abuild/*_*.xml; do + cat "${xmlfile}" >> "${REAL_XMLFILE}" done fi - XMLFILE=$REAL_XMLFILE + XMLFILE=${REAL_XMLFILE} fi junit '</testsuite>' -if [ "$recursive" = "false" ]; then +if [[ "${recursive}" = "false" ]]; then # Print the list of failed configurations - if [ -f "$FAILED_BOARDS" ]; then - printf "%s configuration(s) failed:\n" "$( wc -l < "$FAILED_BOARDS" )" - cat "$FAILED_BOARDS" - echo - if [ "$exitcode" != "0" ]; then + if [[ -f "${FAILED_BOARDS}" ]]; then + printf "%s configuration(s) failed:\n" "$( wc -l < "${FAILED_BOARDS}" )" + cat "${FAILED_BOARDS}" + printf "\n" + if [[ "${exitcode}" != "0" ]]; then failed=1 fi - elif [ -f "$PASSED_BOARDS" ]; then - printf "All %s tested configurations passed.\n" "$( wc -l < "$PASSED_BOARDS" )" + elif [[ -f "${PASSED_BOARDS}" ]]; then + printf "All %s tested configurations passed.\n" "$( wc -l < "${PASSED_BOARDS}" )" else printf "No boards tested.\n" fi fi -exit $failed +exit ${failed} diff --git a/util/lint/lint-stable-031-gofmt b/util/lint/lint-stable-031-gofmt new file mode 100755 index 000000000000..f22d39ae34a0 --- /dev/null +++ b/util/lint/lint-stable-031-gofmt @@ -0,0 +1,33 @@ +#!/usr/bin/env sh +# +# SPDX-License-Identifier: GPL-2.0-only + +# DESCR: Run gofmt on util/intelp2m + +LINTDIR="$( + cd -- "$(dirname "$0")" > /dev/null 2>&1 || return + pwd -P +)" + +# shellcheck source=helper_functions.sh +. "${LINTDIR}/helper_functions.sh" + +# Until we require this by default, we need a list of opted-in directories +# If the script isn't looking at a git repository, just exit +if [ "${IN_GIT_TREE}" -eq 0 ]; then + exit 0 +fi + +files_to_check=$(${GIT} log HEAD~..HEAD --format= --name-only util/intelp2m | grep "\.go$") + +# nothing to do +if [ -z "$files_to_check" ]; then + exit 0 +fi + +diff_files=$(gofmt -l $files_to_check) +if [ "$diff_files" != "" ]; then + echo "Coding style mismatch. Run \"gofmt -w $files_to_check\" before pushing changes" + exit 1 +fi +exit 0 diff --git a/util/superiotool/nuvoton.c b/util/superiotool/nuvoton.c index 05974f27d49b..80ba12ecdd8b 100644 --- a/util/superiotool/nuvoton.c +++ b/util/superiotool/nuvoton.c @@ -596,10 +596,10 @@ static const struct superio_registers reg_table[] = { {0x0b, "Hardware Monitor, Front Panel LED", {0x30,0x60,0x61,0x62,0x63,0x70,0xe0,0xe1,0xe2, 0xe4,0xf0,0xf1,0xf2,0xf5,0xf6,0xf7,0xf8,0xf9, - 0xfa,EOT}, + 0xfa,0xfb,EOT}, {0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x7f,0xff, 0xff,0x00,0x00,0x00,0x10,0x00,0x87,0x47,0x00, - 0x00,EOT}}, + 0x00,0x00,EOT}}, {0x0d, "WDT1", {0xf0,EOT}, {0x00,EOT}}, diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile index 3fb0cb75915b..6443dd2a90ff 100755 --- a/util/xcompile/xcompile +++ b/util/xcompile/xcompile @@ -208,6 +208,9 @@ detect_special_flags() { testcc "$GCC" "$CFLAGS_GCC -Wcalloc-transposed-args" && CFLAGS_GCC="$CFLAGS_GCC -Wcalloc-transposed-args" + testcc "$GCC" "$CFLAGS_GCC -Walloc-size" && + CFLAGS_GCC="$CFLAGS_GCC -Walloc-size" + testcc "$GCC" "$CFLAGS_GCC -Wno-unused-parameter" && CFLAGS_GCC="$CFLAGS_GCC -Wno-unused-parameter" |