From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:28:06
(was: drm: Add driverof PowerPC OF displays)
PowerPC's Open Firmware offers a simple display buffer for graphics
output. Add ofdrm, a DRM driver for the device. As with the existing
simpledrm driver, the graphics hardware is pre-initialized by the
firmware. The driver only provides blitting, no actual DRM modesetting
is possible.
Version 2 of this patchset starts by cleaning up and refactoring
simpledrm, and moving some of the code in a helper library. These
functions are useful for ofdrm as well.
Patch 7 adds ofdrm, which has been significantly reworked since v1.
PCI is now optional and COMPILE_TEST is supported.
Patches 8 to 10 add support for color management. The code has been
taken from fbdev's offb. I have no hardware available for testing the
functionality. Qemu's stdvga apparently does not support gamma tables
in RGB modes. I verified that the color management code is executed
by running Gnome's night-mode settings, but the display's color tone
does not change.
Thomas Zimmermann (10):
drm/simpledrm: Remove mem field from device structure
drm/simpledrm: Inline device-init helpers
drm/simpledrm: Remove pdev field from device structure
drm/simpledrm: Compute framebuffer stride if not set
drm/simpledrm: Convert to atomic helpers
drm/simpledrm: Move some functionality into fwfb helper library
drm/ofdrm: Add ofdrm for Open Firmware framebuffers
drm/ofdrm: Add CRTC state
drm/ofdrm: Add per-model device function
drm/ofdrm: Support color management
Documentation/gpu/drm-kms-helpers.rst | 12 +
MAINTAINERS | 3 +
drivers/gpu/drm/Kconfig | 6 +
drivers/gpu/drm/Makefile | 3 +-
drivers/gpu/drm/drm_fwfb_helper.c | 301 ++++++
drivers/gpu/drm/tiny/Kconfig | 15 +
drivers/gpu/drm/tiny/Makefile | 1 +
drivers/gpu/drm/tiny/ofdrm.c | 1301 +++++++++++++++++++++++++
drivers/gpu/drm/tiny/simpledrm.c | 588 +++++------
drivers/video/fbdev/Kconfig | 1 +
include/drm/drm_fwfb_helper.h | 51 +
11 files changed, 1949 insertions(+), 333 deletions(-)
create mode 100644 drivers/gpu/drm/drm_fwfb_helper.c
create mode 100644 drivers/gpu/drm/tiny/ofdrm.c
create mode 100644 include/drm/drm_fwfb_helper.h
--
2.36.1
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:27:39
Compute the framebuffer's scanline stride length if not given by
the simplefb data.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/simpledrm.c | 3 +++
1 file changed, 3 insertions(+)
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:27:41
Inline the helpers for initializing the hardware FB, the memory
management and the modesetting into the device-creation function.
No functional changes.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/simpledrm.c | 291 ++++++++++++++-----------------
1 file changed, 128 insertions(+), 163 deletions(-)
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:27:45
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 <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/ofdrm.c | 434 ++++++++++++++++++++++++++++++++++-
1 file changed, 433 insertions(+), 1 deletion(-)
@@ -333,12 +382,322 @@ static struct resource *ofdrm_find_fb_resource(struct ofdrm_device *odev,returnmax_res;}+/*+*Colormap/Palette+*/++staticvoid__iomem*get_cmap_address_of(structofdrm_device*odev,structdevice_node*of_node,+intbar_no,unsignedlongoffset,unsignedlongsize)+{+structdrm_device*dev=&odev->dev;+const__be32*addr_p;+u64max_size,address;+unsignedintflags;+void__iomem*mem;++addr_p=of_get_pci_address(of_node,bar_no,&max_size,&flags);+if(!addr_p)+addr_p=of_get_address(of_node,bar_no,&max_size,&flags);+if(!addr_p)+returnERR_PTR(-ENODEV);++if((flags&(IORESOURCE_IO|IORESOURCE_MEM))==0)+returnERR_PTR(-ENODEV);++if((offset+size)>=max_size)+returnERR_PTR(-ENODEV);++address=of_translate_address(of_node,addr_p);+if(address==OF_BAD_ADDR)+returnERR_PTR(-ENODEV);++mem=devm_ioremap(dev->dev,address+offset,size);+if(!mem)+returnERR_PTR(-ENOMEM);++returnmem;+}++staticvoid__iomem*ofdrm_mach64_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+structdrm_device*dev=&odev->dev;+u64address;+void__iomem*cmap_base;++address=fb_base&0xff000000ul;+address+=0x7ff000;++cmap_base=devm_ioremap(dev->dev,address,0x1000);+if(!cmap_base)+returnERR_PTR(-ENOMEM);++returncmap_base;+}++staticvoidofdrm_mach64_cmap_write(structofdrm_device*odev,unsignedcharindex,+unsignedcharr,unsignedcharg,unsignedcharb)+{+void__iomem*addr=odev->cmap_base+0xcc0;+void__iomem*data=odev->cmap_base+0xcc0+1;++writeb(index,addr);+writeb(r,data);+writeb(g,data);+writeb(b,data);+}++staticvoid__iomem*ofdrm_rage128_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+returnget_cmap_address_of(odev,of_node,2,0,0x1fff);+}++staticvoidofdrm_rage128_cmap_write(structofdrm_device*odev,unsignedcharindex,+unsignedcharr,unsignedcharg,unsignedcharb)+{+void__iomem*addr=odev->cmap_base+0xb0;+void__iomem*data=odev->cmap_base+0xb4;+intcolor=(r<<16)|(g<<8)|b;++out_8(addr,index);+out_le32(data,color);+}++staticvoid__iomem*ofdrm_rage_m3a_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+returnget_cmap_address_of(odev,of_node,2,0,0x1fff);+}++staticvoidofdrm_rage_m3a_cmap_write(structofdrm_device*odev,unsignedcharindex,+unsignedcharr,unsignedcharg,unsignedcharb)+{+void__iomem*dac_ctl=odev->cmap_base+0x58;+void__iomem*addr=odev->cmap_base+0xb0;+void__iomem*data=odev->cmap_base+0xb4;+intcolor=(r<<16)|(g<<8)|b;+unsignedintval;++/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */+val=in_le32(dac_ctl);+val&=~0x20;+out_le32(dac_ctl,val);++/* Set color at palette index */+out_8(addr,index);+out_le32(data,color);+}++staticvoid__iomem*ofdrm_rage_m3b_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+returnget_cmap_address_of(odev,of_node,2,0,0x1fff);+}++staticvoidofdrm_rage_m3b_cmap_write(structofdrm_device*odev,unsignedcharindex,+unsignedcharr,unsignedcharg,unsignedcharb)+{+void__iomem*dac_ctl=odev->cmap_base+0x58;+void__iomem*addr=odev->cmap_base+0xb0;+void__iomem*data=odev->cmap_base+0xb4;+intcolor=(r<<16)|(g<<8)|b;+unsignedintval;++/* Set PALETTE_ACCESS_CNTL in DAC_CNTL */+val=in_le32(dac_ctl);+val|=0x20;+out_le32(dac_ctl,val);++/* Set color at palette index */+out_8(addr,index);+out_le32(data,color);+}++staticvoid__iomem*ofdrm_radeon_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+returnget_cmap_address_of(odev,of_node,1,0,0x1fff);+}++staticvoid__iomem*ofdrm_gxt2000_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+returnget_cmap_address_of(odev,of_node,0,0x6000,0x1000);+}++staticvoidofdrm_gxt2000_cmap_write(structofdrm_device*odev,unsignedcharindex,+unsignedcharr,unsignedcharg,unsignedcharb)+{+void__iomem*data=((unsignedint__iomem*)odev->cmap_base)+index;+intcolor=(r<<16)|(g<<8)|b;++out_le32(data,color);+}++staticvoid__iomem*ofdrm_avivo_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+structdevice_node*of_parent;+void__iomem*cmap_base;++of_parent=of_get_parent(of_node);+cmap_base=get_cmap_address_of(odev,of_parent,0,0,0x10000);+of_node_put(of_parent);++returncmap_base;+}++staticvoidofdrm_avivo_cmap_write(structofdrm_device*odev,unsignedcharindex,+unsignedcharr,unsignedcharg,unsignedcharb)+{+void__iomem*lutsel=odev->cmap_base+AVIVO_DC_LUT_RW_SELECT;+void__iomem*addr=odev->cmap_base+AVIVO_DC_LUT_RW_INDEX;+void__iomem*data=odev->cmap_base+AVIVO_DC_LUT_30_COLOR;+u32color=(r<<22)|(g<<12)|(b<<2);++/* Write to both LUTs for now */++writel(1,lutsel);+writeb(index,addr);+writel(color,data);++writel(0,lutsel);+writeb(index,addr);+writel(color,data);+}++staticvoid__iomem*ofdrm_qemu_cmap_ioremap(structofdrm_device*odev,+structdevice_node*of_node,+u64fb_base)+{+#ifdef __BIG_ENDIAN+staticconst__be32io_of_addr[3]={0x01000000,0x0,0x0};+#else+staticconst__be32io_of_addr[3]={0x00000001,0x0,0x0};+#endif++structdrm_device*dev=&odev->dev;+u64address;+void__iomem*cmap_base;++address=of_translate_address(of_node,io_of_addr);+if(address==OF_BAD_ADDR)+returnERR_PTR(-ENODEV);++cmap_base=devm_ioremap(dev->dev,address+0x3c8,2);+if(!cmap_base)+returnERR_PTR(-ENOMEM);++returncmap_base;+}++staticvoidofdrm_qemu_cmap_write(structofdrm_device*odev,unsignedcharindex,+unsignedcharr,unsignedcharg,unsignedcharb)+{+void__iomem*addr=odev->cmap_base;+void__iomem*data=odev->cmap_base+1;++writeb(index,addr);+writeb(r,data);+writeb(g,data);+writeb(b,data);+}++staticvoidofdrm_device_set_gamma_linear(structofdrm_device*odev,+conststructdrm_format_info*format)+{+structdrm_device*dev=&odev->dev;+inti;++switch(format->format){+caseDRM_FORMAT_RGB565:+/* Use better interpolation, to take 32 values from 0 to 255 */+for(i=0;i<OFDRM_GAMMA_LUT_SIZE/8;i++){+unsignedcharr=i*8+i/4;+unsignedcharg=i*4+i/16;+unsignedcharb=i*8+i/4;++odev->funcs->cmap_write(odev,i,r,g,b);+}+/* Green has one more bit, so add padding with 0 for red and blue. */+for(i=OFDRM_GAMMA_LUT_SIZE/8;i<OFDRM_GAMMA_LUT_SIZE/4;i++){+unsignedcharr=0;+unsignedcharg=i*4+i/16;+unsignedcharb=0;++odev->funcs->cmap_write(odev,i,r,g,b);+}+break;+caseDRM_FORMAT_XRGB8888:+for(i=0;i<OFDRM_GAMMA_LUT_SIZE;i++)+odev->funcs->cmap_write(odev,i,i,i,i);+break;+default:+drm_warn_once(dev,"Unsupported format %p4cc for gamma correction\n",+&format->format);+break;+}+}++staticvoidofdrm_device_set_gamma(structofdrm_device*odev,+conststructdrm_format_info*format,+structdrm_color_lut*lut)+{+structdrm_device*dev=&odev->dev;+inti;++switch(format->format){+caseDRM_FORMAT_RGB565:+/* Use better interpolation, to take 32 values from lut[0] to lut[255] */+for(i=0;i<OFDRM_GAMMA_LUT_SIZE/8;i++){+unsignedcharr=lut[i*8+i/4].red>>8;+unsignedcharg=lut[i*4+i/16].green>>8;+unsignedcharb=lut[i*8+i/4].blue>>8;++odev->funcs->cmap_write(odev,i,r,g,b);+}+/* Green has one more bit, so add padding with 0 for red and blue. */+for(i=OFDRM_GAMMA_LUT_SIZE/8;i<OFDRM_GAMMA_LUT_SIZE/4;i++){+unsignedcharr=0;+unsignedcharg=lut[i*4+i/16].green>>8;+unsignedcharb=0;++odev->funcs->cmap_write(odev,i,r,g,b);+}+break;+caseDRM_FORMAT_XRGB8888:+for(i=0;i<OFDRM_GAMMA_LUT_SIZE;i++){+unsignedcharr=lut[i].red>>8;+unsignedcharg=lut[i].green>>8;+unsignedcharb=lut[i].blue>>8;++odev->funcs->cmap_write(odev,i,r,g,b);+}+break;+default:+drm_warn_once(dev,"Unsupported format %p4cc for gamma correction\n",+&format->format);+break;+}+}+/**Modesetting*/structofdrm_crtc_state{structdrm_crtc_statebase;++/* Primary-plane format; required for color mgmt. */+conststructdrm_format_info*format;};staticstructofdrm_crtc_state*to_ofdrm_crtc_state(structdrm_crtc_state*base)
@@ -376,10 +735,12 @@ static int ofdrm_primary_plane_helper_atomic_check(struct drm_plane *plane,structdrm_atomic_state*new_state){structdrm_plane_state*new_plane_state=drm_atomic_get_new_plane_state(new_state,plane);+structdrm_framebuffer*new_fb=new_plane_state->fb;structdrm_crtc_state*new_crtc_state;+structofdrm_crtc_state*new_ofdrm_crtc_state;intret;-if(!new_plane_state->fb)+if(!new_fb)return0;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)returnret;+if(!new_plane_state->visible)+return0;++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;+return0;}
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:27:55
Open Firmware provides basic display output via the 'display' node.
DT platform code already provides a device that represents the node's
framebuffer. Add a DRM driver for the device. The display mode and
color format is pre-initialized by the system's firmware. Runtime
modesetting via DRM is not possible. The display is useful during
early boot stages or as error fallback.
Similar functionality is already provided by fbdev's offb driver,
which is insufficient for modern userspace. The old driver includes
support for BootX device tree, which can be found on old 32-bit
PowerPC Macintosh systems. If these are still in use, the
functionality can be added to ofdrm or implemented in a new
driver. As with simepldrm, the fbdev driver cannot be selected is
ofdrm is already enabled.
Two noteable points about the driver:
* Reading the framebuffer aperture from the device tree is not
reliable on all systems. Ofdrm takes the heuristics and a comment
from offb to pick the correct range.
* No resource management may be tied to the underlying PCI device.
Otherwise the handover to the native driver will fail with a resource
conflict. PCI management is therefore done as part of the platform
device's cleanup.
The driver has been tested on qemu's ppc64le emulation. The device
hand-over has been tested with bochs.
v2:
* removed simple-pipe helpers
* built driver on top of FWFB helpers
* merged all init code into single function
* make PCI support optional (Michal)
* support COMPILE_TEST (Javier)
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
MAINTAINERS | 1 +
drivers/gpu/drm/tiny/Kconfig | 14 +
drivers/gpu/drm/tiny/Makefile | 1 +
drivers/gpu/drm/tiny/ofdrm.c | 692 ++++++++++++++++++++++++++++++++++
drivers/video/fbdev/Kconfig | 1 +
5 files changed, 709 insertions(+)
create mode 100644 drivers/gpu/drm/tiny/ofdrm.c
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:27:59
Replace the remaining uses of the field pdev by upcasts from the Linux
device and remove the field.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/simpledrm.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
@@ -0,0 +1,301 @@+// SPDX-License-Identifier: GPL-2.0-only++#include<drm/drm_atomic.h>+#include<drm/drm_atomic_helper.h>+#include<drm/drm_damage_helper.h>+#include<drm/drm_drv.h>+#include<drm/drm_format_helper.h>+#include<drm/drm_fwfb_helper.h>+#include<drm/drm_gem_atomic_helper.h>+#include<drm/drm_plane_helper.h>+#include<drm/drm_print.h>++/**+*DOC:overview+*+*TheFirmwareFramebufferlibraryFWFBprovideshelpersfordeviceswith+*fixed-modebackingstorage.Ithelpsdriverstoexportadisplaymodeof+*tecorrectsizeandcopyupdatestothebackingstorage.+*/++/*+*Assumeamonitorresolutionof96dpito+*getasomewhatreasonablescreensize.+*/+#define RES_MM(d) \+(((d)*254ul)/(96ul*10ul))++#define DRM_FWFB_MODE(hd, vd) \+DRM_SIMPLE_MODE(hd,vd,RES_MM(hd),RES_MM(vd))++staticstructdrm_display_modedrm_fwfb_mode(unsignedintwidth,unsignedintheight)+{+structdrm_display_modemode={DRM_FWFB_MODE(width,height)};++mode.clock=mode.hdisplay*mode.vdisplay*60/1000/* kHz */;+drm_mode_set_name(&mode);++returnmode;+}++/**+*drm_fwfb_init-Initializesanfwfbbuffer+*@fwfb:fwfbbuffer+*@screen_base:Addressofthebackingbufferinkerneladdressspace+*@width:Numberofpixelsperscanline+*@height:Numberofscanlines+*@format:Colorformat+*@pitch:Distancebetweentwoconsecutivescanlinesinbytes+*+*Returns:+*0onsuccess,oranegativeerrnocodeotherwise.+*/+intdrm_fwfb_init(structdrm_fwfb*fwfb,structiosys_map*screen_base,+unsignedintwidth,unsignedintheight,+conststructdrm_format_info*format,unsignedintpitch)+{+fwfb->screen_base=*screen_base;+fwfb->mode=drm_fwfb_mode(width,height);+fwfb->format=format;+fwfb->pitch=pitch;++return0;+}+EXPORT_SYMBOL(drm_fwfb_init);++staticboolis_listed_fourcc(constuint32_t*fourccs,size_tnfourccs,uint32_tfourcc)+{+constuint32_t*fourccs_end=fourccs+nfourccs;++while(fourccs<fourccs_end){+if(*fourccs==fourcc)+returntrue;+++fourccs;+}+returnfalse;+}++/**+*drm_fwfb_extra_formats-Filtersalistofsupportedcolorformatsagainst+*thedevice'snativeformats+*@dev:DRMdevice+*@native_fourccs:4CCcodesofnativelysupportedcolorformats+*@native_nfourccs:Thenumberofentriesin@native_fourccs+*@extra_fourccs:4CCcodesofadditionallysupportedcolorformats+*@extra_nfourccs:Thenumberofentriesin@extra_fourccs+*@fourccs_out:Returns4CCcodesofsupportedcolorformats+*@nfourccs_out:Thenumberofavailableentriesin@fourccs_out+*+*Thisfunctioncreatealistofsupportedcolorformatfromthedevice's+*nativeformatsandthedriver'semulatedformats.Thereturnedlistcan+*behandedovertodrm_universal_plane_init()etal.+*+*Returns:+*Thenumberofcolorformatsreturnedin@fourccs_out.+*/+size_tdrm_fwfb_extra_formats(structdrm_device*dev,+constuint32_t*native_fourccs,size_tnative_nfourccs,+constuint32_t*extra_fourccs,size_textra_nfourccs,+uint32_t*fourccs_out,size_tnfourccs_out)+{+uint32_t*fourccs=fourccs_out;+constuint32_t*fourccs_end=fourccs_out+nfourccs_out;+boolfound_native=false;+size_tnfourccs,i;++/* native formats go first */++nfourccs=min_t(size_t,native_nfourccs,nfourccs_out);++for(i=0;i<nfourccs;++i){+uint32_tfourcc=native_fourccs[i];++drm_dbg_kms(dev,"adding native format %p4cc\n",&fourcc);++if(!found_native)+found_native=is_listed_fourcc(extra_fourccs,extra_nfourccs,fourcc);+*fourccs=fourcc;+++fourccs;+}++/*+*Theplane'satomic_updatehelperconvertstheframebuffer'scolorformat+*tothenativeformatwhencopyingthemtodevicememory.+*+*Ifthereisnotasingleformatsupportedbyboth,deviceand+*plane,thenativeformatsarelikelynotsupportedbytheconversion+*helpers.Therefore*only*supportthenativeformatsandadda+*conversionhelperASAP.+*/+if(!found_native){+drm_warn(dev,"format conversion helpers required to add extra formats\n");+gotoout;+}++/* extra formats go second */++nfourccs=min_t(size_t,extra_nfourccs,fourccs_end-fourccs);++for(i=0;i<nfourccs;++i){+uint32_tfourcc=extra_fourccs[i];++if(is_listed_fourcc(native_fourccs,native_nfourccs,fourcc))+continue;/* native formats already went first */+*fourccs=fourcc;+++fourccs;+}++out:+returnfourccs-fourccs_out;+}+EXPORT_SYMBOL(drm_fwfb_extra_formats);++/*+*Plane+*/++/**+*drm_fwfb_plane_helper_atomic_update-Helperforimplementingatomicplaneupdates+*@fwfb:fwfbbuffer+*@plane:theplanetoupdate+*@old_state:theoldstate+*+*Thisfunctionupdatestheplane'sdamagedareasinthefwfbbuffer.+*/+voiddrm_fwfb_plane_helper_atomic_update(structdrm_fwfb*fwfb,structdrm_plane*plane,+structdrm_atomic_state*old_state)+{+structdrm_device*dev=plane->dev;+structiosys_mapdst=fwfb->screen_base;+structdrm_plane_state*plane_state=plane->state;+structdrm_plane_state*old_plane_state=drm_atomic_get_old_plane_state(old_state,plane);+structdrm_shadow_plane_state*shadow_plane_state=to_drm_shadow_plane_state(plane_state);+void*vmap=shadow_plane_state->data[0].vaddr;/* TODO: Use mapping abstraction */+structdrm_framebuffer*fb=plane_state->fb;+void__iomem*dst_vmap=dst.vaddr_iomem;/* TODO: Use mapping abstraction */+unsignedintdst_pitch=fwfb->pitch;+conststructdrm_format_info*dst_format=fwfb->format;+structdrm_rectsrc_clip,dst_clip;+intidx;++if(!fb)+return;++if(!drm_atomic_helper_damage_merged(old_plane_state,plane_state,&src_clip))+return;++dst_clip=plane_state->dst;+if(!drm_rect_intersect(&dst_clip,&src_clip))+return;++if(!drm_dev_enter(dev,&idx))+return;++dst_vmap+=drm_fb_clip_offset(dst_pitch,dst_format,&dst_clip);+drm_fb_blit_toio(dst_vmap,dst_pitch,dst_format->format,vmap,fb,&src_clip);++drm_dev_exit(idx);+}+EXPORT_SYMBOL(drm_fwfb_plane_helper_atomic_update);++/**+*drm_fwfb_plane_helper_atomic_disable-Helperfordisablingplanes+*@fwfb:fwfbbuffer+*@plane:theplanetodisable+*@old_state:theoldstate+*+*Thisfunctionclearstheplane'sfwfbbuffertozero.+*/+voiddrm_fwfb_plane_helper_atomic_disable(structdrm_fwfb*fwfb,structdrm_plane*plane,+structdrm_atomic_state*old_state)+{+structdrm_device*dev=plane->dev;+structiosys_mapdst=fwfb->screen_base;+structdrm_plane_state*plane_state=plane->state;+void__iomem*dst_vmap=dst.vaddr_iomem;/* TODO: Use mapping abstraction */+unsignedintdst_pitch=fwfb->pitch;+conststructdrm_format_info*dst_format=fwfb->format;+structdrm_rectdst_clip;+unsignedlonglines,linepixels,i;+intidx;++drm_rect_init(&dst_clip,plane_state->src_x>>16,plane_state->src_y>>16,+plane_state->src_w>>16,plane_state->src_h>>16);+lines=drm_rect_height(&dst_clip);+linepixels=drm_rect_width(&dst_clip);++if(!drm_dev_enter(dev,&idx))+return;++/* Clear buffer to black if disabled */+dst_vmap+=drm_fb_clip_offset(dst_pitch,dst_format,&dst_clip);+for(i=0;i<lines;++i){+memset_io(dst_vmap,0,linepixels*dst_format->cpp[0]);+dst_vmap+=dst_pitch;+}++drm_dev_exit(idx);+}+EXPORT_SYMBOL(drm_fwfb_plane_helper_atomic_disable);++/*+*CRTC+*/++/**+*drm_fwfb_crtc_helper_mode_valid-Validatesadisplaymode+*@fwfb:fwfbbuffer+*@crtc:thecrtc+*@mode:themodetovalidate+*/+enumdrm_mode_statusdrm_fwfb_crtc_helper_mode_valid(structdrm_fwfb*fwfb,structdrm_crtc*crtc,+conststructdrm_display_mode*mode)+{++if(mode->hdisplay!=fwfb->mode.hdisplay&&mode->vdisplay!=fwfb->mode.vdisplay)+returnMODE_ONE_SIZE;+elseif(mode->hdisplay!=fwfb->mode.hdisplay)+returnMODE_ONE_WIDTH;+elseif(mode->vdisplay!=fwfb->mode.vdisplay)+returnMODE_ONE_HEIGHT;++returnMODE_OK;+}+EXPORT_SYMBOL(drm_fwfb_crtc_helper_mode_valid);++/*+*Connector+*/++/**+*drm_fwfb_connector_helper_get_modes-Createsalistofdisplaymodesforaconnector+*@fwfb:fwfbbuffer+*@connector:theconnector+*+*Thisfunctioncreatesalistofdisplaymodesforaconnector.+*+*Returns:+*Thenumberofcreatedmodes.+*/+intdrm_fwfb_connector_helper_get_modes(structdrm_fwfb*fwfb,structdrm_connector*connector)+{+structdrm_display_mode*mode;++mode=drm_mode_duplicate(connector->dev,&fwfb->mode);+if(!mode)+return0;++if(mode->name[0]=='\0')+drm_mode_set_name(mode);++mode->type|=DRM_MODE_TYPE_PREFERRED;+drm_mode_probed_add(connector,mode);++if(mode->width_mm)+connector->display_info.width_mm=mode->width_mm;+if(mode->height_mm)+connector->display_info.height_mm=mode->height_mm;++return1;+}+EXPORT_SYMBOL(drm_fwfb_connector_helper_get_modes);
@@ -504,50 +490,17 @@ static int simpledrm_primary_plane_helper_atomic_check(struct drm_plane *plane,staticvoidsimpledrm_primary_plane_helper_atomic_update(structdrm_plane*plane,structdrm_atomic_state*old_state){-structdrm_plane_state*plane_state=plane->state;-structdrm_plane_state*old_plane_state=drm_atomic_get_old_plane_state(old_state,plane);-structdrm_shadow_plane_state*shadow_plane_state=to_drm_shadow_plane_state(plane_state);-void*vmap=shadow_plane_state->data[0].vaddr;/* TODO: Use mapping abstraction */-structdrm_framebuffer*fb=plane_state->fb;-structdrm_device*dev=plane->dev;-structsimpledrm_device*sdev=simpledrm_device_of_dev(dev);-void__iomem*dst=sdev->screen_base;-structdrm_rectsrc_clip,dst_clip;-intidx;--if(!fb)-return;--if(!drm_atomic_helper_damage_merged(old_plane_state,plane_state,&src_clip))-return;--dst_clip=plane_state->dst;-if(!drm_rect_intersect(&dst_clip,&src_clip))-return;--if(!drm_dev_enter(dev,&idx))-return;--dst+=drm_fb_clip_offset(sdev->pitch,sdev->format,&dst_clip);-drm_fb_blit_toio(dst,sdev->pitch,sdev->format->format,vmap,fb,&src_clip);--drm_dev_exit(idx);+structsimpledrm_device*sdev=simpledrm_device_of_dev(plane->dev);++drm_fwfb_plane_helper_atomic_update(&sdev->fwfb,plane,old_state);}staticvoidsimpledrm_primary_plane_helper_atomic_disable(structdrm_plane*plane,structdrm_atomic_state*old_state){-structdrm_device*dev=plane->dev;-structsimpledrm_device*sdev=simpledrm_device_of_dev(dev);-intidx;--if(!drm_dev_enter(dev,&idx))-return;--/* Clear screen to black if disabled */-memset_io(sdev->screen_base,0,sdev->pitch*sdev->mode.vdisplay);+structsimpledrm_device*sdev=simpledrm_device_of_dev(plane->dev);-drm_dev_exit(idx);+drm_fwfb_plane_helper_atomic_disable(&sdev->fwfb,plane,old_state);}staticconststructdrm_plane_helper_funcssimpledrm_primary_plane_helper_funcs={
@@ -676,56 +605,6 @@ static const struct drm_mode_config_funcs simpledrm_mode_config_funcs = {*Init/Cleanup*/-staticstructdrm_display_modesimpledrm_mode(unsignedintwidth,-unsignedintheight)-{-structdrm_display_modemode={SIMPLEDRM_MODE(width,height)};--mode.clock=mode.hdisplay*mode.vdisplay*60/1000/* kHz */;-drm_mode_set_name(&mode);--returnmode;-}--staticconstuint32_t*simpledrm_device_formats(structsimpledrm_device*sdev,-size_t*nformats_out)-{-structdrm_device*dev=&sdev->dev;-size_ti;--if(sdev->nformats)-gotoout;/* don't rebuild list on recurring calls */--/* native format goes first */-sdev->formats[0]=sdev->format->format;-sdev->nformats=1;--/* default formats go second */-for(i=0;i<ARRAY_SIZE(simpledrm_primary_plane_formats);++i){-if(simpledrm_primary_plane_formats[i]==sdev->format->format)-continue;/* native format already went first */-sdev->formats[sdev->nformats]=simpledrm_primary_plane_formats[i];-sdev->nformats++;-}--/*-*TODO:Thesimpledrmdriverconvertsframebufferstothenative-*formatwhencopyingthemtodevicememory.Iftherearemore-*formatslistedthansupportedbythedriver,thenativeformat-*isnotsupportedbytheconversionhelpers.Therefore*only*-*supportthenativeformatandaddaconversionhelperASAP.-*/-if(drm_WARN_ONCE(dev,i!=sdev->nformats,-"format conversion helpers required for %p4cc",-&sdev->format->format)){-sdev->nformats=1;-}--out:-*nformats_out=sdev->nformats;-returnsdev->formats;-}-staticstructsimpledrm_device*simpledrm_device_create(structdrm_driver*drv,structplatform_device*pdev){
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:28:09
Remove the unused mem field from struct simpledrm_device.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/simpledrm.c | 2 --
1 file changed, 2 deletions(-)
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:28:22
Add a dedicated CRTC state to ofdrm to later store information for
palette updates.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/ofdrm.c | 62 ++++++++++++++++++++++++++++++++++--
1 file changed, 59 insertions(+), 3 deletions(-)
@@ -395,13 +410,54 @@ static const struct drm_crtc_helper_funcs ofdrm_crtc_helper_funcs = {.atomic_disable=ofdrm_crtc_helper_atomic_disable,};+staticvoidofdrm_crtc_reset(structdrm_crtc*crtc)+{+structofdrm_crtc_state*ofdrm_crtc_state;++if(crtc->state){+ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));+crtc->state=NULL;/* must be set to NULL here */+}++ofdrm_crtc_state=kzalloc(sizeof(*ofdrm_crtc_state),GFP_KERNEL);+if(!ofdrm_crtc_state)+return;+__drm_atomic_helper_crtc_reset(crtc,&ofdrm_crtc_state->base);+}++staticstructdrm_crtc_state*ofdrm_crtc_atomic_duplicate_state(structdrm_crtc*crtc)+{+structdrm_crtc_state*crtc_state=crtc->state;+structofdrm_crtc_state*ofdrm_crtc_state;+structofdrm_crtc_state*new_ofdrm_crtc_state;++if(!crtc_state)+returnNULL;++ofdrm_crtc_state=to_ofdrm_crtc_state(crtc_state);++new_ofdrm_crtc_state=kzalloc(sizeof(*new_ofdrm_crtc_state),GFP_KERNEL);+if(!new_ofdrm_crtc_state)+returnNULL;++__drm_atomic_helper_crtc_duplicate_state(crtc,&new_ofdrm_crtc_state->base);++return&new_ofdrm_crtc_state->base;+}++staticvoidofdrm_crtc_atomic_destroy_state(structdrm_crtc*crtc,+structdrm_crtc_state*crtc_state)+{+ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc_state));+}+staticconststructdrm_crtc_funcsofdrm_crtc_funcs={-.reset=drm_atomic_helper_crtc_reset,+.reset=ofdrm_crtc_reset,.destroy=drm_crtc_cleanup,.set_config=drm_atomic_helper_set_config,.page_flip=drm_atomic_helper_page_flip,-.atomic_duplicate_state=drm_atomic_helper_crtc_duplicate_state,-.atomic_destroy_state=drm_atomic_helper_crtc_destroy_state,+.atomic_duplicate_state=ofdrm_crtc_atomic_duplicate_state,+.atomic_destroy_state=ofdrm_crtc_atomic_destroy_state,};staticintofdrm_connector_helper_get_modes(structdrm_connector*connector)
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:28:24
Add a per-model device-function structure in preparation of adding
color-management support. Detection of the individual models has been
taken from fbdev's offb.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/ofdrm.c | 121 +++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
@@ -29,6 +29,18 @@#define DRIVER_MAJOR 1#define DRIVER_MINOR 0+enumofdrm_model{+OFDRM_MODEL_UNKNOWN,+OFDRM_MODEL_MACH64,/* ATI Mach64 */+OFDRM_MODEL_RAGE128,/* ATI Rage128 */+OFDRM_MODEL_RAGE_M3A,/* ATI Rage Mobility M3 Head A */+OFDRM_MODEL_RAGE_M3B,/* ATI Rage Mobility M3 Head B */+OFDRM_MODEL_RADEON,/* ATI Radeon */+OFDRM_MODEL_GXT2000,/* IBM GXT2000 */+OFDRM_MODEL_AVIVO,/* ATI R5xx */+OFDRM_MODEL_QEMU,/* QEMU VGA */+};+/**Helpersfordisplaynodes*/
@@ -150,14 +162,62 @@ static u64 display_get_address_of(struct drm_device *dev, struct device_node *ofreturnaddress;}+staticboolis_avivo(__be32vendor,__be32device)+{+/* This will match most R5xx */+return(vendor==0x1002)&&+((device>=0x7100&&device<0x7800)||(device>=0x9400));+}++staticenumofdrm_modeldisplay_get_model_of(structdrm_device*dev,structdevice_node*of_node)+{+enumofdrm_modelmodel=OFDRM_MODEL_UNKNOWN;++if(of_node_name_prefix(of_node,"ATY,Rage128")){+model=OFDRM_MODEL_RAGE128;+}elseif(of_node_name_prefix(of_node,"ATY,RageM3pA")||+of_node_name_prefix(of_node,"ATY,RageM3p12A")){+model=OFDRM_MODEL_RAGE_M3A;+}elseif(of_node_name_prefix(of_node,"ATY,RageM3pB")){+model=OFDRM_MODEL_RAGE_M3B;+}elseif(of_node_name_prefix(of_node,"ATY,Rage6")){+model=OFDRM_MODEL_RADEON;+}elseif(of_node_name_prefix(of_node,"ATY,")){+returnOFDRM_MODEL_MACH64;+}elseif(of_device_is_compatible(of_node,"pci1014,b7")||+of_device_is_compatible(of_node,"pci1014,21c")){+model=OFDRM_MODEL_GXT2000;+}elseif(of_node_name_prefix(of_node,"vga,Display-")){+structdevice_node*of_parent;+const__be32*vendor_p,*device_p;++/* Look for AVIVO initialized by SLOF */+of_parent=of_get_parent(of_node);+vendor_p=of_get_property(of_parent,"vendor-id",NULL);+device_p=of_get_property(of_parent,"device-id",NULL);+if(vendor_p&&device_p&&is_avivo(*vendor_p,*device_p))+model=OFDRM_MODEL_AVIVO;+of_node_put(of_parent);+}elseif(of_device_is_compatible(of_node,"qemu,std-vga")){+model=OFDRM_MODEL_QEMU;+}++returnmodel;+}+/**OpenFirmwaredisplaydevice*/+structofdrm_device_funcs{+};+structofdrm_device{structdrm_devicedev;structplatform_device*pdev;+conststructofdrm_device_funcs*funcs;+/* firmware framebuffer */structdrm_fwfbfwfb;
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-20 14:28:26
Replace the simple-KMS helpers with the regular atomic helpers. The
regular helpers are better architectured and therefore allow for easier
code sharing among drivers. No functional changes.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/simpledrm.c | 283 ++++++++++++++++++++-----------
1 file changed, 180 insertions(+), 103 deletions(-)
@@ -653,10 +701,10 @@ static const uint32_t *simpledrm_device_formats(struct simpledrm_device *sdev,sdev->nformats=1;/* default formats go second */-for(i=0;i<ARRAY_SIZE(simpledrm_default_formats);++i){-if(simpledrm_default_formats[i]==sdev->format->format)+for(i=0;i<ARRAY_SIZE(simpledrm_primary_plane_formats);++i){+if(simpledrm_primary_plane_formats[i]==sdev->format->format)continue;/* native format already went first */-sdev->formats[sdev->nformats]=simpledrm_default_formats[i];+sdev->formats[sdev->nformats]=simpledrm_primary_plane_formats[i];sdev->nformats++;}
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@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
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-25 15:01:55
Hello Thomas,
On 7/20/22 16:27, Thomas Zimmermann wrote:
Inline the helpers for initializing the hardware FB, the memory
management and the modesetting into the device-creation function.
No functional changes.
Could you please elaborate in the commit message why this change is
desirable? Without this additional context, this feels like going
backwards, since you are dropping few helpers that have quite self
contained code and making simpledrm_device_create() much larger.
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-25 15:02:40
On 7/20/22 16:27, Thomas Zimmermann wrote:
Replace the remaining uses of the field pdev by upcasts from the Linux
device and remove the field.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Much better indeed.
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
I think you meant here:
DIV_ROUND_UP(drm_format_info_bpp(format, 0) * width, 8) ?
With that change,
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-25 15:46:44
On 7/20/22 16:27, Thomas Zimmermann wrote:
Replace the simple-KMS helpers with the regular atomic helpers. The
regular helpers are better architectured and therefore allow for easier
code sharing among drivers. No functional changes.
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
But I've a question below...
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-25 16:23:39
On 7/20/22 16:27, Thomas Zimmermann wrote:
Move some of simpledrm's functionality into a helper library. Other
drivers for firmware-provided framebuffers will also need functions
to handle fixed modes and color formats, or update the back buffer.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Nice patch!
[...]
+
+/**
+ * DOC: overview
+ *
+ * The Firmware Framebuffer library FWFB provides helpers for devices with
+ * fixed-mode backing storage. It helps drivers to export a display mode of
+ * te correct size and copy updates to the backing storage.
the
it is "backing storage" or "backing store" ? I always thought that storage was
used for non-volatile media while "store" could be volatile and non-volatile.
[...]
+/**
+ * drm_fwfb_init - Initializes an fwfb buffer
+ * @fwfb: fwfb buffer
+ * @screen_base: Address of the backing buffer in kernel address space
+ * @width: Number of pixels per scanline
+ * @height: Number of scanlines
+ * @format: Color format
+ * @pitch: Distance between two consecutive scanlines in bytes
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_fwfb_init(struct drm_fwfb *fwfb, struct iosys_map *screen_base,
+ unsigned int width, unsigned int height,
+ const struct drm_format_info *format, unsigned int pitch)
+{
+ fwfb->screen_base = *screen_base;
+ fwfb->mode = drm_fwfb_mode(width, height);
+ fwfb->format = format;
It seems a little bit arbitrary to me that format is the only field that's
a pointer and the other ones are embedded into the struct drm_fwfb. Any
reason for that or is just a consequence of how types were used by the
simpledrm_device_create() function before that code moved into helpers ?
[...]
This seems a helper that could be useful besides the drm_fwfb_helper.c file.
I believe patches 1-6 shouldn't wait for the others in this series and could
just be merged when ready. Patches 7-10 can follow later.
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-26 13:18:04
Hello Thomas,
On 7/20/22 16:27, Thomas Zimmermann wrote:
Open Firmware provides basic display output via the 'display' node.
DT platform code already provides a device that represents the node's
framebuffer. Add a DRM driver for the device. The display mode and
color format is pre-initialized by the system's firmware. Runtime
modesetting via DRM is not possible. The display is useful during
early boot stages or as error fallback.
I'm not familiar with OF display but the driver looks good to me.
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
I just have a few questions below.
[...]
I don't see a binding for this in Documentation/devicetree/bindings/display.
Do we need one or it's that only required for FDT and not Open Firmware DT ?
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-26 13:36:38
On 7/20/22 16:27, Thomas Zimmermann wrote:
Add a dedicated CRTC state to ofdrm to later store information for
palette updates.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/ofdrm.c | 62 ++++++++++++++++++++++++++++++++++--
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
+static void ofdrm_crtc_reset(struct drm_crtc *crtc)
+{
+ struct ofdrm_crtc_state *ofdrm_crtc_state;
+
+ if (crtc->state) {
+ ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));
+ crtc->state = NULL; /* must be set to NULL here */
+ }
+
+ ofdrm_crtc_state = kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);
+ if (!ofdrm_crtc_state)
+ return;
+ __drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
+}
+
IMO this function is hard to read, I would instead write it as following:
static void ofdrm_crtc_reset(struct drm_crtc *crtc)
{
struct ofdrm_crtc_state *ofdrm_crtc_state = kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);
if (!ofdrm_crtc_state)
return;
if (crtc->state) {
ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));
crtc->state = NULL; /* must be set to NULL here */
}
__drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
}
Also with that form I think that the crtc->state = NULL could just be dropped ?
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-26 13:38:48
On 7/20/22 16:27, Thomas Zimmermann wrote:
Add a per-model device-function structure in preparation of adding
color-management support. Detection of the individual models has been
taken from fbdev's offb.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
+static bool is_avivo(__be32 vendor, __be32 device)
+{
+ /* This will match most R5xx */
+ return (vendor == 0x1002) &&
+ ((device >= 0x7100 && device < 0x7800) || (device >= 0x9400));
+}
Maybe add some constant macros to not have these magic numbers ?
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-26 14:02:13
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 <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
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.
[...]
@@ -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
From: Michal Suchánek <hidden> Date: 2022-07-26 14:40:30
Hello,
On Tue, Jul 26, 2022 at 03:38:37PM +0200, Javier Martinez Canillas wrote:
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Add a per-model device-function structure in preparation of adding
color-management support. Detection of the individual models has been
taken from fbdev's offb.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
quoted
+static bool is_avivo(__be32 vendor, __be32 device)
+{
+ /* This will match most R5xx */
+ return (vendor == 0x1002) &&
+ ((device >= 0x7100 && device < 0x7800) || (device >= 0x9400));
+}
Maybe add some constant macros to not have these magic numbers ?
This is based on the existing fbdev implementation's magic numbers:
drivers/video/fbdev/offb.c: ((*did >= 0x7100 && *did < 0x7800) ||
Of course, it would be great if somebody knowledgeable could clarify
those.
Thanks
Michal
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-26 19:22:13
Hello Michal,
On 7/26/22 16:40, Michal Suchánek wrote:
Hello,
On Tue, Jul 26, 2022 at 03:38:37PM +0200, Javier Martinez Canillas wrote:
quoted
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Add a per-model device-function structure in preparation of adding
color-management support. Detection of the individual models has been
taken from fbdev's offb.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
quoted
+static bool is_avivo(__be32 vendor, __be32 device)
+{
+ /* This will match most R5xx */
+ return (vendor == 0x1002) &&
+ ((device >= 0x7100 && device < 0x7800) || (device >= 0x9400));
+}
Maybe add some constant macros to not have these magic numbers ?
This is based on the existing fbdev implementation's magic numbers:
drivers/video/fbdev/offb.c: ((*did >= 0x7100 && *did < 0x7800) ||
Ah, I see. Then we might have to go with the magic numbers...
Of course, it would be great if somebody knowledgeable could clarify
those.
Indeed.
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-27 07:51:16
Hi
Am 25.07.22 um 17:01 schrieb Javier Martinez Canillas:
Hello Thomas,
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Inline the helpers for initializing the hardware FB, the memory
management and the modesetting into the device-creation function.
No functional changes.
Could you please elaborate in the commit message why this change is
desirable? Without this additional context, this feels like going
backwards, since you are dropping few helpers that have quite self
contained code and making simpledrm_device_create() much larger.
To clarify: I want to make the init code more easy to follow. These old
init functions still had to be called in the right order as each
possibly depends on settings from the others. It also feels like it's
easier to extract common code for ofdrm. And the pipeline is static, so
it doesn't require complex chains of helper calls. Having everything in
one helper seems beneficial. (It's a trade-off, I know.)
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
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-27 07:59:04
Hi
Am 25.07.22 um 17:46 schrieb Javier Martinez Canillas:
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Replace the simple-KMS helpers with the regular atomic helpers. The
regular helpers are better architectured and therefore allow for easier
code sharing among drivers. No functional changes.
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
But I've a question below...
The code also looks like we don't need the helpers. I mostly added them
for the comments they contain, but I can also add those next to
simpledrm_crtc_helper_funcs.
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
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-27 08:24:48
Hi
Am 25.07.22 um 18:23 schrieb Javier Martinez Canillas:
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Move some of simpledrm's functionality into a helper library. Other
drivers for firmware-provided framebuffers will also need functions
to handle fixed modes and color formats, or update the back buffer.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Nice patch!
TBH it took me 3 tries to get something done for this library and I'm
still not happy with the result. I want to share code between simpledrm
and ofdrm, but that turns out to be harder then expected. A good part of
this code appears to belong into other libraries (you also mentioned
this below).
I don't want to duplicated code between simpledrm and ofdrm without
reason, but I expect that this library will somewhen be refactored and
dissolved into existing libraries.
[...]
quoted
+
+/**
+ * DOC: overview
+ *
+ * The Firmware Framebuffer library FWFB provides helpers for devices with
+ * fixed-mode backing storage. It helps drivers to export a display mode of
+ * te correct size and copy updates to the backing storage.
the
it is "backing storage" or "backing store" ? I always thought that storage was
used for non-volatile media while "store" could be volatile and non-volatile.
Why store? Isn't that a little shop for fashion or groceries? I'm no
native speaker; I can't tell if either implies that we're sending
pictures to a warehouse or bakery. :)
Would 'back buffer' (in contrast to 'shadow buffer') be clear?
[...]
quoted
+/**
+ * drm_fwfb_init - Initializes an fwfb buffer
+ * @fwfb: fwfb buffer
+ * @screen_base: Address of the backing buffer in kernel address space
+ * @width: Number of pixels per scanline
+ * @height: Number of scanlines
+ * @format: Color format
+ * @pitch: Distance between two consecutive scanlines in bytes
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_fwfb_init(struct drm_fwfb *fwfb, struct iosys_map *screen_base,
+ unsigned int width, unsigned int height,
+ const struct drm_format_info *format, unsigned int pitch)
+{
+ fwfb->screen_base = *screen_base;
+ fwfb->mode = drm_fwfb_mode(width, height);
+ fwfb->format = format;
It seems a little bit arbitrary to me that format is the only field that's
a pointer and the other ones are embedded into the struct drm_fwfb. Any
reason for that or is just a consequence of how types were used by the
simpledrm_device_create() function before that code moved into helpers ?
Format is constant and comes from statically initialized memory in
drm_fourcc.c. I'd expect to be able to compare formats by comparing the
pointers. Copying the format here would break the assumption.
This seems a helper that could be useful besides the drm_fwfb_helper.c file.
I believe patches 1-6 shouldn't wait for the others in this series and could
just be merged when ready. Patches 7-10 can follow later.
Yeah, I'd like to move patches 1 to 5 into a new series for merging.
Patch 6 is only useful for ofdrm and as I said, maybe there's a better
solution then this library. I'd rather keep it here for now.
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
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-27 08:33:31
Hi
Am 26.07.22 um 21:22 schrieb Javier Martinez Canillas:
Hello Michal,
On 7/26/22 16:40, Michal Suchánek wrote:
quoted
Hello,
On Tue, Jul 26, 2022 at 03:38:37PM +0200, Javier Martinez Canillas wrote:
quoted
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Add a per-model device-function structure in preparation of adding
color-management support. Detection of the individual models has been
taken from fbdev's offb.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
quoted
+static bool is_avivo(__be32 vendor, __be32 device)
+{
+ /* This will match most R5xx */
+ return (vendor == 0x1002) &&
+ ((device >= 0x7100 && device < 0x7800) || (device >= 0x9400));
+}
Maybe add some constant macros to not have these magic numbers ?
This is based on the existing fbdev implementation's magic numbers:
drivers/video/fbdev/offb.c: ((*did >= 0x7100 && *did < 0x7800) ||
Ah, I see. Then we might have to go with the magic numbers...
quoted
Of course, it would be great if somebody knowledgeable could clarify
those.
Those are PCI ids. If I find them already defined, I'll use the macros
instead.
Best regards
Thomas
quoted
Indeed.
--
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
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-27 08:41:20
Hi
Am 26.07.22 um 15:49 schrieb Javier Martinez Canillas:
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
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 <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
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.
@@ -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
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-27 09:30:42
Hello Thomas,
On 7/27/22 09:50, Thomas Zimmermann wrote:
Hi
Am 25.07.22 um 17:01 schrieb Javier Martinez Canillas:
quoted
Hello Thomas,
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Inline the helpers for initializing the hardware FB, the memory
management and the modesetting into the device-creation function.
No functional changes.
Could you please elaborate in the commit message why this change is
desirable? Without this additional context, this feels like going
backwards, since you are dropping few helpers that have quite self
contained code and making simpledrm_device_create() much larger.
To clarify: I want to make the init code more easy to follow. These old
init functions still had to be called in the right order as each > possibly depends on settings from the others. It also feels like it's
easier to extract common code for ofdrm. And the pipeline is static, so
it doesn't require complex chains of helper calls. Having everything in
one helper seems beneficial. (It's a trade-off, I know.)
I see. That makes sense to me. Could you please add the explanation to
the commit message ? And feel free to add my Acked-by for this one too.
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
From: Javier Martinez Canillas <javierm@redhat.com> Date: 2022-07-27 09:39:40
On 7/27/22 10:24, Thomas Zimmermann wrote:
Hi
Am 25.07.22 um 18:23 schrieb Javier Martinez Canillas:
quoted
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Move some of simpledrm's functionality into a helper library. Other
drivers for firmware-provided framebuffers will also need functions
to handle fixed modes and color formats, or update the back buffer.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Nice patch!
TBH it took me 3 tries to get something done for this library and I'm
still not happy with the result. I want to share code between simpledrm
and ofdrm, but that turns out to be harder then expected. A good part of
this code appears to belong into other libraries (you also mentioned
this below).
I don't want to duplicated code between simpledrm and ofdrm without
reason, but I expect that this library will somewhen be refactored and
dissolved into existing libraries.
Yes, I think is a step in the right direction and guess it would be even
more useful once/if a 3rd firmware-provided framebuffer driver is added.
quoted
[...]
quoted
+
+/**
+ * DOC: overview
+ *
+ * The Firmware Framebuffer library FWFB provides helpers for devices with
+ * fixed-mode backing storage. It helps drivers to export a display mode of
+ * te correct size and copy updates to the backing storage.
the
it is "backing storage" or "backing store" ? I always thought that storage was
used for non-volatile media while "store" could be volatile and non-volatile.
Why store? Isn't that a little shop for fashion or groceries? I'm no
native speaker; I can't tell if either implies that we're sending
pictures to a warehouse or bakery. :)
LOL.
Would 'back buffer' (in contrast to 'shadow buffer') be clear?
Back buffer is more clear indeed.
[...]
quoted
It seems a little bit arbitrary to me that format is the only field that's
a pointer and the other ones are embedded into the struct drm_fwfb. Any
reason for that or is just a consequence of how types were used by the
simpledrm_device_create() function before that code moved into helpers ?
Format is constant and comes from statically initialized memory in
drm_fourcc.c. I'd expect to be able to compare formats by comparing the
pointers. Copying the format here would break the assumption.
This seems a helper that could be useful besides the drm_fwfb_helper.c file.
I believe patches 1-6 shouldn't wait for the others in this series and could
just be merged when ready. Patches 7-10 can follow later.
Yeah, I'd like to move patches 1 to 5 into a new series for merging.
Patch 6 is only useful for ofdrm and as I said, maybe there's a better
solution then this library. I'd rather keep it here for now.
OK.
--
Best regards,
Javier Martinez Canillas
Linux Engineering
Red Hat
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.
[...]
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
From: Michael Ellerman <mpe@ellerman.id.au> Date: 2022-07-28 11:21:56
Thomas Zimmermann [off-list ref] writes:
(was: drm: Add driverof PowerPC OF displays)
PowerPC's Open Firmware offers a simple display buffer for graphics
output. Add ofdrm, a DRM driver for the device. As with the existing
simpledrm driver, the graphics hardware is pre-initialized by the
firmware. The driver only provides blitting, no actual DRM modesetting
is possible.
Hi Thomas,
I tried to test this on a 32-bit ppc Mac Mini but didn't have much luck.
But I'm probably doing something wrong because I'm a graphics noob.
The machine normally uses CONFIG_DRM_RADEON, so I turned that off, and
turned DRM_OFDRM on.
When I boot I get boot messages but only one screen worth, the messages
don't scroll at all, which is unusual. But I'm not sure if that's
related to ofdrm or something else.
The machine does come up, I can login via SSH. Is there some way to
start X to exercise the driver from an SSH login?
cheers
From: Michal Suchánek <hidden> Date: 2022-07-28 11:32:13
Hello,
On Thu, Jul 28, 2022 at 09:13:59PM +1000, Michael Ellerman wrote:
Thomas Zimmermann [off-list ref] writes:
quoted
(was: drm: Add driverof PowerPC OF displays)
PowerPC's Open Firmware offers a simple display buffer for graphics
output. Add ofdrm, a DRM driver for the device. As with the existing
simpledrm driver, the graphics hardware is pre-initialized by the
firmware. The driver only provides blitting, no actual DRM modesetting
is possible.
Hi Thomas,
I tried to test this on a 32-bit ppc Mac Mini but didn't have much luck.
But I'm probably doing something wrong because I'm a graphics noob.
The machine normally uses CONFIG_DRM_RADEON, so I turned that off, and
turned DRM_OFDRM on.
When I boot I get boot messages but only one screen worth, the messages
don't scroll at all, which is unusual. But I'm not sure if that's
related to ofdrm or something else.
A somewhat interesting datapoint might be how this works with offb.
The machine does come up, I can login via SSH. Is there some way to
start X to exercise the driver from an SSH login?
The startx script provided by distribution usually works.
It's basically a very convoluted way to do something like
X :0&
DISPLAY=:0 xterm&
Thanks
Michal
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-07-28 11:42:54
Hi
Am 28.07.22 um 13:13 schrieb Michael Ellerman:
Thomas Zimmermann [off-list ref] writes:
quoted
(was: drm: Add driverof PowerPC OF displays)
PowerPC's Open Firmware offers a simple display buffer for graphics
output. Add ofdrm, a DRM driver for the device. As with the existing
simpledrm driver, the graphics hardware is pre-initialized by the
firmware. The driver only provides blitting, no actual DRM modesetting
is possible.
Hi Thomas,
I tried to test this on a 32-bit ppc Mac Mini but didn't have much luck.
Awesome! Thanks for testing.
But I'm probably doing something wrong because I'm a graphics noob.
The machine normally uses CONFIG_DRM_RADEON, so I turned that off, and
turned DRM_OFDRM on.
It needs
CONFIG_DRM=y
CONFIG_OFDRM=y
CONFIG_FB=y
CONFIG_DRM_FBDEV_EMULATION=y
plus some dependencies, but menuconfig should select them automatically.
I've attached my config for ppc64le, which has the correct DRM and FB
options.
When I boot I get boot messages but only one screen worth, the messages
don't scroll at all, which is unusual. But I'm not sure if that's
related to ofdrm or something else.
The machine does come up, I can login via SSH. Is there some way to
start X to exercise the driver from an SSH login?
For ofdrm, X needs a patch that isn't there yet. It's a trivial change
along the lines of [1], but still missing. So X is probably not worth
trying yet.
But at least the framebuffer console should work.
I suspect that it's an issue with the framebuffer's color mode, which
might not be supported yet. Could you please fetch the output from dmesg
after the machine booted?
Best regards
Thomas
[1]
https://gitlab.freedesktop.org/xorg/xserver/-/commit/b9218fadf3c09d83566549279d68886d8258f79c
cheers
--
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
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.
From: Benjamin Herrenschmidt <benh@kernel.crashing.org> Date: 2022-08-05 01:10:14
On Tue, 2022-07-26 at 16:40 +0200, Michal Suchánek wrote:
Hello,
On Tue, Jul 26, 2022 at 03:38:37PM +0200, Javier Martinez Canillas wrote:
quoted
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Add a per-model device-function structure in preparation of adding
color-management support. Detection of the individual models has been
taken from fbdev's offb.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
quoted
+static bool is_avivo(__be32 vendor, __be32 device)
+{
+ /* This will match most R5xx */
+ return (vendor == 0x1002) &&
+ ((device >= 0x7100 && device < 0x7800) || (device >= 0x9400));
+}
Maybe add some constant macros to not have these magic numbers ?
This is based on the existing fbdev implementation's magic numbers:
drivers/video/fbdev/offb.c: ((*did >= 0x7100 && *did < 0x7800) ||
Of course, it would be great if somebody knowledgeable could clarify
those.
I don't think anybody remembers :-) Vendor 0x1002 is PCI_VENDOR_ID_ATI,
but the rest is basically ranges of PCI IDs for which we don't have
symbolic constants.
Cheers,
Ben.
I think you meant here:
DIV_ROUND_UP(drm_format_info_bpp(format, 0) * width, 8) ?
I guess, that's the right function. My original code is correct, but cpp
is also deprecated.
You all mean drm_format_info_min_pitch().
I really don't want drivers to go grab any of the legacy format info
fields like bpp or depth. switch() statements on the fourcc code for
programming registers, or one of the real helper functions in
drm_fourcc.c (there might be some gaps), but not ever going through
legacy concepts. Anything else just leads to subtle bugs when new
formats get added and oops suddenly the assumptions don't hold.
Those should be strictly limited to legacy (i.e. not drm_fourcc aware)
interfaces. Heck I think even fbdev emulation should completely switch
over to drm_fourcc/drm_format_info, but alas that's a pile of work and
not much payoff.
I'm trying to volunteer Same to add a legacy_bpp tag to the above
helper and appropriately limit it, I think limiting to formats with
depth!=0 is probably the right thing. And then we should probably
remove a pile of the cargo-culted depth!=0 entries too.
-Daniel
Best regards
Thomas
quoted
With that change,
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
--
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
I think you meant here:
DIV_ROUND_UP(drm_format_info_bpp(format, 0) * width, 8) ?
I guess, that's the right function. My original code is correct, but cpp
is also deprecated.
You all mean drm_format_info_min_pitch().
Thanks a lot. I wasn't even aware of this function, but I had almost
written my own implementation of it. I'll update the patch accordingly.
Best regards
Thomas
I really don't want drivers to go grab any of the legacy format info
fields like bpp or depth. switch() statements on the fourcc code for
programming registers, or one of the real helper functions in
drm_fourcc.c (there might be some gaps), but not ever going through
legacy concepts. Anything else just leads to subtle bugs when new
formats get added and oops suddenly the assumptions don't hold.
Those should be strictly limited to legacy (i.e. not drm_fourcc aware)
interfaces. Heck I think even fbdev emulation should completely switch
over to drm_fourcc/drm_format_info, but alas that's a pile of work and
not much payoff.
I'm trying to volunteer Same to add a legacy_bpp tag to the above
helper and appropriately limit it, I think limiting to formats with
depth!=0 is probably the right thing. And then we should probably
remove a pile of the cargo-culted depth!=0 entries too.
-Daniel
quoted
Best regards
Thomas
quoted
With that change,
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
--
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
--
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
I think you meant here:
DIV_ROUND_UP(drm_format_info_bpp(format, 0) * width, 8) ?
I guess, that's the right function. My original code is correct, but cpp
is also deprecated.
You all mean drm_format_info_min_pitch().
Thanks a lot. I wasn't even aware of this function, but I had almost
written my own implementation of it. I'll update the patch accordingly.
Arghh, too late. I merged that patch already.
Best regards
Thomas
quoted
I really don't want drivers to go grab any of the legacy format info
fields like bpp or depth. switch() statements on the fourcc code for
programming registers, or one of the real helper functions in
drm_fourcc.c (there might be some gaps), but not ever going through
legacy concepts. Anything else just leads to subtle bugs when new
formats get added and oops suddenly the assumptions don't hold.
Those should be strictly limited to legacy (i.e. not drm_fourcc aware)
interfaces. Heck I think even fbdev emulation should completely switch
over to drm_fourcc/drm_format_info, but alas that's a pile of work and
not much payoff.
I'm trying to volunteer Same to add a legacy_bpp tag to the above
helper and appropriately limit it, I think limiting to formats with
depth!=0 is probably the right thing. And then we should probably
remove a pile of the cargo-culted depth!=0 entries too.
-Daniel
quoted
Best regards
Thomas
quoted
With that change,
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
--
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
--
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
I think you meant here:
DIV_ROUND_UP(drm_format_info_bpp(format, 0) * width, 8) ?
I guess, that's the right function. My original code is correct, but cpp
is also deprecated.
You all mean drm_format_info_min_pitch().
Thanks a lot. I wasn't even aware of this function, but I had almost
written my own implementation of it. I'll update the patch accordingly.
Arghh, too late. I merged that patch already.
Reviewed-by: Daniel Vetter <redacted>
Preemptively, if you can do the fixup patch (and it's not yet merged)?
-Daniel
quoted
Best regards
Thomas
quoted
I really don't want drivers to go grab any of the legacy format info
fields like bpp or depth. switch() statements on the fourcc code for
programming registers, or one of the real helper functions in
drm_fourcc.c (there might be some gaps), but not ever going through
legacy concepts. Anything else just leads to subtle bugs when new
formats get added and oops suddenly the assumptions don't hold.
Those should be strictly limited to legacy (i.e. not drm_fourcc aware)
interfaces. Heck I think even fbdev emulation should completely switch
over to drm_fourcc/drm_format_info, but alas that's a pile of work and
not much payoff.
I'm trying to volunteer Same to add a legacy_bpp tag to the above
helper and appropriately limit it, I think limiting to formats with
depth!=0 is probably the right thing. And then we should probably
remove a pile of the cargo-culted depth!=0 entries too.
-Daniel
quoted
Best regards
Thomas
quoted
With that change,
Acked-by: Javier Martinez Canillas <javierm@redhat.com>
--
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
--
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
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-09-21 11:41:52
Hi
Am 26.07.22 um 15:17 schrieb Javier Martinez Canillas:
Hello Thomas,
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Open Firmware provides basic display output via the 'display' node.
DT platform code already provides a device that represents the node's
framebuffer. Add a DRM driver for the device. The display mode and
color format is pre-initialized by the system's firmware. Runtime
modesetting via DRM is not possible. The display is useful during
early boot stages or as error fallback.
I'm not familiar with OF display but the driver looks good to me.
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
I just have a few questions below.
[...]
I don't see a binding for this in Documentation/devicetree/bindings/display.
Do we need one or it's that only required for FDT and not Open Firmware DT ?
No idea. The device is being created in drivers/of/platform.c. If offb
didn't need these bindings, ofdrm probably won't need them either.
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
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-09-21 11:45:21
Hi
Am 26.07.22 um 15:36 schrieb Javier Martinez Canillas:
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Add a dedicated CRTC state to ofdrm to later store information for
palette updates.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
drivers/gpu/drm/tiny/ofdrm.c | 62 ++++++++++++++++++++++++++++++++++--
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
quoted
+static void ofdrm_crtc_reset(struct drm_crtc *crtc)
+{
+ struct ofdrm_crtc_state *ofdrm_crtc_state;
+
+ if (crtc->state) {
+ ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));
+ crtc->state = NULL; /* must be set to NULL here */
+ }
+
+ ofdrm_crtc_state = kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);
+ if (!ofdrm_crtc_state)
+ return;
+ __drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
+}
+
IMO this function is hard to read, I would instead write it as following:
static void ofdrm_crtc_reset(struct drm_crtc *crtc)
{
struct ofdrm_crtc_state *ofdrm_crtc_state = kzalloc(sizeof(*ofdrm_crtc_state), GFP_KERNEL);
if (!ofdrm_crtc_state)
return;
if (crtc->state) {
ofdrm_crtc_state_destroy(to_ofdrm_crtc_state(crtc->state));
crtc->state = NULL; /* must be set to NULL here */
}
__drm_atomic_helper_crtc_reset(crtc, &ofdrm_crtc_state->base);
}
Also with that form I think that the crtc->state = NULL could just be dropped ?
I once had to add this line to a driver to make the DRM helpers work.
But I cannot find any longer why. Maybe it's been resolved meanwhile.
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
From: Thomas Zimmermann <tzimmermann@suse.de> Date: 2022-09-21 12:37:42
Hi
Am 05.08.22 um 02:22 schrieb Benjamin Herrenschmidt:
On Tue, 2022-07-26 at 16:40 +0200, Michal Suchánek wrote:
quoted
Hello,
On Tue, Jul 26, 2022 at 03:38:37PM +0200, Javier Martinez Canillas wrote:
quoted
On 7/20/22 16:27, Thomas Zimmermann wrote:
quoted
Add a per-model device-function structure in preparation of adding
color-management support. Detection of the individual models has been
taken from fbdev's offb.
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
[...]
quoted
+static bool is_avivo(__be32 vendor, __be32 device)
+{
+ /* This will match most R5xx */
+ return (vendor == 0x1002) &&
+ ((device >= 0x7100 && device < 0x7800) || (device >= 0x9400));
+}
Maybe add some constant macros to not have these magic numbers ?
This is based on the existing fbdev implementation's magic numbers:
drivers/video/fbdev/offb.c: ((*did >= 0x7100 && *did < 0x7800) ||
Of course, it would be great if somebody knowledgeable could clarify
those.
I don't think anybody remembers :-) Vendor 0x1002 is PCI_VENDOR_ID_ATI,
I do :)
but the rest is basically ranges of PCI IDs for which we don't have
symbolic constants.
Should we add them to the official list in pci_ids.h? I cannot find
0x7800. The others are R520 and R600.
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
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 -- geert@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
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 -- geert@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