blob: f02af98590c47685e7ecd8c7835da778cb4d6a9e [file] [log] [blame]
/*
* 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