130 lines
3.7 KiB
C
130 lines
3.7 KiB
C
/*
|
|
* Copyright (C) 2011 Google, Inc.
|
|
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
|
*
|
|
* Author:
|
|
* Colin Cross <ccross@android.com>
|
|
* Olof Johansson <olof@lixom.net>
|
|
*
|
|
* This software is licensed under the terms of the GNU General Public
|
|
* License version 2, as published by the Free Software Foundation, and
|
|
* may be copied, distributed, and modified under those terms.
|
|
*
|
|
* 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 __TEGRA_EMC_H_
|
|
#define __TEGRA_EMC_H_
|
|
|
|
#include <linux/platform_data/tegra_mc.h>
|
|
|
|
#define TEGRA_EMC_NUM_REGS 46
|
|
|
|
enum emc_user_id {
|
|
EMC_USER_DC1 = 0,
|
|
EMC_USER_DC2,
|
|
EMC_USER_VI,
|
|
EMC_USER_MSENC,
|
|
EMC_USER_2D,
|
|
EMC_USER_3D,
|
|
EMC_USER_BB,
|
|
EMC_USER_VDE,
|
|
EMC_USER_VI2,
|
|
EMC_USER_ISPA,
|
|
EMC_USER_ISPB,
|
|
EMC_USER_NUM,
|
|
};
|
|
|
|
struct tegra_emc_table {
|
|
unsigned long rate;
|
|
u32 regs[TEGRA_EMC_NUM_REGS];
|
|
};
|
|
|
|
struct tegra_emc_pdata {
|
|
int num_tables;
|
|
struct tegra_emc_table *tables;
|
|
};
|
|
|
|
struct emc_clk_ops {
|
|
long (*emc_round_rate)(unsigned long);
|
|
int (*emc_set_rate)(unsigned long);
|
|
unsigned long (*emc_get_rate)(void);
|
|
struct clk * (*emc_predict_parent)(unsigned long, unsigned long *);
|
|
void (*emc_get_backup_parent)(struct clk **,
|
|
unsigned long *);
|
|
unsigned long (*emc_apply_efficiency)(unsigned long total_bw,
|
|
unsigned long iso_bw, unsigned long max_rate, u32 usage_flags,
|
|
unsigned long *iso_bw_min);
|
|
};
|
|
|
|
struct emc_iso_usage {
|
|
u32 emc_usage_flags;
|
|
u8 iso_usage_share;
|
|
u8 (*iso_share_calculator)(unsigned long iso_bw);
|
|
};
|
|
|
|
#ifdef CONFIG_TEGRA114_EMC
|
|
long tegra114_emc_round_rate(unsigned long rate);
|
|
int tegra114_emc_set_rate(unsigned long rate);
|
|
unsigned long tegra114_emc_get_rate(void);
|
|
struct clk *tegra114_emc_predict_parent(unsigned long rate);
|
|
void tegra114_emc_timing_invalidate(void);
|
|
bool tegra114_emc_is_ready(void);
|
|
unsigned long tegra114_predict_emc_rate(int millivolts);
|
|
#else
|
|
static inline long tegra114_emc_round_rate(unsigned long rate)
|
|
{ return 0; }
|
|
static inline int tegra114_emc_set_rate(unsigned long rate) { return -ENODEV; }
|
|
static inline unsigned long tegra114_emc_get_rate(void) { return -ENODEV; }
|
|
static inline struct clk *tegra114_emc_predict_parent(unsigned long rate)
|
|
{ return ERR_PTR(-ENODEV); }
|
|
static inline void tegra114_emc_timing_invalidate(void) { return; };
|
|
static inline bool tegra114_emc_is_ready(void) { return true; };
|
|
static inline unsigned long tegra114_predict_emc_rate(int millivolts)
|
|
{ return -ENODEV; }
|
|
#endif
|
|
|
|
#ifdef CONFIG_TEGRA124_EMC
|
|
void tegra124_emc_timing_invalidate(void);
|
|
bool tegra124_emc_is_ready(void);
|
|
unsigned long tegra124_predict_emc_rate(int millivolts);
|
|
const struct emc_clk_ops *tegra124_emc_get_ops(void);
|
|
#else
|
|
static inline void tegra124_emc_timing_invalidate(void) { return; };
|
|
static inline bool tegra124_emc_is_ready(void) { return true; };
|
|
static inline unsigned long tegra124_predict_emc_rate(int millivolts)
|
|
{ return -ENODEV; }
|
|
static inline const struct emc_clk_ops *tegra124_emc_get_ops(void)
|
|
{ return NULL; }
|
|
#endif
|
|
|
|
static __maybe_unused unsigned int
|
|
tegra_emc_bw_to_freq_req(unsigned int bw_kbps)
|
|
{
|
|
unsigned int freq;
|
|
unsigned int bytes_per_emc_clk;
|
|
|
|
bytes_per_emc_clk = tegra_mc_get_effective_bytes_width() * 2;
|
|
/* EMC_TO_DDR_CLOCK is 1 */
|
|
freq = (bw_kbps + bytes_per_emc_clk - 1) / bytes_per_emc_clk;
|
|
return freq;
|
|
}
|
|
|
|
static __maybe_unused unsigned int
|
|
tegra_emc_freq_req_to_bw(unsigned int freq_khz)
|
|
{
|
|
unsigned int bw;
|
|
unsigned int bytes_per_emc_clk;
|
|
|
|
bytes_per_emc_clk = tegra_mc_get_effective_bytes_width() * 2;
|
|
/* EMC_TO_DDR_CLOCK is 1 */
|
|
bw = freq_khz * bytes_per_emc_clk;
|
|
return bw;
|
|
}
|
|
|
|
#endif
|