Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ARM Specific GTDT table Support
0004  *
0005  * Copyright (C) 2016, Linaro Ltd.
0006  * Author: Daniel Lezcano <daniel.lezcano@linaro.org>
0007  *         Fu Wei <fu.wei@linaro.org>
0008  *         Hanjun Guo <hanjun.guo@linaro.org>
0009  */
0010 
0011 #include <linux/acpi.h>
0012 #include <linux/init.h>
0013 #include <linux/irqdomain.h>
0014 #include <linux/kernel.h>
0015 #include <linux/platform_device.h>
0016 
0017 #include <clocksource/arm_arch_timer.h>
0018 
0019 #undef pr_fmt
0020 #define pr_fmt(fmt) "ACPI GTDT: " fmt
0021 
0022 /**
0023  * struct acpi_gtdt_descriptor - Store the key info of GTDT for all functions
0024  * @gtdt:   The pointer to the struct acpi_table_gtdt of GTDT table.
0025  * @gtdt_end:   The pointer to the end of GTDT table.
0026  * @platform_timer: The pointer to the start of Platform Timer Structure
0027  *
0028  * The struct store the key info of GTDT table, it should be initialized by
0029  * acpi_gtdt_init.
0030  */
0031 struct acpi_gtdt_descriptor {
0032     struct acpi_table_gtdt *gtdt;
0033     void *gtdt_end;
0034     void *platform_timer;
0035 };
0036 
0037 static struct acpi_gtdt_descriptor acpi_gtdt_desc __initdata;
0038 
0039 static inline __init void *next_platform_timer(void *platform_timer)
0040 {
0041     struct acpi_gtdt_header *gh = platform_timer;
0042 
0043     platform_timer += gh->length;
0044     if (platform_timer < acpi_gtdt_desc.gtdt_end)
0045         return platform_timer;
0046 
0047     return NULL;
0048 }
0049 
0050 #define for_each_platform_timer(_g)             \
0051     for (_g = acpi_gtdt_desc.platform_timer; _g;    \
0052          _g = next_platform_timer(_g))
0053 
0054 static inline bool is_timer_block(void *platform_timer)
0055 {
0056     struct acpi_gtdt_header *gh = platform_timer;
0057 
0058     return gh->type == ACPI_GTDT_TYPE_TIMER_BLOCK;
0059 }
0060 
0061 static inline bool is_non_secure_watchdog(void *platform_timer)
0062 {
0063     struct acpi_gtdt_header *gh = platform_timer;
0064     struct acpi_gtdt_watchdog *wd = platform_timer;
0065 
0066     if (gh->type != ACPI_GTDT_TYPE_WATCHDOG)
0067         return false;
0068 
0069     return !(wd->timer_flags & ACPI_GTDT_WATCHDOG_SECURE);
0070 }
0071 
0072 static int __init map_gt_gsi(u32 interrupt, u32 flags)
0073 {
0074     int trigger, polarity;
0075 
0076     trigger = (flags & ACPI_GTDT_INTERRUPT_MODE) ? ACPI_EDGE_SENSITIVE
0077             : ACPI_LEVEL_SENSITIVE;
0078 
0079     polarity = (flags & ACPI_GTDT_INTERRUPT_POLARITY) ? ACPI_ACTIVE_LOW
0080             : ACPI_ACTIVE_HIGH;
0081 
0082     return acpi_register_gsi(NULL, interrupt, trigger, polarity);
0083 }
0084 
0085 /**
0086  * acpi_gtdt_map_ppi() - Map the PPIs of per-cpu arch_timer.
0087  * @type:   the type of PPI.
0088  *
0089  * Note: Secure state is not managed by the kernel on ARM64 systems.
0090  * So we only handle the non-secure timer PPIs,
0091  * ARCH_TIMER_PHYS_SECURE_PPI is treated as invalid type.
0092  *
0093  * Return: the mapped PPI value, 0 if error.
0094  */
0095 int __init acpi_gtdt_map_ppi(int type)
0096 {
0097     struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;
0098 
0099     switch (type) {
0100     case ARCH_TIMER_PHYS_NONSECURE_PPI:
0101         return map_gt_gsi(gtdt->non_secure_el1_interrupt,
0102                   gtdt->non_secure_el1_flags);
0103     case ARCH_TIMER_VIRT_PPI:
0104         return map_gt_gsi(gtdt->virtual_timer_interrupt,
0105                   gtdt->virtual_timer_flags);
0106 
0107     case ARCH_TIMER_HYP_PPI:
0108         return map_gt_gsi(gtdt->non_secure_el2_interrupt,
0109                   gtdt->non_secure_el2_flags);
0110     default:
0111         pr_err("Failed to map timer interrupt: invalid type.\n");
0112     }
0113 
0114     return 0;
0115 }
0116 
0117 /**
0118  * acpi_gtdt_c3stop() - Got c3stop info from GTDT according to the type of PPI.
0119  * @type:   the type of PPI.
0120  *
0121  * Return: true if the timer HW state is lost when a CPU enters an idle state,
0122  * false otherwise
0123  */
0124 bool __init acpi_gtdt_c3stop(int type)
0125 {
0126     struct acpi_table_gtdt *gtdt = acpi_gtdt_desc.gtdt;
0127 
0128     switch (type) {
0129     case ARCH_TIMER_PHYS_NONSECURE_PPI:
0130         return !(gtdt->non_secure_el1_flags & ACPI_GTDT_ALWAYS_ON);
0131 
0132     case ARCH_TIMER_VIRT_PPI:
0133         return !(gtdt->virtual_timer_flags & ACPI_GTDT_ALWAYS_ON);
0134 
0135     case ARCH_TIMER_HYP_PPI:
0136         return !(gtdt->non_secure_el2_flags & ACPI_GTDT_ALWAYS_ON);
0137 
0138     default:
0139         pr_err("Failed to get c3stop info: invalid type.\n");
0140     }
0141 
0142     return false;
0143 }
0144 
0145 /**
0146  * acpi_gtdt_init() - Get the info of GTDT table to prepare for further init.
0147  * @table:          The pointer to GTDT table.
0148  * @platform_timer_count:   It points to a integer variable which is used
0149  *              for storing the number of platform timers.
0150  *              This pointer could be NULL, if the caller
0151  *              doesn't need this info.
0152  *
0153  * Return: 0 if success, -EINVAL if error.
0154  */
0155 int __init acpi_gtdt_init(struct acpi_table_header *table,
0156               int *platform_timer_count)
0157 {
0158     void *platform_timer;
0159     struct acpi_table_gtdt *gtdt;
0160 
0161     gtdt = container_of(table, struct acpi_table_gtdt, header);
0162     acpi_gtdt_desc.gtdt = gtdt;
0163     acpi_gtdt_desc.gtdt_end = (void *)table + table->length;
0164     acpi_gtdt_desc.platform_timer = NULL;
0165     if (platform_timer_count)
0166         *platform_timer_count = 0;
0167 
0168     if (table->revision < 2) {
0169         pr_warn("Revision:%d doesn't support Platform Timers.\n",
0170             table->revision);
0171         return 0;
0172     }
0173 
0174     if (!gtdt->platform_timer_count) {
0175         pr_debug("No Platform Timer.\n");
0176         return 0;
0177     }
0178 
0179     platform_timer = (void *)gtdt + gtdt->platform_timer_offset;
0180     if (platform_timer < (void *)table + sizeof(struct acpi_table_gtdt)) {
0181         pr_err(FW_BUG "invalid timer data.\n");
0182         return -EINVAL;
0183     }
0184     acpi_gtdt_desc.platform_timer = platform_timer;
0185     if (platform_timer_count)
0186         *platform_timer_count = gtdt->platform_timer_count;
0187 
0188     return 0;
0189 }
0190 
0191 static int __init gtdt_parse_timer_block(struct acpi_gtdt_timer_block *block,
0192                      struct arch_timer_mem *timer_mem)
0193 {
0194     int i;
0195     struct arch_timer_mem_frame *frame;
0196     struct acpi_gtdt_timer_entry *gtdt_frame;
0197 
0198     if (!block->timer_count) {
0199         pr_err(FW_BUG "GT block present, but frame count is zero.\n");
0200         return -ENODEV;
0201     }
0202 
0203     if (block->timer_count > ARCH_TIMER_MEM_MAX_FRAMES) {
0204         pr_err(FW_BUG "GT block lists %d frames, ACPI spec only allows 8\n",
0205                block->timer_count);
0206         return -EINVAL;
0207     }
0208 
0209     timer_mem->cntctlbase = (phys_addr_t)block->block_address;
0210     /*
0211      * The CNTCTLBase frame is 4KB (register offsets 0x000 - 0xFFC).
0212      * See ARM DDI 0487A.k_iss10775, page I1-5129, Table I1-3
0213      * "CNTCTLBase memory map".
0214      */
0215     timer_mem->size = SZ_4K;
0216 
0217     gtdt_frame = (void *)block + block->timer_offset;
0218     if (gtdt_frame + block->timer_count != (void *)block + block->header.length)
0219         return -EINVAL;
0220 
0221     /*
0222      * Get the GT timer Frame data for every GT Block Timer
0223      */
0224     for (i = 0; i < block->timer_count; i++, gtdt_frame++) {
0225         if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER)
0226             continue;
0227         if (gtdt_frame->frame_number >= ARCH_TIMER_MEM_MAX_FRAMES ||
0228             !gtdt_frame->base_address || !gtdt_frame->timer_interrupt)
0229             goto error;
0230 
0231         frame = &timer_mem->frame[gtdt_frame->frame_number];
0232 
0233         /* duplicate frame */
0234         if (frame->valid)
0235             goto error;
0236 
0237         frame->phys_irq = map_gt_gsi(gtdt_frame->timer_interrupt,
0238                          gtdt_frame->timer_flags);
0239         if (frame->phys_irq <= 0) {
0240             pr_warn("failed to map physical timer irq in frame %d.\n",
0241                 gtdt_frame->frame_number);
0242             goto error;
0243         }
0244 
0245         if (gtdt_frame->virtual_timer_interrupt) {
0246             frame->virt_irq =
0247                 map_gt_gsi(gtdt_frame->virtual_timer_interrupt,
0248                        gtdt_frame->virtual_timer_flags);
0249             if (frame->virt_irq <= 0) {
0250                 pr_warn("failed to map virtual timer irq in frame %d.\n",
0251                     gtdt_frame->frame_number);
0252                 goto error;
0253             }
0254         } else {
0255             pr_debug("virtual timer in frame %d not implemented.\n",
0256                  gtdt_frame->frame_number);
0257         }
0258 
0259         frame->cntbase = gtdt_frame->base_address;
0260         /*
0261          * The CNTBaseN frame is 4KB (register offsets 0x000 - 0xFFC).
0262          * See ARM DDI 0487A.k_iss10775, page I1-5130, Table I1-4
0263          * "CNTBaseN memory map".
0264          */
0265         frame->size = SZ_4K;
0266         frame->valid = true;
0267     }
0268 
0269     return 0;
0270 
0271 error:
0272     do {
0273         if (gtdt_frame->common_flags & ACPI_GTDT_GT_IS_SECURE_TIMER ||
0274             gtdt_frame->frame_number >= ARCH_TIMER_MEM_MAX_FRAMES)
0275             continue;
0276 
0277         frame = &timer_mem->frame[gtdt_frame->frame_number];
0278 
0279         if (frame->phys_irq > 0)
0280             acpi_unregister_gsi(gtdt_frame->timer_interrupt);
0281         frame->phys_irq = 0;
0282 
0283         if (frame->virt_irq > 0)
0284             acpi_unregister_gsi(gtdt_frame->virtual_timer_interrupt);
0285         frame->virt_irq = 0;
0286     } while (i-- >= 0 && gtdt_frame--);
0287 
0288     return -EINVAL;
0289 }
0290 
0291 /**
0292  * acpi_arch_timer_mem_init() - Get the info of all GT blocks in GTDT table.
0293  * @timer_mem:  The pointer to the array of struct arch_timer_mem for returning
0294  *      the result of parsing. The element number of this array should
0295  *      be platform_timer_count(the total number of platform timers).
0296  * @timer_count: It points to a integer variable which is used for storing the
0297  *      number of GT blocks we have parsed.
0298  *
0299  * Return: 0 if success, -EINVAL/-ENODEV if error.
0300  */
0301 int __init acpi_arch_timer_mem_init(struct arch_timer_mem *timer_mem,
0302                     int *timer_count)
0303 {
0304     int ret;
0305     void *platform_timer;
0306 
0307     *timer_count = 0;
0308     for_each_platform_timer(platform_timer) {
0309         if (is_timer_block(platform_timer)) {
0310             ret = gtdt_parse_timer_block(platform_timer, timer_mem);
0311             if (ret)
0312                 return ret;
0313             timer_mem++;
0314             (*timer_count)++;
0315         }
0316     }
0317 
0318     if (*timer_count)
0319         pr_info("found %d memory-mapped timer block(s).\n",
0320             *timer_count);
0321 
0322     return 0;
0323 }
0324 
0325 /*
0326  * Initialize a SBSA generic Watchdog platform device info from GTDT
0327  */
0328 static int __init gtdt_import_sbsa_gwdt(struct acpi_gtdt_watchdog *wd,
0329                     int index)
0330 {
0331     struct platform_device *pdev;
0332     int irq;
0333 
0334     /*
0335      * According to SBSA specification the size of refresh and control
0336      * frames of SBSA Generic Watchdog is SZ_4K(Offset 0x000 – 0xFFF).
0337      */
0338     struct resource res[] = {
0339         DEFINE_RES_MEM(wd->control_frame_address, SZ_4K),
0340         DEFINE_RES_MEM(wd->refresh_frame_address, SZ_4K),
0341         {},
0342     };
0343     int nr_res = ARRAY_SIZE(res);
0344 
0345     pr_debug("found a Watchdog (0x%llx/0x%llx gsi:%u flags:0x%x).\n",
0346          wd->refresh_frame_address, wd->control_frame_address,
0347          wd->timer_interrupt, wd->timer_flags);
0348 
0349     if (!(wd->refresh_frame_address && wd->control_frame_address)) {
0350         pr_err(FW_BUG "failed to get the Watchdog base address.\n");
0351         return -EINVAL;
0352     }
0353 
0354     irq = map_gt_gsi(wd->timer_interrupt, wd->timer_flags);
0355     res[2] = (struct resource)DEFINE_RES_IRQ(irq);
0356     if (irq <= 0) {
0357         pr_warn("failed to map the Watchdog interrupt.\n");
0358         nr_res--;
0359     }
0360 
0361     /*
0362      * Add a platform device named "sbsa-gwdt" to match the platform driver.
0363      * "sbsa-gwdt": SBSA(Server Base System Architecture) Generic Watchdog
0364      * The platform driver can get device info below by matching this name.
0365      */
0366     pdev = platform_device_register_simple("sbsa-gwdt", index, res, nr_res);
0367     if (IS_ERR(pdev)) {
0368         if (irq > 0)
0369             acpi_unregister_gsi(wd->timer_interrupt);
0370         return PTR_ERR(pdev);
0371     }
0372 
0373     return 0;
0374 }
0375 
0376 static int __init gtdt_sbsa_gwdt_init(void)
0377 {
0378     void *platform_timer;
0379     struct acpi_table_header *table;
0380     int ret, timer_count, gwdt_count = 0;
0381 
0382     if (acpi_disabled)
0383         return 0;
0384 
0385     if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_GTDT, 0, &table)))
0386         return -EINVAL;
0387 
0388     /*
0389      * Note: Even though the global variable acpi_gtdt_desc has been
0390      * initialized by acpi_gtdt_init() while initializing the arch timers,
0391      * when we call this function to get SBSA watchdogs info from GTDT, the
0392      * pointers stashed in it are stale (since they are early temporary
0393      * mappings carried out before acpi_permanent_mmap is set) and we need
0394      * to re-initialize them with permanent mapped pointer values to let the
0395      * GTDT parsing possible.
0396      */
0397     ret = acpi_gtdt_init(table, &timer_count);
0398     if (ret || !timer_count)
0399         goto out_put_gtdt;
0400 
0401     for_each_platform_timer(platform_timer) {
0402         if (is_non_secure_watchdog(platform_timer)) {
0403             ret = gtdt_import_sbsa_gwdt(platform_timer, gwdt_count);
0404             if (ret)
0405                 break;
0406             gwdt_count++;
0407         }
0408     }
0409 
0410     if (gwdt_count)
0411         pr_info("found %d SBSA generic Watchdog(s).\n", gwdt_count);
0412 
0413 out_put_gtdt:
0414     acpi_put_table(table);
0415     return ret;
0416 }
0417 
0418 device_initcall(gtdt_sbsa_gwdt_init);