diff options
| author | David Dai <daidavid1@codeaurora.org> | 2016-01-22 11:15:06 -0800 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-22 11:02:41 -0700 |
| commit | 8461868fb6ff3a670bb2e8d3ba8938f4e4b7ba53 (patch) | |
| tree | 265b7fb8341fea3363e35ad2d9efa4dc536b3ecf /include/linux | |
| parent | ab4128452749bd89dbabf285ecf0fadd9939e497 (diff) | |
platform: msm: msm_bus: Add support for bus scaling
This snapshot is taken as of msm-3.18 commit 1513280 (Merge "platform: msm: msm_bus:
Fix memory leak during client unregister)"
Change Kconfig option to say QCOM_BUS* instead of MSM_BUS*
Change-Id: I6dd9aba5b26984a914714ca49ae7253c1f267b4b
Signed-off-by: David Dai <daidavid1@codeaurora.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/msm-bus-board.h | 198 | ||||
| -rw-r--r-- | include/linux/msm-bus.h | 213 | ||||
| -rw-r--r-- | include/linux/msm_bus_rules.h | 91 |
3 files changed, 502 insertions, 0 deletions
diff --git a/include/linux/msm-bus-board.h b/include/linux/msm-bus-board.h new file mode 100644 index 000000000000..c9d648d38ec4 --- /dev/null +++ b/include/linux/msm-bus-board.h @@ -0,0 +1,198 @@ +/* Copyright (c) 2010-2014, 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. + */ + +#ifndef __ASM_ARCH_MSM_BUS_BOARD_H +#define __ASM_ARCH_MSM_BUS_BOARD_H + +#include <linux/types.h> +#include <linux/input.h> + +enum context { + DUAL_CTX, + ACTIVE_CTX, + NUM_CTX +}; + +struct msm_bus_fabric_registration { + unsigned int id; + const char *name; + struct msm_bus_node_info *info; + unsigned int len; + int ahb; + const char *fabclk[NUM_CTX]; + const char *iface_clk; + unsigned int offset; + unsigned int haltid; + unsigned int rpm_enabled; + unsigned int nmasters; + unsigned int nslaves; + unsigned int ntieredslaves; + bool il_flag; + const struct msm_bus_board_algorithm *board_algo; + int hw_sel; + void *hw_data; + uint32_t qos_freq; + uint32_t qos_baseoffset; + u64 nr_lim_thresh; + uint32_t eff_fact; + uint32_t qos_delta; + bool virt; +}; + +struct msm_bus_device_node_registration { + struct msm_bus_node_device_type *info; + unsigned int num_devices; + bool virt; +}; + +enum msm_bus_bw_tier_type { + MSM_BUS_BW_TIER1 = 1, + MSM_BUS_BW_TIER2, + MSM_BUS_BW_COUNT, + MSM_BUS_BW_SIZE = 0x7FFFFFFF, +}; + +struct msm_bus_halt_vector { + uint32_t haltval; + uint32_t haltmask; +}; + +extern struct msm_bus_fabric_registration msm_bus_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_cpss_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_def_fab_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8960_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sg_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8960_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8064_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8064_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_9615_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_9615_def_fab_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata; +extern struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata; + +extern struct msm_bus_fabric_registration msm_bus_8974_sys_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_mmss_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_bimc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_periph_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_config_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_8974_ocmem_vnoc_pdata; + +extern struct msm_bus_fabric_registration msm_bus_9625_sys_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_bimc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_periph_noc_pdata; +extern struct msm_bus_fabric_registration msm_bus_9625_config_noc_pdata; + +extern int msm_bus_device_match_adhoc(struct device *dev, void *id); + +void msm_bus_rpm_set_mt_mask(void); +int msm_bus_board_rpm_get_il_ids(uint16_t *id); +int msm_bus_board_get_iid(int id); + +#define NFAB_MSM8226 6 +#define NFAB_MSM8610 5 + +/* + * These macros specify the convention followed for allocating + * ids to fabrics, masters and slaves for 8x60. + * + * A node can be identified as a master/slave/fabric by using + * these ids. + */ +#define FABRIC_ID_KEY 1024 +#define SLAVE_ID_KEY ((FABRIC_ID_KEY) >> 1) +#define MAX_FAB_KEY 7168 /* OR(All fabric ids) */ +#define INT_NODE_START 10000 + +#define GET_FABID(id) ((id) & MAX_FAB_KEY) + +#define NODE_ID(id) ((id) & (FABRIC_ID_KEY - 1)) +#define IS_SLAVE(id) ((NODE_ID(id)) >= SLAVE_ID_KEY ? 1 : 0) +#define CHECK_ID(iid, id) (((iid & id) != id) ? -ENXIO : iid) + +/* + * The following macros are used to format the data for port halt + * and unhalt requests. + */ +#define MSM_BUS_CLK_HALT 0x1 +#define MSM_BUS_CLK_HALT_MASK 0x1 +#define MSM_BUS_CLK_HALT_FIELDSIZE 0x1 +#define MSM_BUS_CLK_UNHALT 0x0 + +#define MSM_BUS_MASTER_SHIFT(master, fieldsize) \ + ((master) * (fieldsize)) + +#define MSM_BUS_SET_BITFIELD(word, fieldmask, fieldvalue) \ + { \ + (word) &= ~(fieldmask); \ + (word) |= (fieldvalue); \ + } + + +#define MSM_BUS_MASTER_HALT(u32haltmask, u32haltval, master) \ + MSM_BUS_SET_BITFIELD(u32haltmask, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + MSM_BUS_SET_BITFIELD(u32haltval, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + +#define MSM_BUS_MASTER_UNHALT(u32haltmask, u32haltval, master) \ + MSM_BUS_SET_BITFIELD(u32haltmask, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + MSM_BUS_SET_BITFIELD(u32haltval, \ + MSM_BUS_CLK_HALT_MASK<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE), \ + MSM_BUS_CLK_UNHALT<<MSM_BUS_MASTER_SHIFT((master),\ + MSM_BUS_CLK_HALT_FIELDSIZE))\ + +#define RPM_BUS_SLAVE_REQ 0x766c7362 +#define RPM_BUS_MASTER_REQ 0x73616d62 + +enum msm_bus_rpm_slave_field_type { + RPM_SLAVE_FIELD_BW = 0x00007762, +}; + +enum msm_bus_rpm_mas_field_type { + RPM_MASTER_FIELD_BW = 0x00007762, + RPM_MASTER_FIELD_BW_T0 = 0x30747762, + RPM_MASTER_FIELD_BW_T1 = 0x31747762, + RPM_MASTER_FIELD_BW_T2 = 0x32747762, +}; + +#include <dt-bindings/msm/msm-bus-ids.h> + + +#endif /*__ASM_ARCH_MSM_BUS_BOARD_H */ diff --git a/include/linux/msm-bus.h b/include/linux/msm-bus.h new file mode 100644 index 000000000000..8ea8c97f4972 --- /dev/null +++ b/include/linux/msm-bus.h @@ -0,0 +1,213 @@ +/* Copyright (c) 2010-2015, 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. + */ + +#ifndef _ARCH_ARM_MACH_MSM_BUS_H +#define _ARCH_ARM_MACH_MSM_BUS_H + +#include <linux/types.h> +#include <linux/input.h> +#include <linux/platform_device.h> + +/* + * Macros for clients to convert their data to ib and ab + * Ws : Time window over which to transfer the data in SECONDS + * Bs : Size of the data block in bytes + * Per : Recurrence period + * Tb : Throughput bandwidth to prevent stalling + * R : Ratio of actual bandwidth used to Tb + * Ib : Instantaneous bandwidth + * Ab : Arbitrated bandwidth + * + * IB_RECURRBLOCK and AB_RECURRBLOCK: + * These are used if the requirement is to transfer a + * recurring block of data over a known time window. + * + * IB_THROUGHPUTBW and AB_THROUGHPUTBW: + * These are used for CPU style masters. Here the requirement + * is to have minimum throughput bandwidth available to avoid + * stalling. + */ +#define IB_RECURRBLOCK(Ws, Bs) ((Ws) == 0 ? 0 : ((Bs)/(Ws))) +#define AB_RECURRBLOCK(Ws, Per) ((Ws) == 0 ? 0 : ((Bs)/(Per))) +#define IB_THROUGHPUTBW(Tb) (Tb) +#define AB_THROUGHPUTBW(Tb, R) ((Tb) * (R)) + +struct msm_bus_vectors { + int src; /* Master */ + int dst; /* Slave */ + uint64_t ab; /* Arbitrated bandwidth */ + uint64_t ib; /* Instantaneous bandwidth */ +}; + +struct msm_bus_paths { + int num_paths; + struct msm_bus_vectors *vectors; +}; + +struct msm_bus_scale_pdata { + struct msm_bus_paths *usecase; + int num_usecases; + const char *name; + /* + * If the active_only flag is set to 1, the BW request is applied + * only when at least one CPU is active (powered on). If the flag + * is set to 0, then the BW request is always applied irrespective + * of the CPU state. + */ + unsigned int active_only; +}; + +struct msm_bus_client_handle { + char *name; + int mas; + int slv; + int first_hop; + struct device *mas_dev; + u64 cur_act_ib; + u64 cur_act_ab; + u64 cur_slp_ib; + u64 cur_slp_ab; + bool active_only; +}; + +/* Scaling APIs */ + +/* + * This function returns a handle to the client. This should be used to + * call msm_bus_scale_client_update_request. + * The function returns 0 if bus driver is unable to register a client + */ + +#if (defined(CONFIG_QCOM_BUS_SCALING) || defined(CONFIG_QCOM_BUS_TOPOLOGY_ADHOC)) +int __init msm_bus_fabric_init_driver(void); +uint32_t msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata); +int msm_bus_scale_client_update_request(uint32_t cl, unsigned int index); +void msm_bus_scale_unregister_client(uint32_t cl); +int msm_bus_scale_client_update_context(uint32_t cl, bool active_only, + unsigned int ctx_idx); + +struct msm_bus_client_handle* +msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, + bool active_only); +void msm_bus_scale_unregister(struct msm_bus_client_handle *cl); +int msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib); +int msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl, + u64 act_ab, u64 act_ib, u64 slp_ib, u64 slp_ab); +/* AXI Port configuration APIs */ +int msm_bus_axi_porthalt(int master_port); +int msm_bus_axi_portunhalt(int master_port); + +#else +static inline int __init msm_bus_fabric_init_driver(void) { return 0; } +static struct msm_bus_client_handle dummy_cl; + +static inline uint32_t +msm_bus_scale_register_client(struct msm_bus_scale_pdata *pdata) +{ + return 1; +} + +static inline int +msm_bus_scale_client_update_request(uint32_t cl, unsigned int index) +{ + return 0; +} + +static inline int +msm_bus_scale_client_update_context(uint32_t cl, bool active_only, + unsigned int ctx_idx) +{ + return 0; +} + +static inline void +msm_bus_scale_unregister_client(uint32_t cl) +{ +} + +static inline int msm_bus_axi_porthalt(int master_port) +{ + return 0; +} + +static inline int msm_bus_axi_portunhalt(int master_port) +{ + return 0; +} + +static inline struct msm_bus_client_handle* +msm_bus_scale_register(uint32_t mas, uint32_t slv, char *name, + bool active_only) +{ + return &dummy_cl; +} + +static inline void msm_bus_scale_unregister(struct msm_bus_client_handle *cl) +{ +} + +static inline int +msm_bus_scale_update_bw(struct msm_bus_client_handle *cl, u64 ab, u64 ib) +{ + return 0; +} + +static inline int +msm_bus_scale_update_bw_context(struct msm_bus_client_handle *cl, u64 act_ab, + u64 act_ib, u64 slp_ib, u64 slp_ab) + +{ + return 0; +} + +#endif + +#if defined(CONFIG_OF) && defined(CONFIG_QCOM_BUS_SCALING) +struct msm_bus_scale_pdata *msm_bus_pdata_from_node( + struct platform_device *pdev, struct device_node *of_node); +struct msm_bus_scale_pdata *msm_bus_cl_get_pdata(struct platform_device *pdev); +void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata); +#else +static inline struct msm_bus_scale_pdata +*msm_bus_cl_get_pdata(struct platform_device *pdev) +{ + return NULL; +} + +static inline struct msm_bus_scale_pdata *msm_bus_pdata_from_node( + struct platform_device *pdev, struct device_node *of_node) +{ + return NULL; +} + +static inline void msm_bus_cl_clear_pdata(struct msm_bus_scale_pdata *pdata) +{ +} +#endif + +#ifdef CONFIG_DEBUG_BUS_VOTER +int msm_bus_floor_vote_context(const char *name, u64 floor_hz, + bool active_only); +int msm_bus_floor_vote(const char *name, u64 floor_hz); +#else +static inline int msm_bus_floor_vote(const char *name, u64 floor_hz) +{ + return -EINVAL; +} + +static inline int msm_bus_floor_vote_context(const char *name, u64 floor_hz, + bool active_only) +{ + return -EINVAL; +} +#endif /*defined(CONFIG_DEBUG_BUS_VOTER) && defined(CONFIG_BUS_TOPOLOGY_ADHOC)*/ +#endif /*_ARCH_ARM_MACH_MSM_BUS_H*/ diff --git a/include/linux/msm_bus_rules.h b/include/linux/msm_bus_rules.h new file mode 100644 index 000000000000..6bcbca081fe8 --- /dev/null +++ b/include/linux/msm_bus_rules.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2014-2015, 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. + */ + +#ifndef _ARCH_ARM_MACH_MSM_BUS_RULES_H +#define _ARCH_ARM_MACH_MSM_BUS_RULES_H + +#include <linux/types.h> +#include <linux/list.h> +#include <linux/notifier.h> +#include <dt-bindings/msm/msm-bus-rule-ops.h> + +#define MAX_NODES (5) + +struct rule_update_path_info { + u32 id; + u64 ab; + u64 ib; + u64 clk; + bool added; + struct list_head link; +}; + +struct rule_apply_rcm_info { + u32 id; + u64 lim_bw; + int throttle; + bool after_clk_commit; + struct list_head link; +}; + +struct bus_rule_type { + int num_src; + int *src_id; + int src_field; + int op; + u64 thresh; + int num_dst; + int *dst_node; + u64 dst_bw; + int mode; + void *client_data; +}; + +#if (defined(CONFIG_QCOM_BUS_TOPOLOGY_ADHOC)) +void msm_rule_register(int num_rules, struct bus_rule_type *rule, + struct notifier_block *nb); +void msm_rule_unregister(int num_rules, struct bus_rule_type *rule, + struct notifier_block *nb); +bool msm_rule_update(struct bus_rule_type *old_rule, + struct bus_rule_type *new_rule, + struct notifier_block *nb); +void msm_rule_evaluate_rules(int node); +void print_rules_buf(char *buf, int count); +bool msm_rule_are_rules_registered(void); +#else +static inline void msm_rule_register(int num_rules, struct bus_rule_type *rule, + struct notifier_block *nb) +{ +} +static inline void msm_rule_unregister(int num_rules, + struct bus_rule_type *rule, + struct notifier_block *nb) +{ +} +static inline void print_rules_buf(char *buf, int count) +{ +} +static inline bool msm_rule_are_rules_registered(void) +{ + return false; +} +static inline bool msm_rule_update(struct bus_rule_type *old_rule, + struct bus_rule_type *new_rule, + struct notifier_block *nb) +{ + return false; +} +static inline void msm_rule_evaluate_rules(int node) +{ +} +#endif /* defined(CONFIG_BUS_TOPOLOGY_ADHOC) */ +#endif /* _ARCH_ARM_MACH_MSM_BUS_RULES_H */ |
