|
@@ -10,6 +10,8 @@
|
|
* published by the Free Software Foundation.
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
+#include <asm/unaligned.h>
|
|
|
|
+
|
|
#include <drm/drmP.h>
|
|
#include <drm/drmP.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_crtc_helper.h>
|
|
#include <drm/drm_mipi_dsi.h>
|
|
#include <drm/drm_mipi_dsi.h>
|
|
@@ -209,12 +211,6 @@
|
|
|
|
|
|
#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
|
|
#define OLD_SCLK_MIPI_CLK_NAME "pll_clk"
|
|
|
|
|
|
-#define REG_ADDR(dsi, reg_idx) ((dsi)->reg_base + \
|
|
|
|
- dsi->driver_data->reg_ofs[(reg_idx)])
|
|
|
|
-#define DSI_WRITE(dsi, reg_idx, val) writel((val), \
|
|
|
|
- REG_ADDR((dsi), (reg_idx)))
|
|
|
|
-#define DSI_READ(dsi, reg_idx) readl(REG_ADDR((dsi), (reg_idx)))
|
|
|
|
-
|
|
|
|
static char *clk_names[5] = { "bus_clk", "sclk_mipi",
|
|
static char *clk_names[5] = { "bus_clk", "sclk_mipi",
|
|
"phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0",
|
|
"phyclk_mipidphy0_bitclkdiv8", "phyclk_mipidphy0_rxclkesc0",
|
|
"sclk_rgb_vclk_to_dsim0" };
|
|
"sclk_rgb_vclk_to_dsim0" };
|
|
@@ -228,12 +224,8 @@ struct exynos_dsi_transfer {
|
|
struct list_head list;
|
|
struct list_head list;
|
|
struct completion completed;
|
|
struct completion completed;
|
|
int result;
|
|
int result;
|
|
- u8 data_id;
|
|
|
|
- u8 data[2];
|
|
|
|
|
|
+ struct mipi_dsi_packet packet;
|
|
u16 flags;
|
|
u16 flags;
|
|
-
|
|
|
|
- const u8 *tx_payload;
|
|
|
|
- u16 tx_len;
|
|
|
|
u16 tx_done;
|
|
u16 tx_done;
|
|
|
|
|
|
u8 *rx_payload;
|
|
u8 *rx_payload;
|
|
@@ -247,7 +239,7 @@ struct exynos_dsi_transfer {
|
|
#define DSIM_STATE_VIDOUT_AVAILABLE BIT(3)
|
|
#define DSIM_STATE_VIDOUT_AVAILABLE BIT(3)
|
|
|
|
|
|
struct exynos_dsi_driver_data {
|
|
struct exynos_dsi_driver_data {
|
|
- unsigned int *reg_ofs;
|
|
|
|
|
|
+ const unsigned int *reg_ofs;
|
|
unsigned int plltmr_reg;
|
|
unsigned int plltmr_reg;
|
|
unsigned int has_freqband:1;
|
|
unsigned int has_freqband:1;
|
|
unsigned int has_clklane_stop:1;
|
|
unsigned int has_clklane_stop:1;
|
|
@@ -255,7 +247,7 @@ struct exynos_dsi_driver_data {
|
|
unsigned int max_freq;
|
|
unsigned int max_freq;
|
|
unsigned int wait_for_reset;
|
|
unsigned int wait_for_reset;
|
|
unsigned int num_bits_resol;
|
|
unsigned int num_bits_resol;
|
|
- unsigned int *reg_values;
|
|
|
|
|
|
+ const unsigned int *reg_values;
|
|
};
|
|
};
|
|
|
|
|
|
struct exynos_dsi {
|
|
struct exynos_dsi {
|
|
@@ -324,7 +316,20 @@ enum reg_idx {
|
|
DSIM_PHYTIMING2_REG,
|
|
DSIM_PHYTIMING2_REG,
|
|
NUM_REGS
|
|
NUM_REGS
|
|
};
|
|
};
|
|
-static unsigned int exynos_reg_ofs[] = {
|
|
|
|
|
|
+
|
|
|
|
+static inline void exynos_dsi_write(struct exynos_dsi *dsi, enum reg_idx idx,
|
|
|
|
+ u32 val)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+ writel(val, dsi->reg_base + dsi->driver_data->reg_ofs[idx]);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static inline u32 exynos_dsi_read(struct exynos_dsi *dsi, enum reg_idx idx)
|
|
|
|
+{
|
|
|
|
+ return readl(dsi->reg_base + dsi->driver_data->reg_ofs[idx]);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static const unsigned int exynos_reg_ofs[] = {
|
|
[DSIM_STATUS_REG] = 0x00,
|
|
[DSIM_STATUS_REG] = 0x00,
|
|
[DSIM_SWRST_REG] = 0x04,
|
|
[DSIM_SWRST_REG] = 0x04,
|
|
[DSIM_CLKCTRL_REG] = 0x08,
|
|
[DSIM_CLKCTRL_REG] = 0x08,
|
|
@@ -348,7 +353,7 @@ static unsigned int exynos_reg_ofs[] = {
|
|
[DSIM_PHYTIMING2_REG] = 0x6c,
|
|
[DSIM_PHYTIMING2_REG] = 0x6c,
|
|
};
|
|
};
|
|
|
|
|
|
-static unsigned int exynos5433_reg_ofs[] = {
|
|
|
|
|
|
+static const unsigned int exynos5433_reg_ofs[] = {
|
|
[DSIM_STATUS_REG] = 0x04,
|
|
[DSIM_STATUS_REG] = 0x04,
|
|
[DSIM_SWRST_REG] = 0x0C,
|
|
[DSIM_SWRST_REG] = 0x0C,
|
|
[DSIM_CLKCTRL_REG] = 0x10,
|
|
[DSIM_CLKCTRL_REG] = 0x10,
|
|
@@ -390,7 +395,7 @@ enum reg_value_idx {
|
|
PHYTIMING_HS_TRAIL
|
|
PHYTIMING_HS_TRAIL
|
|
};
|
|
};
|
|
|
|
|
|
-static unsigned int reg_values[] = {
|
|
|
|
|
|
+static const unsigned int reg_values[] = {
|
|
[RESET_TYPE] = DSIM_SWRST,
|
|
[RESET_TYPE] = DSIM_SWRST,
|
|
[PLL_TIMER] = 500,
|
|
[PLL_TIMER] = 500,
|
|
[STOP_STATE_CNT] = 0xf,
|
|
[STOP_STATE_CNT] = 0xf,
|
|
@@ -408,7 +413,25 @@ static unsigned int reg_values[] = {
|
|
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
|
|
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0b),
|
|
};
|
|
};
|
|
|
|
|
|
-static unsigned int exynos5433_reg_values[] = {
|
|
|
|
|
|
+static const unsigned int exynos5422_reg_values[] = {
|
|
|
|
+ [RESET_TYPE] = DSIM_SWRST,
|
|
|
|
+ [PLL_TIMER] = 500,
|
|
|
|
+ [STOP_STATE_CNT] = 0xf,
|
|
|
|
+ [PHYCTRL_ULPS_EXIT] = DSIM_PHYCTRL_ULPS_EXIT(0xaf),
|
|
|
|
+ [PHYCTRL_VREG_LP] = 0,
|
|
|
|
+ [PHYCTRL_SLEW_UP] = 0,
|
|
|
|
+ [PHYTIMING_LPX] = DSIM_PHYTIMING_LPX(0x08),
|
|
|
|
+ [PHYTIMING_HS_EXIT] = DSIM_PHYTIMING_HS_EXIT(0x0d),
|
|
|
|
+ [PHYTIMING_CLK_PREPARE] = DSIM_PHYTIMING1_CLK_PREPARE(0x09),
|
|
|
|
+ [PHYTIMING_CLK_ZERO] = DSIM_PHYTIMING1_CLK_ZERO(0x30),
|
|
|
|
+ [PHYTIMING_CLK_POST] = DSIM_PHYTIMING1_CLK_POST(0x0e),
|
|
|
|
+ [PHYTIMING_CLK_TRAIL] = DSIM_PHYTIMING1_CLK_TRAIL(0x0a),
|
|
|
|
+ [PHYTIMING_HS_PREPARE] = DSIM_PHYTIMING2_HS_PREPARE(0x0c),
|
|
|
|
+ [PHYTIMING_HS_ZERO] = DSIM_PHYTIMING2_HS_ZERO(0x11),
|
|
|
|
+ [PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0d),
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const unsigned int exynos5433_reg_values[] = {
|
|
[RESET_TYPE] = DSIM_FUNCRST,
|
|
[RESET_TYPE] = DSIM_FUNCRST,
|
|
[PLL_TIMER] = 22200,
|
|
[PLL_TIMER] = 22200,
|
|
[STOP_STATE_CNT] = 0xa,
|
|
[STOP_STATE_CNT] = 0xa,
|
|
@@ -426,7 +449,7 @@ static unsigned int exynos5433_reg_values[] = {
|
|
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
|
|
[PHYTIMING_HS_TRAIL] = DSIM_PHYTIMING2_HS_TRAIL(0x0c),
|
|
};
|
|
};
|
|
|
|
|
|
-static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
|
|
|
|
|
|
+static const struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.plltmr_reg = 0x50,
|
|
.plltmr_reg = 0x50,
|
|
.has_freqband = 1,
|
|
.has_freqband = 1,
|
|
@@ -438,7 +461,7 @@ static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
|
|
.reg_values = reg_values,
|
|
.reg_values = reg_values,
|
|
};
|
|
};
|
|
|
|
|
|
-static struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
|
|
|
|
|
|
+static const struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.plltmr_reg = 0x50,
|
|
.plltmr_reg = 0x50,
|
|
.has_freqband = 1,
|
|
.has_freqband = 1,
|
|
@@ -450,7 +473,7 @@ static struct exynos_dsi_driver_data exynos4_dsi_driver_data = {
|
|
.reg_values = reg_values,
|
|
.reg_values = reg_values,
|
|
};
|
|
};
|
|
|
|
|
|
-static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
|
|
|
|
|
|
+static const struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.plltmr_reg = 0x58,
|
|
.plltmr_reg = 0x58,
|
|
.has_clklane_stop = 1,
|
|
.has_clklane_stop = 1,
|
|
@@ -461,7 +484,7 @@ static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
|
|
.reg_values = reg_values,
|
|
.reg_values = reg_values,
|
|
};
|
|
};
|
|
|
|
|
|
-static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
|
|
|
|
|
|
+static const struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.reg_ofs = exynos_reg_ofs,
|
|
.plltmr_reg = 0x58,
|
|
.plltmr_reg = 0x58,
|
|
.num_clks = 2,
|
|
.num_clks = 2,
|
|
@@ -471,7 +494,7 @@ static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
|
|
.reg_values = reg_values,
|
|
.reg_values = reg_values,
|
|
};
|
|
};
|
|
|
|
|
|
-static struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
|
|
|
|
|
|
+static const struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
|
|
.reg_ofs = exynos5433_reg_ofs,
|
|
.reg_ofs = exynos5433_reg_ofs,
|
|
.plltmr_reg = 0xa0,
|
|
.plltmr_reg = 0xa0,
|
|
.has_clklane_stop = 1,
|
|
.has_clklane_stop = 1,
|
|
@@ -482,7 +505,18 @@ static struct exynos_dsi_driver_data exynos5433_dsi_driver_data = {
|
|
.reg_values = exynos5433_reg_values,
|
|
.reg_values = exynos5433_reg_values,
|
|
};
|
|
};
|
|
|
|
|
|
-static struct of_device_id exynos_dsi_of_match[] = {
|
|
|
|
|
|
+static const struct exynos_dsi_driver_data exynos5422_dsi_driver_data = {
|
|
|
|
+ .reg_ofs = exynos5433_reg_ofs,
|
|
|
|
+ .plltmr_reg = 0xa0,
|
|
|
|
+ .has_clklane_stop = 1,
|
|
|
|
+ .num_clks = 2,
|
|
|
|
+ .max_freq = 1500,
|
|
|
|
+ .wait_for_reset = 1,
|
|
|
|
+ .num_bits_resol = 12,
|
|
|
|
+ .reg_values = exynos5422_reg_values,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static const struct of_device_id exynos_dsi_of_match[] = {
|
|
{ .compatible = "samsung,exynos3250-mipi-dsi",
|
|
{ .compatible = "samsung,exynos3250-mipi-dsi",
|
|
.data = &exynos3_dsi_driver_data },
|
|
.data = &exynos3_dsi_driver_data },
|
|
{ .compatible = "samsung,exynos4210-mipi-dsi",
|
|
{ .compatible = "samsung,exynos4210-mipi-dsi",
|
|
@@ -491,6 +525,8 @@ static struct of_device_id exynos_dsi_of_match[] = {
|
|
.data = &exynos4415_dsi_driver_data },
|
|
.data = &exynos4415_dsi_driver_data },
|
|
{ .compatible = "samsung,exynos5410-mipi-dsi",
|
|
{ .compatible = "samsung,exynos5410-mipi-dsi",
|
|
.data = &exynos5_dsi_driver_data },
|
|
.data = &exynos5_dsi_driver_data },
|
|
|
|
+ { .compatible = "samsung,exynos5422-mipi-dsi",
|
|
|
|
+ .data = &exynos5422_dsi_driver_data },
|
|
{ .compatible = "samsung,exynos5433-mipi-dsi",
|
|
{ .compatible = "samsung,exynos5433-mipi-dsi",
|
|
.data = &exynos5433_dsi_driver_data },
|
|
.data = &exynos5433_dsi_driver_data },
|
|
{ }
|
|
{ }
|
|
@@ -515,10 +551,10 @@ static void exynos_dsi_wait_for_reset(struct exynos_dsi *dsi)
|
|
|
|
|
|
static void exynos_dsi_reset(struct exynos_dsi *dsi)
|
|
static void exynos_dsi_reset(struct exynos_dsi *dsi)
|
|
{
|
|
{
|
|
- struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
|
|
|
|
|
|
+ u32 reset_val = dsi->driver_data->reg_values[RESET_TYPE];
|
|
|
|
|
|
reinit_completion(&dsi->completed);
|
|
reinit_completion(&dsi->completed);
|
|
- DSI_WRITE(dsi, DSIM_SWRST_REG, driver_data->reg_values[RESET_TYPE]);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_SWRST_REG, reset_val);
|
|
}
|
|
}
|
|
|
|
|
|
#ifndef MHZ
|
|
#ifndef MHZ
|
|
@@ -621,7 +657,7 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
|
|
reg |= DSIM_FREQ_BAND(band);
|
|
reg |= DSIM_FREQ_BAND(band);
|
|
}
|
|
}
|
|
|
|
|
|
- DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PLLCTRL_REG, reg);
|
|
|
|
|
|
timeout = 1000;
|
|
timeout = 1000;
|
|
do {
|
|
do {
|
|
@@ -629,7 +665,7 @@ static unsigned long exynos_dsi_set_pll(struct exynos_dsi *dsi,
|
|
dev_err(dsi->dev, "PLL failed to stabilize\n");
|
|
dev_err(dsi->dev, "PLL failed to stabilize\n");
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
- reg = DSI_READ(dsi, DSIM_STATUS_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_STATUS_REG);
|
|
} while ((reg & DSIM_PLL_STABLE) == 0);
|
|
} while ((reg & DSIM_PLL_STABLE) == 0);
|
|
|
|
|
|
return fout;
|
|
return fout;
|
|
@@ -659,7 +695,7 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
|
|
dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",
|
|
dev_dbg(dsi->dev, "hs_clk = %lu, byte_clk = %lu, esc_clk = %lu\n",
|
|
hs_clk, byte_clk, esc_clk);
|
|
hs_clk, byte_clk, esc_clk);
|
|
|
|
|
|
- reg = DSI_READ(dsi, DSIM_CLKCTRL_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_CLKCTRL_REG);
|
|
reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK
|
|
reg &= ~(DSIM_ESC_PRESCALER_MASK | DSIM_LANE_ESC_CLK_EN_CLK
|
|
| DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS
|
|
| DSIM_LANE_ESC_CLK_EN_DATA_MASK | DSIM_PLL_BYPASS
|
|
| DSIM_BYTE_CLK_SRC_MASK);
|
|
| DSIM_BYTE_CLK_SRC_MASK);
|
|
@@ -669,7 +705,7 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
|
|
| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1)
|
|
| DSIM_LANE_ESC_CLK_EN_DATA(BIT(dsi->lanes) - 1)
|
|
| DSIM_BYTE_CLK_SRC(0)
|
|
| DSIM_BYTE_CLK_SRC(0)
|
|
| DSIM_TX_REQUEST_HSCLK;
|
|
| DSIM_TX_REQUEST_HSCLK;
|
|
- DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_CLKCTRL_REG, reg);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -677,7 +713,7 @@ static int exynos_dsi_enable_clock(struct exynos_dsi *dsi)
|
|
static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
|
|
static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
|
|
{
|
|
{
|
|
struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
|
|
struct exynos_dsi_driver_data *driver_data = dsi->driver_data;
|
|
- unsigned int *reg_values = driver_data->reg_values;
|
|
|
|
|
|
+ const unsigned int *reg_values = driver_data->reg_values;
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
if (driver_data->has_freqband)
|
|
if (driver_data->has_freqband)
|
|
@@ -686,7 +722,7 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
|
|
/* B D-PHY: D-PHY Master & Slave Analog Block control */
|
|
/* B D-PHY: D-PHY Master & Slave Analog Block control */
|
|
reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |
|
|
reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] |
|
|
reg_values[PHYCTRL_SLEW_UP];
|
|
reg_values[PHYCTRL_SLEW_UP];
|
|
- DSI_WRITE(dsi, DSIM_PHYCTRL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PHYCTRL_REG, reg);
|
|
|
|
|
|
/*
|
|
/*
|
|
* T LPX: Transmitted length of any Low-Power state period
|
|
* T LPX: Transmitted length of any Low-Power state period
|
|
@@ -694,7 +730,7 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
|
|
* burst
|
|
* burst
|
|
*/
|
|
*/
|
|
reg = reg_values[PHYTIMING_LPX] | reg_values[PHYTIMING_HS_EXIT];
|
|
reg = reg_values[PHYTIMING_LPX] | reg_values[PHYTIMING_HS_EXIT];
|
|
- DSI_WRITE(dsi, DSIM_PHYTIMING_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PHYTIMING_REG, reg);
|
|
|
|
|
|
/*
|
|
/*
|
|
* T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00
|
|
* T CLK-PREPARE: Time that the transmitter drives the Clock Lane LP-00
|
|
@@ -714,7 +750,7 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
|
|
reg_values[PHYTIMING_CLK_POST] |
|
|
reg_values[PHYTIMING_CLK_POST] |
|
|
reg_values[PHYTIMING_CLK_TRAIL];
|
|
reg_values[PHYTIMING_CLK_TRAIL];
|
|
|
|
|
|
- DSI_WRITE(dsi, DSIM_PHYTIMING1_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PHYTIMING1_REG, reg);
|
|
|
|
|
|
/*
|
|
/*
|
|
* T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00
|
|
* T HS-PREPARE: Time that the transmitter drives the Data Lane LP-00
|
|
@@ -727,29 +763,29 @@ static void exynos_dsi_set_phy_ctrl(struct exynos_dsi *dsi)
|
|
*/
|
|
*/
|
|
reg = reg_values[PHYTIMING_HS_PREPARE] | reg_values[PHYTIMING_HS_ZERO] |
|
|
reg = reg_values[PHYTIMING_HS_PREPARE] | reg_values[PHYTIMING_HS_ZERO] |
|
|
reg_values[PHYTIMING_HS_TRAIL];
|
|
reg_values[PHYTIMING_HS_TRAIL];
|
|
- DSI_WRITE(dsi, DSIM_PHYTIMING2_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PHYTIMING2_REG, reg);
|
|
}
|
|
}
|
|
|
|
|
|
static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
|
|
static void exynos_dsi_disable_clock(struct exynos_dsi *dsi)
|
|
{
|
|
{
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
- reg = DSI_READ(dsi, DSIM_CLKCTRL_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_CLKCTRL_REG);
|
|
reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK
|
|
reg &= ~(DSIM_LANE_ESC_CLK_EN_CLK | DSIM_LANE_ESC_CLK_EN_DATA_MASK
|
|
| DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);
|
|
| DSIM_ESC_CLKEN | DSIM_BYTE_CLKEN);
|
|
- DSI_WRITE(dsi, DSIM_CLKCTRL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_CLKCTRL_REG, reg);
|
|
|
|
|
|
- reg = DSI_READ(dsi, DSIM_PLLCTRL_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_PLLCTRL_REG);
|
|
reg &= ~DSIM_PLL_EN;
|
|
reg &= ~DSIM_PLL_EN;
|
|
- DSI_WRITE(dsi, DSIM_PLLCTRL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PLLCTRL_REG, reg);
|
|
}
|
|
}
|
|
|
|
|
|
static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane)
|
|
static void exynos_dsi_enable_lane(struct exynos_dsi *dsi, u32 lane)
|
|
{
|
|
{
|
|
- u32 reg = DSI_READ(dsi, DSIM_CONFIG_REG);
|
|
|
|
|
|
+ u32 reg = exynos_dsi_read(dsi, DSIM_CONFIG_REG);
|
|
reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |
|
|
reg |= (DSIM_NUM_OF_DATA_LANE(dsi->lanes - 1) | DSIM_LANE_EN_CLK |
|
|
DSIM_LANE_EN(lane));
|
|
DSIM_LANE_EN(lane));
|
|
- DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_CONFIG_REG, reg);
|
|
}
|
|
}
|
|
|
|
|
|
static int exynos_dsi_init_link(struct exynos_dsi *dsi)
|
|
static int exynos_dsi_init_link(struct exynos_dsi *dsi)
|
|
@@ -760,14 +796,14 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
|
|
u32 lanes_mask;
|
|
u32 lanes_mask;
|
|
|
|
|
|
/* Initialize FIFO pointers */
|
|
/* Initialize FIFO pointers */
|
|
- reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_FIFOCTRL_REG);
|
|
reg &= ~0x1f;
|
|
reg &= ~0x1f;
|
|
- DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_FIFOCTRL_REG, reg);
|
|
|
|
|
|
usleep_range(9000, 11000);
|
|
usleep_range(9000, 11000);
|
|
|
|
|
|
reg |= 0x1f;
|
|
reg |= 0x1f;
|
|
- DSI_WRITE(dsi, DSIM_FIFOCTRL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_FIFOCTRL_REG, reg);
|
|
usleep_range(9000, 11000);
|
|
usleep_range(9000, 11000);
|
|
|
|
|
|
/* DSI configuration */
|
|
/* DSI configuration */
|
|
@@ -836,7 +872,7 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
|
|
dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
|
|
dsi->mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
|
|
reg |= DSIM_CLKLANE_STOP;
|
|
reg |= DSIM_CLKLANE_STOP;
|
|
}
|
|
}
|
|
- DSI_WRITE(dsi, DSIM_CONFIG_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_CONFIG_REG, reg);
|
|
|
|
|
|
lanes_mask = BIT(dsi->lanes) - 1;
|
|
lanes_mask = BIT(dsi->lanes) - 1;
|
|
exynos_dsi_enable_lane(dsi, lanes_mask);
|
|
exynos_dsi_enable_lane(dsi, lanes_mask);
|
|
@@ -849,19 +885,19 @@ static int exynos_dsi_init_link(struct exynos_dsi *dsi)
|
|
return -EFAULT;
|
|
return -EFAULT;
|
|
}
|
|
}
|
|
|
|
|
|
- reg = DSI_READ(dsi, DSIM_STATUS_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_STATUS_REG);
|
|
if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))
|
|
if ((reg & DSIM_STOP_STATE_DAT(lanes_mask))
|
|
!= DSIM_STOP_STATE_DAT(lanes_mask))
|
|
!= DSIM_STOP_STATE_DAT(lanes_mask))
|
|
continue;
|
|
continue;
|
|
} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));
|
|
} while (!(reg & (DSIM_STOP_STATE_CLK | DSIM_TX_READY_HS_CLK)));
|
|
|
|
|
|
- reg = DSI_READ(dsi, DSIM_ESCMODE_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_ESCMODE_REG);
|
|
reg &= ~DSIM_STOP_STATE_CNT_MASK;
|
|
reg &= ~DSIM_STOP_STATE_CNT_MASK;
|
|
reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]);
|
|
reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]);
|
|
- DSI_WRITE(dsi, DSIM_ESCMODE_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_ESCMODE_REG, reg);
|
|
|
|
|
|
reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);
|
|
reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff);
|
|
- DSI_WRITE(dsi, DSIM_TIMEOUT_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_TIMEOUT_REG, reg);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -876,20 +912,20 @@ static void exynos_dsi_set_display_mode(struct exynos_dsi *dsi)
|
|
reg = DSIM_CMD_ALLOW(0xf)
|
|
reg = DSIM_CMD_ALLOW(0xf)
|
|
| DSIM_STABLE_VFP(vm->vfront_porch)
|
|
| DSIM_STABLE_VFP(vm->vfront_porch)
|
|
| DSIM_MAIN_VBP(vm->vback_porch);
|
|
| DSIM_MAIN_VBP(vm->vback_porch);
|
|
- DSI_WRITE(dsi, DSIM_MVPORCH_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_MVPORCH_REG, reg);
|
|
|
|
|
|
reg = DSIM_MAIN_HFP(vm->hfront_porch)
|
|
reg = DSIM_MAIN_HFP(vm->hfront_porch)
|
|
| DSIM_MAIN_HBP(vm->hback_porch);
|
|
| DSIM_MAIN_HBP(vm->hback_porch);
|
|
- DSI_WRITE(dsi, DSIM_MHPORCH_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_MHPORCH_REG, reg);
|
|
|
|
|
|
reg = DSIM_MAIN_VSA(vm->vsync_len)
|
|
reg = DSIM_MAIN_VSA(vm->vsync_len)
|
|
| DSIM_MAIN_HSA(vm->hsync_len);
|
|
| DSIM_MAIN_HSA(vm->hsync_len);
|
|
- DSI_WRITE(dsi, DSIM_MSYNC_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_MSYNC_REG, reg);
|
|
}
|
|
}
|
|
reg = DSIM_MAIN_HRESOL(vm->hactive, num_bits_resol) |
|
|
reg = DSIM_MAIN_HRESOL(vm->hactive, num_bits_resol) |
|
|
DSIM_MAIN_VRESOL(vm->vactive, num_bits_resol);
|
|
DSIM_MAIN_VRESOL(vm->vactive, num_bits_resol);
|
|
|
|
|
|
- DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_MDRESOL_REG, reg);
|
|
|
|
|
|
dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive);
|
|
dev_dbg(dsi->dev, "LCD size = %dx%d\n", vm->hactive, vm->vactive);
|
|
}
|
|
}
|
|
@@ -898,12 +934,12 @@ static void exynos_dsi_set_display_enable(struct exynos_dsi *dsi, bool enable)
|
|
{
|
|
{
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
- reg = DSI_READ(dsi, DSIM_MDRESOL_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_MDRESOL_REG);
|
|
if (enable)
|
|
if (enable)
|
|
reg |= DSIM_MAIN_STAND_BY;
|
|
reg |= DSIM_MAIN_STAND_BY;
|
|
else
|
|
else
|
|
reg &= ~DSIM_MAIN_STAND_BY;
|
|
reg &= ~DSIM_MAIN_STAND_BY;
|
|
- DSI_WRITE(dsi, DSIM_MDRESOL_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_MDRESOL_REG, reg);
|
|
}
|
|
}
|
|
|
|
|
|
static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
|
|
static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
|
|
@@ -911,7 +947,7 @@ static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
|
|
int timeout = 2000;
|
|
int timeout = 2000;
|
|
|
|
|
|
do {
|
|
do {
|
|
- u32 reg = DSI_READ(dsi, DSIM_FIFOCTRL_REG);
|
|
|
|
|
|
+ u32 reg = exynos_dsi_read(dsi, DSIM_FIFOCTRL_REG);
|
|
|
|
|
|
if (!(reg & DSIM_SFR_HEADER_FULL))
|
|
if (!(reg & DSIM_SFR_HEADER_FULL))
|
|
return 0;
|
|
return 0;
|
|
@@ -925,34 +961,35 @@ static int exynos_dsi_wait_for_hdr_fifo(struct exynos_dsi *dsi)
|
|
|
|
|
|
static void exynos_dsi_set_cmd_lpm(struct exynos_dsi *dsi, bool lpm)
|
|
static void exynos_dsi_set_cmd_lpm(struct exynos_dsi *dsi, bool lpm)
|
|
{
|
|
{
|
|
- u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG);
|
|
|
|
|
|
+ u32 v = exynos_dsi_read(dsi, DSIM_ESCMODE_REG);
|
|
|
|
|
|
if (lpm)
|
|
if (lpm)
|
|
v |= DSIM_CMD_LPDT_LP;
|
|
v |= DSIM_CMD_LPDT_LP;
|
|
else
|
|
else
|
|
v &= ~DSIM_CMD_LPDT_LP;
|
|
v &= ~DSIM_CMD_LPDT_LP;
|
|
|
|
|
|
- DSI_WRITE(dsi, DSIM_ESCMODE_REG, v);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_ESCMODE_REG, v);
|
|
}
|
|
}
|
|
|
|
|
|
static void exynos_dsi_force_bta(struct exynos_dsi *dsi)
|
|
static void exynos_dsi_force_bta(struct exynos_dsi *dsi)
|
|
{
|
|
{
|
|
- u32 v = DSI_READ(dsi, DSIM_ESCMODE_REG);
|
|
|
|
|
|
+ u32 v = exynos_dsi_read(dsi, DSIM_ESCMODE_REG);
|
|
v |= DSIM_FORCE_BTA;
|
|
v |= DSIM_FORCE_BTA;
|
|
- DSI_WRITE(dsi, DSIM_ESCMODE_REG, v);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_ESCMODE_REG, v);
|
|
}
|
|
}
|
|
|
|
|
|
static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
|
|
static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
|
|
struct exynos_dsi_transfer *xfer)
|
|
struct exynos_dsi_transfer *xfer)
|
|
{
|
|
{
|
|
struct device *dev = dsi->dev;
|
|
struct device *dev = dsi->dev;
|
|
- const u8 *payload = xfer->tx_payload + xfer->tx_done;
|
|
|
|
- u16 length = xfer->tx_len - xfer->tx_done;
|
|
|
|
|
|
+ struct mipi_dsi_packet *pkt = &xfer->packet;
|
|
|
|
+ const u8 *payload = pkt->payload + xfer->tx_done;
|
|
|
|
+ u16 length = pkt->payload_length - xfer->tx_done;
|
|
bool first = !xfer->tx_done;
|
|
bool first = !xfer->tx_done;
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",
|
|
dev_dbg(dev, "< xfer %p: tx len %u, done %u, rx len %u, done %u\n",
|
|
- xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
|
|
|
|
|
|
+ xfer, length, xfer->tx_done, xfer->rx_len, xfer->rx_done);
|
|
|
|
|
|
if (length > DSI_TX_FIFO_SIZE)
|
|
if (length > DSI_TX_FIFO_SIZE)
|
|
length = DSI_TX_FIFO_SIZE;
|
|
length = DSI_TX_FIFO_SIZE;
|
|
@@ -961,9 +998,8 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
|
|
|
|
|
|
/* Send payload */
|
|
/* Send payload */
|
|
while (length >= 4) {
|
|
while (length >= 4) {
|
|
- reg = (payload[3] << 24) | (payload[2] << 16)
|
|
|
|
- | (payload[1] << 8) | payload[0];
|
|
|
|
- DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg);
|
|
|
|
|
|
+ reg = get_unaligned_le32(payload);
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PAYLOAD_REG, reg);
|
|
payload += 4;
|
|
payload += 4;
|
|
length -= 4;
|
|
length -= 4;
|
|
}
|
|
}
|
|
@@ -978,10 +1014,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
|
|
/* Fall through */
|
|
/* Fall through */
|
|
case 1:
|
|
case 1:
|
|
reg |= payload[0];
|
|
reg |= payload[0];
|
|
- DSI_WRITE(dsi, DSIM_PAYLOAD_REG, reg);
|
|
|
|
- break;
|
|
|
|
- case 0:
|
|
|
|
- /* Do nothing */
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PAYLOAD_REG, reg);
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -989,7 +1022,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
|
|
if (!first)
|
|
if (!first)
|
|
return;
|
|
return;
|
|
|
|
|
|
- reg = (xfer->data[1] << 16) | (xfer->data[0] << 8) | xfer->data_id;
|
|
|
|
|
|
+ reg = get_unaligned_le32(pkt->header);
|
|
if (exynos_dsi_wait_for_hdr_fifo(dsi)) {
|
|
if (exynos_dsi_wait_for_hdr_fifo(dsi)) {
|
|
dev_err(dev, "waiting for header FIFO timed out\n");
|
|
dev_err(dev, "waiting for header FIFO timed out\n");
|
|
return;
|
|
return;
|
|
@@ -1001,7 +1034,7 @@ static void exynos_dsi_send_to_fifo(struct exynos_dsi *dsi,
|
|
dsi->state ^= DSIM_STATE_CMD_LPM;
|
|
dsi->state ^= DSIM_STATE_CMD_LPM;
|
|
}
|
|
}
|
|
|
|
|
|
- DSI_WRITE(dsi, DSIM_PKTHDR_REG, reg);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_PKTHDR_REG, reg);
|
|
|
|
|
|
if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)
|
|
if (xfer->flags & MIPI_DSI_MSG_REQ_ACK)
|
|
exynos_dsi_force_bta(dsi);
|
|
exynos_dsi_force_bta(dsi);
|
|
@@ -1017,7 +1050,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
|
|
u32 reg;
|
|
u32 reg;
|
|
|
|
|
|
if (first) {
|
|
if (first) {
|
|
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
|
|
|
|
|
|
switch (reg & 0x3f) {
|
|
switch (reg & 0x3f) {
|
|
case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
|
|
case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
|
|
@@ -1056,7 +1089,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
|
|
|
|
|
|
/* Receive payload */
|
|
/* Receive payload */
|
|
while (length >= 4) {
|
|
while (length >= 4) {
|
|
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
|
|
payload[0] = (reg >> 0) & 0xff;
|
|
payload[0] = (reg >> 0) & 0xff;
|
|
payload[1] = (reg >> 8) & 0xff;
|
|
payload[1] = (reg >> 8) & 0xff;
|
|
payload[2] = (reg >> 16) & 0xff;
|
|
payload[2] = (reg >> 16) & 0xff;
|
|
@@ -1066,7 +1099,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
|
|
}
|
|
}
|
|
|
|
|
|
if (length) {
|
|
if (length) {
|
|
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
|
|
switch (length) {
|
|
switch (length) {
|
|
case 3:
|
|
case 3:
|
|
payload[2] = (reg >> 16) & 0xff;
|
|
payload[2] = (reg >> 16) & 0xff;
|
|
@@ -1085,7 +1118,7 @@ static void exynos_dsi_read_from_fifo(struct exynos_dsi *dsi,
|
|
clear_fifo:
|
|
clear_fifo:
|
|
length = DSI_RX_FIFO_SIZE / 4;
|
|
length = DSI_RX_FIFO_SIZE / 4;
|
|
do {
|
|
do {
|
|
- reg = DSI_READ(dsi, DSIM_RXFIFO_REG);
|
|
|
|
|
|
+ reg = exynos_dsi_read(dsi, DSIM_RXFIFO_REG);
|
|
if (reg == DSI_RX_FIFO_EMPTY)
|
|
if (reg == DSI_RX_FIFO_EMPTY)
|
|
break;
|
|
break;
|
|
} while (--length);
|
|
} while (--length);
|
|
@@ -1110,13 +1143,14 @@ again:
|
|
|
|
|
|
spin_unlock_irqrestore(&dsi->transfer_lock, flags);
|
|
spin_unlock_irqrestore(&dsi->transfer_lock, flags);
|
|
|
|
|
|
- if (xfer->tx_len && xfer->tx_done == xfer->tx_len)
|
|
|
|
|
|
+ if (xfer->packet.payload_length &&
|
|
|
|
+ xfer->tx_done == xfer->packet.payload_length)
|
|
/* waiting for RX */
|
|
/* waiting for RX */
|
|
return;
|
|
return;
|
|
|
|
|
|
exynos_dsi_send_to_fifo(dsi, xfer);
|
|
exynos_dsi_send_to_fifo(dsi, xfer);
|
|
|
|
|
|
- if (xfer->tx_len || xfer->rx_len)
|
|
|
|
|
|
+ if (xfer->packet.payload_length || xfer->rx_len)
|
|
return;
|
|
return;
|
|
|
|
|
|
xfer->result = 0;
|
|
xfer->result = 0;
|
|
@@ -1152,10 +1186,11 @@ static bool exynos_dsi_transfer_finish(struct exynos_dsi *dsi)
|
|
spin_unlock_irqrestore(&dsi->transfer_lock, flags);
|
|
spin_unlock_irqrestore(&dsi->transfer_lock, flags);
|
|
|
|
|
|
dev_dbg(dsi->dev,
|
|
dev_dbg(dsi->dev,
|
|
- "> xfer %p, tx_len %u, tx_done %u, rx_len %u, rx_done %u\n",
|
|
|
|
- xfer, xfer->tx_len, xfer->tx_done, xfer->rx_len, xfer->rx_done);
|
|
|
|
|
|
+ "> xfer %p, tx_len %zu, tx_done %u, rx_len %u, rx_done %u\n",
|
|
|
|
+ xfer, xfer->packet.payload_length, xfer->tx_done, xfer->rx_len,
|
|
|
|
+ xfer->rx_done);
|
|
|
|
|
|
- if (xfer->tx_done != xfer->tx_len)
|
|
|
|
|
|
+ if (xfer->tx_done != xfer->packet.payload_length)
|
|
return true;
|
|
return true;
|
|
|
|
|
|
if (xfer->rx_done != xfer->rx_len)
|
|
if (xfer->rx_done != xfer->rx_len)
|
|
@@ -1226,9 +1261,10 @@ static int exynos_dsi_transfer(struct exynos_dsi *dsi,
|
|
wait_for_completion_timeout(&xfer->completed,
|
|
wait_for_completion_timeout(&xfer->completed,
|
|
msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));
|
|
msecs_to_jiffies(DSI_XFER_TIMEOUT_MS));
|
|
if (xfer->result == -ETIMEDOUT) {
|
|
if (xfer->result == -ETIMEDOUT) {
|
|
|
|
+ struct mipi_dsi_packet *pkt = &xfer->packet;
|
|
exynos_dsi_remove_transfer(dsi, xfer);
|
|
exynos_dsi_remove_transfer(dsi, xfer);
|
|
- dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 2, xfer->data,
|
|
|
|
- xfer->tx_len, xfer->tx_payload);
|
|
|
|
|
|
+ dev_err(dsi->dev, "xfer timed out: %*ph %*ph\n", 4, pkt->header,
|
|
|
|
+ (int)pkt->payload_length, pkt->payload);
|
|
return -ETIMEDOUT;
|
|
return -ETIMEDOUT;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1241,20 +1277,20 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id)
|
|
struct exynos_dsi *dsi = dev_id;
|
|
struct exynos_dsi *dsi = dev_id;
|
|
u32 status;
|
|
u32 status;
|
|
|
|
|
|
- status = DSI_READ(dsi, DSIM_INTSRC_REG);
|
|
|
|
|
|
+ status = exynos_dsi_read(dsi, DSIM_INTSRC_REG);
|
|
if (!status) {
|
|
if (!status) {
|
|
static unsigned long int j;
|
|
static unsigned long int j;
|
|
if (printk_timed_ratelimit(&j, 500))
|
|
if (printk_timed_ratelimit(&j, 500))
|
|
dev_warn(dsi->dev, "spurious interrupt\n");
|
|
dev_warn(dsi->dev, "spurious interrupt\n");
|
|
return IRQ_HANDLED;
|
|
return IRQ_HANDLED;
|
|
}
|
|
}
|
|
- DSI_WRITE(dsi, DSIM_INTSRC_REG, status);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_INTSRC_REG, status);
|
|
|
|
|
|
if (status & DSIM_INT_SW_RST_RELEASE) {
|
|
if (status & DSIM_INT_SW_RST_RELEASE) {
|
|
u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |
|
|
u32 mask = ~(DSIM_INT_RX_DONE | DSIM_INT_SFR_FIFO_EMPTY |
|
|
DSIM_INT_SFR_HDR_FIFO_EMPTY | DSIM_INT_FRAME_DONE |
|
|
DSIM_INT_SFR_HDR_FIFO_EMPTY | DSIM_INT_FRAME_DONE |
|
|
DSIM_INT_RX_ECC_ERR | DSIM_INT_SW_RST_RELEASE);
|
|
DSIM_INT_RX_ECC_ERR | DSIM_INT_SW_RST_RELEASE);
|
|
- DSI_WRITE(dsi, DSIM_INTMSK_REG, mask);
|
|
|
|
|
|
+ exynos_dsi_write(dsi, DSIM_INTMSK_REG, mask);
|
|
complete(&dsi->completed);
|
|
complete(&dsi->completed);
|
|
return IRQ_HANDLED;
|
|
return IRQ_HANDLED;
|
|
}
|
|
}
|
|
@@ -1401,12 +1437,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-/* distinguish between short and long DSI packet types */
|
|
|
|
-static bool exynos_dsi_is_short_dsi_type(u8 type)
|
|
|
|
-{
|
|
|
|
- return (type & 0x0f) <= 8;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
|
|
static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
|
|
const struct mipi_dsi_msg *msg)
|
|
const struct mipi_dsi_msg *msg)
|
|
{
|
|
{
|
|
@@ -1424,25 +1454,9 @@ static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
|
|
dsi->state |= DSIM_STATE_INITIALIZED;
|
|
dsi->state |= DSIM_STATE_INITIALIZED;
|
|
}
|
|
}
|
|
|
|
|
|
- if (msg->tx_len == 0)
|
|
|
|
- return -EINVAL;
|
|
|
|
-
|
|
|
|
- xfer.data_id = msg->type | (msg->channel << 6);
|
|
|
|
-
|
|
|
|
- if (exynos_dsi_is_short_dsi_type(msg->type)) {
|
|
|
|
- const char *tx_buf = msg->tx_buf;
|
|
|
|
-
|
|
|
|
- if (msg->tx_len > 2)
|
|
|
|
- return -EINVAL;
|
|
|
|
- xfer.tx_len = 0;
|
|
|
|
- xfer.data[0] = tx_buf[0];
|
|
|
|
- xfer.data[1] = (msg->tx_len == 2) ? tx_buf[1] : 0;
|
|
|
|
- } else {
|
|
|
|
- xfer.tx_len = msg->tx_len;
|
|
|
|
- xfer.data[0] = msg->tx_len & 0xff;
|
|
|
|
- xfer.data[1] = msg->tx_len >> 8;
|
|
|
|
- xfer.tx_payload = msg->tx_buf;
|
|
|
|
- }
|
|
|
|
|
|
+ ret = mipi_dsi_create_packet(&xfer.packet, msg);
|
|
|
|
+ if (ret < 0)
|
|
|
|
+ return ret;
|
|
|
|
|
|
xfer.rx_len = msg->rx_len;
|
|
xfer.rx_len = msg->rx_len;
|
|
xfer.rx_payload = msg->rx_buf;
|
|
xfer.rx_payload = msg->rx_buf;
|
|
@@ -1774,6 +1788,7 @@ static int exynos_dsi_bind(struct device *dev, struct device *master,
|
|
|
|
|
|
bridge = of_drm_find_bridge(dsi->bridge_node);
|
|
bridge = of_drm_find_bridge(dsi->bridge_node);
|
|
if (bridge) {
|
|
if (bridge) {
|
|
|
|
+ encoder->bridge = bridge;
|
|
drm_bridge_attach(drm_dev, bridge);
|
|
drm_bridge_attach(drm_dev, bridge);
|
|
}
|
|
}
|
|
|
|
|