* Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-01 10:24 [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid() Jani Nikula
@ 2023-09-01 14:45 ` kernel test robot
2023-09-01 14:52 ` Jani Nikula
` (3 subsequent siblings)
4 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2023-09-01 14:45 UTC (permalink / raw)
To: Jani Nikula; +Cc: llvm, oe-kbuild-all
Hi Jani,
[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:
[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on drm/drm-next drm-exynos/exynos-drm-next drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip linus/master v6.5 next-20230831]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jani-Nikula/drm-bridge-megachips-stdpxxxx-ge-b850v3-fw-switch-to-drm_do_get_edid/20230901-182521
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/20230901102400.552254-1-jani.nikula%40intel.com
patch subject: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
config: hexagon-randconfig-002-20230901 (https://download.01.org/0day-ci/archive/20230901/202309012218.hjriMIl0-lkp@intel.com/config)
compiler: clang version 17.0.0 (https://github.com/llvm/llvm-project.git 4a5ac14ee968ff0ad5d2cc1ffa0299048db4c88a)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230901/202309012218.hjriMIl0-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309012218.hjriMIl0-lkp@intel.com/
All errors (new ones prefixed by >>):
In file included from drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c:22:
In file included from include/linux/i2c.h:19:
In file included from include/linux/regulator/consumer.h:35:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:13:
In file included from include/linux/cgroup.h:26:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:11:
In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/hexagon/include/asm/io.h:334:
include/asm-generic/io.h:547:31: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
547 | val = __raw_readb(PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:560:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
560 | val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/little_endian.h:37:51: note: expanded from macro '__le16_to_cpu'
37 | #define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
| ^
In file included from drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c:22:
In file included from include/linux/i2c.h:19:
In file included from include/linux/regulator/consumer.h:35:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:13:
In file included from include/linux/cgroup.h:26:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:11:
In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/hexagon/include/asm/io.h:334:
include/asm-generic/io.h:573:61: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
573 | val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
| ~~~~~~~~~~ ^
include/uapi/linux/byteorder/little_endian.h:35:51: note: expanded from macro '__le32_to_cpu'
35 | #define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
| ^
In file included from drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c:22:
In file included from include/linux/i2c.h:19:
In file included from include/linux/regulator/consumer.h:35:
In file included from include/linux/suspend.h:5:
In file included from include/linux/swap.h:9:
In file included from include/linux/memcontrol.h:13:
In file included from include/linux/cgroup.h:26:
In file included from include/linux/kernel_stat.h:9:
In file included from include/linux/interrupt.h:11:
In file included from include/linux/hardirq.h:11:
In file included from ./arch/hexagon/include/generated/asm/hardirq.h:1:
In file included from include/asm-generic/hardirq.h:17:
In file included from include/linux/irq.h:20:
In file included from include/linux/io.h:13:
In file included from arch/hexagon/include/asm/io.h:334:
include/asm-generic/io.h:584:33: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
584 | __raw_writeb(value, PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:594:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
594 | __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
include/asm-generic/io.h:604:59: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
604 | __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
| ~~~~~~~~~~ ^
>> drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c:101:65: error: too many arguments to function call, expected 3, have 4
101 | return drm_do_get_edid(connector, stdp2690_read_block, client, NULL);
| ~~~~~~~~~~~~~~~ ^~~~
include/linux/stddef.h:8:14: note: expanded from macro 'NULL'
8 | #define NULL ((void *)0)
| ^~~~~~~~~~~
include/drm/drm_edid.h:568:14: note: 'drm_do_get_edid' declared here
568 | struct edid *drm_do_get_edid(struct drm_connector *connector,
| ^
6 warnings and 1 error generated.
vim +101 drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
93
94 static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
95 struct drm_connector *connector)
96 {
97 struct i2c_client *client;
98
99 client = ge_b850v3_lvds_ptr->stdp2690_i2c;
100
> 101 return drm_do_get_edid(connector, stdp2690_read_block, client, NULL);
102 }
103
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-01 10:24 [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid() Jani Nikula
2023-09-01 14:45 ` kernel test robot
@ 2023-09-01 14:52 ` Jani Nikula
2023-09-08 9:13 ` EXT: " Ian Ray
2023-09-01 16:09 ` kernel test robot
` (2 subsequent siblings)
4 siblings, 1 reply; 12+ messages in thread
From: Jani Nikula @ 2023-09-01 14:52 UTC (permalink / raw)
To: dri-devel
Cc: Neil Armstrong, Zheyu Ma, Robert Foss, Martyn Welch,
Jonas Karlman, Peter Senna Tschudin, Yuan Can, Jernej Skrabec,
Ian Ray, Laurent Pinchart, Andrzej Hajda, Martin Donnelly
On Fri, 01 Sep 2023, Jani Nikula <jani.nikula@intel.com> wrote:
> The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
> Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
> look up the discussion, but didn't find anyone questioning the EDID
> reading part.
>
> Why does it not use drm_get_edid() or drm_do_get_edid()?
>
> I don't know where client->addr comes from, so I guess it could be
> different from DDC_ADDR, rendering drm_get_edid() unusable.
>
> There's also the comment:
>
> /* Yes, read the entire buffer, and do not skip the first
> * EDID_LENGTH bytes.
> */
>
> But again, there's not a word on *why*.
>
> Maybe we could just use drm_do_get_edid()? I'd like drivers to migrate
> away from their own EDID parsing and validity checks, including stop
> using drm_edid_block_valid(). (And long term switch to drm_edid_read(),
> struct drm_edid, and friends, but this is the first step.)
>
> Cc: Andrzej Hajda <andrzej.hajda@intel.com>
> Cc: Ian Ray <ian.ray@ge.com>
> Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> Cc: Jonas Karlman <jonas@kwiboo.se>
> Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> Cc: Martin Donnelly <martin.donnelly@ge.com>
> Cc: Martyn Welch <martyn.welch@collabora.co.uk>
> Cc: Neil Armstrong <neil.armstrong@linaro.org>
> Cc: Peter Senna Tschudin <peter.senna@gmail.com>
> Cc: Robert Foss <rfoss@kernel.org>
> Cc: Yuan Can <yuancan@huawei.com>
> Cc: Zheyu Ma <zheyuma97@gmail.com>
> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>
> ---
>
> I haven't even tried to compile this, and I have no way to test
> this. Apologies for the long Cc list; I'm hoping someone could explain
> the existing code, and perhaps give this approach a spin.
> ---
> .../bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 57 +++----------------
> 1 file changed, 9 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
> index 460db3c8a08c..0d9eacf3d9b7 100644
> --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
> +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
> @@ -65,12 +65,11 @@ struct ge_b850v3_lvds {
>
> static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;
>
> -static u8 *stdp2690_get_edid(struct i2c_client *client)
> +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len)
> {
> + struct i2c_client *client = context;
> struct i2c_adapter *adapter = client->adapter;
> - unsigned char start = 0x00;
> - unsigned int total_size;
> - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL);
> + unsigned char start = block * EDID_LENGTH;
>
> struct i2c_msg msgs[] = {
> {
> @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client)
> }, {
> .addr = client->addr,
> .flags = I2C_M_RD,
> - .len = EDID_LENGTH,
> - .buf = block,
> + .len = len,
> + .buf = buf,
> }
> };
>
> - if (!block)
> - return NULL;
> + if (i2c_transfer(adapter, msgs, 2) != 2)
> + return -1;
>
> - if (i2c_transfer(adapter, msgs, 2) != 2) {
> - DRM_ERROR("Unable to read EDID.\n");
> - goto err;
> - }
> -
> - if (!drm_edid_block_valid(block, 0, false, NULL)) {
> - DRM_ERROR("Invalid EDID data\n");
> - goto err;
> - }
> -
> - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH;
> - if (total_size > EDID_LENGTH) {
> - kfree(block);
> - block = kmalloc(total_size, GFP_KERNEL);
> - if (!block)
> - return NULL;
> -
> - /* Yes, read the entire buffer, and do not skip the first
> - * EDID_LENGTH bytes.
> - */
> - start = 0x00;
> - msgs[1].len = total_size;
> - msgs[1].buf = block;
> -
> - if (i2c_transfer(adapter, msgs, 2) != 2) {
> - DRM_ERROR("Unable to read EDID extension blocks.\n");
> - goto err;
> - }
> - if (!drm_edid_block_valid(block, 1, false, NULL)) {
> - DRM_ERROR("Invalid EDID data\n");
> - goto err;
> - }
> - }
> -
> - return block;
> -
> -err:
> - kfree(block);
> - return NULL;
> + return 0;
> }
>
> static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
> @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
>
> client = ge_b850v3_lvds_ptr->stdp2690_i2c;
>
> - return (struct edid *)stdp2690_get_edid(client);
> + return drm_do_get_edid(connector, stdp2690_read_block, client, NULL);
The last NULL param should be dropped, as noted by the build bot.
BR,
Jani.
> }
>
> static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
--
Jani Nikula, Intel Open Source Graphics Center
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: EXT: Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-01 14:52 ` Jani Nikula
@ 2023-09-08 9:13 ` Ian Ray
2023-09-12 12:17 ` Jani Nikula
0 siblings, 1 reply; 12+ messages in thread
From: Ian Ray @ 2023-09-08 9:13 UTC (permalink / raw)
To: Jani Nikula
Cc: Neil Armstrong, Zheyu Ma, Robert Foss, Martyn Welch,
Jonas Karlman, dri-devel, Peter Senna Tschudin, Yuan Can,
Jernej Skrabec, Ian Ray, Laurent Pinchart, Andrzej Hajda
On Fri, Sep 01, 2023 at 05:52:02PM +0300, Jani Nikula wrote:
>
> On Fri, 01 Sep 2023, Jani Nikula <jani.nikula@intel.com> wrote:
> > The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
> > Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
> > look up the discussion, but didn't find anyone questioning the EDID
> > reading part.
> >
> > Why does it not use drm_get_edid() or drm_do_get_edid()?
> >
> > I don't know where client->addr comes from, so I guess it could be
> > different from DDC_ADDR, rendering drm_get_edid() unusable.
> >
> > There's also the comment:
> >
> > /* Yes, read the entire buffer, and do not skip the first
> > * EDID_LENGTH bytes.
> > */
> >
> > But again, there's not a word on *why*.
> >
> > Maybe we could just use drm_do_get_edid()? I'd like drivers to migrate
> > away from their own EDID parsing and validity checks, including stop
> > using drm_edid_block_valid(). (And long term switch to drm_edid_read(),
> > struct drm_edid, and friends, but this is the first step.)
> >
> > Cc: Andrzej Hajda <andrzej.hajda@intel.com>
> > Cc: Ian Ray <ian.ray@ge.com>
> > Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
> > Cc: Jonas Karlman <jonas@kwiboo.se>
> > Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
> > Cc: Martin Donnelly <martin.donnelly@ge.com>
> > Cc: Martyn Welch <martyn.welch@collabora.co.uk>
> > Cc: Neil Armstrong <neil.armstrong@linaro.org>
> > Cc: Peter Senna Tschudin <peter.senna@gmail.com>
> > Cc: Robert Foss <rfoss@kernel.org>
> > Cc: Yuan Can <yuancan@huawei.com>
> > Cc: Zheyu Ma <zheyuma97@gmail.com>
> > Signed-off-by: Jani Nikula <jani.nikula@intel.com>
> >
> > ---
> >
> > I haven't even tried to compile this, and I have no way to test
> > this. Apologies for the long Cc list; I'm hoping someone could explain
> > the existing code, and perhaps give this approach a spin.
> > ---
> > .../bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 57 +++----------------
> > 1 file changed, 9 insertions(+), 48 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
> > index 460db3c8a08c..0d9eacf3d9b7 100644
> > --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
> > +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
> > @@ -65,12 +65,11 @@ struct ge_b850v3_lvds {
> >
> > static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;
> >
> > -static u8 *stdp2690_get_edid(struct i2c_client *client)
> > +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len)
> > {
> > + struct i2c_client *client = context;
> > struct i2c_adapter *adapter = client->adapter;
> > - unsigned char start = 0x00;
> > - unsigned int total_size;
> > - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL);
> > + unsigned char start = block * EDID_LENGTH;
> >
> > struct i2c_msg msgs[] = {
> > {
> > @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client)
> > }, {
> > .addr = client->addr,
> > .flags = I2C_M_RD,
> > - .len = EDID_LENGTH,
> > - .buf = block,
> > + .len = len,
> > + .buf = buf,
> > }
> > };
> >
> > - if (!block)
> > - return NULL;
> > + if (i2c_transfer(adapter, msgs, 2) != 2)
> > + return -1;
> >
> > - if (i2c_transfer(adapter, msgs, 2) != 2) {
> > - DRM_ERROR("Unable to read EDID.\n");
> > - goto err;
> > - }
> > -
> > - if (!drm_edid_block_valid(block, 0, false, NULL)) {
> > - DRM_ERROR("Invalid EDID data\n");
> > - goto err;
> > - }
> > -
> > - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH;
> > - if (total_size > EDID_LENGTH) {
> > - kfree(block);
> > - block = kmalloc(total_size, GFP_KERNEL);
> > - if (!block)
> > - return NULL;
> > -
> > - /* Yes, read the entire buffer, and do not skip the first
> > - * EDID_LENGTH bytes.
> > - */
> > - start = 0x00;
> > - msgs[1].len = total_size;
> > - msgs[1].buf = block;
> > -
> > - if (i2c_transfer(adapter, msgs, 2) != 2) {
> > - DRM_ERROR("Unable to read EDID extension blocks.\n");
> > - goto err;
> > - }
> > - if (!drm_edid_block_valid(block, 1, false, NULL)) {
> > - DRM_ERROR("Invalid EDID data\n");
> > - goto err;
> > - }
> > - }
> > -
> > - return block;
> > -
> > -err:
> > - kfree(block);
> > - return NULL;
> > + return 0;
> > }
> >
> > static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
> > @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
> >
> > client = ge_b850v3_lvds_ptr->stdp2690_i2c;
> >
> > - return (struct edid *)stdp2690_get_edid(client);
> > + return drm_do_get_edid(connector, stdp2690_read_block, client, NULL);
>
> The last NULL param should be dropped, as noted by the build bot.
Tested with various displays, including displays that have one block of
EDID (DELL P2417H) and a second EDID extension block (VES/55UHD_LCD_TV).
Tested-by: Ian Ray <ian.ray@ge.com>
Would you like me to submit the patch Jani?
>
> BR,
> Jani.
>
>
> > }
> >
> > static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
>
> --
> Jani Nikula, Intel Open Source Graphics Center
>
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: EXT: Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-08 9:13 ` EXT: " Ian Ray
@ 2023-09-12 12:17 ` Jani Nikula
0 siblings, 0 replies; 12+ messages in thread
From: Jani Nikula @ 2023-09-12 12:17 UTC (permalink / raw)
To: Ian Ray
Cc: Neil Armstrong, Peter Senna Tschudin, Robert Foss, Martyn Welch,
Jonas Karlman, Zheyu Ma, Yuan Can, dri-devel, Ian Ray,
Jernej Skrabec, Andrzej Hajda, Laurent Pinchart
On Fri, 08 Sep 2023, Ian Ray <ian.ray@ge.com> wrote:
> On Fri, Sep 01, 2023 at 05:52:02PM +0300, Jani Nikula wrote:
>>
>> On Fri, 01 Sep 2023, Jani Nikula <jani.nikula@intel.com> wrote:
>> > The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
>> > Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
>> > look up the discussion, but didn't find anyone questioning the EDID
>> > reading part.
>> >
>> > Why does it not use drm_get_edid() or drm_do_get_edid()?
>> >
>> > I don't know where client->addr comes from, so I guess it could be
>> > different from DDC_ADDR, rendering drm_get_edid() unusable.
>> >
>> > There's also the comment:
>> >
>> > /* Yes, read the entire buffer, and do not skip the first
>> > * EDID_LENGTH bytes.
>> > */
>> >
>> > But again, there's not a word on *why*.
>> >
>> > Maybe we could just use drm_do_get_edid()? I'd like drivers to migrate
>> > away from their own EDID parsing and validity checks, including stop
>> > using drm_edid_block_valid(). (And long term switch to drm_edid_read(),
>> > struct drm_edid, and friends, but this is the first step.)
>> >
>> > Cc: Andrzej Hajda <andrzej.hajda@intel.com>
>> > Cc: Ian Ray <ian.ray@ge.com>
>> > Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
>> > Cc: Jonas Karlman <jonas@kwiboo.se>
>> > Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
>> > Cc: Martin Donnelly <martin.donnelly@ge.com>
>> > Cc: Martyn Welch <martyn.welch@collabora.co.uk>
>> > Cc: Neil Armstrong <neil.armstrong@linaro.org>
>> > Cc: Peter Senna Tschudin <peter.senna@gmail.com>
>> > Cc: Robert Foss <rfoss@kernel.org>
>> > Cc: Yuan Can <yuancan@huawei.com>
>> > Cc: Zheyu Ma <zheyuma97@gmail.com>
>> > Signed-off-by: Jani Nikula <jani.nikula@intel.com>
>> >
>> > ---
>> >
>> > I haven't even tried to compile this, and I have no way to test
>> > this. Apologies for the long Cc list; I'm hoping someone could explain
>> > the existing code, and perhaps give this approach a spin.
>> > ---
>> > .../bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 57 +++----------------
>> > 1 file changed, 9 insertions(+), 48 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
>> > index 460db3c8a08c..0d9eacf3d9b7 100644
>> > --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
>> > +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
>> > @@ -65,12 +65,11 @@ struct ge_b850v3_lvds {
>> >
>> > static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;
>> >
>> > -static u8 *stdp2690_get_edid(struct i2c_client *client)
>> > +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len)
>> > {
>> > + struct i2c_client *client = context;
>> > struct i2c_adapter *adapter = client->adapter;
>> > - unsigned char start = 0x00;
>> > - unsigned int total_size;
>> > - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL);
>> > + unsigned char start = block * EDID_LENGTH;
>> >
>> > struct i2c_msg msgs[] = {
>> > {
>> > @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client)
>> > }, {
>> > .addr = client->addr,
>> > .flags = I2C_M_RD,
>> > - .len = EDID_LENGTH,
>> > - .buf = block,
>> > + .len = len,
>> > + .buf = buf,
>> > }
>> > };
>> >
>> > - if (!block)
>> > - return NULL;
>> > + if (i2c_transfer(adapter, msgs, 2) != 2)
>> > + return -1;
>> >
>> > - if (i2c_transfer(adapter, msgs, 2) != 2) {
>> > - DRM_ERROR("Unable to read EDID.\n");
>> > - goto err;
>> > - }
>> > -
>> > - if (!drm_edid_block_valid(block, 0, false, NULL)) {
>> > - DRM_ERROR("Invalid EDID data\n");
>> > - goto err;
>> > - }
>> > -
>> > - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH;
>> > - if (total_size > EDID_LENGTH) {
>> > - kfree(block);
>> > - block = kmalloc(total_size, GFP_KERNEL);
>> > - if (!block)
>> > - return NULL;
>> > -
>> > - /* Yes, read the entire buffer, and do not skip the first
>> > - * EDID_LENGTH bytes.
>> > - */
>> > - start = 0x00;
>> > - msgs[1].len = total_size;
>> > - msgs[1].buf = block;
>> > -
>> > - if (i2c_transfer(adapter, msgs, 2) != 2) {
>> > - DRM_ERROR("Unable to read EDID extension blocks.\n");
>> > - goto err;
>> > - }
>> > - if (!drm_edid_block_valid(block, 1, false, NULL)) {
>> > - DRM_ERROR("Invalid EDID data\n");
>> > - goto err;
>> > - }
>> > - }
>> > -
>> > - return block;
>> > -
>> > -err:
>> > - kfree(block);
>> > - return NULL;
>> > + return 0;
>> > }
>> >
>> > static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
>> > @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
>> >
>> > client = ge_b850v3_lvds_ptr->stdp2690_i2c;
>> >
>> > - return (struct edid *)stdp2690_get_edid(client);
>> > + return drm_do_get_edid(connector, stdp2690_read_block, client, NULL);
>>
>> The last NULL param should be dropped, as noted by the build bot.
>
> Tested with various displays, including displays that have one block of
> EDID (DELL P2417H) and a second EDID extension block (VES/55UHD_LCD_TV).
>
> Tested-by: Ian Ray <ian.ray@ge.com>
>
> Would you like me to submit the patch Jani?
If you have the time to take that on, by all means!
Thanks for testing!
BR,
Jani
>
>
>>
>> BR,
>> Jani.
>>
>>
>> > }
>> >
>> > static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
>>
>> --
>> Jani Nikula, Intel Open Source Graphics Center
>>
--
Jani Nikula, Intel
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-01 10:24 [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid() Jani Nikula
2023-09-01 14:45 ` kernel test robot
2023-09-01 14:52 ` Jani Nikula
@ 2023-09-01 16:09 ` kernel test robot
2023-09-02 5:39 ` Peter Senna Tschudin
2023-10-06 9:54 ` [PATCH v2] " Jani Nikula
4 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2023-09-01 16:09 UTC (permalink / raw)
To: Jani Nikula; +Cc: llvm, oe-kbuild-all
Hi Jani,
[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:
[auto build test ERROR on drm-misc/drm-misc-next]
[also build test ERROR on drm/drm-next drm-exynos/exynos-drm-next drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-tip/drm-tip linus/master v6.5 next-20230831]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Jani-Nikula/drm-bridge-megachips-stdpxxxx-ge-b850v3-fw-switch-to-drm_do_get_edid/20230901-182521
base: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next
patch link: https://lore.kernel.org/r/20230901102400.552254-1-jani.nikula%40intel.com
patch subject: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
config: x86_64-randconfig-072-20230901 (https://download.01.org/0day-ci/archive/20230902/202309020015.A2hvv45r-lkp@intel.com/config)
compiler: clang version 16.0.4 (https://github.com/llvm/llvm-project.git ae42196bc493ffe877a7e3dff8be32035dea4d07)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20230902/202309020015.A2hvv45r-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202309020015.A2hvv45r-lkp@intel.com/
All errors (new ones prefixed by >>):
>> drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c:101:65: error: too many arguments to function call, expected 3, have 4
return drm_do_get_edid(connector, stdp2690_read_block, client, NULL);
~~~~~~~~~~~~~~~ ^~~~
include/linux/stddef.h:8:14: note: expanded from macro 'NULL'
#define NULL ((void *)0)
^~~~~~~~~~~
include/drm/drm_edid.h:568:14: note: 'drm_do_get_edid' declared here
struct edid *drm_do_get_edid(struct drm_connector *connector,
^
1 error generated.
vim +101 drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
93
94 static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
95 struct drm_connector *connector)
96 {
97 struct i2c_client *client;
98
99 client = ge_b850v3_lvds_ptr->stdp2690_i2c;
100
> 101 return drm_do_get_edid(connector, stdp2690_read_block, client, NULL);
102 }
103
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-01 10:24 [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid() Jani Nikula
` (2 preceding siblings ...)
2023-09-01 16:09 ` kernel test robot
@ 2023-09-02 5:39 ` Peter Senna Tschudin
2023-09-04 10:04 ` Jani Nikula
2023-10-06 9:54 ` [PATCH v2] " Jani Nikula
4 siblings, 1 reply; 12+ messages in thread
From: Peter Senna Tschudin @ 2023-09-02 5:39 UTC (permalink / raw)
To: Jani Nikula
Cc: Neil Armstrong, Robert Foss, Martyn Welch, Jonas Karlman,
dri-devel, Zheyu Ma, Yuan Can, Jernej Skrabec, Ian Ray,
Laurent Pinchart, Andrzej Hajda, Martin Donnelly
Good morning Jani,
It has been a long time since I wrote the driver, and many many years
since I sent my last kernel patch, so my memory does not serve me very
well, but I will try to shed some light.
On Fri, Sep 1, 2023 at 12:24 PM Jani Nikula <jani.nikula@intel.com> wrote:
>
> The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
> Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
> look up the discussion, but didn't find anyone questioning the EDID
> reading part.
>
> Why does it not use drm_get_edid() or drm_do_get_edid()?
>
> I don't know where client->addr comes from, so I guess it could be
> different from DDC_ADDR, rendering drm_get_edid() unusable.
>
> There's also the comment:
>
> /* Yes, read the entire buffer, and do not skip the first
> * EDID_LENGTH bytes.
> */
>
> But again, there's not a word on *why*.
The video pipeline has two hardware bridges between the LVDS from the
SoC and DP+ output. For reasons, we would get hot plug events from one
of these bridges, and EDID from the other. If I am not mistaken, I
documented this strangeness in the DTS readme file.
Did this shed any light on the *why* or did I tell you something you
already knew?
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-02 5:39 ` Peter Senna Tschudin
@ 2023-09-04 10:04 ` Jani Nikula
2023-09-04 11:40 ` EXT: " Ian Ray
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Jani Nikula @ 2023-09-04 10:04 UTC (permalink / raw)
To: Peter Senna Tschudin
Cc: Neil Armstrong, Robert Foss, Martyn Welch, Jonas Karlman,
dri-devel, Zheyu Ma, Yuan Can, Jernej Skrabec, Ian Ray,
Laurent Pinchart, Andrzej Hajda, Martin Donnelly
On Sat, 02 Sep 2023, Peter Senna Tschudin <peter.senna@gmail.com> wrote:
> Good morning Jani,
>
> It has been a long time since I wrote the driver, and many many years
> since I sent my last kernel patch, so my memory does not serve me very
> well, but I will try to shed some light.
>
> On Fri, Sep 1, 2023 at 12:24 PM Jani Nikula <jani.nikula@intel.com> wrote:
>>
>> The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
>> Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
>> look up the discussion, but didn't find anyone questioning the EDID
>> reading part.
>>
>> Why does it not use drm_get_edid() or drm_do_get_edid()?
>>
>> I don't know where client->addr comes from, so I guess it could be
>> different from DDC_ADDR, rendering drm_get_edid() unusable.
>>
>> There's also the comment:
>>
>> /* Yes, read the entire buffer, and do not skip the first
>> * EDID_LENGTH bytes.
>> */
>>
>> But again, there's not a word on *why*.
>
> The video pipeline has two hardware bridges between the LVDS from the
> SoC and DP+ output. For reasons, we would get hot plug events from one
> of these bridges, and EDID from the other. If I am not mistaken, I
> documented this strangeness in the DTS readme file.
>
> Did this shed any light on the *why* or did I tell you something you
> already knew?
I guess that answers the question why it's necessary to specify the ddc
to use, but not why drm_do_get_edid() could not be used. Is it really
necessary to read the EDID in one go?
BR,
Jani.
--
Jani Nikula, Intel Open Source Graphics Center
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: EXT: Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-04 10:04 ` Jani Nikula
@ 2023-09-04 11:40 ` Ian Ray
2023-09-04 13:09 ` Laurent Pinchart
2023-09-04 13:45 ` Peter Senna Tschudin
2 siblings, 0 replies; 12+ messages in thread
From: Ian Ray @ 2023-09-04 11:40 UTC (permalink / raw)
To: Jani Nikula
Cc: Neil Armstrong, Zheyu Ma, Robert Foss, Martyn Welch,
Jonas Karlman, dri-devel, Peter Senna Tschudin, Yuan Can,
Jernej Skrabec, Laurent Pinchart, Andrzej Hajda, Martin Donnelly
On Mon, Sep 04, 2023 at 01:04:40PM +0300, Jani Nikula wrote:
>
> On Sat, 02 Sep 2023, Peter Senna Tschudin <peter.senna@gmail.com> wrote:
> > Good morning Jani,
> >
> > It has been a long time since I wrote the driver, and many many years
> > since I sent my last kernel patch, so my memory does not serve me very
> > well, but I will try to shed some light.
> >
> > On Fri, Sep 1, 2023 at 12:24 PM Jani Nikula <jani.nikula@intel.com> wrote:
> >>
> >> The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
> >> Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
> >> look up the discussion, but didn't find anyone questioning the EDID
> >> reading part.
> >>
> >> Why does it not use drm_get_edid() or drm_do_get_edid()?
> >>
> >> I don't know where client->addr comes from, so I guess it could be
> >> different from DDC_ADDR, rendering drm_get_edid() unusable.
> >>
> >> There's also the comment:
> >>
> >> /* Yes, read the entire buffer, and do not skip the first
> >> * EDID_LENGTH bytes.
> >> */
> >>
> >> But again, there's not a word on *why*.
> >
> > The video pipeline has two hardware bridges between the LVDS from the
> > SoC and DP+ output. For reasons, we would get hot plug events from one
> > of these bridges, and EDID from the other. If I am not mistaken, I
> > documented this strangeness in the DTS readme file.
> >
> > Did this shed any light on the *why* or did I tell you something you
> > already knew?
>
> I guess that answers the question why it's necessary to specify the ddc
> to use, but not why drm_do_get_edid() could not be used. Is it really
> necessary to read the EDID in one go?
Moi Jani,
Sorry for slow reply -- I will look into this during this week. I would
hope and expect that we could use common APIs.
>
> BR,
> Jani.
>
> --
> Jani Nikula, Intel Open Source Graphics Center
>
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-04 10:04 ` Jani Nikula
2023-09-04 11:40 ` EXT: " Ian Ray
@ 2023-09-04 13:09 ` Laurent Pinchart
2023-09-04 13:45 ` Peter Senna Tschudin
2 siblings, 0 replies; 12+ messages in thread
From: Laurent Pinchart @ 2023-09-04 13:09 UTC (permalink / raw)
To: Jani Nikula
Cc: Neil Armstrong, Zheyu Ma, Robert Foss, Martyn Welch,
Jonas Karlman, Peter Senna Tschudin, Yuan Can, Jernej Skrabec,
Ian Ray, dri-devel, Andrzej Hajda, Martin Donnelly
On Mon, Sep 04, 2023 at 01:04:40PM +0300, Jani Nikula wrote:
> On Sat, 02 Sep 2023, Peter Senna Tschudin wrote:
> > Good morning Jani,
> >
> > It has been a long time since I wrote the driver, and many many years
> > since I sent my last kernel patch, so my memory does not serve me very
> > well, but I will try to shed some light.
> >
> > On Fri, Sep 1, 2023 at 12:24 PM Jani Nikula wrote:
> >>
> >> The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
> >> Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
> >> look up the discussion, but didn't find anyone questioning the EDID
> >> reading part.
> >>
> >> Why does it not use drm_get_edid() or drm_do_get_edid()?
> >>
> >> I don't know where client->addr comes from, so I guess it could be
> >> different from DDC_ADDR, rendering drm_get_edid() unusable.
> >>
> >> There's also the comment:
> >>
> >> /* Yes, read the entire buffer, and do not skip the first
> >> * EDID_LENGTH bytes.
> >> */
> >>
> >> But again, there's not a word on *why*.
> >
> > The video pipeline has two hardware bridges between the LVDS from the
> > SoC and DP+ output. For reasons, we would get hot plug events from one
> > of these bridges, and EDID from the other. If I am not mistaken, I
> > documented this strangeness in the DTS readme file.
This should be supported properly by the drm_bridge_connector helper,
which supports delegating HPD and EDID retrieval to different bridges.
> > Did this shed any light on the *why* or did I tell you something you
> > already knew?
>
> I guess that answers the question why it's necessary to specify the ddc
> to use, but not why drm_do_get_edid() could not be used. Is it really
> necessary to read the EDID in one go?
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-04 10:04 ` Jani Nikula
2023-09-04 11:40 ` EXT: " Ian Ray
2023-09-04 13:09 ` Laurent Pinchart
@ 2023-09-04 13:45 ` Peter Senna Tschudin
2 siblings, 0 replies; 12+ messages in thread
From: Peter Senna Tschudin @ 2023-09-04 13:45 UTC (permalink / raw)
To: Jani Nikula
Cc: Neil Armstrong, Robert Foss, Martyn Welch, Jonas Karlman,
dri-devel, Zheyu Ma, Yuan Can, Jernej Skrabec, Ian Ray,
Laurent Pinchart, Andrzej Hajda, Martin Donnelly
On Mon, Sep 4, 2023 at 12:16 PM Jani Nikula <jani.nikula@intel.com> wrote:
>
> On Sat, 02 Sep 2023, Peter Senna Tschudin <peter.senna@gmail.com> wrote:
> > Good morning Jani,
> >
> > It has been a long time since I wrote the driver, and many many years
> > since I sent my last kernel patch, so my memory does not serve me very
> > well, but I will try to shed some light.
> >
> > On Fri, Sep 1, 2023 at 12:24 PM Jani Nikula <jani.nikula@intel.com> wrote:
> >>
> >> The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
> >> Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
> >> look up the discussion, but didn't find anyone questioning the EDID
> >> reading part.
> >>
> >> Why does it not use drm_get_edid() or drm_do_get_edid()?
> >>
> >> I don't know where client->addr comes from, so I guess it could be
> >> different from DDC_ADDR, rendering drm_get_edid() unusable.
> >>
> >> There's also the comment:
> >>
> >> /* Yes, read the entire buffer, and do not skip the first
> >> * EDID_LENGTH bytes.
> >> */
> >>
> >> But again, there's not a word on *why*.
> >
> > The video pipeline has two hardware bridges between the LVDS from the
> > SoC and DP+ output. For reasons, we would get hot plug events from one
> > of these bridges, and EDID from the other. If I am not mistaken, I
> > documented this strangeness in the DTS readme file.
> >
> > Did this shed any light on the *why* or did I tell you something you
> > already knew?
>
> I guess that answers the question why it's necessary to specify the ddc
> to use, but not why drm_do_get_edid() could not be used. Is it really
> necessary to read the EDID in one go?
I have a very weak recollection about hotplug and EDID issues with the
LVDS driver. I am not very confident about this, but maybe I needed to
find ways to read EDID early enough to please the LVDS display driver
during the LVDS driver startup.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid()
2023-09-01 10:24 [RFC] drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid() Jani Nikula
` (3 preceding siblings ...)
2023-09-02 5:39 ` Peter Senna Tschudin
@ 2023-10-06 9:54 ` Jani Nikula
4 siblings, 0 replies; 12+ messages in thread
From: Jani Nikula @ 2023-10-06 9:54 UTC (permalink / raw)
To: dri-devel
Cc: Neil Armstrong, Zheyu Ma, Robert Foss, Martyn Welch,
Jonas Karlman, Jani Nikula, Peter Senna Tschudin, Yuan Can,
Jernej Skrabec, Ian Ray, Laurent Pinchart, Andrzej Hajda,
Martin Donnelly
The driver was originally added in commit fcfa0ddc18ed ("drm/bridge:
Drivers for megachips-stdpxxxx-ge-b850v3-fw (LVDS-DP++)"). I tried to
look up the discussion, but didn't find anyone questioning the EDID
reading part.
Why does it not use drm_get_edid() or drm_do_get_edid()?
I don't know where client->addr comes from, so I guess it could be
different from DDC_ADDR, rendering drm_get_edid() unusable.
There's also the comment:
/* Yes, read the entire buffer, and do not skip the first
* EDID_LENGTH bytes.
*/
But again, there's not a word on *why*.
Maybe we could just use drm_do_get_edid()? I'd like drivers to migrate
away from their own EDID parsing and validity checks, including stop
using drm_edid_block_valid(). (And long term switch to drm_edid_read(),
struct drm_edid, and friends, but this is the first step.)
v2: Fix build
Cc: Andrzej Hajda <andrzej.hajda@intel.com>
Cc: Ian Ray <ian.ray@ge.com>
Cc: Jernej Skrabec <jernej.skrabec@gmail.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>
Cc: Martin Donnelly <martin.donnelly@ge.com>
Cc: Martyn Welch <martyn.welch@collabora.co.uk>
Cc: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Peter Senna Tschudin <peter.senna@gmail.com>
Cc: Robert Foss <rfoss@kernel.org>
Cc: Yuan Can <yuancan@huawei.com>
Cc: Zheyu Ma <zheyuma97@gmail.com>
Tested-by: Ian Ray <ian.ray@ge.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
---
I haven't even tried to compile this, and I have no way to test
this. Apologies for the long Cc list; I'm hoping someone could explain
the existing code, and perhaps give this approach a spin.
---
.../bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 57 +++----------------
1 file changed, 9 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
index 460db3c8a08c..e93083bbec9d 100644
--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
+++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c
@@ -65,12 +65,11 @@ struct ge_b850v3_lvds {
static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;
-static u8 *stdp2690_get_edid(struct i2c_client *client)
+static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len)
{
+ struct i2c_client *client = context;
struct i2c_adapter *adapter = client->adapter;
- unsigned char start = 0x00;
- unsigned int total_size;
- u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL);
+ unsigned char start = block * EDID_LENGTH;
struct i2c_msg msgs[] = {
{
@@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client)
}, {
.addr = client->addr,
.flags = I2C_M_RD,
- .len = EDID_LENGTH,
- .buf = block,
+ .len = len,
+ .buf = buf,
}
};
- if (!block)
- return NULL;
+ if (i2c_transfer(adapter, msgs, 2) != 2)
+ return -1;
- if (i2c_transfer(adapter, msgs, 2) != 2) {
- DRM_ERROR("Unable to read EDID.\n");
- goto err;
- }
-
- if (!drm_edid_block_valid(block, 0, false, NULL)) {
- DRM_ERROR("Invalid EDID data\n");
- goto err;
- }
-
- total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH;
- if (total_size > EDID_LENGTH) {
- kfree(block);
- block = kmalloc(total_size, GFP_KERNEL);
- if (!block)
- return NULL;
-
- /* Yes, read the entire buffer, and do not skip the first
- * EDID_LENGTH bytes.
- */
- start = 0x00;
- msgs[1].len = total_size;
- msgs[1].buf = block;
-
- if (i2c_transfer(adapter, msgs, 2) != 2) {
- DRM_ERROR("Unable to read EDID extension blocks.\n");
- goto err;
- }
- if (!drm_edid_block_valid(block, 1, false, NULL)) {
- DRM_ERROR("Invalid EDID data\n");
- goto err;
- }
- }
-
- return block;
-
-err:
- kfree(block);
- return NULL;
+ return 0;
}
static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
@@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
client = ge_b850v3_lvds_ptr->stdp2690_i2c;
- return (struct edid *)stdp2690_get_edid(client);
+ return drm_do_get_edid(connector, stdp2690_read_block, client);
}
static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
--
2.39.2
^ permalink raw reply related [flat|nested] 12+ messages in thread