/* * Copyright (c) 2011-2013, 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_ACPUCLOCK_KRAIT_H #define __ARCH_ARM_MACH_MSM_ACPUCLOCK_KRAIT_H #define L2(x) (x) #define BW_MBPS(_bw) \ { \ .vectors = (struct msm_bus_vectors[]){ \ {\ .src = MSM_BUS_MASTER_AMPSS_M0, \ .dst = MSM_BUS_SLAVE_EBI_CH0, \ .ib = (_bw) * 1000000ULL, \ }, \ { \ .src = MSM_BUS_MASTER_AMPSS_M1, \ .dst = MSM_BUS_SLAVE_EBI_CH0, \ .ib = (_bw) * 1000000ULL, \ }, \ }, \ .num_paths = 2, \ } /** * src_id - Clock source IDs. */ enum src_id { PLL_0 = 0, HFPLL, PLL_8, NUM_SRC_ID }; /** * enum pvs - IDs to distinguish between CPU frequency tables. */ enum pvs { PVS_SLOW = 0, PVS_NOMINAL = 1, PVS_FAST = 3, PVS_FASTER = 4, NUM_PVS = 8 }; /** * The maximum number of speed bins. */ #define NUM_SPEED_BINS (16) /** * enum scalables - IDs of frequency scalable hardware blocks. */ enum scalables { CPU0 = 0, CPU1, CPU2, CPU3, L2, MAX_SCALABLES }; /** * enum hfpll_vdd_level - IDs of HFPLL voltage levels. */ enum hfpll_vdd_levels { HFPLL_VDD_NONE, HFPLL_VDD_LOW, HFPLL_VDD_NOM, HFPLL_VDD_HIGH, NUM_HFPLL_VDD }; /** * enum vregs - IDs of voltage regulators. */ enum vregs { VREG_CORE, VREG_MEM, VREG_DIG, VREG_HFPLL_A, VREG_HFPLL_B, NUM_VREG }; /** * struct vreg - Voltage regulator data. * @name: Name of requlator. * @max_vdd: Limit the maximum-settable voltage. * @reg: Regulator handle. * @rpm_reg: RPM Regulator handle. * @cur_vdd: Last-set voltage in uV. * @cur_ua: Last-set current in uA. */ struct vreg { const char *name; const int max_vdd; struct regulator *reg; struct rpm_regulator *rpm_reg; int cur_vdd; int cur_ua; }; /** * struct core_speed - Clock tree and configuration parameters. * @khz: Clock rate in KHz. * @src: Clock source ID. * @pri_src_sel: Input to select on the primary MUX. * @pll_l_val: HFPLL "L" value to be applied when an HFPLL source is selected. */ struct core_speed { unsigned long khz; int src; u32 pri_src_sel; u32 pll_l_val; }; /** * struct l2_level - L2 clock rate and associated voltage and b/w requirements. * @speed: L2 clock configuration. * @vdd_dig: vdd_dig voltage in uV. * @vdd_mem: vdd_mem voltage in uV. * @bw_level: Bandwidth performance level number. */ struct l2_level { const struct core_speed speed; const int vdd_dig; const int vdd_mem; const unsigned int bw_level; }; /** * struct acpu_level - CPU clock rate and L2 rate and voltage requirements. * @use_for_scaling: Flag indicating whether or not the level should be used. * @speed: CPU clock configuration. * @l2_level: L2 configuration to use. * @vdd_core: CPU core voltage in uV. * @ua_core: CPU core current consumption in uA. * @avsdscr_setting: AVS DSCR configuration. */ struct acpu_level { const int use_for_scaling; const struct core_speed speed; unsigned int l2_level; int vdd_core; int ua_core; unsigned int avsdscr_setting; }; /** * struct hfpll_data - Descriptive data of HFPLL hardware. * @mode_offset: Mode register offset from base address. * @l_offset: "L" value register offset from base address. * @m_offset: "M" value register offset from base address. * @n_offset: "N" value register offset from base address. * @config_offset: Configuration register offset from base address. * @config_val: Value to initialize the @config_offset register to. * @has_user_reg: Indicates the presence of an addition config register. * @user_offset: User register offset from base address, if applicable. * @user_val: Value to initialize the @user_offset register to. * @user_vco_mask: Bit in the @user_offset to enable high-frequency VCO mode. * @has_droop_ctl: Indicates the presence of a voltage droop controller. * @has_lock_status: Indicates the presence of a lock status bit. * @droop_offset: Droop controller register offset from base address. * @droop_val: Value to initialize the @config_offset register to. * @status_offset: PLL status register offset. * @low_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_LOW. * @nom_vdd_l_max: Maximum "L" value supported at HFPLL_VDD_NOM. * @low_vco_l_max: Maximum "L" value supported in low-frequency VCO mode. * @vdd: voltage requirements for each VDD level for the L2 PLL. */ struct hfpll_data { const u32 mode_offset; const u32 l_offset; const u32 m_offset; const u32 n_offset; const u32 config_offset; const u32 config_val; const bool has_user_reg; const u32 user_offset; const u32 user_val; const u32 user_vco_mask; const bool has_droop_ctl; const bool has_lock_status; const u32 droop_offset; const u32 droop_val; const u32 status_offset; u32 low_vdd_l_max; u32 nom_vdd_l_max; const u32 low_vco_l_max; const int vdd[NUM_HFPLL_VDD]; }; /** * struct scalable - Register locations and state associated with a scalable HW. * @hfpll_phys_base: Physical base address of HFPLL register. * @hfpll_base: Virtual base address of HFPLL registers. * @aux_clk_sel_phys: Physical address of auxiliary MUX. * @aux_clk_sel: Auxiliary mux input to select at boot. * @sec_clk_sel: Secondary mux input to select at boot. * @l2cpmr_iaddr: Indirect address of the CPMR MUX/divider CP15 register. * @cur_speed: Pointer to currently-set speed. * @l2_vote: L2 performance level vote associate with the current CPU speed. * @vreg: Array of voltage regulators needed by the scalable. * @initialized: Flag set to true when per_cpu_init() has been called. * @avs_enabled: True if avs is enabled for the scalabale. False otherwise. */ struct scalable { const phys_addr_t hfpll_phys_base; void __iomem *hfpll_base; const phys_addr_t aux_clk_sel_phys; const u32 aux_clk_sel; const u32 sec_clk_sel; const u32 l2cpmr_iaddr; const struct core_speed *cur_speed; unsigned int l2_vote; struct vreg vreg[NUM_VREG]; bool initialized; bool avs_enabled; }; /** * struct bin_info - Hardware speed and voltage binning info. * @speed_valid: @speed field is valid * @pvs_valid: @pvs field is valid * @speed: Speed bin ID * @pvs: PVS bin ID */ struct bin_info { bool speed_valid; bool pvs_valid; int speed; int pvs; }; /** * struct pvs_table - CPU performance level table and size. * @table: CPU performance level table * @size: sizeof(@table) * @boost_uv: Voltage boost amount */ struct pvs_table { struct acpu_level *table; size_t size; int boost_uv; }; /** * struct acpuclk_krait_params - SoC specific driver parameters. * @scalable: Array of scalables. * @scalable_size: Size of @scalable. * @hfpll_data: HFPLL configuration data. * @pvs_tables: 2D array of CPU frequency tables. * @l2_freq_tbl: L2 frequency table. * @l2_freq_tbl_size: Size of @l2_freq_tbl. * @pte_efuse_phys: Physical address of PTE EFUSE. * @get_bin_info: Function to populate bin_info from pte_efuse. * @bus_scale: MSM bus driver parameters. * @stby_khz: KHz value corresponding to an always-on clock source. */ struct acpuclk_krait_params { struct scalable *scalable; size_t scalable_size; struct hfpll_data *hfpll_data; struct pvs_table (*pvs_tables)[NUM_PVS]; struct l2_level *l2_freq_tbl; size_t l2_freq_tbl_size; phys_addr_t pte_efuse_phys; void (*get_bin_info)(void __iomem *base, struct bin_info *bin); struct msm_bus_scale_pdata *bus_scale; unsigned long stby_khz; }; /** * struct drv_data - Driver state * @acpu_freq_tbl: CPU frequency table. * @l2_freq_tbl: L2 frequency table. * @scalable: Array of scalables (CPUs and L2). * @hfpll_data: High-frequency PLL data. * @bus_perf_client: Bus driver client handle. * @bus_scale: Bus driver scaling data. * @boost_uv: Voltage boost amount * @speed_bin: Speed bin ID. * @pvs_bin: PVS bin ID. * @dev: Device. */ struct drv_data { struct acpu_level *acpu_freq_tbl; const struct l2_level *l2_freq_tbl; struct scalable *scalable; struct hfpll_data *hfpll_data; u32 bus_perf_client; struct msm_bus_scale_pdata *bus_scale; int boost_uv; int speed_bin; int pvs_bin; struct device *dev; }; /** * struct acpuclk_platform_data - PMIC configuration data. * @uses_pm8917: Boolean indicates presence of pm8917. */ struct acpuclk_platform_data { bool uses_pm8917; }; /** * get_krait_bin_format_a - Populate bin_info from a 'Format A' pte_efuse */ void __init get_krait_bin_format_a(void __iomem *base, struct bin_info *bin); /** * get_krait_bin_format_b - Populate bin_info from a 'Format B' pte_efuse */ void __init get_krait_bin_format_b(void __iomem *base, struct bin_info *bin); /** * acpuclk_krait_init - Initialize the Krait CPU clock driver give SoC params. */ extern int acpuclk_krait_init(struct device *dev, const struct acpuclk_krait_params *params); #ifdef CONFIG_DEBUG_FS /** * acpuclk_krait_debug_init - Initialize debugfs interface. */ extern void __init acpuclk_krait_debug_init(struct drv_data *drv); #else static inline void acpuclk_krait_debug_init(void) { } #endif #endif