Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-09-22 Thread Thomas Zimmermann

Hi

Am 22.09.22 um 09:28 schrieb Maxime Ripard:

On Thu, Sep 22, 2022 at 08:42:23AM +0200, Thomas Zimmermann wrote:

Hi

Am 21.09.22 um 18:48 schrieb Geert Uytterhoeven:

Hi Thomas,

On Wed, Sep 21, 2022 at 2:55 PM Thomas Zimmermann  wrote:

Am 05.08.22 um 02:19 schrieb Benjamin Herrenschmidt:

On Wed, 2022-07-20 at 16:27 +0200, Thomas Zimmermann wrote:

+#if !defined(CONFIG_PPC)
+static inline void out_8(void __iomem *addr, int val)
+{ }
+static inline void out_le32(void __iomem *addr, int val)
+{ }
+static inline unsigned int in_le32(const void __iomem *addr)
+{
+   return 0;
+}
+#endif


These guys could just be replaced with readb/writel/readl respectively
(beware of the argument swap).


I only added them for COMPILE_TEST. There appears to be no portable
interface that implements out_le32() and in_le32()?


iowrite32() and ioread32()?


Do they always use little endian, as these *_le32 helpers do? I though they
use host byte order.


They use either outl or writel under the hood, which are always little-endian


I see. I'll replace the custom helpers.

Best regards
Thomas



Maxime


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-09-22 Thread Maxime Ripard
On Thu, Sep 22, 2022 at 08:42:23AM +0200, Thomas Zimmermann wrote:
> Hi
> 
> Am 21.09.22 um 18:48 schrieb Geert Uytterhoeven:
> > Hi Thomas,
> > 
> > On Wed, Sep 21, 2022 at 2:55 PM Thomas Zimmermann  
> > wrote:
> > > Am 05.08.22 um 02:19 schrieb Benjamin Herrenschmidt:
> > > > On Wed, 2022-07-20 at 16:27 +0200, Thomas Zimmermann wrote:
> > > > > +#if !defined(CONFIG_PPC)
> > > > > +static inline void out_8(void __iomem *addr, int val)
> > > > > +{ }
> > > > > +static inline void out_le32(void __iomem *addr, int val)
> > > > > +{ }
> > > > > +static inline unsigned int in_le32(const void __iomem *addr)
> > > > > +{
> > > > > +   return 0;
> > > > > +}
> > > > > +#endif
> > > > 
> > > > These guys could just be replaced with readb/writel/readl respectively
> > > > (beware of the argument swap).
> > > 
> > > I only added them for COMPILE_TEST. There appears to be no portable
> > > interface that implements out_le32() and in_le32()?
> > 
> > iowrite32() and ioread32()?
> 
> Do they always use little endian, as these *_le32 helpers do? I though they
> use host byte order.

They use either outl or writel under the hood, which are always little-endian

Maxime


signature.asc
Description: PGP signature


Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-09-22 Thread Thomas Zimmermann

Hi

Am 21.09.22 um 18:48 schrieb Geert Uytterhoeven:

Hi Thomas,

On Wed, Sep 21, 2022 at 2:55 PM Thomas Zimmermann  wrote:

Am 05.08.22 um 02:19 schrieb Benjamin Herrenschmidt:

On Wed, 2022-07-20 at 16:27 +0200, Thomas Zimmermann wrote:

+#if !defined(CONFIG_PPC)
+static inline void out_8(void __iomem *addr, int val)
+{ }
+static inline void out_le32(void __iomem *addr, int val)
+{ }
+static inline unsigned int in_le32(const void __iomem *addr)
+{
+   return 0;
+}
+#endif


These guys could just be replaced with readb/writel/readl respectively
(beware of the argument swap).


I only added them for COMPILE_TEST. There appears to be no portable
interface that implements out_le32() and in_le32()?


iowrite32() and ioread32()?


Do they always use little endian, as these *_le32 helpers do? I though 
they use host byte order.


Best regards
Thomas



Gr{oetje,eeting}s,

 Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
 -- Linus Torvalds


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-09-21 Thread Geert Uytterhoeven
Hi Thomas,

