345 lines
9.2 KiB
C
345 lines
9.2 KiB
C
/*
|
|
* 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
|