summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrzej Hajda <a.hajda@samsung.com>2016-10-24 09:57:34 +0200
committerSeung-Woo Kim <sw0312.kim@samsung.com>2016-12-14 13:54:05 +0900
commit6819384b23df144ba8a5c0d61ac2e99941e6f575 (patch)
treefdb0c03c4b706e98d75bbff77dd5c99ef078eb9f
parentf9ef42a26716569f46902ef2e91af637e9cadf77 (diff)
drm/exynos/hdmi: use mappings for registers with IP dependent address
Some registers resides at different offsets depending on device version. This patch adds infrastructure for mapping such registers to proper address based on hdmi_type. It adds also mappings to some registers. Change-Id: Ic345e1a4cb398aebea62b50fd86a44f30b5fd1e5 Signed-off-by: Andrzej Hajda <a.hajda@samsung.com> Reviewed-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk> Signed-off-by: Inki Dae <inki.dae@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c60
-rw-r--r--drivers/gpu/drm/exynos/regs-hdmi.h4
2 files changed, 37 insertions, 27 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index a0566151f2a0..74c08deddfe8 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -79,6 +79,21 @@
enum hdmi_type {
HDMI_TYPE13,
HDMI_TYPE14,
+ HDMI_TYPE_COUNT
+};
+
+#define HDMI_MAPPED_BASE 0xffff0000
+
+enum hdmi_mapped_regs {
+ HDMI_PHY_STATUS = HDMI_MAPPED_BASE,
+ HDMI_PHY_RSTOUT,
+ HDMI_ACR_CON,
+};
+
+static const u32 hdmi_reg_map[][HDMI_TYPE_COUNT] = {
+ { HDMI_V13_PHY_STATUS, HDMI_PHY_STATUS_0 },
+ { HDMI_V13_PHY_RSTOUT, HDMI_V14_PHY_RSTOUT },
+ { HDMI_V13_ACR_CON, HDMI_V14_ACR_CON },
};
struct string_array_spec {
@@ -96,7 +111,6 @@ struct hdmi_driver_data {
unsigned int has_sysreg:1;
unsigned int has_phy_power:1;
u8 phy_mode_set_done;
- u32 phy_status;
u32 sysreg_clksel;
struct string_array_spec clk_gates;
struct string_array_spec clk_muxes;
@@ -654,7 +668,6 @@ static struct hdmi_driver_data exynos5430_hdmi_driver_data = {
.clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates5430),
.clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes5430),
.phy_mode_set_done = HDMIPHY5433_MODE_SET_DONE,
- .phy_status = HDMI_V14_PHY_STATUS_0,
};
static struct hdmi_driver_data exynos5420_hdmi_driver_data = {
@@ -665,7 +678,6 @@ static struct hdmi_driver_data exynos5420_hdmi_driver_data = {
.clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
.clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
.phy_mode_set_done = HDMIPHY_MODE_SET_DONE,
- .phy_status = HDMI_V14_PHY_STATUS_0,
};
static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
@@ -676,7 +688,6 @@ static struct hdmi_driver_data exynos4212_hdmi_driver_data = {
.clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
.clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
.phy_mode_set_done = HDMIPHY_MODE_SET_DONE,
- .phy_status = HDMI_V14_PHY_STATUS_0,
};
static struct hdmi_driver_data exynos4210_hdmi_driver_data = {
@@ -687,7 +698,6 @@ static struct hdmi_driver_data exynos4210_hdmi_driver_data = {
.clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
.clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
.phy_mode_set_done = HDMIPHY_MODE_SET_DONE,
- .phy_status = HDMI_V13_PHY_STATUS,
};
static struct hdmi_driver_data exynos5_hdmi_driver_data = {
@@ -698,23 +708,31 @@ static struct hdmi_driver_data exynos5_hdmi_driver_data = {
.clk_gates = INIT_ARRAY_SPEC(hdmi_clk_gates4),
.clk_muxes = INIT_ARRAY_SPEC(hdmi_clk_muxes4),
.phy_mode_set_done = HDMIPHY_MODE_SET_DONE,
- .phy_status = HDMI_V14_PHY_STATUS_0,
};
+static inline u32 hdmi_map_reg(struct hdmi_context *hdata, u32 reg_id)
+{
+ if ((reg_id & 0xffff0000) == HDMI_MAPPED_BASE)
+ return hdmi_reg_map[reg_id & 0xffff][hdata->drv_data->type];
+ return reg_id;
+}
+
static inline u32 hdmi_reg_read(struct hdmi_context *hdata, u32 reg_id)
{
- return readl(hdata->regs + reg_id);
+ return readl(hdata->regs + hdmi_map_reg(hdata, reg_id));
}
static inline void hdmi_reg_writeb(struct hdmi_context *hdata,
u32 reg_id, u8 value)
{
- writel(value, hdata->regs + reg_id);
+ writel(value, hdata->regs + hdmi_map_reg(hdata, reg_id));
}
static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
int bytes, u32 val)
{
+ reg_id = hdmi_map_reg(hdata, reg_id);
+
while (--bytes >= 0) {
writel(val & 0xff, hdata->regs + reg_id);
val >>= 8;
@@ -725,7 +743,10 @@ static inline void hdmi_reg_writev(struct hdmi_context *hdata, u32 reg_id,
static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
u32 reg_id, u32 value, u32 mask)
{
- u32 old = readl(hdata->regs + reg_id);
+ u32 old;
+
+ reg_id = hdmi_map_reg(hdata, reg_id);
+ old = readl(hdata->regs + reg_id);
value = (value & mask) | (old & ~mask);
writel(value, hdata->regs + reg_id);
}
@@ -876,7 +897,7 @@ static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
DUMPREG(HDMI_PHY_STATUS_0);
DUMPREG(HDMI_PHY_STATUS_PLL);
DUMPREG(HDMI_PHY_CON_0);
- DUMPREG(HDMI_PHY_RSTOUT);
+ DUMPREG(HDMI_V14_PHY_RSTOUT);
DUMPREG(HDMI_PHY_VPLL);
DUMPREG(HDMI_PHY_CMU);
DUMPREG(HDMI_CORE_RSTOUT);
@@ -1356,11 +1377,7 @@ static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
-
- if (hdata->drv_data->type == HDMI_TYPE13)
- hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
- else
- hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
+ hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
}
static void hdmi_audio_init(struct hdmi_context *hdata)
@@ -1769,23 +1786,16 @@ static void hdmi_mode_apply(struct hdmi_context *hdata)
static void hdmiphy_conf_reset(struct hdmi_context *hdata)
{
- u32 reg;
-
hdmi_clk_set_parents(hdata, false);
/* operation mode */
hdmiphy_reg_writeb(hdata, HDMIPHY_MODE_SET_DONE,
HDMI_PHY_ENABLE_MODE_SET);
- if (hdata->drv_data->type == HDMI_TYPE13)
- reg = HDMI_V13_PHY_RSTOUT;
- else
- reg = HDMI_PHY_RSTOUT;
-
/* reset hdmiphy */
- hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
+ hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
usleep_range(10000, 12000);
- hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
+ hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT);
usleep_range(10000, 12000);
}
@@ -1821,7 +1831,7 @@ static void hdmiphy_wait_for_pll(struct hdmi_context *hdata)
int tries;
for (tries = 0; tries < 100; ++tries) {
- u32 val = hdmi_reg_read(hdata, hdata->drv_data->phy_status);
+ u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS);
if (val & HDMI_PHY_STATUS_READY) {
DRM_DEBUG_KMS("PLL stabilized after %d tries", tries);
diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h
index 4e7bcac734ef..e7adc2525466 100644
--- a/drivers/gpu/drm/exynos/regs-hdmi.h
+++ b/drivers/gpu/drm/exynos/regs-hdmi.h
@@ -173,7 +173,7 @@
#define HDMI_HPD_ST HDMI_CTRL_BASE(0x0044)
#define HDMI_HPD_TH_X HDMI_CTRL_BASE(0x0050)
#define HDMI_AUDIO_CLKSEL HDMI_CTRL_BASE(0x0070)
-#define HDMI_PHY_RSTOUT HDMI_CTRL_BASE(0x0074)
+#define HDMI_V14_PHY_RSTOUT HDMI_CTRL_BASE(0x0074)
#define HDMI_PHY_VPLL HDMI_CTRL_BASE(0x0078)
#define HDMI_PHY_CMU HDMI_CTRL_BASE(0x007C)
#define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0080)
@@ -279,7 +279,7 @@
#define HDMI_ASP_CHCFG2 HDMI_CORE_BASE(0x0318)
#define HDMI_ASP_CHCFG3 HDMI_CORE_BASE(0x031C)
-#define HDMI_ACR_CON HDMI_CORE_BASE(0x0400)
+#define HDMI_V14_ACR_CON HDMI_CORE_BASE(0x0400)
#define HDMI_ACR_MCTS0 HDMI_CORE_BASE(0x0410)
#define HDMI_ACR_MCTS1 HDMI_CORE_BASE(0x0414)
#define HDMI_ACR_MCTS2 HDMI_CORE_BASE(0x0418)