On Wed, Sep 21, 2022 at 2:55 PM Thomas Zimmermann  wrote:
> Am 05.08.22 um 02:19 schrieb Benjamin Herrenschmidt:
> > On Wed, 2022-07-20 at 16:27 +0200, Thomas Zimmermann wrote:
> >> +#if !defined(CONFIG_PPC)
> >> +static inline void out_8(void __iomem *addr, int val)
> >> +{ }
> >> +static inline void out_le32(void __iomem *addr, int val)
> >> +{ }
> >> +static inline unsigned int in_le32(const void __iomem *addr)
> >> +{
> >> +   return 0;
> >> +}
> >> +#endif
> >
> > These guys could just be replaced with readb/writel/readl respectively
> > (beware of the argument swap).
>
> I only added them for COMPILE_TEST. There appears to be no portable
> interface that implements out_le32() and in_le32()?

iowrite32() and ioread32()?

Gr{oetje,eeting}s,

Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds


Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-09-21 Thread Thomas Zimmermann

Hi

Am 05.08.22 um 02:19 schrieb Benjamin Herrenschmidt:

On Wed, 2022-07-20 at 16:27 +0200, Thomas Zimmermann wrote:

+#if !defined(CONFIG_PPC)
+static inline void out_8(void __iomem *addr, int val)
+{ }
+static inline void out_le32(void __iomem *addr, int val)
+{ }
+static inline unsigned int in_le32(const void __iomem *addr)
+{
+   return 0;
+}
+#endif


These guys could just be replaced with readb/writel/readl respectively
(beware of the argument swap).


I only added them for COMPILE_TEST. There appears to be no portable 
interface that implements out_le32() and in_le32()?


Best regards
Thomas



Cheers,
Ben.



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-08-04 Thread Benjamin Herrenschmidt
On Wed, 2022-07-27 at 10:41 +0200, Thomas Zimmermann wrote:
> 
> > > +static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
> > > +struct device_node *of_node,
> > > +u64 fb_base)
> > > +{
> > > + struct drm_device *dev = >dev;
> > > + u64 address;
> > > + void __iomem *cmap_base;
> > > +
> > > + address = fb_base & 0xff00ul;
> > > + address += 0x7ff000;
> > > +
> > 
> > It would be good to know where these addresses are coming from. Maybe some
> > constant macros or a comment ? Same for the other places where addresses
> > and offsets are used.
> 
> I have no idea where these values come from. I took them from offb. And 
> I suspect that some of these CMAP helpers could be further merged if 
> only it was clear where the numbers come from.  But as i don't have the 
> equipment for testing, I took most of this literally as-is from offb.

Ancient black magic :-) Old ATI mach64 chips had the registers sitting
at the end of the framebuffer. You can find an equivalent in
drivers/video/aty/atyfb_base.c:atyfb_setup_generic():

raddr = addr + 0x7ff000UL;

Cheers,
Ben.



Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-08-04 Thread Benjamin Herrenschmidt
On Wed, 2022-07-20 at 16:27 +0200, Thomas Zimmermann wrote:
> +#if !defined(CONFIG_PPC)
> +static inline void out_8(void __iomem *addr, int val)
> +{ }
> +static inline void out_le32(void __iomem *addr, int val)
> +{ }
> +static inline unsigned int in_le32(const void __iomem *addr)
> +{
> +   return 0;
> +}
> +#endif

These guys could just be replaced with readb/writel/readl respectively
(beware of the argument swap).

Cheers,
Ben.



Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-07-27 Thread Javier Martinez Canillas
On 7/27/22 10:41, Thomas Zimmermann wrote:

[...]

