summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_hdmi.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c60
1 files changed, 35 insertions, 25 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);