From: Brian Norris <briannorris@chromium.org>
To: Philippe CORNU <philippe.cornu@st.com>
Cc: "hl@rock-chips.com" <hl@rock-chips.com>,
"linux-rockchip@lists.infradead.org"
<linux-rockchip@lists.infradead.org>,
David Airlie <airlied@linux.ie>,
"hoegsberg@gmail.com" <hoegsberg@gmail.com>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"dri-devel@lists.freedesktop.org"
<dri-devel@lists.freedesktop.org>,
Yannick FERTRE <yannick.fertre@st.com>,
Nickey Yang <nickey.yang@rock-chips.com>,
"mka@chromium.org" <mka@chromium.org>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
"zyw@rock-chips.com" <zyw@rock-chips.com>,
"xbl@rock-chips.com" <xbl@rock-chips.com>,
Vincent ABRIOU <vincent.abriou@st.com>
Subject: Re: [PATCH] drm/bridge/synopsys: dsi: use common mipi_dsi_create_packet()
Date: Tue, 9 Jan 2018 10:55:13 -0800 [thread overview]
Message-ID: <20180109185512.GA73309@google.com> (raw)
In-Reply-To: <715bb58c-efa6-7944-f186-c186d7fae569@st.com>
Hi Philippe,
On Tue, Jan 09, 2018 at 10:48:43AM +0000, Philippe CORNU wrote:
> Hi Brian,
>
> And many thanks for implementing these TODOs.
And thanks for adding them; it gave me a better option than just adding
yet another switch case (MIPI_DSI_GENERIC_LONG_WRITE) ;)
> On 01/06/2018 01:38 AM, Brian Norris wrote:
> > This takes care of 2 TODOs in this driver, by using the common DSI
> > packet-marshalling code instead of our custom short/long write code.
> > This both saves us some duplicated code and gets us free support for
> > command types that weren't already part of our switch block (e.g.,
> > MIPI_DSI_GENERIC_LONG_WRITE).
> >
> > The code logic stays mostly intact, except that it becomes unnecessary
> > to split the short/long write functions, and we have to copy data a bit
> > more.
> >
> > Along the way, I noticed that loop bounds were a little odd:
> >
> > while (DIV_ROUND_UP(len, pld_data_bytes))
> >
> > This really was just supposed to be 'len != 0', so I made that more
> > clear.
> >
> > Tested on RK3399 with some pending refactoring patches by Nickey Yang,
> > to make the Rockchip DSI driver wrap this common driver.
> >
> > Signed-off-by: Brian Norris <briannorris@chromium.org>
> > ---
> > Could use an extra look from folks. This looks like the correct trivial
> > transformation, but I'm not that familiar with DSI.
> >
> > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 78 ++++++---------------------
> > 1 file changed, 16 insertions(+), 62 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > index d9cca4fd66ec..2fed20e44dfe 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > @@ -136,10 +136,6 @@
> > GEN_SW_0P_TX_LP)
> >
> > #define DSI_GEN_HDR 0x6c
> > -/* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() */
> > -#define GEN_HDATA(data) (((data) & 0xffff) << 8)
> > -#define GEN_HTYPE(type) (((type) & 0xff) << 0)
> > -
> > #define DSI_GEN_PLD_DATA 0x70
> >
> > #define DSI_CMD_PKT_STATUS 0x74
> > @@ -359,44 +355,15 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
> > return 0;
> > }
> >
> > -static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
> > - const struct mipi_dsi_msg *msg)
> > -{
> > - const u8 *tx_buf = msg->tx_buf;
> > - u16 data = 0;
> > - u32 val;
> > -
> > - if (msg->tx_len > 0)
> > - data |= tx_buf[0];
> > - if (msg->tx_len > 1)
> > - data |= tx_buf[1] << 8;
> > -
> > - if (msg->tx_len > 2) {
> > - dev_err(dsi->dev, "too long tx buf length %zu for short write\n",
> > - msg->tx_len);
> > - return -EINVAL;
> > - }
> > -
> > - val = GEN_HDATA(data) | GEN_HTYPE(msg->type);
> > - return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
> > -}
> > -
> > -static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
> > - const struct mipi_dsi_msg *msg)
> > +static int dw_mipi_dsi_dcs_write(struct dw_mipi_dsi *dsi,
> > + const struct mipi_dsi_packet *packet)
>
> Both DCS and Generic dsi transfers are managed by drm_mipi_dsi.c
> helpers. So maybe dw_mipi_dsi_dcs_write() should be renamed
> dw_mipi_dsi_write()...
Ah, good point. I really meant to remove the _dcs naming too, but I
guess I missed it. Will follow up.
> > {
> > - 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);
> > + const u8 *tx_buf = packet->payload;
> > + int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
> > u32 remainder;
> > u32 val;
> >
> > - if (msg->tx_len < 3) {
> > - dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
> > - msg->tx_len);
> > - return -EINVAL;
> > - }
> > -
> > - while (DIV_ROUND_UP(len, pld_data_bytes)) {
> > + while (len) {
> > if (len < pld_data_bytes) {
> > remainder = 0;
> > memcpy(&remainder, tx_buf, len);
> > @@ -419,40 +386,27 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
> > }
> > }
> >
> > - return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);
> > + remainder = 0;
> > + memcpy(&remainder, packet->header, sizeof(packet->header));
By the way: I don't think it's an issue that should block this patch,
since if I'm right, this function already is "broken", but isn't this
actually a bad way to handle byte-to-word marshalling? Particularly,
we're copying bytes into a word in LE ordering, but then we later write
them to IO registers with writel() (which does endian swapping).
So I think we have an endianness problem on BE systems.
One solution would be to write these to IO registers with a non-swapped
writel() (e.g., __raw_writel()? but that's not very nice...). Another
would be to avoid memcpy, and just read this out a word at a time --
that works fine for the aligned pieces, but not so well for any
non-aligned bits ('if (len < pld_data_bytes)' above) I think?
WDYT?
> > + return dw_mipi_dsi_gen_pkt_hdr_write(dsi, remainder);
> > }
> >
> > static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
> > const struct mipi_dsi_msg *msg)
> > {
> > struct dw_mipi_dsi *dsi = host_to_dsi(host);
> > + struct mipi_dsi_packet packet;
> > int ret;
> >
> > - /*
> > - * TODO dw drv improvements
> > - * use mipi_dsi_create_packet() instead of all following
> > - * functions and code (no switch cases, no
> > - * dw_mipi_dsi_dcs_short_write(), only the loop in long_write...)
> > - * and use packet.header...
> > - */
> > - dw_mipi_message_config(dsi, msg);
> > -
> > - switch (msg->type) {
> > - case MIPI_DSI_DCS_SHORT_WRITE:
> > - case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
> > - case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
> > - ret = dw_mipi_dsi_dcs_short_write(dsi, msg);
> > - break;
> > - case MIPI_DSI_DCS_LONG_WRITE:
> > - ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
> > - break;
> > - default:
> > - dev_err(dsi->dev, "unsupported message type 0x%02x\n",
> > - msg->type);
> > - ret = -EINVAL;
> > + ret = mipi_dsi_create_packet(&packet, msg);
> > + if (ret) {
> > + dev_err(dsi->dev, "failed to create packet: %d\n", ret);
> > + return ret;
> > }
> >
> > - return ret;
> > + dw_mipi_message_config(dsi, msg);
> > +
> > + return dw_mipi_dsi_dcs_write(dsi, &packet);
> > }
> >
> > static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
> >
>
> I performed some tests tracing all DSI_GEN_HDR & DSI_GEN_PLD_DATA reg
> writes with panel/panel-orisetech-otm8009a.c (using long dcs commands)
> before and after your patch and this is "100% perfect"!
>
> So, apart the un-important "dcs" in dw_mipi_dsi_dcs_write() function name:
>
> Reviewed-by: Philippe Cornu <philippe.cornu@st.com>
> Tested-by: Philippe Cornu <philippe.cornu@st.com>
>
> This clean-up will help a lot to add the dsi read feature in the future.
>
> Very good patch Brian and big "thank you" !
Thanks for the review and test! I'll likely send a v2 with only the
naming change + your tags, and I'll see about what do about the
endianness issues I noticed as a follow-up.
Brian
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
WARNING: multiple messages have this Message-ID (diff)
From: Brian Norris <briannorris@chromium.org>
To: Philippe CORNU <philippe.cornu@st.com>
Cc: Archit Taneja <architt@codeaurora.org>,
Andrzej Hajda <a.hajda@samsung.com>,
Laurent Pinchart <Laurent.pinchart@ideasonboard.com>,
David Airlie <airlied@linux.ie>,
Yannick FERTRE <yannick.fertre@st.com>,
Vincent ABRIOU <vincent.abriou@st.com>,
"dri-devel@lists.freedesktop.org"
<dri-devel@lists.freedesktop.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Sean Paul <seanpaul@chromium.org>,
Nickey Yang <nickey.yang@rock-chips.com>,
"hl@rock-chips.com" <hl@rock-chips.com>,
"linux-rockchip@lists.infradead.org"
<linux-rockchip@lists.infradead.org>,
"mka@chromium.org" <mka@chromium.org>,
"hoegsberg@gmail.com" <hoegsberg@gmail.com>,
"zyw@rock-chips.com" <zyw@rock-chips.com>,
"xbl@rock-chips.com" <xbl@rock-chips.com>
Subject: Re: [PATCH] drm/bridge/synopsys: dsi: use common mipi_dsi_create_packet()
Date: Tue, 9 Jan 2018 10:55:13 -0800 [thread overview]
Message-ID: <20180109185512.GA73309@google.com> (raw)
In-Reply-To: <715bb58c-efa6-7944-f186-c186d7fae569@st.com>
Hi Philippe,
On Tue, Jan 09, 2018 at 10:48:43AM +0000, Philippe CORNU wrote:
> Hi Brian,
>
> And many thanks for implementing these TODOs.
And thanks for adding them; it gave me a better option than just adding
yet another switch case (MIPI_DSI_GENERIC_LONG_WRITE) ;)
> On 01/06/2018 01:38 AM, Brian Norris wrote:
> > This takes care of 2 TODOs in this driver, by using the common DSI
> > packet-marshalling code instead of our custom short/long write code.
> > This both saves us some duplicated code and gets us free support for
> > command types that weren't already part of our switch block (e.g.,
> > MIPI_DSI_GENERIC_LONG_WRITE).
> >
> > The code logic stays mostly intact, except that it becomes unnecessary
> > to split the short/long write functions, and we have to copy data a bit
> > more.
> >
> > Along the way, I noticed that loop bounds were a little odd:
> >
> > while (DIV_ROUND_UP(len, pld_data_bytes))
> >
> > This really was just supposed to be 'len != 0', so I made that more
> > clear.
> >
> > Tested on RK3399 with some pending refactoring patches by Nickey Yang,
> > to make the Rockchip DSI driver wrap this common driver.
> >
> > Signed-off-by: Brian Norris <briannorris@chromium.org>
> > ---
> > Could use an extra look from folks. This looks like the correct trivial
> > transformation, but I'm not that familiar with DSI.
> >
> > drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 78 ++++++---------------------
> > 1 file changed, 16 insertions(+), 62 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > index d9cca4fd66ec..2fed20e44dfe 100644
> > --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c
> > @@ -136,10 +136,6 @@
> > GEN_SW_0P_TX_LP)
> >
> > #define DSI_GEN_HDR 0x6c
> > -/* TODO These 2 defines will be reworked thanks to mipi_dsi_create_packet() */
> > -#define GEN_HDATA(data) (((data) & 0xffff) << 8)
> > -#define GEN_HTYPE(type) (((type) & 0xff) << 0)
> > -
> > #define DSI_GEN_PLD_DATA 0x70
> >
> > #define DSI_CMD_PKT_STATUS 0x74
> > @@ -359,44 +355,15 @@ static int dw_mipi_dsi_gen_pkt_hdr_write(struct dw_mipi_dsi *dsi, u32 hdr_val)
> > return 0;
> > }
> >
> > -static int dw_mipi_dsi_dcs_short_write(struct dw_mipi_dsi *dsi,
> > - const struct mipi_dsi_msg *msg)
> > -{
> > - const u8 *tx_buf = msg->tx_buf;
> > - u16 data = 0;
> > - u32 val;
> > -
> > - if (msg->tx_len > 0)
> > - data |= tx_buf[0];
> > - if (msg->tx_len > 1)
> > - data |= tx_buf[1] << 8;
> > -
> > - if (msg->tx_len > 2) {
> > - dev_err(dsi->dev, "too long tx buf length %zu for short write\n",
> > - msg->tx_len);
> > - return -EINVAL;
> > - }
> > -
> > - val = GEN_HDATA(data) | GEN_HTYPE(msg->type);
> > - return dw_mipi_dsi_gen_pkt_hdr_write(dsi, val);
> > -}
> > -
> > -static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
> > - const struct mipi_dsi_msg *msg)
> > +static int dw_mipi_dsi_dcs_write(struct dw_mipi_dsi *dsi,
> > + const struct mipi_dsi_packet *packet)
>
> Both DCS and Generic dsi transfers are managed by drm_mipi_dsi.c
> helpers. So maybe dw_mipi_dsi_dcs_write() should be renamed
> dw_mipi_dsi_write()...
Ah, good point. I really meant to remove the _dcs naming too, but I
guess I missed it. Will follow up.
> > {
> > - 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);
> > + const u8 *tx_buf = packet->payload;
> > + int len = packet->payload_length, pld_data_bytes = sizeof(u32), ret;
> > u32 remainder;
> > u32 val;
> >
> > - if (msg->tx_len < 3) {
> > - dev_err(dsi->dev, "wrong tx buf length %zu for long write\n",
> > - msg->tx_len);
> > - return -EINVAL;
> > - }
> > -
> > - while (DIV_ROUND_UP(len, pld_data_bytes)) {
> > + while (len) {
> > if (len < pld_data_bytes) {
> > remainder = 0;
> > memcpy(&remainder, tx_buf, len);
> > @@ -419,40 +386,27 @@ static int dw_mipi_dsi_dcs_long_write(struct dw_mipi_dsi *dsi,
> > }
> > }
> >
> > - return dw_mipi_dsi_gen_pkt_hdr_write(dsi, hdr_val);
> > + remainder = 0;
> > + memcpy(&remainder, packet->header, sizeof(packet->header));
By the way: I don't think it's an issue that should block this patch,
since if I'm right, this function already is "broken", but isn't this
actually a bad way to handle byte-to-word marshalling? Particularly,
we're copying bytes into a word in LE ordering, but then we later write
them to IO registers with writel() (which does endian swapping).
So I think we have an endianness problem on BE systems.
One solution would be to write these to IO registers with a non-swapped
writel() (e.g., __raw_writel()? but that's not very nice...). Another
would be to avoid memcpy, and just read this out a word at a time --
that works fine for the aligned pieces, but not so well for any
non-aligned bits ('if (len < pld_data_bytes)' above) I think?
WDYT?
> > + return dw_mipi_dsi_gen_pkt_hdr_write(dsi, remainder);
> > }
> >
> > static ssize_t dw_mipi_dsi_host_transfer(struct mipi_dsi_host *host,
> > const struct mipi_dsi_msg *msg)
> > {
> > struct dw_mipi_dsi *dsi = host_to_dsi(host);
> > + struct mipi_dsi_packet packet;
> > int ret;
> >
> > - /*
> > - * TODO dw drv improvements
> > - * use mipi_dsi_create_packet() instead of all following
> > - * functions and code (no switch cases, no
> > - * dw_mipi_dsi_dcs_short_write(), only the loop in long_write...)
> > - * and use packet.header...
> > - */
> > - dw_mipi_message_config(dsi, msg);
> > -
> > - switch (msg->type) {
> > - case MIPI_DSI_DCS_SHORT_WRITE:
> > - case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
> > - case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
> > - ret = dw_mipi_dsi_dcs_short_write(dsi, msg);
> > - break;
> > - case MIPI_DSI_DCS_LONG_WRITE:
> > - ret = dw_mipi_dsi_dcs_long_write(dsi, msg);
> > - break;
> > - default:
> > - dev_err(dsi->dev, "unsupported message type 0x%02x\n",
> > - msg->type);
> > - ret = -EINVAL;
> > + ret = mipi_dsi_create_packet(&packet, msg);
> > + if (ret) {
> > + dev_err(dsi->dev, "failed to create packet: %d\n", ret);
> > + return ret;
> > }
> >
> > - return ret;
> > + dw_mipi_message_config(dsi, msg);
> > +
> > + return dw_mipi_dsi_dcs_write(dsi, &packet);
> > }
> >
> > static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = {
> >
>
> I performed some tests tracing all DSI_GEN_HDR & DSI_GEN_PLD_DATA reg
> writes with panel/panel-orisetech-otm8009a.c (using long dcs commands)
> before and after your patch and this is "100% perfect"!
>
> So, apart the un-important "dcs" in dw_mipi_dsi_dcs_write() function name:
>
> Reviewed-by: Philippe Cornu <philippe.cornu@st.com>
> Tested-by: Philippe Cornu <philippe.cornu@st.com>
>
> This clean-up will help a lot to add the dsi read feature in the future.
>
> Very good patch Brian and big "thank you" !
Thanks for the review and test! I'll likely send a v2 with only the
naming change + your tags, and I'll see about what do about the
endianness issues I noticed as a follow-up.
Brian
next prev parent reply other threads:[~2018-01-09 18:55 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-06 0:38 [PATCH] drm/bridge/synopsys: dsi: use common mipi_dsi_create_packet() Brian Norris
2018-01-06 0:38 ` Brian Norris
2018-01-09 10:48 ` Philippe CORNU
2018-01-09 10:48 ` Philippe CORNU
2018-01-09 18:55 ` Brian Norris [this message]
2018-01-09 18:55 ` Brian Norris
2018-01-11 11:16 ` Philippe CORNU
2018-01-11 11:16 ` Philippe CORNU
2018-01-18 11:40 ` Philippe CORNU
2018-01-18 11:40 ` Philippe CORNU
2018-01-23 21:15 ` Brian Norris
2018-01-23 21:15 ` Brian Norris
2018-01-24 9:51 ` Philippe CORNU
2018-01-24 9:51 ` Philippe CORNU
2018-01-25 11:07 ` Andrzej Hajda
2018-01-25 11:07 ` Andrzej Hajda
2018-01-25 11:38 ` Philippe CORNU
2018-01-25 11:38 ` Philippe CORNU
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180109185512.GA73309@google.com \
--to=briannorris@chromium.org \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@linux.ie \
--cc=dri-devel@lists.freedesktop.org \
--cc=hl@rock-chips.com \
--cc=hoegsberg@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=mka@chromium.org \
--cc=nickey.yang@rock-chips.com \
--cc=philippe.cornu@st.com \
--cc=vincent.abriou@st.com \
--cc=xbl@rock-chips.com \
--cc=yannick.fertre@st.com \
--cc=zyw@rock-chips.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.