>>
>>> +static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
>>> +  struct device_node *of_node,
>>> +  u64 fb_base)
>>> +{
>>> +   struct drm_device *dev = >dev;
>>> +   u64 address;
>>> +   void __iomem *cmap_base;
>>> +
>>> +   address = fb_base & 0xff00ul;
>>> +   address += 0x7ff000;
>>> +
>>
>> It would be good to know where these addresses are coming from. Maybe some
>> constant macros or a comment ? Same for the other places where addresses
>> and offsets are used.
> 
> I have no idea where these values come from. I took them from offb. And 
> I suspect that some of these CMAP helpers could be further merged if 
> only it was clear where the numbers come from.  But as i don't have the 
> equipment for testing, I took most of this literally as-is from offb.
>

I see. As Michal mentioned maybe someone more familiar with this platform
could shed some light about these but in any case that could be done later.

[...]

>>> +
>>> +   new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
>>> new_plane_state->crtc);
>>> +
>>> +   new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);
>>> +   new_ofdrm_crtc_state->format = new_fb->format;
>>> +
>>
>> Ah, I understand now why you didn't factor out the .atomic_check callbacks
>> for the two drivers in a fwfb helper. Maybe you can also add a comment to
>> mention that this updates the format so the CRTC palette can be applied in
>> the .atomic_flush callback ?
> 
> Yeah, this code is one reason for not sharing atomic_check in fwfb.  The 
> other reason is that the fwfb code is only a wrapper around the atomic 
> helpers with little extra value.  I did have such fwfb helpers a some 
> point, but removed them.
>

Got it.

-- 
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat



Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-07-27 Thread Thomas Zimmermann

Hi

Am 26.07.22 um 15:49 schrieb Javier Martinez Canillas:

On 7/20/22 16:27, Thomas Zimmermann wrote:

Support the CRTC's color-management property and implement each model's
palette support.

The OF hardware has different methods of setting the palette. The
respective code has been taken from fbdev's offb and refactored into
per-model device functions. The device functions integrate this
functionality into the overall modesetting.

As palette handling is a CRTC property that depends on the primary
plane's color format, the plane's atomic_check helper now updates the
format field in ofdrm's custom CRTC state. The CRTC's atomic_flush
helper updates the palette for the format as needed.

Signed-off-by: Thomas Zimmermann 
---


Reviewed-by: Javier Martinez Canillas 

[...]


+static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
+  struct device_node *of_node,
+  u64 fb_base)
+{
+   struct drm_device *dev = >dev;
+   u64 address;
+   void __iomem *cmap_base;
+
+   address = fb_base & 0xff00ul;
+   address += 0x7ff000;
+


It would be good to know where these addresses are coming from. Maybe some
constant macros or a comment ? Same for the other places where addresses
and offsets are used.


I have no idea where these values come from. I took them from offb. And 
I suspect that some of these CMAP helpers could be further merged if 
only it was clear where the numbers come from.  But as i don't have the 
equipment for testing, I took most of this literally as-is from offb.




[...]


  static struct ofdrm_crtc_state *to_ofdrm_crtc_state(struct drm_crtc_state 
*base)
@@ -376,10 +735,12 @@ static int ofdrm_primary_plane_helper_atomic_check(struct 
drm_plane *plane,
   struct drm_atomic_state 
*new_state)
  {
struct drm_plane_state *new_plane_state = 
drm_atomic_get_new_plane_state(new_state, plane);
+   struct drm_framebuffer *new_fb = new_plane_state->fb;
struct drm_crtc_state *new_crtc_state;
+   struct ofdrm_crtc_state *new_ofdrm_crtc_state;
int ret;
  
-	if (!new_plane_state->fb)

+   if (!new_fb)
return 0;
  
  	new_crtc_state = drm_atomic_get_new_crtc_state(new_state, new_plane_state->crtc);

@@ -391,6 +752,14 @@ static int ofdrm_primary_plane_helper_atomic_check(struct 
drm_plane *plane,
if (ret)
return ret;
  
+	if (!new_plane_state->visible)

+   return 0;
+
+   new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
new_plane_state->crtc);
+
+   new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);
+   new_ofdrm_crtc_state->format = new_fb->format;
+


Ah, I understand now why you didn't factor out the .atomic_check callbacks
for the two drivers in a fwfb helper. Maybe you can also add a comment to
mention that this updates the format so the CRTC palette can be applied in
the .atomic_flush callback ?


Yeah, this code is one reason for not sharing atomic_check in fwfb.  The 
other reason is that the fwfb code is only a wrapper around the atomic 
helpers with little extra value.  I did have such fwfb helpers a some 
point, but removed them.


Best regards
Thomas





--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Maxfeldstr. 5, 90409 Nürnberg, Germany
(HRB 36809, AG Nürnberg)
Geschäftsführer: Ivo Totev


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PATCH v2 10/10] drm/ofdrm: Support color management

