| // SPDX-License-Identifier: GPL-2.0 |
| /* |
| * Copyright (c) 2019 MediaTek Inc. |
| */ |
| |
| #include <linux/device.h> |
| #include <linux/kconfig.h> |
| #include <linux/kthread.h> |
| #include <linux/kernel.h> |
| #include <linux/module.h> |
| #include <linux/mutex.h> |
| #include <linux/of.h> |
| #include <linux/of_address.h> |
| #include <linux/platform_device.h> |
| #include <linux/pm_wakeup.h> |
| #include <linux/proc_fs.h> |
| #include <linux/seq_file.h> |
| #include <linux/uaccess.h> |
| #include <linux/errno.h> |
| |
| #include <slbc.h> |
| |
| unsigned int slbc_enable; |
| EXPORT_SYMBOL_GPL(slbc_enable); |
| |
| struct slbc_common_ops *common_ops; |
| |
| /* need to modify enum slbc_uid */ |
| char *slbc_uid_str[UID_MAX + 1] = { |
| "UID_ZERO", |
| "UID_MM_VENC", |
| "UID_MM_DISP", |
| "UID_MM_MDP", |
| "UID_MM_VDEC", |
| "UID_AI_MDLA", |
| "UID_AI_ISP", |
| "UID_GPU", |
| "UID_HIFI3", |
| "UID_CPU", |
| "UID_AOV", |
| "UID_SH_P2", |
| "UID_SH_APU", |
| "UID_MML", |
| "UID_DSC_IDLE", |
| "UID_AINR", |
| "UID_TEST_BUFFER", |
| "UID_TEST_CACHE", |
| "UID_TEST_ACP", |
| "UID_DISP", |
| "UID_AOV_DC", |
| "UID_AOV_APU", |
| "UID_AISR_APU", |
| "UID_AISR_MML", |
| "UID_SH_P1", |
| "UID_SMT", |
| "UID_APU", |
| "UID_AOD", |
| "UID_BIF", |
| "UID_MAX", |
| }; |
| EXPORT_SYMBOL_GPL(slbc_uid_str); |
| |
| /* bit count */ |
| int popcount(unsigned int x) |
| { |
| x = x - ((x >> 1) & 0x55555555); |
| x = (x & 0x33333333) + ((x >> 2) & 0x33333333); |
| x = (x + (x >> 4)) & 0x0F0F0F0F; |
| x = x + (x >> 8); |
| x = x + (x >> 16); |
| |
| /* pr_info("popcount %d\n", x & 0x0000003F); */ |
| |
| return x & 0x0000003F; |
| } |
| EXPORT_SYMBOL_GPL(popcount); |
| |
| u32 slbc_sram_read(u32 offset) |
| { |
| if (common_ops && common_ops->slbc_sram_read) |
| return common_ops->slbc_sram_read(offset); |
| else |
| return 0; |
| } |
| EXPORT_SYMBOL_GPL(slbc_sram_read); |
| |
| void slbc_sram_write(u32 offset, u32 val) |
| { |
| if (common_ops && common_ops->slbc_sram_write) |
| return common_ops->slbc_sram_write(offset, val); |
| else |
| return; |
| } |
| EXPORT_SYMBOL_GPL(slbc_sram_write); |
| |
| int slbc_status(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_status) |
| return common_ops->slbc_status(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_status); |
| |
| int slbc_request(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_request) |
| return common_ops->slbc_request(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_request); |
| |
| int slbc_release(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_release) |
| return common_ops->slbc_release(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_release); |
| |
| int slbc_power_on(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_power_on) |
| return common_ops->slbc_power_on(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_power_on); |
| |
| int slbc_power_off(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_power_off) |
| return common_ops->slbc_power_off(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_power_off); |
| |
| int slbc_secure_on(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_secure_on) |
| return common_ops->slbc_secure_on(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_secure_on); |
| |
| int slbc_secure_off(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_secure_off) |
| return common_ops->slbc_secure_off(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_secure_off); |
| |
| int slbc_register_activate_ops(struct slbc_ops *ops) |
| { |
| if (common_ops && common_ops->slbc_register_activate_ops) |
| return common_ops->slbc_register_activate_ops(ops); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_register_activate_ops); |
| |
| int slbc_activate_status(struct slbc_data *d) |
| { |
| if (common_ops && common_ops->slbc_activate_status) |
| return common_ops->slbc_activate_status(d); |
| else |
| return -ENODEV; |
| } |
| EXPORT_SYMBOL_GPL(slbc_activate_status); |
| |
| void slbc_update_mm_bw(unsigned int bw) |
| { |
| if (common_ops && common_ops->slbc_update_mm_bw) |
| return common_ops->slbc_update_mm_bw(bw); |
| else |
| return; |
| } |
| EXPORT_SYMBOL_GPL(slbc_update_mm_bw); |
| |
| void slbc_update_mic_num(unsigned int num) |
| { |
| if (common_ops && common_ops->slbc_update_mic_num) |
| return common_ops->slbc_update_mic_num(num); |
| else |
| return; |
| } |
| EXPORT_SYMBOL_GPL(slbc_update_mic_num); |
| |
| void slbc_register_common_ops(struct slbc_common_ops *ops) |
| { |
| common_ops = ops; |
| } |
| EXPORT_SYMBOL_GPL(slbc_register_common_ops); |
| |
| void slbc_unregister_common_ops(struct slbc_common_ops *ops) |
| { |
| common_ops = NULL; |
| } |
| EXPORT_SYMBOL_GPL(slbc_unregister_common_ops); |
| |
| int __init slbc_common_module_init(void) |
| { |
| return 0; |
| } |
| |
| late_initcall(slbc_common_module_init); |
| |
| MODULE_DESCRIPTION("SLBC Driver common v0.1"); |
| MODULE_LICENSE("GPL"); |