
This change brings msm display driver including sde, dp, dsi, rotator, dsi pll and dp pll from base 4.19 kernel project. It is first source code snapshot from base kernel project. Change-Id: Iec864c064ce5ea04e170f24414c728684002f284 Signed-off-by: Narendra Muppalla <NarendraM@codeaurora.org>
245 baris
5.4 KiB
C
245 baris
5.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
|
|
*/
|
|
|
|
#ifndef __MDSS_PLL_H
|
|
#define __MDSS_PLL_H
|
|
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/io.h>
|
|
#include <linux/clk.h>
|
|
#include <linux/clkdev.h>
|
|
#include <linux/regmap.h>
|
|
#include "clk-regmap.h"
|
|
#include "clk-regmap-divider.h"
|
|
#include "clk-regmap-mux.h"
|
|
|
|
#if defined(CONFIG_DRM)
|
|
#include <linux/sde_io_util.h>
|
|
#else
|
|
#include <linux/mdss_io_util.h>
|
|
#endif
|
|
|
|
#define MDSS_PLL_REG_W(base, offset, data) \
|
|
writel_relaxed((data), (base) + (offset))
|
|
#define MDSS_PLL_REG_R(base, offset) readl_relaxed((base) + (offset))
|
|
|
|
#define PLL_CALC_DATA(addr0, addr1, data0, data1) \
|
|
(((data1) << 24) | ((((addr1) / 4) & 0xFF) << 16) | \
|
|
((data0) << 8) | (((addr0) / 4) & 0xFF))
|
|
|
|
#define MDSS_DYN_PLL_REG_W(base, offset, addr0, addr1, data0, data1) \
|
|
writel_relaxed(PLL_CALC_DATA(addr0, addr1, data0, data1), \
|
|
(base) + (offset))
|
|
|
|
enum {
|
|
MDSS_DSI_PLL_10NM,
|
|
MDSS_DP_PLL_10NM,
|
|
MDSS_DSI_PLL_7NM,
|
|
MDSS_DSI_PLL_7NM_V2,
|
|
MDSS_DSI_PLL_7NM_V4_1,
|
|
MDSS_DP_PLL_7NM,
|
|
MDSS_DSI_PLL_28LPM,
|
|
MDSS_DSI_PLL_14NM,
|
|
MDSS_DP_PLL_14NM,
|
|
MDSS_HDMI_PLL_28LPM,
|
|
MDSS_UNKNOWN_PLL,
|
|
};
|
|
|
|
enum {
|
|
MDSS_PLL_TARGET_8996,
|
|
};
|
|
|
|
#define DFPS_MAX_NUM_OF_FRAME_RATES 20
|
|
|
|
struct dfps_panel_info {
|
|
uint32_t enabled;
|
|
uint32_t frame_rate_cnt;
|
|
uint32_t frame_rate[DFPS_MAX_NUM_OF_FRAME_RATES]; /* hz */
|
|
};
|
|
|
|
struct dfps_pll_codes {
|
|
uint32_t pll_codes_1;
|
|
uint32_t pll_codes_2;
|
|
};
|
|
|
|
struct dfps_codes_info {
|
|
uint32_t is_valid;
|
|
uint32_t frame_rate; /* hz */
|
|
uint32_t clk_rate; /* hz */
|
|
struct dfps_pll_codes pll_codes;
|
|
};
|
|
|
|
struct dfps_info {
|
|
struct dfps_panel_info panel_dfps;
|
|
struct dfps_codes_info codes_dfps[DFPS_MAX_NUM_OF_FRAME_RATES];
|
|
void *dfps_fb_base;
|
|
};
|
|
|
|
struct mdss_pll_resources {
|
|
|
|
/* Pll specific resources like GPIO, power supply, clocks, etc*/
|
|
struct dss_module_power mp;
|
|
|
|
/*
|
|
* dsi/edp/hmdi plls' base register, phy, gdsc and dynamic refresh
|
|
* register mapping
|
|
*/
|
|
void __iomem *pll_base;
|
|
void __iomem *phy_base;
|
|
void __iomem *ln_tx0_base;
|
|
void __iomem *ln_tx1_base;
|
|
void __iomem *gdsc_base;
|
|
void __iomem *dyn_pll_base;
|
|
|
|
bool is_init_locked;
|
|
s64 vco_current_rate;
|
|
s64 vco_locking_rate;
|
|
s64 vco_ref_clk_rate;
|
|
|
|
/*
|
|
* Certain pll's needs to update the same vco rate after resume in
|
|
* suspend/resume scenario. Cached the vco rate for such plls.
|
|
*/
|
|
unsigned long vco_cached_rate;
|
|
u32 cached_cfg0;
|
|
u32 cached_cfg1;
|
|
u32 cached_outdiv;
|
|
|
|
u32 cached_postdiv1;
|
|
u32 cached_postdiv3;
|
|
u32 cached_vreg_cfg;
|
|
|
|
/* dsi/edp/hmdi pll interface type */
|
|
u32 pll_interface_type;
|
|
|
|
/*
|
|
* Target ID. Used in pll_register API for valid target check before
|
|
* registering the PLL clocks.
|
|
*/
|
|
u32 target_id;
|
|
|
|
/* HW recommended delay during configuration of vco clock rate */
|
|
u32 vco_delay;
|
|
|
|
/* Ref-count of the PLL resources */
|
|
u32 resource_ref_cnt;
|
|
|
|
/*
|
|
* Keep track to resource status to avoid updating same status for the
|
|
* pll from different paths
|
|
*/
|
|
bool resource_enable;
|
|
|
|
/*
|
|
* Certain plls' do not allow vco rate update if it is on. Keep track of
|
|
* status for them to turn on/off after set rate success.
|
|
*/
|
|
bool pll_on;
|
|
|
|
/*
|
|
* handoff_status is true of pll is already enabled by bootloader with
|
|
* continuous splash enable case. Clock API will call the handoff API
|
|
* to enable the status. It is disabled if continuous splash
|
|
* feature is disabled.
|
|
*/
|
|
bool handoff_resources;
|
|
|
|
/*
|
|
* caching the pll trim codes in the case of dynamic refresh
|
|
*/
|
|
int cache_pll_trim_codes[2];
|
|
|
|
/*
|
|
* for maintaining the status of saving trim codes
|
|
*/
|
|
bool reg_upd;
|
|
|
|
/*
|
|
* Notifier callback for MDSS gdsc regulator events
|
|
*/
|
|
struct notifier_block gdsc_cb;
|
|
|
|
/*
|
|
* Worker function to call PLL off event
|
|
*/
|
|
struct work_struct pll_off;
|
|
|
|
/*
|
|
* PLL index if multiple index are available. Eg. in case of
|
|
* DSI we have 2 plls.
|
|
*/
|
|
uint32_t index;
|
|
|
|
bool ssc_en; /* share pll with master */
|
|
bool ssc_center; /* default is down spread */
|
|
u32 ssc_freq;
|
|
u32 ssc_ppm;
|
|
|
|
struct mdss_pll_resources *slave;
|
|
|
|
/*
|
|
* target pll revision information
|
|
*/
|
|
int revision;
|
|
|
|
void *priv;
|
|
|
|
/*
|
|
* dynamic refresh pll codes stored in this structure
|
|
*/
|
|
struct dfps_info *dfps;
|
|
|
|
};
|
|
|
|
struct mdss_pll_vco_calc {
|
|
s32 div_frac_start1;
|
|
s32 div_frac_start2;
|
|
s32 div_frac_start3;
|
|
s64 dec_start1;
|
|
s64 dec_start2;
|
|
s64 pll_plllock_cmp1;
|
|
s64 pll_plllock_cmp2;
|
|
s64 pll_plllock_cmp3;
|
|
};
|
|
|
|
static inline bool is_gdsc_disabled(struct mdss_pll_resources *pll_res)
|
|
{
|
|
if (!pll_res->gdsc_base) {
|
|
WARN(1, "gdsc_base register is not defined\n");
|
|
return true;
|
|
}
|
|
return readl_relaxed(pll_res->gdsc_base) & BIT(31) ? false : true;
|
|
}
|
|
|
|
static inline int mdss_pll_div_prepare(struct clk_hw *hw)
|
|
{
|
|
struct clk_hw *parent_hw = clk_hw_get_parent(hw);
|
|
/* Restore the divider's value */
|
|
return hw->init->ops->set_rate(hw, clk_hw_get_rate(hw),
|
|
clk_hw_get_rate(parent_hw));
|
|
}
|
|
|
|
static inline int mdss_set_mux_sel(void *context, unsigned int reg,
|
|
unsigned int val)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline int mdss_get_mux_sel(void *context, unsigned int reg,
|
|
unsigned int *val)
|
|
{
|
|
*val = 0;
|
|
return 0;
|
|
}
|
|
|
|
int mdss_pll_resource_enable(struct mdss_pll_resources *pll_res, bool enable);
|
|
int mdss_pll_util_resource_enable(struct mdss_pll_resources *pll_res,
|
|
bool enable);
|
|
int mdss_pll_util_resource_parse(struct platform_device *pdev,
|
|
struct mdss_pll_resources *pll_res);
|
|
struct dss_vreg *mdss_pll_get_mp_by_reg_name(struct mdss_pll_resources *pll_res
|
|
, char *name);
|
|
#endif
|