2022-07-26 Thread Javier Martinez Canillas
On 7/20/22 16:27, Thomas Zimmermann wrote:
> Support the CRTC's color-management property and implement each model's
> palette support.
> 
> The OF hardware has different methods of setting the palette. The
> respective code has been taken from fbdev's offb and refactored into
> per-model device functions. The device functions integrate this
> functionality into the overall modesetting.
> 
> As palette handling is a CRTC property that depends on the primary
> plane's color format, the plane's atomic_check helper now updates the
> format field in ofdrm's custom CRTC state. The CRTC's atomic_flush
> helper updates the palette for the format as needed.
> 
> Signed-off-by: Thomas Zimmermann 
> ---

Reviewed-by: Javier Martinez Canillas 

[...]

> +static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
> +struct device_node *of_node,
> +u64 fb_base)
> +{
> + struct drm_device *dev = >dev;
> + u64 address;
> + void __iomem *cmap_base;
> +
> + address = fb_base & 0xff00ul;
> + address += 0x7ff000;
> +

It would be good to know where these addresses are coming from. Maybe some
constant macros or a comment ? Same for the other places where addresses
and offsets are used.

[...]

>  static struct ofdrm_crtc_state *to_ofdrm_crtc_state(struct drm_crtc_state 
> *base)
> @@ -376,10 +735,12 @@ static int 
> ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
>  struct drm_atomic_state 
> *new_state)
>  {
>   struct drm_plane_state *new_plane_state = 
> drm_atomic_get_new_plane_state(new_state, plane);
> + struct drm_framebuffer *new_fb = new_plane_state->fb;
>   struct drm_crtc_state *new_crtc_state;
> + struct ofdrm_crtc_state *new_ofdrm_crtc_state;
>   int ret;
>  
> - if (!new_plane_state->fb)
> + if (!new_fb)
>   return 0;
>  
>   new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
> new_plane_state->crtc);
> @@ -391,6 +752,14 @@ static int 
> ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,
>   if (ret)
>   return ret;
>  
> + if (!new_plane_state->visible)
> + return 0;
> +
> + new_crtc_state = drm_atomic_get_new_crtc_state(new_state, 
> new_plane_state->crtc);
> +
> + new_ofdrm_crtc_state = to_ofdrm_crtc_state(new_crtc_state);
> + new_ofdrm_crtc_state->format = new_fb->format;
> +

Ah, I understand now why you didn't factor out the .atomic_check callbacks
for the two drivers in a fwfb helper. Maybe you can also add a comment to
mention that this updates the format so the CRTC palette can be applied in
the .atomic_flush callback ?

-- 
Best regards,

Javier Martinez Canillas
Linux Engineering
Red Hat



[PATCH v2 10/10] drm/ofdrm: Support color management

2022-07-20 Thread Thomas Zimmermann
Support the CRTC's color-management property and implement each model's
palette support.

The OF hardware has different methods of setting the palette. The
respective code has been taken from fbdev's offb and refactored into
per-model device functions. The device functions integrate this
functionality into the overall modesetting.

As palette handling is a CRTC property that depends on the primary
plane's color format, the plane's atomic_check helper now updates the
format field in ofdrm's custom CRTC state. The CRTC's atomic_flush
helper updates the palette for the format as needed.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/tiny/ofdrm.c | 434 ++-
 1 file changed, 433 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
index 62136b8ab975..2964eb9951c5 100644
--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -29,6 +30,44 @@
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   0
 
