* [PATCH] arm: dts: fix rk3066a based boards vdd_log voltage initialization
From: Boris Brezillon @ 2016-09-19 17:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAD=FV=UOXcUZyXRj++GkKksyFedGt59vQz8958nhhF9UM7rOuw@mail.gmail.com>
On Mon, 19 Sep 2016 09:38:34 -0700
Doug Anderson <dianders@chromium.org> wrote:
> Hi,
>
> On Mon, Sep 19, 2016 at 9:15 AM, Heiko Stuebner <heiko@sntech.de> wrote:
> > Am Montag, 19. September 2016, 08:15:30 CEST schrieb Doug Anderson:
> >> Hi,
> >>
> >> On Mon, Sep 19, 2016 at 1:44 AM, Andy Yan <andy.yan@rock-chips.com> wrote:
> >> > The current rk3066a based boards(Rayeager, Bqcurie2, Marsboard) use
> >> > pwm modulate vdd_logic voltage, but the pwm is default disabled and
> >> > the pwm pin acts as a gpio before pwm regulator probed, so the pwm
> >> > regulator driver will get a zero dutycycle at probe time, so change
> >> > the initial dutycycle to zero to match pwm_regulator_init_state check.
> >> >
> >> > Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
> >> >
> >> > ---
> >> >
> >> > arch/arm/boot/dts/rk3066a-bqcurie2.dts | 2 +-
> >> > arch/arm/boot/dts/rk3066a-marsboard.dts | 2 +-
> >> > arch/arm/boot/dts/rk3066a-rayeager.dts | 2 +-
> >> > 3 files changed, 3 insertions(+), 3 deletions(-)
> >> >
> >> > diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts
> >> > b/arch/arm/boot/dts/rk3066a-bqcurie2.dts index bc674ee..618450d 100644
> >> > --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts
> >> > +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
> >> > @@ -61,7 +61,7 @@
> >> >
> >> > regulator-min-microvolt = <1200000>;
> >> > regulator-max-microvolt = <1200000>;
> >> > regulator-always-on;
> >> >
> >> > - voltage-table = <1000000 100>,
> >> > + voltage-table = <1000000 0>,
> >>
> >> In my opinion this isn't quite the right answer. I think that you
> >> should add a new property describing the voltage in the case that the
> >> pin is an input and you should fill that property in, like:
> >>
> >> voltage-when-input = <1000000>;
> >
> > I'd think this would be more of a pwm issue, not something the pwm-regulator
> > should need to care about.
> >
> > Ideally the pwm driver should be able to return some state information even if
> > disabled? I.e. deriving a duty-cycle value from its pin state similar to what
> > Doug described below (it's either 0% or 100%)
> >
> > But right now I have a hard time understanding how the pwm could return any
> > duty-cycle information for an input gpio to the pwm-regulator, as I assume the
> > pwm-driver has to probe (and thus set pinctrl to the pwm function) before the
> > pwm-regulator is able to get the pwm handle?
>
> Hrm, right. The PWM ought to own the pinctrl, not the regulator.
> Hrm. Then I guess this gets more complicated.
>
> One thing to point out, though, is that an EE I talked to said that
> the "voltage when input" is actually a well defined property and is
> unrelated to the min/max voltage. AKA: it's not guaranteed to be
> equal to the 50% duty cycle. ...so adding a property to the PWM
> regulator that includes this value is something very sane. The
> "voltage when input" is defined by the pile of resistors and
> capacitors that are used to actually make the PWM control the
> regulator.
>
> The "voltage when input" is super important because this is the
> voltage that's used at bootup (when all pins are configured as inputs,
> possible with a pull applied) and that's used during suspend time when
> the PWM stops.
Correct me if I'm wrong, but the main problem here is that, when we try
to detect the initial regulator state, we ran into a "missing entry in
the duty-cycle <-> voltage table" error, which then triggers an -EINVAL
error preventing the PWM regulator probe to succeed.
Of course, adding an entry for the 0% dutycle case would solve the
issue, but I wonder if we should not allow "unknown value" at probe
time, and let the regulator user set the voltage output when it claims
it.
Another option would be to fake a valid value in this case (choose the
closest entry in the voltage table?).
^ permalink raw reply
* [PATCH 00/27] drm/rockchip: MIPI fixes & improvements
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
This is a bit of a mixed selection of patches to all areas of the
Rockchip dw-mipi-dsi driver, which I've been using for a while.
The first few patches fix the driver's use of the atomic API by removing
hardware manipulation from the mode_set hook:
drm/rockchip: dw-mipi-dsi: use mode from display state
drm/rockchip: dw-mipi-dsi: pass new mode into MIPI mode set
drm/rockchip: dw-mipi-dsi: don't configure hardware in mode_set for
MIPI
drm/rockchip: dw-mipi-dsi: rename commit hook to enable
The following several patches fix various aspects of DSI host transfers
in order to improve support for displays that need to be set up via DSI
commands:
drm/rockchip: dw-mipi-dsi: fix command header writes
drm/rockchip: dw-mipi-dsi: fix generic packet status check
drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
drm/rockchip: dw-mipi-dsi: include bad value in error message
drm/rockchip: dw-mipi-dsi: respect message flags
drm/rockchip: dw-mipi-dsi: only request HS clock when required
drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
drm/rockchip: dw-mipi-dsi: prepare panel after phy init
drm/rockchip: dw-mipi-dsi: allow commands in panel_disable
Then a bunch of patches to improve the PHY PLL and other clock setup:
drm/rockchip: dw-mipi-dsi: fix escape clock rate
drm/rockchip: dw-mipi-dsi: ensure PHY is reset
drm/rockchip: dw-mipi-dsi: configure bias and bandgap before enable
drm/rockchip: dw-mipi-dsi: don't enable PHY PLL until it's configured
drm/rockchip: dw-mipi-dsi: properly configure PHY timing
drm/rockchip: dw-mipi-dsi: improve PLL configuration
A couple of patches make the VOP and MIPI host consistent when panels do
not set explicit hsync/vsync polarities:
drm/rockchip: dw-mipi-dsi: use positive check for N{H,V}SYNC
drm/rockchip: vop: test for P{H,V}SYNC
The following patch fixes fbcon by making sure that the output
resolution is known before it loads:
drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded
Then a patch that should be self-explanatory:
drm/rockchip: dw-mipi-dsi: support non-burst modes
And the final two patches were useful in development but aren't really
needed once everything's working:
drm/rockchip: dw-mipi-dsi: add reset control
drm/rockchip: dw-mipi-dsi: support read commands
John Keeping (26):
drm/rockchip: dw-mipi-dsi: use mode from display state
drm/rockchip: dw-mipi-dsi: pass new mode into MIPI mode set
drm/rockchip: dw-mipi-dsi: don't configure hardware in mode_set for
MIPI
drm/rockchip: dw-mipi-dsi: rename commit hook to enable
drm/rockchip: dw-mipi-dsi: fix command header writes
drm/rockchip: dw-mipi-dsi: fix generic packet status check
drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
drm/rockchip: dw-mipi-dsi: include bad value in error message
drm/rockchip: dw-mipi-dsi: respect message flags
drm/rockchip: dw-mipi-dsi: only request HS clock when required
drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
drm/rockchip: dw-mipi-dsi: prepare panel after phy init
drm/rockchip: dw-mipi-dsi: allow commands in panel_disable
drm/rockchip: dw-mipi-dsi: fix escape clock rate
drm/rockchip: dw-mipi-dsi: ensure PHY is reset
drm/rockchip: dw-mipi-dsi: configure bias and bandgap before enable
drm/rockchip: dw-mipi-dsi: don't enable PHY PLL until it's configured
drm/rockchip: dw-mipi-dsi: properly configure PHY timing
drm/rockchip: dw-mipi-dsi: improve PLL configuration
drm/rockchip: dw-mipi-dsi: use specific poll helper
drm/rockchip: dw-mipi-dsi: use positive check for N{H,V}SYNC
drm/rockchip: vop: test for P{H,V}SYNC
drm/rockchip: dw-mipi-dsi: defer probe if panel is not loaded
drm/rockchip: dw-mipi-dsi: support non-burst modes
drm/rockchip: dw-mipi-dsi: add reset control
drm/rockchip: dw-mipi-dsi: support read commands
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 325 ++++++++++++++++++++--------
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 +-
2 files changed, 234 insertions(+), 95 deletions(-)
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply
* [PATCH 01/26] drm/rockchip: dw-mipi-dsi: use mode from display state
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
There is no need to keep a pointer to the mode around since we know it
will be present in the connector state.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index ca22e5ee89ca..a87037556f5c 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -286,7 +286,6 @@ struct dw_mipi_dsi {
u32 format;
u16 input_div;
u16 feedback_div;
- struct drm_display_mode *mode;
const struct dw_mipi_dsi_plat_data *pdata;
};
@@ -332,9 +331,10 @@ static int max_mbps_to_testdin(unsigned int max_mbps)
*/
static void dw_mipi_dsi_wait_for_two_frames(struct dw_mipi_dsi *dsi)
{
+ struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
int refresh, two_frames;
- refresh = drm_mode_vrefresh(dsi->mode);
+ refresh = drm_mode_vrefresh(mode);
two_frames = DIV_ROUND_UP(MSEC_PER_SEC, refresh) * 2;
msleep(two_frames);
}
@@ -461,6 +461,7 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi)
{
+ struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
unsigned int i, pre;
unsigned long mpclk, pllref, tmp;
unsigned int m = 1, n = 1, target_mbps = 1000;
@@ -474,7 +475,7 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi)
return bpp;
}
- mpclk = DIV_ROUND_UP(dsi->mode->clock, MSEC_PER_SEC);
+ mpclk = DIV_ROUND_UP(mode->clock, MSEC_PER_SEC);
if (mpclk) {
/* take 1 / 0.9, since mbps must big than bandwidth of RGB */
tmp = mpclk * (bpp / dsi->lanes) * 10 / 9;
@@ -689,9 +690,9 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
}
-static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi,
- struct drm_display_mode *mode)
+static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi)
{
+ struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
u32 val = 0, color = 0;
switch (dsi->format) {
@@ -726,9 +727,10 @@ static void dw_mipi_dsi_packet_handler_config(struct dw_mipi_dsi *dsi)
dsi_write(dsi, DSI_PCKHDL_CFG, EN_CRC_RX | EN_ECC_RX | EN_BTA);
}
-static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi,
- struct drm_display_mode *mode)
+static void dw_mipi_dsi_video_packet_config(struct dw_mipi_dsi *dsi)
{
+ struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
+
dsi_write(dsi, DSI_VID_PKT_SIZE, VID_PKT_SIZE(mode->hdisplay));
}
@@ -744,12 +746,13 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
u32 hcomponent)
{
+ struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
u32 frac, lbcc;
lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8;
- frac = lbcc % dsi->mode->clock;
- lbcc = lbcc / dsi->mode->clock;
+ frac = lbcc % mode->clock;
+ lbcc = lbcc / mode->clock;
if (frac)
lbcc++;
@@ -759,7 +762,7 @@ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi,
static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi)
{
u32 htotal, hsa, hbp, lbcc;
- struct drm_display_mode *mode = dsi->mode;
+ struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
htotal = mode->htotal;
hsa = mode->hsync_end - mode->hsync_start;
@@ -778,7 +781,7 @@ static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi)
static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi)
{
u32 vactive, vsa, vfp, vbp;
- struct drm_display_mode *mode = dsi->mode;
+ struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
vactive = mode->vdisplay;
vsa = mode->vsync_end - mode->vsync_start;
@@ -821,8 +824,6 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
int ret;
- dsi->mode = adjusted_mode;
-
ret = dw_mipi_dsi_get_lane_bps(dsi);
if (ret < 0)
return;
@@ -833,10 +834,10 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
}
dw_mipi_dsi_init(dsi);
- dw_mipi_dsi_dpi_config(dsi, mode);
+ dw_mipi_dsi_dpi_config(dsi);
dw_mipi_dsi_packet_handler_config(dsi);
dw_mipi_dsi_video_mode_config(dsi);
- dw_mipi_dsi_video_packet_config(dsi, mode);
+ dw_mipi_dsi_video_packet_config(dsi);
dw_mipi_dsi_command_mode_config(dsi);
dw_mipi_dsi_line_timer_config(dsi);
dw_mipi_dsi_vertical_timing_config(dsi);
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 02/26] drm/rockchip: dw-mipi-dsi: pass new mode into MIPI mode set
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
In the atomic world the new connector state is not set when mode_set is
called and we should use the adjusted_mode parameter.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index a87037556f5c..fa90bb615fd0 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -459,9 +459,9 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
return ret;
}
-static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi)
+static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi,
+ struct drm_display_mode *mode)
{
- struct drm_display_mode *mode = &dsi->connector.state->crtc->state->adjusted_mode;
unsigned int i, pre;
unsigned long mpclk, pllref, tmp;
unsigned int m = 1, n = 1, target_mbps = 1000;
@@ -824,7 +824,7 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
int ret;
- ret = dw_mipi_dsi_get_lane_bps(dsi);
+ ret = dw_mipi_dsi_get_lane_bps(dsi, adjusted_mode);
if (ret < 0)
return;
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 03/26] drm/rockchip: dw-mipi-dsi: don't configure hardware in mode_set for MIPI
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
With atomic modesetting the hardware will be powered off when the
mode_set function is called. We should configure the hardware in the
commit function (or even the enable function, but switching from commit
to enable is left for a future patch).
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 40 +++++++++++++---------------------
1 file changed, 15 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index fa90bb615fd0..5925a185ed76 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -822,32 +822,8 @@ static void dw_mipi_dsi_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *adjusted_mode)
{
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
- int ret;
-
- ret = dw_mipi_dsi_get_lane_bps(dsi, adjusted_mode);
- if (ret < 0)
- return;
-
- if (clk_prepare_enable(dsi->pclk)) {
- dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__);
- return;
- }
- dw_mipi_dsi_init(dsi);
- dw_mipi_dsi_dpi_config(dsi);
- dw_mipi_dsi_packet_handler_config(dsi);
- dw_mipi_dsi_video_mode_config(dsi);
- dw_mipi_dsi_video_packet_config(dsi);
- dw_mipi_dsi_command_mode_config(dsi);
- dw_mipi_dsi_line_timer_config(dsi);
- dw_mipi_dsi_vertical_timing_config(dsi);
- dw_mipi_dsi_dphy_timing_config(dsi);
- dw_mipi_dsi_dphy_interface_config(dsi);
- dw_mipi_dsi_clear_err(dsi);
- if (drm_panel_prepare(dsi->panel))
- dev_err(dsi->dev, "failed to prepare panel\n");
-
- clk_disable_unprepare(dsi->pclk);
+ dw_mipi_dsi_get_lane_bps(dsi, adjusted_mode);
}
static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
@@ -887,6 +863,20 @@ static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
return;
}
+ dw_mipi_dsi_init(dsi);
+ dw_mipi_dsi_dpi_config(dsi);
+ dw_mipi_dsi_packet_handler_config(dsi);
+ dw_mipi_dsi_video_mode_config(dsi);
+ dw_mipi_dsi_video_packet_config(dsi);
+ dw_mipi_dsi_command_mode_config(dsi);
+ dw_mipi_dsi_line_timer_config(dsi);
+ dw_mipi_dsi_vertical_timing_config(dsi);
+ dw_mipi_dsi_dphy_timing_config(dsi);
+ dw_mipi_dsi_dphy_interface_config(dsi);
+ dw_mipi_dsi_clear_err(dsi);
+ if (drm_panel_prepare(dsi->panel))
+ dev_err(dsi->dev, "failed to prepare panel\n");
+
dw_mipi_dsi_phy_init(dsi);
dw_mipi_dsi_wait_for_two_frames(dsi);
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 04/26] drm/rockchip: dw-mipi-dsi: rename commit hook to enable
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Rockchip DRM is fully atomic and commit is deprecated for atomic
drivers. No changed are needed beyond renaming the function.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 5925a185ed76..fac2429b9d6d 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -852,7 +852,7 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
clk_disable_unprepare(dsi->pclk);
}
-static void dw_mipi_dsi_encoder_commit(struct drm_encoder *encoder)
+static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
{
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
int mux = drm_of_encoder_active_endpoint_id(dsi->dev->of_node, encoder);
@@ -924,7 +924,7 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
static struct drm_encoder_helper_funcs
dw_mipi_dsi_encoder_helper_funcs = {
- .commit = dw_mipi_dsi_encoder_commit,
+ .enable = dw_mipi_dsi_encoder_enable,
.mode_set = dw_mipi_dsi_encoder_mode_set,
.disable = dw_mipi_dsi_encoder_disable,
.atomic_check = dw_mipi_dsi_encoder_atomic_check,
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 05/26] drm/rockchip: dw-mipi-dsi: fix command header writes
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
In a couple of places here we use "val" for the value that is about to
be written to a register but then reuse the same variable for the value
of a status register before we get around to writing it. Rename the
value to be written to so that we write the value we intend to and not
what we have just read from the status register.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index fac2429b9d6d..03915bf9c97d 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -543,9 +543,10 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
return 0;
}
-static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val)
+static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
{
int ret;
+ u32 val;
ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
val, !(val & GEN_CMD_FULL), 1000,
@@ -555,7 +556,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 val)
return ret;
}
- dsi_write(dsi, DSI_GEN_HDR, val);
+ dsi_write(dsi, DSI_GEN_HDR, hdr_val);
ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
val, val & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY),
@@ -588,8 +589,9 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
{
const u32 *tx_buf = msg->tx_buf;
int len = msg->tx_len, pld_data_bytes = sizeof(*tx_buf), ret;
- u32 val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
+ u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
u32 remainder = 0;
+ u32 val;
if (msg->tx_len < 3) {
dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
@@ -618,7 +620,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
}
}
- return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
+ return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);
}
static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 06/26] drm/rockchip: dw-mipi-dsi: fix generic packet status check
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
We want to check that both the GEN_CMD_EMPTY and GEN_PLD_W_EMPTY bits
are set so we can't just check "val & mask" because that will be true if
either bit is set.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 03915bf9c97d..f2bed2a0f907 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -546,7 +546,7 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
{
int ret;
- u32 val;
+ u32 val, mask;
ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
val, !(val & GEN_CMD_FULL), 1000,
@@ -558,8 +558,9 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
dsi_write(dsi, DSI_GEN_HDR, hdr_val);
+ mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
- val, val & (GEN_CMD_EMPTY | GEN_PLD_W_EMPTY),
+ val, (val & mask) == mask,
1000, CMD_PKT_STATUS_TIMEOUT_US);
if (ret < 0) {
dev_err(dsi->dev, "failed to write command FIFO\n");
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 07/26] drm/rockchip: dw-mipi-dsi: avoid out-of-bounds read on tx_buf
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
As a side-effect of this, encode the endianness explicitly rather than
casting a u16.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index f2bed2a0f907..38186df8476e 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -573,8 +573,13 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
const struct mipi_dsi_msg *msg)
{
- const u16 *tx_buf = msg->tx_buf;
- u32 val = GEN_HDATA(*tx_buf) | GEN_HTYPE(msg->type);
+ const u8 *tx_buf = msg->tx_buf;
+ u32 val = GEN_HTYPE(msg->type);
+
+ if (msg->tx_len > 0)
+ val |= GEN_HDATA(tx_buf[0]);
+ if (msg->tx_len > 1)
+ val |= GEN_HDATA(tx_buf[1] << 8);
if (msg->tx_len > 2) {
dev_err(dsi->dev, "too long tx buf length %zu for short write\n",
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 08/26] drm/rockchip: dw-mipi-dsi: include bad value in error message
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
As an aid to debugging.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 38186df8476e..a25db02e1c19 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -645,7 +645,8 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
break;
default:
- dev_err(dsi->dev, "unsupported message type\n");
+ dev_err(dsi->dev, "unsupported message type 0x%02x\n",
+ msg->type);
ret = -EINVAL;
}
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 09/26] drm/rockchip: dw-mipi-dsi: respect message flags
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Instead of always sending commands in LP mode, respect the
MIPI_DSI_MSG_USE_LPM flag to decide how to send each message. Also
request acks if MIPI_DSI_MSG_REQ_ACK is set.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index a25db02e1c19..554336f8023e 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -543,6 +543,19 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
return 0;
}
+static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
+ const struct mipi_dsi_msg *msg)
+{
+ u32 val = 0;
+
+ if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
+ val |= EN_ACK_RQST;
+ if (msg->flags & MIPI_DSI_MSG_USE_LPM)
+ val |= CMD_MODE_ALL_LP;
+
+ dsi_write(dsi, DSI_CMD_MODE_CFG, val);
+}
+
static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
{
int ret;
@@ -635,6 +648,8 @@ static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
struct dw_mipi_dsi *dsi = host_to_dsi(host);
int ret;
+ dw_mipi_message_config(dsi, msg);
+
switch (msg->type) {
case MIPI_DSI_DCS_SHORT_WRITE:
case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
@@ -747,7 +762,6 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi)
{
dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000));
dsi_write(dsi, DSI_BTA_TO_CNT, 0xd00);
- dsi_write(dsi, DSI_CMD_MODE_CFG, CMD_MODE_ALL_LP);
dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE);
}
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 10/26] drm/rockchip: dw-mipi-dsi: only request HS clock when required
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Requesting the HS clock from the PHY before we initialize it causes an
invalid signal to be sent out since the input clock is not yet
configured. The PHY databook suggests only asserting this signal when
performing HS transfers, so let's do that.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 554336f8023e..ed2da1bbada9 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -546,13 +546,15 @@ static int dw_mipi_dsi_host_detach(struct mipi_dsi_host *host,
static void dw_mipi_message_config(struct dw_mipi_dsi *dsi,
const struct mipi_dsi_msg *msg)
{
+ bool lpm = msg->flags & MIPI_DSI_MSG_USE_LPM;
u32 val = 0;
if (msg->flags & MIPI_DSI_MSG_REQ_ACK)
val |= EN_ACK_RQST;
- if (msg->flags & MIPI_DSI_MSG_USE_LPM)
+ if (lpm)
val |= CMD_MODE_ALL_LP;
+ dsi_write(dsi, DSI_LPCLK_CTRL, lpm ? 0 : PHY_TXREQUESTCLKHS);
dsi_write(dsi, DSI_CMD_MODE_CFG, val);
}
@@ -694,6 +696,7 @@ static void dw_mipi_dsi_set_mode(struct dw_mipi_dsi *dsi,
dsi_write(dsi, DSI_PWR_UP, RESET);
dsi_write(dsi, DSI_MODE_CFG, ENABLE_VIDEO_MODE);
dw_mipi_dsi_video_mode_config(dsi);
+ dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
dsi_write(dsi, DSI_PWR_UP, POWERUP);
}
}
@@ -711,7 +714,6 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
| PHY_RSTZ | PHY_SHUTDOWNZ);
dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
TX_ESC_CLK_DIVIDSION(7));
- dsi_write(dsi, DSI_LPCLK_CTRL, PHY_TXREQUESTCLKHS);
}
static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi)
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 11/26] drm/rockchip: dw-mipi-dsi: don't assume buffer is aligned
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
By dereferencing the MIPI command buffer as a u32* we rely on it being
correctly aligned on ARM, but this may not be the case. Copy it into a
stack variable that will be correctly aligned.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index ed2da1bbada9..4c945cc4d31a 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -608,10 +608,10 @@ static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
const struct mipi_dsi_msg *msg)
{
- const u32 *tx_buf = msg->tx_buf;
- int len = msg->tx_len, pld_data_bytes = sizeof(*tx_buf), ret;
+ const u8 *tx_buf = msg->tx_buf;
+ int len = msg->tx_len, pld_data_bytes = sizeof(u32), ret;
u32 hdr_val = GEN_HDATA(msg->tx_len) | GEN_HTYPE(msg->type);
- u32 remainder = 0;
+ u32 remainder;
u32 val;
if (msg->tx_len < 3) {
@@ -622,12 +622,14 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
while (DIV_ROUND_UP(len, pld_data_bytes)) {
if (len < pld_data_bytes) {
+ remainder = 0;
memcpy(&remainder, tx_buf, len);
dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
len = 0;
} else {
- dsi_write(dsi, DSI_GEN_PLD_DATA, *tx_buf);
- tx_buf++;
+ memcpy(&remainder, tx_buf, pld_data_bytes);
+ dsi_write(dsi, DSI_GEN_PLD_DATA, remainder);
+ tx_buf += pld_data_bytes;
len -= pld_data_bytes;
}
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 12/26] drm/rockchip: dw-mipi-dsi: prepare panel after phy init
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Some panels need to be configured with commands sent over the MIPI link,
which they will do in the prepare hook. Call this after the PHY has
been initialized so that we are able to send commands to the panel.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 4c945cc4d31a..9ff1cac5ef63 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -901,12 +901,14 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
dw_mipi_dsi_dphy_timing_config(dsi);
dw_mipi_dsi_dphy_interface_config(dsi);
dw_mipi_dsi_clear_err(dsi);
- if (drm_panel_prepare(dsi->panel))
- dev_err(dsi->dev, "failed to prepare panel\n");
dw_mipi_dsi_phy_init(dsi);
dw_mipi_dsi_wait_for_two_frames(dsi);
+ dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_CMD_MODE);
+ if (drm_panel_prepare(dsi->panel))
+ dev_err(dsi->dev, "failed to prepare panel\n");
+
dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE);
drm_panel_enable(dsi->panel);
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 13/26] drm/rockchip: dw-mipi-dsi: allow commands in panel_disable
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Panel drivers may want to sent commands during the disable function, for
example MIPI_DCS_SET_DISPLAY_OFF before the video signal ends. In order
to send commands we need to write to registers, so pclk must be enabled.
While changing this, remove the unnecessary code after the panel
unprepare call which seems to be a workaround for a specific panel and
thus belongs in the panel driver.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 9ff1cac5ef63..5e343b54f0d0 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -857,24 +857,16 @@ static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
{
struct dw_mipi_dsi *dsi = encoder_to_dsi(encoder);
- drm_panel_disable(dsi->panel);
-
if (clk_prepare_enable(dsi->pclk)) {
dev_err(dsi->dev, "%s: Failed to enable pclk\n", __func__);
return;
}
+ drm_panel_disable(dsi->panel);
+
dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_CMD_MODE);
drm_panel_unprepare(dsi->panel);
- dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_VID_MODE);
- /*
- * This is necessary to make sure the peripheral will be driven
- * normally when the display is enabled again later.
- */
- msleep(120);
-
- dw_mipi_dsi_set_mode(dsi, DW_MIPI_DSI_CMD_MODE);
dw_mipi_dsi_disable(dsi);
clk_disable_unprepare(dsi->pclk);
}
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 14/26] drm/rockchip: dw-mipi-dsi: fix escape clock rate
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Use the same calculation as the vendor kernel to derive the escape clock
speed.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 5e343b54f0d0..8854b8670d72 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -711,11 +711,13 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
{
+ u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
+
dsi_write(dsi, DSI_PWR_UP, RESET);
dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
| PHY_RSTZ | PHY_SHUTDOWNZ);
dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
- TX_ESC_CLK_DIVIDSION(7));
+ TX_ESC_CLK_DIVIDSION(esc_clk_division));
}
static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi)
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 14/27] drm/rockchip: dw-mipi-dsi: use specific poll helper
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
As the documentation for readx_poll_timeout says, we want to use the
specialized macro for readl rather than using the generic version
directly.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 5e343b54f0d0..097b3b0af78f 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -440,14 +440,14 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
- ret = readx_poll_timeout(readl, dsi->base + DSI_PHY_STATUS,
+ ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
val, val & LOCK, 1000, PHY_STATUS_TIMEOUT_US);
if (ret < 0) {
dev_err(dsi->dev, "failed to wait for phy lock state\n");
return ret;
}
- ret = readx_poll_timeout(readl, dsi->base + DSI_PHY_STATUS,
+ ret = readl_poll_timeout(dsi->base + DSI_PHY_STATUS,
val, val & STOP_STATE_CLK_LANE, 1000,
PHY_STATUS_TIMEOUT_US);
if (ret < 0) {
@@ -563,7 +563,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
int ret;
u32 val, mask;
- ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
val, !(val & GEN_CMD_FULL), 1000,
CMD_PKT_STATUS_TIMEOUT_US);
if (ret < 0) {
@@ -574,7 +574,7 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
dsi_write(dsi, DSI_GEN_HDR, hdr_val);
mask = GEN_CMD_EMPTY | GEN_PLD_W_EMPTY;
- ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
val, (val & mask) == mask,
1000, CMD_PKT_STATUS_TIMEOUT_US);
if (ret < 0) {
@@ -633,7 +633,7 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
len -= pld_data_bytes;
}
- ret = readx_poll_timeout(readl, dsi->base + DSI_CMD_PKT_STATUS,
+ ret = readl_poll_timeout(dsi->base + DSI_CMD_PKT_STATUS,
val, !(val & GEN_PLD_W_FULL), 1000,
CMD_PKT_STATUS_TIMEOUT_US);
if (ret < 0) {
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 15/26] drm/rockchip: dw-mipi-dsi: ensure PHY is reset
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Also don't power up the DSI host at this point since this is not
necessary in order to configure the PHY and we do so later when
selecting video or command mode.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 8854b8670d72..73c28e205fc5 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -398,7 +398,10 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
return testdin;
}
- dsi_write(dsi, DSI_PWR_UP, POWERUP);
+ /* Start by clearing PHY state */
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE |
VCO_RANGE_CON_SEL(vco) |
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 15/27] drm/rockchip: dw-mipi-dsi: use positive check for N{H, V}SYNC
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
This matches other drivers.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 097b3b0af78f..7b4f4f150a0d 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -738,9 +738,9 @@ static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi)
break;
}
- if (!(mode->flags & DRM_MODE_FLAG_PVSYNC))
+ if (mode->flags & DRM_MODE_FLAG_NVSYNC)
val |= VSYNC_ACTIVE_LOW;
- if (!(mode->flags & DRM_MODE_FLAG_PHSYNC))
+ if (mode->flags & DRM_MODE_FLAG_NHSYNC)
val |= HSYNC_ACTIVE_LOW;
dsi_write(dsi, DSI_DPI_VCID, DPI_VID(dsi->channel));
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 16/26] drm/rockchip: dw-mipi-dsi: configure bias and bandgap before enable
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
We should configure these functions before enabling them.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 73c28e205fc5..f824c99b872e 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -421,6 +421,11 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
HIGH_PROGRAM_EN);
+ dw_mipi_dsi_phy_write(dsi, 0x22, LOW_PROGRAM_EN |
+ BIASEXTR_SEL(BIASEXTR_127_7));
+ dw_mipi_dsi_phy_write(dsi, 0x22, HIGH_PROGRAM_EN |
+ BANDGAP_SEL(BANDGAP_96_10));
+
dw_mipi_dsi_phy_write(dsi, 0x20, POWER_CONTROL | INTERNAL_REG_CURRENT |
BIAS_BLOCK_ON | BANDGAP_ON);
@@ -430,10 +435,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
SETRD_MAX | POWER_MANAGE |
TER_RESISTORS_ON);
- dw_mipi_dsi_phy_write(dsi, 0x22, LOW_PROGRAM_EN |
- BIASEXTR_SEL(BIASEXTR_127_7));
- dw_mipi_dsi_phy_write(dsi, 0x22, HIGH_PROGRAM_EN |
- BANDGAP_SEL(BANDGAP_96_10));
dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | 0xf);
dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x55);
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 16/27] drm/rockchip: dw-mipi-dsi: fix escape clock rate
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Use the same calculation as the vendor kernel to derive the escape clock
speed.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 7b4f4f150a0d..e621b66b9617 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -711,11 +711,13 @@ static void dw_mipi_dsi_disable(struct dw_mipi_dsi *dsi)
static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi)
{
+ u32 esc_clk_division = (dsi->lane_mbps >> 3) / 20 + 1;
+
dsi_write(dsi, DSI_PWR_UP, RESET);
dsi_write(dsi, DSI_PHY_RSTZ, PHY_DISFORCEPLL | PHY_DISABLECLK
| PHY_RSTZ | PHY_SHUTDOWNZ);
dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVIDSION(10) |
- TX_ESC_CLK_DIVIDSION(7));
+ TX_ESC_CLK_DIVIDSION(esc_clk_division));
}
static void dw_mipi_dsi_dpi_config(struct dw_mipi_dsi *dsi)
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 17/26] drm/rockchip: dw-mipi-dsi: don't enable PHY PLL until it's configured
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index f824c99b872e..463e469fd1b8 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -414,12 +414,12 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dw_mipi_dsi_phy_write(dsi, 0x44, HSFREQRANGE_SEL(testdin));
- dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
dw_mipi_dsi_phy_write(dsi, 0x17, INPUT_DIVIDER(dsi->input_div));
dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_LOW_SEL(dsi->feedback_div) |
LOW_PROGRAM_EN);
dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
HIGH_PROGRAM_EN);
+ dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN);
dw_mipi_dsi_phy_write(dsi, 0x22, LOW_PROGRAM_EN |
BIASEXTR_SEL(BIASEXTR_127_7));
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 17/27] drm/rockchip: dw-mipi-dsi: ensure PHY is reset
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
Also don't power up the DSI host at this point since this is not
necessary in order to configure the PHY and we do so later when
selecting video or command mode.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index e621b66b9617..e310c3d81bb8 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -398,7 +398,10 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
return testdin;
}
- dsi_write(dsi, DSI_PWR_UP, POWERUP);
+ /* Start by clearing PHY state */
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLR);
+ dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_UNTESTCLR);
dw_mipi_dsi_phy_write(dsi, 0x10, BYPASS_VCO_RANGE |
VCO_RANGE_CON_SEL(vco) |
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 18/27] drm/rockchip: dw-mipi-dsi: configure bias and bandgap before enable
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
We should configure these functions before enabling them.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index e310c3d81bb8..65c89367d8b2 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -421,6 +421,11 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) |
HIGH_PROGRAM_EN);
+ dw_mipi_dsi_phy_write(dsi, 0x22, LOW_PROGRAM_EN |
+ BIASEXTR_SEL(BIASEXTR_127_7));
+ dw_mipi_dsi_phy_write(dsi, 0x22, HIGH_PROGRAM_EN |
+ BANDGAP_SEL(BANDGAP_96_10));
+
dw_mipi_dsi_phy_write(dsi, 0x20, POWER_CONTROL | INTERNAL_REG_CURRENT |
BIAS_BLOCK_ON | BANDGAP_ON);
@@ -430,10 +435,6 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
SETRD_MAX | POWER_MANAGE |
TER_RESISTORS_ON);
- dw_mipi_dsi_phy_write(dsi, 0x22, LOW_PROGRAM_EN |
- BIASEXTR_SEL(BIASEXTR_127_7));
- dw_mipi_dsi_phy_write(dsi, 0x22, HIGH_PROGRAM_EN |
- BANDGAP_SEL(BANDGAP_96_10));
dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | 0xf);
dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x55);
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
* [PATCH 18/26] drm/rockchip: dw-mipi-dsi: properly configure PHY timing
From: John Keeping @ 2016-09-19 17:17 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20160919171747.28512-1-john@metanate.com>
These values are specified as constant time periods but the PHY
configuration is in terms of the current lane byte clock so using
constant values guarantees that the timings will be outside the
specification with some display configurations.
Derive the necessary configuration from the byte clock in order to
ensure that the PHY configuration is correct.
Signed-off-by: John Keeping <john@metanate.com>
---
drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 36 ++++++++++++++++++++++++++++++----
1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
index 463e469fd1b8..55237d72f3f9 100644
--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
+++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c
@@ -384,6 +384,26 @@ static void dw_mipi_dsi_phy_write(struct dw_mipi_dsi *dsi, u8 test_code,
dsi_write(dsi, DSI_PHY_TST_CTRL0, PHY_TESTCLK | PHY_UNTESTCLR);
}
+/**
+ * ns2bc - Nanoseconds to byte clock cycles
+ */
+static inline unsigned int ns2bc(struct dw_mipi_dsi *dsi, int ns)
+{
+ unsigned long byte_clk_khz = dsi->lane_mbps * MSEC_PER_SEC / 8;
+
+ return (ns * (byte_clk_khz / 1000) + 999) / 1000;
+}
+
+/**
+ * ns2ui - Nanoseconds to UI time periods
+ */
+static inline unsigned int ns2ui(struct dw_mipi_dsi *dsi, int ns)
+{
+ unsigned long byte_clk_khz = dsi->lane_mbps * MSEC_PER_SEC;
+
+ return (ns * (byte_clk_khz / 1000) + 999) / 1000;
+}
+
static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
{
int ret, testdin, vco, val;
@@ -435,10 +455,18 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
SETRD_MAX | POWER_MANAGE |
TER_RESISTORS_ON);
-
- dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | 0xf);
- dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | 0x55);
- dw_mipi_dsi_phy_write(dsi, 0x72, THS_ZERO_PROGRAM_EN | 0xa);
+ dw_mipi_dsi_phy_write(dsi, 0x60, TLP_PROGRAM_EN | ns2bc(dsi, 500));
+ dw_mipi_dsi_phy_write(dsi, 0x61, THS_PRE_PROGRAM_EN | ns2ui(dsi, 40));
+ dw_mipi_dsi_phy_write(dsi, 0x62, THS_ZERO_PROGRAM_EN | ns2bc(dsi, 300));
+ dw_mipi_dsi_phy_write(dsi, 0x63, THS_PRE_PROGRAM_EN | ns2ui(dsi, 100));
+ dw_mipi_dsi_phy_write(dsi, 0x64, BIT(5) | ns2bc(dsi, 100));
+ dw_mipi_dsi_phy_write(dsi, 0x65, BIT(5) | (ns2bc(dsi, 60) + 7));
+
+ dw_mipi_dsi_phy_write(dsi, 0x70, TLP_PROGRAM_EN | ns2bc(dsi, 500));
+ dw_mipi_dsi_phy_write(dsi, 0x71, THS_PRE_PROGRAM_EN | (ns2ui(dsi, 50) + 5));
+ dw_mipi_dsi_phy_write(dsi, 0x72, THS_ZERO_PROGRAM_EN | (ns2bc(dsi, 140) + 2));
+ dw_mipi_dsi_phy_write(dsi, 0x73, THS_PRE_PROGRAM_EN | (ns2ui(dsi, 60) + 8));
+ dw_mipi_dsi_phy_write(dsi, 0x74, BIT(5) | ns2bc(dsi, 100));
dsi_write(dsi, DSI_PHY_RSTZ, PHY_ENFORCEPLL | PHY_ENABLECLK |
PHY_UNRSTZ | PHY_UNSHUTDOWNZ);
--
2.10.0.278.g4f427b1.dirty
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox