diff options
author | Vivek Kumar <vivekuma@codeaurora.org> | 2018-11-19 13:11:48 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-11-23 01:10:49 -0800 |
commit | 59b22dae44a822d5d77c1cd9c7cbbb5851deaecc (patch) | |
tree | b53151df38a87d63c5df1b08145f718a8987279b /include/soc | |
parent | 446c44cf31efda87bf5e9cefdbe91f462b6d6a59 (diff) |
soc: qcom: Implement early domain handoff driver
Early domain in LK runs in parallel with kernel
with some memory and cpu core(s) reserved for it.
LK updates the status of early services on a shared
memory location. In Kernel, this driver provides
new APIs to check any early service's status and to
communicate with them. It hot adds the reserved
cpu(s) and frees lk text once all early services end.
Change-Id: I0b29b1886abea3280543d76492044c8946d7690e
Signed-off-by: Vivek Kumar <vivekuma@codeaurora.org>
Diffstat (limited to 'include/soc')
-rw-r--r-- | include/soc/qcom/early_domain.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/include/soc/qcom/early_domain.h b/include/soc/qcom/early_domain.h new file mode 100644 index 000000000000..076f2d6fac2b --- /dev/null +++ b/include/soc/qcom/early_domain.h @@ -0,0 +1,98 @@ +/* Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* Early domain services invoked in bootloaders run in parallel after + * kernel takes over. One page in memory is reserved to pass information + * between bootloader and kernel. This page has a header to capture status, + * request and cpumask described in structure early_domain_header. Early + * domain core driver in kernel reads this header to decide the status of + * services and takes necessary action. The rest of the page is intended to + * pass service specific information. Offset for service specific area are + * defined in macros, and its the service specific driver's responsiblity + * to operate in their defined areas to pass service specific information. + * * + * * + * * + * ***************************************** + * * Header * + * * * + * ***************************************** + * * * + * * Early display * + * * * + * * * + * ***************************************** + * * * + * * Early camera * + * * * + * * * + * ***************************************** + * * * + * * Early audio * + * * * + * * * + * ***************************************** + * * + */ + +enum service_id { + EARLY_DOMAIN_CORE = 0, + EARLY_DISPLAY, + EARLY_CAMERA, + EARLY_AUDIO, +}; + +#ifdef CONFIG_QCOM_EARLY_DOMAIN +#include <linux/workqueue.h> +#include <linux/cpumask.h> +#include <linux/pm_qos.h> +#include <linux/notifier.h> + +#define EARLY_DOMAIN_MAGIC "ERLYDOM" +#define MAGIC_SIZE 8 +#define NUM_SERVICES 3 +#define SERVICE_SHARED_MEM_SIZE ((PAGE_SIZE)/(NUM_SERVICES)) + +struct early_domain_header { + char magic[MAGIC_SIZE]; + unsigned long cpumask; + unsigned long early_domain_status; + unsigned long early_domain_request; +}; + +struct early_domain_core { + struct platform_device *pdev; + struct early_domain_header *pdata; + struct work_struct early_domain_work; + phys_addr_t lk_pool_paddr; + size_t lk_pool_size; + phys_addr_t early_domain_shm; + size_t early_domain_shm_size; + cpumask_t cpumask; + struct notifier_block ed_notifier; + struct pm_qos_request ed_qos_request; + struct wakeup_source ed_wake_lock; +}; + +void request_early_service_shutdown(enum service_id); +bool get_early_service_status(enum service_id sid); +void *get_service_shared_mem_start(enum service_id sid); + +#else + +static inline void request_early_service_shutdown(enum service_id sid) {} +static inline bool get_early_service_status(enum service_id sid) + { return false; } +static inline void *get_service_shared_mem_start(enum service_id sid) + { return NULL; } + +#endif |