+#if !defined(CONFIG_PPC)
+static inline void out_8(void __iomem *addr, int val)
+{ }
+static inline void out_le32(void __iomem *addr, int val)
+{ }
+static inline unsigned int in_le32(const void __iomem *addr)
+{
+   return 0;
+}
+#endif
+
+#define OFDRM_GAMMA_LUT_SIZE   256
+
+/* Definitions used by the Avivo palette  */
+#define AVIVO_DC_LUT_RW_SELECT  0x6480
+#define AVIVO_DC_LUT_RW_MODE0x6484
+#define AVIVO_DC_LUT_RW_INDEX   0x6488
+#define AVIVO_DC_LUT_SEQ_COLOR  0x648c
+#define AVIVO_DC_LUT_PWL_DATA   0x6490
+#define AVIVO_DC_LUT_30_COLOR   0x6494
+#define AVIVO_DC_LUT_READ_PIPE_SELECT   0x6498
+#define AVIVO_DC_LUT_WRITE_EN_MASK  0x649c
+#define AVIVO_DC_LUT_AUTOFILL   0x64a0
+#define AVIVO_DC_LUTA_CONTROL   0x64c0
+#define AVIVO_DC_LUTA_BLACK_OFFSET_BLUE 0x64c4
+#define AVIVO_DC_LUTA_BLACK_OFFSET_GREEN0x64c8
+#define AVIVO_DC_LUTA_BLACK_OFFSET_RED  0x64cc
+#define AVIVO_DC_LUTA_WHITE_OFFSET_BLUE 0x64d0
+#define AVIVO_DC_LUTA_WHITE_OFFSET_GREEN0x64d4
+#define AVIVO_DC_LUTA_WHITE_OFFSET_RED  0x64d8
+#define AVIVO_DC_LUTB_CONTROL   0x6cc0
+#define AVIVO_DC_LUTB_BLACK_OFFSET_BLUE 0x6cc4
+#define AVIVO_DC_LUTB_BLACK_OFFSET_GREEN0x6cc8
+#define AVIVO_DC_LUTB_BLACK_OFFSET_RED  0x6ccc
+#define AVIVO_DC_LUTB_WHITE_OFFSET_BLUE 0x6cd0
+#define AVIVO_DC_LUTB_WHITE_OFFSET_GREEN0x6cd4
+#define AVIVO_DC_LUTB_WHITE_OFFSET_RED  0x6cd8
+
 enum ofdrm_model {
OFDRM_MODEL_UNKNOWN,
OFDRM_MODEL_MACH64, /* ATI Mach64 */
@@ -209,7 +248,14 @@ static enum ofdrm_model display_get_model_of(struct 
drm_device *dev, struct devi
  * Open Firmware display device
  */
 
+struct ofdrm_device;
+
 struct ofdrm_device_funcs {
+   void __iomem *(*cmap_ioremap)(struct ofdrm_device *odev,
+ struct device_node *of_node,
+ u64 fb_bas);
+   void (*cmap_write)(struct ofdrm_device *odev, unsigned char index,
+  unsigned char r, unsigned char g, unsigned char b);
 };
 
 struct ofdrm_device {
@@ -221,6 +267,9 @@ struct ofdrm_device {
/* firmware framebuffer */
struct drm_fwfb fwfb;
 
+   /* colormap */
+   void __iomem *cmap_base;
+
/* modesetting */
uint32_t formats[8];
struct drm_plane primary_plane;
@@ -333,12 +382,322 @@ static struct resource *ofdrm_find_fb_resource(struct 
ofdrm_device *odev,
return max_res;
 }
 
+/*
+ * Colormap / Palette
+ */
+
+static void __iomem *get_cmap_address_of(struct ofdrm_device *odev, struct 
device_node *of_node,
+int bar_no, unsigned long offset, 
unsigned long size)
+{
+   struct drm_device *dev = >dev;
+   const __be32 *addr_p;
+   u64 max_size, address;
+   unsigned int flags;
+   void __iomem *mem;
+
+   addr_p = of_get_pci_address(of_node, bar_no, _size, );
+   if (!addr_p)
+   addr_p = of_get_address(of_node, bar_no, _size, );
+   if (!addr_p)
+   return ERR_PTR(-ENODEV);
+
+   if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+   return ERR_PTR(-ENODEV);
+
+   if ((offset + size) >= max_size)
+   return ERR_PTR(-ENODEV);
+
+   address = of_translate_address(of_node, addr_p);
+   if (address == OF_BAD_ADDR)
+   return ERR_PTR(-ENODEV);
+
+   mem = devm_ioremap(dev->dev, address + offset, size);
+   if (!mem)
+   return ERR_PTR(-ENOMEM);
+
+   return mem;
+}
+
+static void __iomem *ofdrm_mach64_cmap_ioremap(struct ofdrm_device *odev,
+  struct device_node *of_node,
+