Re: [PATCH v8 6/8] MIPS: DTS: CI20: Add DT nodes for HDMI setup
Hi Nikolaus, On Wed, Nov 24, 2021 at 5:31 PM H. Nikolaus Schaller wrote: > > Am 24.11.2021 um 17:21 schrieb Geert Uytterhoeven : > > On Wed, Nov 24, 2021 at 5:19 PM H. Nikolaus Schaller > > wrote: > >>> Am 23.11.2021 um 21:10 schrieb Paul Cercueil : > >>> Le mar., nov. 23 2021 at 19:13:59 +0100, H. Nikolaus Schaller > >>> a écrit : > +assigned-clock-rates = <4800>, <0>, <5400>, <0>, <2700>; > }; > &tcu { > @@ -509,6 +534,19 @@ pins_i2c4: i2c4 { > bias-disable; > }; > +pins_hdmi_ddc: hdmi_ddc { > +function = "hdmi-ddc"; > +groups = "hdmi-ddc"; > +bias-disable; > +}; > + > +/* switch to PF25 as gpio driving DDC_SDA low */ > +pins_hdmi_ddc_unwedge: hdmi_ddc { > +function = "hdmi-ddc"; > +groups = "hdmi-ddc"; > +bias-disable; > +}; > >>> > >>> Your pins_hdmi_ddc and pins_hdmi_ddc_unwedge are the exact same? You > >>> could just use the former and pass it to both pinctrl-0 and pinctrl-1. > >> > >> This was forgotten to remove. We do not make use of the unwedge feature > >> because I could not find out how to use pinctrl to switch this to gpio25 > >> and drive it low. > > > > Using gpio-hog? > > well, AFAIR it activates the gpio permanently and is a propery of the gpio > controller and not of pinmux. Yes, hogs are permanently (ignoring DT overlay tricks). > The driver assumes it can use pinmux state switching to drive the DDC_SDA > line low on demand. Add an optional wedge-gpios property for switching? 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 07/11] dmaengine: qcom-adm: stop abusing slave_id config
Hi Arnd, I love your patch! Perhaps something to improve: [auto build test WARNING on vkoul-dmaengine/next] [also build test WARNING on tiwai-sound/for-next staging/staging-testing linus/master v5.16-rc2 next-20211125] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Arnd-Bergmann/dmaengine-kill-off-dma_slave_config-slave_id/2025-165731 base: https://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine.git next config: riscv-randconfig-r016-2025 (https://download.01.org/0day-ci/archive/20211125/202111251538.x6sjncka-...@intel.com/config) compiler: clang version 14.0.0 (https://github.com/llvm/llvm-project fbe72e41b99dc7994daac300d208a955be3e4a0a) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install riscv cross compiling tool for clang build # apt-get install binutils-riscv64-linux-gnu # https://github.com/0day-ci/linux/commit/f2e7f9ee67ce784864f75db39f20d1060c932279 git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Arnd-Bergmann/dmaengine-kill-off-dma_slave_config-slave_id/2025-165731 git checkout f2e7f9ee67ce784864f75db39f20d1060c932279 # save the config file to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 ARCH=riscv If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/dma/qcom/qcom_adm.c:712:18: warning: no previous prototype for >> function 'adm_dma_xlate' [-Wmissing-prototypes] struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec, ^ drivers/dma/qcom/qcom_adm.c:712:1: note: declare 'static' if the function is not intended to be used outside of this translation unit struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec, ^ static 1 warning generated. vim +/adm_dma_xlate +712 drivers/dma/qcom/qcom_adm.c 700 701 /** 702 * adm_dma_xlate 703 * @dma_spec: pointer to DMA specifier as found in the device tree 704 * @ofdma: pointer to DMA controller data 705 * 706 * This can use either 1-cell or 2-cell formats, the first cell 707 * identifies the slave device, while the optional second cell 708 * contains the crci value. 709 * 710 * Returns pointer to appropriate dma channel on success or NULL on error. 711 */ > 712 struct dma_chan *adm_dma_xlate(struct of_phandle_args *dma_spec, 713 struct of_dma *ofdma) 714 { 715 struct dma_device *dev = ofdma->of_dma_data; 716 struct dma_chan *chan, *candidate = NULL; 717 struct adm_chan *achan; 718 719 if (!dev || dma_spec->args_count > 2) 720 return NULL; 721 722 list_for_each_entry(chan, &dev->channels, device_node) 723 if (chan->chan_id == dma_spec->args[0]) { 724 candidate = chan; 725 break; 726 } 727 728 if (!candidate) 729 return NULL; 730 731 achan = to_adm_chan(candidate); 732 if (dma_spec->args_count == 2) 733 achan->crci = dma_spec->args[1]; 734 else 735 achan->crci = 0; 736 737 return dma_get_slave_channel(candidate); 738 } 739 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-...@lists.01.org
Re: [PATCH 1/2] drm/msm: Handle ringbuffer overflow
On 28/04/2021 22:36, Rob Clark wrote: From: Rob Clark Currently if userspace manages to fill up the ring faster than the GPU can consume we (a) spin for up to 1sec, and then (b) overwrite the ringbuffer contents from previous submits that the GPU is still busy executing. Which predictably goes rather badly. Instead, just skip flushing (updating WPTR) and reset ring->next back to where it was before we tried writing the submit into the ringbuffer, and return an error to userspace (which can then try again). Signed-off-by: Rob Clark Rob, you've posted this patch, but never merged it. Should it be merged at some point? --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 3 +++ drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 24 +- drivers/gpu/drm/msm/msm_gem_submit.c| 7 +- drivers/gpu/drm/msm/msm_gpu.c | 33 +++-- drivers/gpu/drm/msm/msm_gpu.h | 2 +- drivers/gpu/drm/msm/msm_ringbuffer.h| 5 7 files changed, 72 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index ce13d49e615b..0c8faad3b328 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -36,6 +36,9 @@ void a5xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, OUT_RING(ring, upper_32_bits(shadowptr(a5xx_gpu, ring))); } + if (unlikely(ring->overflow)) + return; + spin_lock_irqsave(&ring->preempt_lock, flags); /* Copy the shadow to the actual register */ diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index d553f62f4eeb..4a4728a774c0 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -68,6 +68,9 @@ static void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring) OUT_RING(ring, upper_32_bits(shadowptr(a6xx_gpu, ring))); } + if (unlikely(ring->overflow)) + return; + spin_lock_irqsave(&ring->preempt_lock, flags); /* Copy the shadow to the actual register */ diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 0f184c3dd9d9..a658777e07b1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -467,6 +467,9 @@ void adreno_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring, u32 reg) { uint32_t wptr; + if (unlikely(ring->overflow)) + return; + /* Copy the shadow to the actual register */ ring->cur = ring->next; @@ -788,12 +791,31 @@ static uint32_t ring_freewords(struct msm_ringbuffer *ring) return (rptr + (size - 1) - wptr) % size; } +static bool space_avail(struct msm_ringbuffer *ring, uint32_t ndwords) +{ + if (ring_freewords(ring) >= ndwords) + return true; + + /* We don't have a good way to know in general when the RPTR has +* advanced.. newer things that use CP_WHERE_AM_I to update the +* shadow rptr could possibly insert a packet to generate an irq. +* But that doesn't cover older GPUs. But if the ringbuffer is +* full, it could take a while before it is empty again, so just +* insert a blind sleep to avoid a busy loop. +*/ + msleep(1); + + return false; +} + void adreno_wait_ring(struct msm_ringbuffer *ring, uint32_t ndwords) { - if (spin_until(ring_freewords(ring) >= ndwords)) + if (spin_until(space_avail(ring, ndwords))) { DRM_DEV_ERROR(ring->gpu->dev->dev, "timeout waiting for space in ringbuffer %d\n", ring->id); + ring->overflow = true; + } } /* Get legacy powerlevels from qcom,gpu-pwrlevels and populate the opp table */ diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 5480852bdeda..4bc669460fda 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -683,6 +683,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, submitid = atomic_inc_return(&ident) - 1; ring = gpu->rb[queue->prio]; + + GEM_WARN_ON(ring->overflow); + trace_msm_gpu_submit(pid_nr(pid), ring->id, submitid, args->nr_bos, args->nr_cmds); @@ -829,7 +832,9 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, } } - msm_gpu_submit(gpu, submit); + ret = msm_gpu_submit(gpu, submit); + if (ret) + goto out; args->fence = submit->fence->seqno; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index ab7c167b0623..7655ad9108c8 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -787,7 +787,7 @@ void msm_
Re: [PATCH v4 4/4] drm/msm/dp: dp_link_parse_sink_count() return immediately if aux read failed
On 04/05/2021 07:35, Stephen Boyd wrote: Quoting Kuogee Hsieh (2021-04-21 16:37:38) Add checking aux read/write status at both dp_link_parse_sink_count() and dp_link_parse_sink_status_filed() to avoid long timeout delay if s/filed/field/ dp aux read/write failed at timeout due to cable unplugged. Changes in V4: -- split this patch as stand alone patch Signed-off-by: Kuogee Hsieh Can this patch come before the one previously? And then some fixes tag be added? Otherwise looks good to me. Reviewed-by: Stephen Boyd Tested-by: Stephen Boyd Is this something that we still need to pursue/merge? There were changes requested for this and for the previous patch, but no new versions were posted. -- With best wishes Dmitry
Exynos DSI bridge conversion
Hi Andrej and all, I'm trying to convert existing exynos dsi driver to bridge and make them accessible for i.MX8MM platform. I've a few questions on the existing exynos dsi driver and which is indeed incompatible to proceed to make the bridge conversion. 1. Hotplug event Commit from 295e7954c0d3fdbe0550d13e3cf4dd4604d42c68 which is waiting for drm to hotplug the downstream devices like panel or bridge to probe. Any idea how it works? what if we move drm_bridge_attach in bind callback so-that binding will start once all the devices get attached. 2. Host register in bind Usual host registration is done in the probe, but the driver registers host in bind once the in_bridge is attached. any idea why? What if we find the DSI as an output port in MIC and start attaching from there? 3. CRTC handling in DSI Commit from c038f53842cf840889473d219ace7f9121694e8d is trying to send the DSI flags information to CRTC with a function call. any specific reason for this? Any proper way of doing this move out from DSI? 4. Mutex calls while assigning device attributes. Assignment of lanes, format, mode_flags are done in mutex context, I think we can even do it in normal context isn't it? or any specific reason for doing this? 5. Clock rates. pll_clk_rate, burst_clk_rate, burst_clk_rate are these clock rates retrieved from DT. which is not a proper way to support multi platform. I think pll-clock and burst-clock are computed based on panel pixel or bridge clocks. any specific computation for these to handle dynamically on code? All this information is essential for me to move this further as I don't have direct hardware and I'm trying to take some help from Marek Szyprowski. Please take some time, and help me. Thanks, Jagan.
Re: [PATCH 1/2] dt-bindings: display: bridge: Add TI DLPC3433 bindings
Hi Laurent, On Thu, Nov 25, 2021 at 3:53 AM Laurent Pinchart wrote: > > Hi Jagan, > > Thank you for the patch. > > On Wed, Nov 24, 2021 at 10:55:52PM +0530, Jagan Teki wrote: > > TI DLPC3433 is a MIPI DSI based display controller bridge > > for processing high resolution DMD based projectors. > > > > It has a flexible configuration of MIPI DSI signal input > > produces RGB565, RGB666, RGB888 output format with maximum > > of 720p resolution in 60 and 120 Hz refresh rates. > > > > Add dt-bingings for it. > > > > Signed-off-by: Christopher Vollo > > Signed-off-by: Jagan Teki > > --- > > .../bindings/display/bridge/ti,dlpc3433.yaml | 112 ++ > > MAINTAINERS | 6 + > > 2 files changed, 118 insertions(+) > > create mode 100644 > > Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > > > > diff --git > > a/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > > b/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > > new file mode 100644 > > index ..3ade3a575c3e > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > > @@ -0,0 +1,112 @@ > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > > +%YAML 1.2 > > +--- > > +$id: http://devicetree.org/schemas/display/bridge/ti,dlpc3433.yaml# > > +$schema: http://devicetree.org/meta-schemas/core.yaml# > > + > > +title: TI DLPC3433 Display Controller > > + > > +maintainers: > > + - Jagan Teki > > + - Christopher Vollo > > + > > +description: | > > + The DLPC3433 or DLPC3438 controllers provide a convenient, > > + multi-functional interface between system electronics and > > + the DMD, enabling small form factor, low power, and high > > + resolution HD displays. > > You may want to mention in the title and/or description that this is a > DSI to DMD bridge. Actually, the device also supports a DPI input, which > should be modelled in the DT bindings. How can we model DPI since it is a DSI bridge bindings? Does it mean we can add another node example to have DPI instead of DSI? > > > + > > +properties: > > + compatible: > > +enum: > > + - ti,dlpc3433 > > Or just > > compatible: > const: ti,dlpc3433 > > > + > > + reg: > > +maxItems: 1 > > +description: virtual channel number of a DSI peripheral > > I don't think this is right, the reg is the I2C address. You can drop > the description. > > > + > > + enable-gpios: > > +description: PROJ_EN pin, chip powers up PROJ_EN is high. > > It's called PROJ_ON, not PROJ_EN, in the datasheet. > > > + > > + vcc_intf-supply: > > +description: A 1.8V/3.3V supply that power the Host I/O. > > + > > + vcc_flsh-supply: > > +description: A 1.8V/3.3V supply that power the Flash I/O. > > + > > + ports: > > +$ref: /schemas/graph.yaml#/properties/ports > > + > > +properties: > > + port@0: > > +$ref: /schemas/graph.yaml#/$defs/port-base > > +unevaluatedProperties: false > > +description: Video port for MIPI DSI input. > > + > > +properties: > > + endpoint: > > +$ref: /schemas/media/video-interfaces.yaml# > > +unevaluatedProperties: false > > + > > +properties: > > + data-lanes: > > +description: array of physical DSI data lane indexes. > > +minItems: 1 > > +items: > > + - const: 1 > > + - const: 2 > > + - const: 3 > > + - const: 4 > > + > > + port@1: > > +$ref: /schemas/graph.yaml#/properties/port > > +description: Video port for DPI output (DMD Projector). > > The output isn't DPI, but DMD. > > > + > > +required: > > + - port@0 > > + - port@1 > > + > > +required: > > + - compatible > > + - reg > > + - enable-gpios > > Can the chip be used with the PROJ_ON input hardwired to a high logic > state, or does it need to be controlled ? PROJ_ON require an explicit enablement via driver in order to have device out-of-reset. Thanks, Jagan.
Re: [PATCH 1/2] dt-bindings: display: bridge: Add TI DLPC3433 bindings
Hi Fabio, On Thu, Nov 25, 2021 at 12:47 AM Fabio Estevam wrote: > > Hi Jagan, > > On Wed, Nov 24, 2021 at 2:26 PM Jagan Teki wrote: > > > > TI DLPC3433 is a MIPI DSI based display controller bridge > > for processing high resolution DMD based projectors. > > > > It has a flexible configuration of MIPI DSI signal input > > produces RGB565, RGB666, RGB888 output format with maximum > > of 720p resolution in 60 and 120 Hz refresh rates. > > > > Add dt-bingings for it. > > > > Signed-off-by: Christopher Vollo > > Signed-off-by: Jagan Teki > > --- > > .../bindings/display/bridge/ti,dlpc3433.yaml | 112 ++ > > MAINTAINERS | 6 + > > Shouldn't the MAINTAINERS change be part of patch 2/2 instead? I usually go the initial entry as part of bindings patch since checkpatch fires a warning if i added 2/2 WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? #23: new file mode 100644 Jagan.
Re: [PATCH v3 1/9] drm: vkms: Replace the deprecated drm_mode_config_init
Hi Igor, just some nits on the commit message. On Mon, Nov 22, 2021 at 04:43:52PM -0300, Igor Torrente wrote: > The `drm_mode_config_init` was deprecated since c3b790e commit, and it's When referring to other commits, it's best to write it as 'commit <12-digit-SHA> ("description")' [1]. Also, imperative mood works best, so my suggestion would be: `drm_mode_config_init` is deprecated since commit c3b790ea07a1 ("drm: Manage drm_mode_config_init with drmm_") in favor of `drmm_mode_config_init`. Update the former to the latter. Thanks, Nícolas [1] https://www.kernel.org/doc/html/latest/process/submitting-patches.html#describe-your-changes > being replaced by the `drmm_mode_config_init`. > > Signed-off-by: Igor Torrente > --- > V2: Change the code style(Thomas Zimmermann). > --- > drivers/gpu/drm/vkms/vkms_drv.c | 6 +- > 1 file changed, 5 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c > index 0ffe5f0e33f7..ee4d96dabe19 100644 > --- a/drivers/gpu/drm/vkms/vkms_drv.c > +++ b/drivers/gpu/drm/vkms/vkms_drv.c > @@ -140,8 +140,12 @@ static const struct drm_mode_config_helper_funcs > vkms_mode_config_helpers = { > static int vkms_modeset_init(struct vkms_device *vkmsdev) > { > struct drm_device *dev = &vkmsdev->drm; > + int ret; > + > + ret = drmm_mode_config_init(dev); > + if (ret < 0) > + return ret; > > - drm_mode_config_init(dev); > dev->mode_config.funcs = &vkms_mode_funcs; > dev->mode_config.min_width = XRES_MIN; > dev->mode_config.min_height = YRES_MIN; > -- > 2.30.2 >
Re: [PATCH v1 7/9] lib: add support for device coherent type in test_hmm
Am 2021-11-15 um 2:30 p.m. schrieb Alex Sierra: > Device Coherent type uses device memory that is coherently accesible by > the CPU. This could be shown as SP (special purpose) memory range > at the BIOS-e820 memory enumeration. If no SP memory is supported in > system, this could be faked by setting CONFIG_EFI_FAKE_MEMMAP. > > Currently, test_hmm only supports two different SP ranges of at least > 256MB size. This could be specified in the kernel parameter variable > efi_fake_mem. Ex. Two SP ranges of 1GB starting at 0x1 & > 0x14000 physical address. Ex. > efi_fake_mem=1G@0x1:0x4,1G@0x14000:0x4 > > Signed-off-by: Alex Sierra > --- > lib/test_hmm.c | 191 +--- > lib/test_hmm_uapi.h | 15 ++-- > 2 files changed, 153 insertions(+), 53 deletions(-) > > diff --git a/lib/test_hmm.c b/lib/test_hmm.c > index 45334df28d7b..9e2cc0cd4412 100644 > --- a/lib/test_hmm.c > +++ b/lib/test_hmm.c > @@ -471,6 +471,7 @@ static int dmirror_allocate_chunk(struct dmirror_device > *mdevice, > unsigned long pfn_first; > unsigned long pfn_last; > void *ptr; > + int ret = -ENOMEM; > > devmem = kzalloc(sizeof(*devmem), GFP_KERNEL); > if (!devmem) > @@ -553,7 +554,7 @@ static int dmirror_allocate_chunk(struct dmirror_device > *mdevice, > } > spin_unlock(&mdevice->lock); > > - return true; > + return 0; You're changing the meaning of the return value, but you're not updating the callers. I think at least dmirror_devmem_alloc_page will be broken by this change. > > err_release: > mutex_unlock(&mdevice->devmem_lock); > @@ -562,7 +563,7 @@ static int dmirror_allocate_chunk(struct dmirror_device > *mdevice, > err_devmem: > kfree(devmem); > > - return false; > + return ret; > } > > static struct page *dmirror_devmem_alloc_page(struct dmirror_device *mdevice) > @@ -571,8 +572,10 @@ static struct page *dmirror_devmem_alloc_page(struct > dmirror_device *mdevice) > struct page *rpage; > > /* > - * This is a fake device so we alloc real system memory to store > - * our device memory. > + * For ZONE_DEVICE private type, this is a fake device so we alloc real > + * system memory to store our device memory. > + * For ZONE_DEVICE coherent type we use the actual dpage to store the > data > + * and ignore rpage. >*/ > rpage = alloc_page(GFP_HIGHUSER); > if (!rpage) > @@ -623,12 +626,17 @@ static void dmirror_migrate_alloc_and_copy(struct > migrate_vma *args, >* unallocated pte_none() or read-only zero page. >*/ > spage = migrate_pfn_to_page(*src); > + if (spage && is_zone_device_page(spage)) > + pr_err("page already in device spage pfn: 0x%lx\n", > + page_to_pfn(spage)); > + WARN_ON(spage && is_zone_device_page(spage)); You can write WARN_ON inside the if-condition: if (WARN_ON(spage && is_zone_device_page(spage)) ... But I don't see why you need both pr_err and WARN_ON. You can add a custom message by using WARN instead of WARN_ON: WARN(spage && is_zone_device_page(spage), "page already in device spage pfn: 0x%lx\n", page_to_pfn(spage)); > > dpage = dmirror_devmem_alloc_page(mdevice); > if (!dpage) > continue; > > - rpage = dpage->zone_device_data; > + rpage = is_device_private_page(dpage) ? dpage->zone_device_data > : > + dpage; > if (spage) > copy_highpage(rpage, spage); > else > @@ -640,8 +648,11 @@ static void dmirror_migrate_alloc_and_copy(struct > migrate_vma *args, >* the simulated device memory and that page holds the pointer >* to the mirror. >*/ > + rpage = dpage->zone_device_data; > rpage->zone_device_data = dmirror; > > + pr_debug("migrating from sys to dev pfn src: 0x%lx pfn dst: > 0x%lx\n", > + page_to_pfn(spage), page_to_pfn(dpage)); > *dst = migrate_pfn(page_to_pfn(dpage)) | > MIGRATE_PFN_LOCKED; > if ((*src & MIGRATE_PFN_WRITE) || > @@ -721,10 +732,13 @@ static int dmirror_migrate_finalize_and_map(struct > migrate_vma *args, > continue; > > /* > - * Store the page that holds the data so the page table > - * doesn't have to deal with ZONE_DEVICE private pages. > + * For ZONE_DEVICE private pages we store the page that > + * holds the data so the page table doesn't have to deal it. > + * For ZONE_DEVICE coherent pages we store the actual page, > since > + * the CPU
Re: [PATCH 1/2] dt-bindings: display: bridge: Add TI DLPC3433 bindings
Hi Jagan, Thank you for the patch. On Wed, Nov 24, 2021 at 10:55:52PM +0530, Jagan Teki wrote: > TI DLPC3433 is a MIPI DSI based display controller bridge > for processing high resolution DMD based projectors. > > It has a flexible configuration of MIPI DSI signal input > produces RGB565, RGB666, RGB888 output format with maximum > of 720p resolution in 60 and 120 Hz refresh rates. > > Add dt-bingings for it. > > Signed-off-by: Christopher Vollo > Signed-off-by: Jagan Teki > --- > .../bindings/display/bridge/ti,dlpc3433.yaml | 112 ++ > MAINTAINERS | 6 + > 2 files changed, 118 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > > diff --git > a/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > b/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > new file mode 100644 > index ..3ade3a575c3e > --- /dev/null > +++ b/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml > @@ -0,0 +1,112 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/display/bridge/ti,dlpc3433.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: TI DLPC3433 Display Controller > + > +maintainers: > + - Jagan Teki > + - Christopher Vollo > + > +description: | > + The DLPC3433 or DLPC3438 controllers provide a convenient, > + multi-functional interface between system electronics and > + the DMD, enabling small form factor, low power, and high > + resolution HD displays. You may want to mention in the title and/or description that this is a DSI to DMD bridge. Actually, the device also supports a DPI input, which should be modelled in the DT bindings. > + > +properties: > + compatible: > +enum: > + - ti,dlpc3433 Or just compatible: const: ti,dlpc3433 > + > + reg: > +maxItems: 1 > +description: virtual channel number of a DSI peripheral I don't think this is right, the reg is the I2C address. You can drop the description. > + > + enable-gpios: > +description: PROJ_EN pin, chip powers up PROJ_EN is high. It's called PROJ_ON, not PROJ_EN, in the datasheet. > + > + vcc_intf-supply: > +description: A 1.8V/3.3V supply that power the Host I/O. > + > + vcc_flsh-supply: > +description: A 1.8V/3.3V supply that power the Flash I/O. > + > + ports: > +$ref: /schemas/graph.yaml#/properties/ports > + > +properties: > + port@0: > +$ref: /schemas/graph.yaml#/$defs/port-base > +unevaluatedProperties: false > +description: Video port for MIPI DSI input. > + > +properties: > + endpoint: > +$ref: /schemas/media/video-interfaces.yaml# > +unevaluatedProperties: false > + > +properties: > + data-lanes: > +description: array of physical DSI data lane indexes. > +minItems: 1 > +items: > + - const: 1 > + - const: 2 > + - const: 3 > + - const: 4 > + > + port@1: > +$ref: /schemas/graph.yaml#/properties/port > +description: Video port for DPI output (DMD Projector). The output isn't DPI, but DMD. > + > +required: > + - port@0 > + - port@1 > + > +required: > + - compatible > + - reg > + - enable-gpios Can the chip be used with the PROJ_ON input hardwired to a high logic state, or does it need to be controlled ? > + - ports > + > +additionalProperties: false > + > +examples: > + - | > +#include > + > +i2c1 { > +#address-cells = <1>; > +#size-cells = <0>; > + > +bridge@1d { > +compatible = "ti,dlpc3433"; > +reg = <0x1d>; > +enable-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; > + > +ports { > +#address-cells = <1>; > +#size-cells = <0>; > + > +port@0 { > +reg = <0>; > + > +bridge_in_dsi: endpoint { > +remote-endpoint = <&dsi_out_bridge>; > +data-lanes = <1 2 3 4>; > +}; > +}; > + > +port@1 { > +reg = <1>; > + > +bridge_out_panel: endpoint { > +remote-endpoint = <&panel_out_bridge>; > +}; > +}; > +}; > +}; > +}; > diff --git a/MAINTAINERS b/MAINTAINERS > index f32c7d733255..a3019399dec0 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -6198,6 +6198,12 @@ DRM DRIVER FOR TDFX VIDEO CARDS > S: Orphan / Obsolete > F: drivers/gpu/drm/tdfx/ > > +DRM DRIVER FOR TI DLPC3433 MIPI DSI DISPLAY CONTROLLER BRIDGE > +M: Jagan Teki > +M: Christopher Vollo > +S: Maintained > +F: Documentation/devicetree/bindings/d
Re: [PATCH 0/6] drm/tiny/st7735r: Match up with staging/fbtft driver
On 11/24/21 9:07 AM, Noralf Trønnes wrote: Hi, This patchset adds a missing piece for decommissioning the staging/fbtft/fb_st7735r.c driver namely a way to configure the controller from Device Tree. All fbtft drivers have builtin support for one display panel and all other panels using that controller are configured using the Device Tree 'init' property. This property is supported by all fbtft drivers and provides a generic way to set register values or issue commands (depending on the type of controller). It is common for these types of displays to have a datasheet listing the necessary controller settings/commands or some example code doing the same. This is how the panel directly supported by the fb_st7735r staging driver is described using Device Tree with that driver: width = <160>; height = <128>; init = <0x101 0x296 0x111 0x2ff 0x1B1 0x01 0x2C 0x2D 0x1B4 0x07 0x1C0 0xA2 0x02 0x84 0x1C1 0xC5 0x1C2 0x0A 0x00 0x1C5 0x0E 0x13a 0x55 0x136 0x60 0x1E0 0x0F 0x1A 0x0F 0x18 0x2F 0x28 0x20 0x22 0x1F 0x1B 0x23 0x37 0x00 0x07 0x02 0x10 0x1E1 0x0F 0x1B 0x0F 0x17 0x33 0x2C 0x29 0x2E 0x30 0x30 0x39 0x3F 0x00 0x07 0x03 0x10 0x129 0x264>; This is how the same panel is described using the st7735r drm driver and this patchset: width = <160>; height = <128>; frmctr1 = [ 01 2C 2D ]; invctr = [ 07 ]; pwctr1 = [ A2 02 84 ]; pwctr2 = [ C5 ]; pwctr3 = [ 0A 00 ]; vmctr1 = [ 0E ]; madctl = [ 60 ]; gamctrp1 = [ 0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10 ]; gamctrn1 = [ 0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10 ]; Do these setting correspond to actual physical properties of the display? What is the advantage of this compared to just adding a new compatible string if a new display requires different settings? (Other than being able to use a new display without compiling a new kernel/module.) It is nice for the driver implementation to be able to use the byte arrays from the binding directly, but it doesn't really make sense from a "device tree describes the hardware" point of view. For example, looking at the data sheet, frmctr1 looks like it is actually multiple properties, the 1-line period, front porch and back porch. Back when the fbtft drivers were added to staging I asked on the DT mailinglist if it was OK to use the 'init' property but it was turned down. In this patchset I'm trying the same approach used by the solomon,ssd1307fb.yaml binding in describing the attached panel. That binding prefixes the properties with the vendor name, not sure why that is and I think it looks strange so I try without it. Because [1] says so? "DO use a vendor prefix on device-specific property names. Consider if properties could be common among devices of the same class. Check other existing bindings for similar devices." Do all displays have "frmctr1" or only sitronix displays? [1]: https://www.kernel.org/doc/html/latest/devicetree/bindings/writing-bindings.html Noralf. Noralf Trønnes (6): dt-bindings: display: sitronix,st7735r: Fix backlight in example dt-bindings: display: sitronix,st7735r: Make reset-gpios optional dt-bindings: display: sitronix,st7735r: Remove spi-max-frequency limit dt-bindings: display: sitronix,st7735r: Add initialization properties drm/mipi-dbi: Add device property functions drm: tiny: st7735r: Support DT initialization of controller .../bindings/display/sitronix,st7735r.yaml| 122 ++- drivers/gpu/drm/drm_mipi_dbi.c| 139 ++ drivers/gpu/drm/tiny/st7735r.c| 87 +-- include/drm/drm_mipi_dbi.h| 3 + 4 files changed, 334 insertions(+), 17 deletions(-)
[PULL] drm-intel-fixes
Hi Dave and Daniel, Only one fix for this round. Sending earlier today due to Holiday in US tomorrow. Here goes drm-intel-fixes-2021-11-24: Fix wakeref handling of PXP suspend. Thanks, Rodrigo. The following changes since commit 136057256686de39cc3a07c2e39ef6bc43003ff6: Linux 5.16-rc2 (2021-11-21 13:47:39 -0800) are available in the Git repository at: git://anongit.freedesktop.org/drm/drm-intel tags/drm-intel-fixes-2021-11-24 for you to fetch changes up to b8d8436840caa2e9b6d156e69336d2135f49f10f: drm/i915/gt: Hold RPM wakelock during PXP suspend (2021-11-24 09:07:18 -0500) Fix wakeref handling of PXP suspend. Tejas Upadhyay (1): drm/i915/gt: Hold RPM wakelock during PXP suspend drivers/gpu/drm/i915/gt/intel_gt_pm.c | 7 --- drivers/gpu/drm/i915/pxp/intel_pxp_pm.c | 37 +++-- drivers/gpu/drm/i915/pxp/intel_pxp_pm.h | 19 ++--- 3 files changed, 46 insertions(+), 17 deletions(-)
[PATCH 7/7] drm/msm/gpu: Add a comment in a6xx_gmu_init()
From: Rob Clark If you don't realize is_a650_family() also encompasses a660 family, you'd think that the debug buffer is double allocated. Add a comment to make this more clear. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index e1774ea342b1..3e325e2a2b1b 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1531,6 +1531,7 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) if (ret) goto err_memory; + /* Note that a650 family also includes a660 family: */ if (adreno_is_a650_family(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache, SZ_16M - SZ_16K, 0x04000, "icache"); @@ -1547,6 +1548,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) if (ret) goto err_memory; } else { + BUG_ON(adreno_is_a660_family(adreno_gpu)); + /* HFI v1, has sptprac */ gmu->legacy = true; -- 2.33.1
[PATCH 6/7] drm/msm/gpu: Snapshot GMU debug buffer
From: Rob Clark It appears to be a GMU fw build option whether it does anything with debug and log buffers, but if they are all zeros it won't add anything to the devcore size. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 12 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index a84ba8982cb8..bdd0059a81ff 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -44,6 +44,7 @@ struct a6xx_gpu_state { struct msm_gpu_state_bo *gmu_log; struct msm_gpu_state_bo *gmu_hfi; + struct msm_gpu_state_bo *gmu_debug; s32 hfi_queue_history[2][HFI_HISTORY_SZ]; @@ -983,6 +984,7 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) a6xx_state->gmu_log = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.log); a6xx_state->gmu_hfi = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.hfi); + a6xx_state->gmu_debug = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.debug); a6xx_snapshot_gmu_hfi_history(gpu, a6xx_state); @@ -1274,6 +1276,16 @@ void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, &gmu_hfi->encoded); } + drm_puts(p, "gmu-debug:\n"); + if (a6xx_state->gmu_debug) { + struct msm_gpu_state_bo *gmu_debug = a6xx_state->gmu_debug; + + drm_printf(p, "iova: 0x%016llx\n", gmu_debug->iova); + drm_printf(p, "size: %zu\n", gmu_debug->size); + adreno_show_object(p, &gmu_debug->data, gmu_debug->size, + &gmu_debug->encoded); + } + drm_puts(p, "registers:\n"); for (i = 0; i < a6xx_state->nr_registers; i++) { struct a6xx_gpu_state_obj *obj = &a6xx_state->registers[i]; -- 2.33.1
[PATCH 5/7] drm/msm/gpu: Also snapshot GMU HFI buffer
From: Rob Clark This also includes a history of start index of the last 8 messages on each queue, since parsing backwards to decode recently sent HFI messages is hard(ish). Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 48 - drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 10 + drivers/gpu/drm/msm/adreno/a6xx_hfi.h | 11 + 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 1de103f29d25..a84ba8982cb8 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -43,6 +43,9 @@ struct a6xx_gpu_state { int nr_cx_debugbus; struct msm_gpu_state_bo *gmu_log; + struct msm_gpu_state_bo *gmu_hfi; + + s32 hfi_queue_history[2][HFI_HISTORY_SZ]; struct list_head objs; }; @@ -822,6 +825,25 @@ static struct msm_gpu_state_bo *a6xx_snapshot_gmu_bo( return snapshot; } +static void a6xx_snapshot_gmu_hfi_history(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; + unsigned i, j; + + BUILD_BUG_ON(ARRAY_SIZE(gmu->queues) != ARRAY_SIZE(a6xx_state->hfi_queue_history)); + + for (i = 0; i < ARRAY_SIZE(gmu->queues); i++) { + struct a6xx_hfi_queue *queue = &gmu->queues[i]; + for (j = 0; j < HFI_HISTORY_SZ; j++) { + unsigned idx = (j + queue->history_idx) % HFI_HISTORY_SZ; + a6xx_state->hfi_queue_history[i][j] = queue->history[idx]; + } + } +} + #define A6XX_GBIF_REGLIST_SIZE 1 static void a6xx_get_registers(struct msm_gpu *gpu, struct a6xx_gpu_state *a6xx_state, @@ -960,6 +982,9 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) a6xx_get_gmu_registers(gpu, a6xx_state); a6xx_state->gmu_log = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.log); + a6xx_state->gmu_hfi = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.hfi); + + a6xx_snapshot_gmu_hfi_history(gpu, a6xx_state); /* If GX isn't on the rest of the data isn't going to be accessible */ if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) @@ -1005,6 +1030,9 @@ static void a6xx_gpu_state_destroy(struct kref *kref) if (a6xx_state->gmu_log) kvfree(a6xx_state->gmu_log->data); + if (a6xx_state->gmu_hfi) + kvfree(a6xx_state->gmu_hfi->data); + list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) kfree(obj); @@ -1223,11 +1251,29 @@ void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, struct msm_gpu_state_bo *gmu_log = a6xx_state->gmu_log; drm_printf(p, "iova: 0x%016llx\n", gmu_log->iova); - drm_printf(p, "size: %d\n", gmu_log->size); + drm_printf(p, "size: %zu\n", gmu_log->size); adreno_show_object(p, &gmu_log->data, gmu_log->size, &gmu_log->encoded); } + drm_puts(p, "gmu-hfi:\n"); + if (a6xx_state->gmu_hfi) { + struct msm_gpu_state_bo *gmu_hfi = a6xx_state->gmu_hfi; + unsigned i, j; + + drm_printf(p, "iova: 0x%016llx\n", gmu_hfi->iova); + drm_printf(p, "size: %zu\n", gmu_hfi->size); + for (i = 0; i < ARRAY_SIZE(a6xx_state->hfi_queue_history); i++) { + drm_printf(p, "queue-history[%u]:", i); + for (j = 0; j < HFI_HISTORY_SZ; j++) { + drm_printf(p, " %d", a6xx_state->hfi_queue_history[i][j]); + } + drm_printf(p, "\n"); + } + adreno_show_object(p, &gmu_hfi->data, gmu_hfi->size, + &gmu_hfi->encoded); + } + drm_puts(p, "registers:\n"); for (i = 0; i < a6xx_state->nr_registers; i++) { struct a6xx_gpu_state_obj *obj = &a6xx_state->registers[i]; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c index d4c65bf0a1b7..d73fce5fdf1f 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_hfi.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_hfi.c @@ -36,6 +36,8 @@ static int a6xx_hfi_queue_read(struct a6xx_gmu *gmu, hdr = queue->data[index]; + queue->history[(queue->history_idx++) % HFI_HISTORY_SZ] = index; + /* * If we are to assume that the GMU firmware is in fact a rational actor * and is programmed to not send us a larger response than we expect @@ -75,6 +77,8 @@ static int a6xx_hfi_queue_write(struct a6xx_gmu *gmu, return -ENOSP
[PATCH 4/7] drm/msm/gpu: Make a6xx_get_gmu_log() more generic
From: Rob Clark Turn it into a thing we can use to snapshot other GMU buffers. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 34 + 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index f1b1a9bffb37..1de103f29d25 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -802,28 +802,24 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, &a6xx_state->gmu_registers[2], false); } -static void a6xx_get_gmu_log(struct msm_gpu *gpu, - struct a6xx_gpu_state *a6xx_state) +static struct msm_gpu_state_bo *a6xx_snapshot_gmu_bo( + struct a6xx_gpu_state *a6xx_state, struct a6xx_gmu_bo *bo) { - struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); - struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); - struct a6xx_gmu *gmu = &a6xx_gpu->gmu; - struct msm_gpu_state_bo *gmu_log; + struct msm_gpu_state_bo *snapshot; - gmu_log = state_kcalloc(a6xx_state, - 1, sizeof(*a6xx_state->gmu_log)); - if (!gmu_log) - return; + snapshot = state_kcalloc(a6xx_state, 1, sizeof(*snapshot)); + if (!snapshot) + return NULL; - gmu_log->iova = gmu->log.iova; - gmu_log->size = gmu->log.size; - gmu_log->data = kvzalloc(gmu_log->size, GFP_KERNEL); - if (!gmu_log->data) - return; + snapshot->iova = bo->iova; + snapshot->size = bo->size; + snapshot->data = kvzalloc(snapshot->size, GFP_KERNEL); + if (!snapshot->data) + return NULL; - memcpy(gmu_log->data, gmu->log.virt, gmu->log.size); + memcpy(snapshot->data, bo->virt, bo->size); - a6xx_state->gmu_log = gmu_log; + return snapshot; } #define A6XX_GBIF_REGLIST_SIZE 1 @@ -963,7 +959,7 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) a6xx_get_gmu_registers(gpu, a6xx_state); - a6xx_get_gmu_log(gpu, a6xx_state); + a6xx_state->gmu_log = a6xx_snapshot_gmu_bo(a6xx_state, &a6xx_gpu->gmu.log); /* If GX isn't on the rest of the data isn't going to be accessible */ if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) @@ -1006,7 +1002,7 @@ static void a6xx_gpu_state_destroy(struct kref *kref) struct a6xx_gpu_state *a6xx_state = container_of(state, struct a6xx_gpu_state, base); - if (a6xx_state->gmu_log && a6xx_state->gmu_log->data) + if (a6xx_state->gmu_log) kvfree(a6xx_state->gmu_log->data); list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) -- 2.33.1
[PATCH 3/7] drm/msm/gpu: Add some WARN_ON()s
From: Rob Clark We don't expect either of these conditions to ever be true, so let's get shouty if they are. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index a379f98aca54..6c42cc0ebe84 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -504,6 +504,9 @@ int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state) struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); int i, count = 0; + WARN_ON(gpu->needs_hw_init); + WARN_ON(!mutex_is_locked(&gpu->dev->struct_mutex)); + kref_init(&state->ref); ktime_get_real_ts64(&state->time); -- 2.33.1
[PATCH v2 3/3] drm/msm/gpu: Respect PM QoS constraints
From: Rob Clark Re-work the boost and idle clamping to use PM QoS requests instead, so they get aggreggated with other requests (such as cooling device). This does have the minor side-effect that devfreq sysfs min_freq/ max_freq files now reflect the boost and idle clamping, as they show (despite what they are documented to show) the aggregated min/max freq. Fixing that in devfreq does not look straightforward after considering that OPPs can be dynamically added/removed. However writes to the sysfs files still behave as expected. v2: Use 64b math to avoid potential 32b overflow Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.h | 33 +++--- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 87 +++ 2 files changed, 71 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 59cdd00b69d0..96d8d37dd5b7 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -87,6 +87,21 @@ struct msm_gpu_devfreq { /** devfreq: devfreq instance */ struct devfreq *devfreq; + /** +* idle_constraint: +* +* A PM QoS constraint to limit max freq while the GPU is idle. +*/ + struct dev_pm_qos_request idle_freq; + + /** +* boost_constraint: +* +* A PM QoS constraint to boost min freq for a period of time +* until the boost expires. +*/ + struct dev_pm_qos_request boost_freq; + /** * busy_cycles: * @@ -103,22 +118,19 @@ struct msm_gpu_devfreq { ktime_t idle_time; /** -* idle_freq: +* idle_work: * -* Shadow frequency used while the GPU is idle. From the PoV of -* the devfreq governor, we are continuing to sample busyness and -* adjust frequency while the GPU is idle, but we use this shadow -* value as the GPU is actually clamped to minimum frequency while -* it is inactive. +* Used to delay clamping to idle freq on active->idle transition. */ - unsigned long idle_freq; + struct msm_hrtimer_work idle_work; /** -* idle_work: +* boost_work: * -* Used to delay clamping to idle freq on active->idle transition. +* Used to reset the boost_constraint after the boost period has +* elapsed */ - struct msm_hrtimer_work idle_work; + struct msm_hrtimer_work boost_work; }; struct msm_gpu { @@ -498,6 +510,7 @@ void msm_devfreq_init(struct msm_gpu *gpu); void msm_devfreq_cleanup(struct msm_gpu *gpu); void msm_devfreq_resume(struct msm_gpu *gpu); void msm_devfreq_suspend(struct msm_gpu *gpu); +void msm_devfreq_boost(struct msm_gpu *gpu, unsigned factor); void msm_devfreq_active(struct msm_gpu *gpu); void msm_devfreq_idle(struct msm_gpu *gpu); diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 1f55242bb6a1..11be623de2ab 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -9,6 +9,7 @@ #include #include +#include /* * Power Management: @@ -22,15 +23,6 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, opp = devfreq_recommended_opp(dev, freq, flags); - /* -* If the GPU is idle, devfreq is not aware, so just ignore -* it's requests -*/ - if (gpu->devfreq.idle_freq) { - gpu->devfreq.idle_freq = *freq; - return 0; - } - if (IS_ERR(opp)) return PTR_ERR(opp); @@ -48,9 +40,6 @@ static int msm_devfreq_target(struct device *dev, unsigned long *freq, static unsigned long get_freq(struct msm_gpu *gpu) { - if (gpu->devfreq.idle_freq) - return gpu->devfreq.idle_freq; - if (gpu->funcs->gpu_get_freq) return gpu->funcs->gpu_get_freq(gpu); @@ -88,6 +77,7 @@ static struct devfreq_dev_profile msm_devfreq_profile = { .get_cur_freq = msm_devfreq_get_cur_freq, }; +static void msm_devfreq_boost_work(struct kthread_work *work); static void msm_devfreq_idle_work(struct kthread_work *work); void msm_devfreq_init(struct msm_gpu *gpu) @@ -98,6 +88,12 @@ void msm_devfreq_init(struct msm_gpu *gpu) if (!gpu->funcs->gpu_busy) return; + dev_pm_qos_add_request(&gpu->pdev->dev, &df->idle_freq, + DEV_PM_QOS_MAX_FREQUENCY, + PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); + dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq, + DEV_PM_QOS_MIN_FREQUENCY, 0); + msm_devfreq_profile.initial_freq = gpu->fast_rate; /* @@ -128,13 +124,19 @@ void msm_devfreq_init(struct msm_gpu *gpu) gpu->cooling = NULL; } + msm_hrtimer_work_init(&df->boost_work, gpu->worker, msm_devfreq_boost_
[PATCH 2/7] drm/msm/gpu: Name GMU bos
From: Rob Clark Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 22 +- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 71e52b2b2025..e1774ea342b1 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1146,7 +1146,7 @@ static void a6xx_gmu_memory_free(struct a6xx_gmu *gmu) } static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo, - size_t size, u64 iova) + size_t size, u64 iova, const char *name) { struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); struct drm_device *dev = a6xx_gpu->base.base.dev; @@ -1181,6 +1181,8 @@ static int a6xx_gmu_memory_alloc(struct a6xx_gmu *gmu, struct a6xx_gmu_bo *bo, bo->virt = msm_gem_get_vaddr(bo->obj); bo->size = size; + msm_gem_object_set_name(bo->obj, name); + return 0; } @@ -1515,7 +1517,8 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) */ gmu->dummy.size = SZ_4K; if (adreno_is_a660_family(adreno_gpu)) { - ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, 0x6040); + ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_4K * 7, + 0x6040, "debug"); if (ret) goto err_memory; @@ -1523,23 +1526,24 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) } /* Allocate memory for the GMU dummy page */ - ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, gmu->dummy.size, 0x6000); + ret = a6xx_gmu_memory_alloc(gmu, &gmu->dummy, gmu->dummy.size, + 0x6000, "dummy"); if (ret) goto err_memory; if (adreno_is_a650_family(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache, - SZ_16M - SZ_16K, 0x04000); + SZ_16M - SZ_16K, 0x04000, "icache"); if (ret) goto err_memory; } else if (adreno_is_a640_family(adreno_gpu)) { ret = a6xx_gmu_memory_alloc(gmu, &gmu->icache, - SZ_256K - SZ_16K, 0x04000); + SZ_256K - SZ_16K, 0x04000, "icache"); if (ret) goto err_memory; ret = a6xx_gmu_memory_alloc(gmu, &gmu->dcache, - SZ_256K - SZ_16K, 0x44000); + SZ_256K - SZ_16K, 0x44000, "dcache"); if (ret) goto err_memory; } else { @@ -1547,18 +1551,18 @@ int a6xx_gmu_init(struct a6xx_gpu *a6xx_gpu, struct device_node *node) gmu->legacy = true; /* Allocate memory for the GMU debug region */ - ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_16K, 0); + ret = a6xx_gmu_memory_alloc(gmu, &gmu->debug, SZ_16K, 0, "debug"); if (ret) goto err_memory; } /* Allocate memory for for the HFI queues */ - ret = a6xx_gmu_memory_alloc(gmu, &gmu->hfi, SZ_16K, 0); + ret = a6xx_gmu_memory_alloc(gmu, &gmu->hfi, SZ_16K, 0, "hfi"); if (ret) goto err_memory; /* Allocate memory for the GMU log region */ - ret = a6xx_gmu_memory_alloc(gmu, &gmu->log, SZ_4K, 0); + ret = a6xx_gmu_memory_alloc(gmu, &gmu->log, SZ_4K, 0, "log"); if (ret) goto err_memory; -- 2.33.1
[PATCH v2 2/3] drm/msm/gpu: Fix check for devices without devfreq
From: Rob Clark Looks like 658f4c829688 ("drm/msm/devfreq: Add 1ms delay before clamping freq") was badly rebased on top of efb8a170a367 ("drm/msm: Fix devfreq NULL pointer dereference on a3xx") and ended up with the NULL check in the wrong place. Fixes: 658f4c829688 ("drm/msm/devfreq: Add 1ms delay before clamping freq") Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 7285041c737e..1f55242bb6a1 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -203,9 +203,6 @@ static void msm_devfreq_idle_work(struct kthread_work *work) struct msm_gpu *gpu = container_of(df, struct msm_gpu, devfreq); unsigned long idle_freq, target_freq = 0; - if (!df->devfreq) - return; - /* * Hold devfreq lock to synchronize with get_dev_status()/ * target() callbacks @@ -227,6 +224,9 @@ void msm_devfreq_idle(struct msm_gpu *gpu) { struct msm_gpu_devfreq *df = &gpu->devfreq; + if (!df->devfreq) + return; + msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), HRTIMER_MODE_REL); } -- 2.33.1
[PATCH v2 1/3] drm/msm/gpu: Fix idle_work time
From: Rob Clark This was supposed to be a relative timer, not absolute. Fixes: 658f4c829688 ("drm/msm/devfreq: Add 1ms delay before clamping freq") Signed-off-by: Rob Clark Reviewed-by: Douglas Anderson --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gpu_devfreq.c b/drivers/gpu/drm/msm/msm_gpu_devfreq.c index 43468919df61..7285041c737e 100644 --- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -228,5 +228,5 @@ void msm_devfreq_idle(struct msm_gpu *gpu) struct msm_gpu_devfreq *df = &gpu->devfreq; msm_hrtimer_queue_work(&df->idle_work, ms_to_ktime(1), - HRTIMER_MODE_ABS); + HRTIMER_MODE_REL); } -- 2.33.1
[PATCH 1/7] drm/msm/a6xx: Capture gmu log in devcoredump
From: Akhil P Oommen Capture gmu log in coredump to enhance debugging. Signed-off-by: Akhil P Oommen Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 41 + drivers/gpu/drm/msm/adreno/adreno_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 2 + 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index 6e90209cd543..f1b1a9bffb37 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -42,6 +42,8 @@ struct a6xx_gpu_state { struct a6xx_gpu_state_obj *cx_debugbus; int nr_cx_debugbus; + struct msm_gpu_state_bo *gmu_log; + struct list_head objs; }; @@ -800,6 +802,30 @@ static void a6xx_get_gmu_registers(struct msm_gpu *gpu, &a6xx_state->gmu_registers[2], false); } +static void a6xx_get_gmu_log(struct msm_gpu *gpu, + struct a6xx_gpu_state *a6xx_state) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_gmu *gmu = &a6xx_gpu->gmu; + struct msm_gpu_state_bo *gmu_log; + + gmu_log = state_kcalloc(a6xx_state, + 1, sizeof(*a6xx_state->gmu_log)); + if (!gmu_log) + return; + + gmu_log->iova = gmu->log.iova; + gmu_log->size = gmu->log.size; + gmu_log->data = kvzalloc(gmu_log->size, GFP_KERNEL); + if (!gmu_log->data) + return; + + memcpy(gmu_log->data, gmu->log.virt, gmu->log.size); + + a6xx_state->gmu_log = gmu_log; +} + #define A6XX_GBIF_REGLIST_SIZE 1 static void a6xx_get_registers(struct msm_gpu *gpu, struct a6xx_gpu_state *a6xx_state, @@ -937,6 +963,8 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) a6xx_get_gmu_registers(gpu, a6xx_state); + a6xx_get_gmu_log(gpu, a6xx_state); + /* If GX isn't on the rest of the data isn't going to be accessible */ if (!a6xx_gmu_gx_is_on(&a6xx_gpu->gmu)) return &a6xx_state->base; @@ -978,6 +1006,9 @@ static void a6xx_gpu_state_destroy(struct kref *kref) struct a6xx_gpu_state *a6xx_state = container_of(state, struct a6xx_gpu_state, base); + if (a6xx_state->gmu_log && a6xx_state->gmu_log->data) + kvfree(a6xx_state->gmu_log->data); + list_for_each_entry_safe(obj, tmp, &a6xx_state->objs, node) kfree(obj); @@ -1191,6 +1222,16 @@ void a6xx_show(struct msm_gpu *gpu, struct msm_gpu_state *state, adreno_show(gpu, state, p); + drm_puts(p, "gmu-log:\n"); + if (a6xx_state->gmu_log) { + struct msm_gpu_state_bo *gmu_log = a6xx_state->gmu_log; + + drm_printf(p, "iova: 0x%016llx\n", gmu_log->iova); + drm_printf(p, "size: %d\n", gmu_log->size); + adreno_show_object(p, &gmu_log->data, gmu_log->size, + &gmu_log->encoded); + } + drm_puts(p, "registers:\n"); for (i = 0; i < a6xx_state->nr_registers; i++) { struct a6xx_gpu_state_obj *obj = &a6xx_state->registers[i]; diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 7bac86b01f30..a379f98aca54 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -630,7 +630,7 @@ static char *adreno_gpu_ascii85_encode(u32 *src, size_t len) } /* len is expected to be in bytes */ -static void adreno_show_object(struct drm_printer *p, void **ptr, int len, +void adreno_show_object(struct drm_printer *p, void **ptr, int len, bool *encoded) { if (!*ptr || !len) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 225c277a6223..676230862671 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -306,6 +306,8 @@ void adreno_gpu_state_destroy(struct msm_gpu_state *state); int adreno_gpu_state_get(struct msm_gpu *gpu, struct msm_gpu_state *state); int adreno_gpu_state_put(struct msm_gpu_state *state); +void adreno_show_object(struct drm_printer *p, void **ptr, int len, + bool *encoded); /* * Common helper function to initialize the default address space for arm-smmu -- 2.33.1
[PATCH 0/7] drm/msm: Improve GMU debugging
From: Rob Clark This adds additional snapshotting for interesting GMU buffers to the devcore dumps, adds a couple WARN_ON()s, etc. (Plus a bonus comment) Akhil P Oommen (1): drm/msm/a6xx: Capture gmu log in devcoredump Rob Clark (6): drm/msm/gpu: Name GMU bos drm/msm/gpu: Add some WARN_ON()s drm/msm/gpu: Make a6xx_get_gmu_log() more generic drm/msm/gpu: Also snapshot GMU HFI buffer drm/msm/gpu: Snapshot GMU debug buffer drm/msm/gpu: Add a comment in a6xx_gmu_init() drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 25 -- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c | 95 + drivers/gpu/drm/msm/adreno/a6xx_hfi.c | 10 +++ drivers/gpu/drm/msm/adreno/a6xx_hfi.h | 11 +++ drivers/gpu/drm/msm/adreno/adreno_gpu.c | 5 +- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 2 + 6 files changed, 138 insertions(+), 10 deletions(-) -- 2.33.1
[PATCH v9 8/8] [RFC] MIPS: DTS: Ingenic: adjust register size to available registers
After getting the regmap size from the device tree we should reduce the ranges to the really available registers. This allows to read only existing registers from the debug fs and makes the regmap check out-of-bounds access. For the jz4780 we have done this already. Suggested-for: Paul Cercueil Signed-off-by: H. Nikolaus Schaller --- arch/mips/boot/dts/ingenic/jz4725b.dtsi | 2 +- arch/mips/boot/dts/ingenic/jz4740.dtsi | 2 +- arch/mips/boot/dts/ingenic/jz4770.dtsi | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/mips/boot/dts/ingenic/jz4725b.dtsi b/arch/mips/boot/dts/ingenic/jz4725b.dtsi index 0c6a5a4266f43..e9e48022f6316 100644 --- a/arch/mips/boot/dts/ingenic/jz4725b.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4725b.dtsi @@ -321,7 +321,7 @@ udc: usb@1304 { lcd: lcd-controller@1305 { compatible = "ingenic,jz4725b-lcd"; - reg = <0x1305 0x1000>; + reg = <0x1305 0x130>; /* tbc */ interrupt-parent = <&intc>; interrupts = <31>; diff --git a/arch/mips/boot/dts/ingenic/jz4740.dtsi b/arch/mips/boot/dts/ingenic/jz4740.dtsi index 772542e1f266a..7f76cba03a089 100644 --- a/arch/mips/boot/dts/ingenic/jz4740.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4740.dtsi @@ -323,7 +323,7 @@ udc: usb@1304 { lcd: lcd-controller@1305 { compatible = "ingenic,jz4740-lcd"; - reg = <0x1305 0x1000>; + reg = <0x1305 0x60>; /* LCDCMD1+4 */ interrupt-parent = <&intc>; interrupts = <30>; diff --git a/arch/mips/boot/dts/ingenic/jz4770.dtsi b/arch/mips/boot/dts/ingenic/jz4770.dtsi index dfe74328ae5dc..bda0a3a86ed5f 100644 --- a/arch/mips/boot/dts/ingenic/jz4770.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4770.dtsi @@ -399,7 +399,7 @@ gpu: gpu@1304 { lcd: lcd-controller@1305 { compatible = "ingenic,jz4770-lcd"; - reg = <0x1305 0x300>; + reg = <0x1305 0x130>; /* tbc */ interrupt-parent = <&intc>; interrupts = <31>; -- 2.33.0
[PATCH v9 6/8] MIPS: DTS: CI20: Add DT nodes for HDMI setup
From: Paul Boddie We need to hook up * HDMI connector * HDMI power regulator * JZ4780_CLK_HDMI @ 27 MHz * DDC pinmux * HDMI and LCDC endpoint connections Signed-off-by: Paul Boddie Signed-off-by: H. Nikolaus Schaller --- arch/mips/boot/dts/ingenic/ci20.dts | 72 - 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/arch/mips/boot/dts/ingenic/ci20.dts b/arch/mips/boot/dts/ingenic/ci20.dts index b249a4f0f6b62..3e336b3dbb109 100644 --- a/arch/mips/boot/dts/ingenic/ci20.dts +++ b/arch/mips/boot/dts/ingenic/ci20.dts @@ -78,6 +78,18 @@ eth0_power: fixedregulator@0 { enable-active-high; }; + hdmi_out: connector { + compatible = "hdmi-connector"; + label = "HDMI OUT"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&dw_hdmi_out>; + }; + }; + }; + ir: ir { compatible = "gpio-ir-receiver"; gpios = <&gpe 3 GPIO_ACTIVE_LOW>; @@ -102,6 +114,17 @@ otg_power: fixedregulator@2 { gpio = <&gpf 14 GPIO_ACTIVE_LOW>; enable-active-high; }; + + hdmi_power: fixedregulator@3 { + compatible = "regulator-fixed"; + + regulator-name = "hdmi_power"; + regulator-min-microvolt = <500>; + regulator-max-microvolt = <500>; + + gpio = <&gpa 25 0>; + enable-active-high; + }; }; &ext { @@ -114,11 +137,12 @@ &cgu { * precision. */ assigned-clocks = <&cgu JZ4780_CLK_OTGPHY>, <&cgu JZ4780_CLK_RTC>, - <&cgu JZ4780_CLK_SSIPLL>, <&cgu JZ4780_CLK_SSI>; + <&cgu JZ4780_CLK_SSIPLL>, <&cgu JZ4780_CLK_SSI>, + <&cgu JZ4780_CLK_HDMI>; assigned-clock-parents = <0>, <&cgu JZ4780_CLK_RTCLK>, <&cgu JZ4780_CLK_MPLL>, <&cgu JZ4780_CLK_SSIPLL>; - assigned-clock-rates = <4800>, <0>, <5400>; + assigned-clock-rates = <4800>, <0>, <5400>, <0>, <2700>; }; &tcu { @@ -509,6 +533,12 @@ pins_i2c4: i2c4 { bias-disable; }; + pins_hdmi_ddc: hdmi_ddc { + function = "hdmi-ddc"; + groups = "hdmi-ddc"; + bias-disable; + }; + pins_nemc: nemc { function = "nemc"; groups = "nemc-data", "nemc-cle-ale", "nemc-rd-we", "nemc-frd-fwe"; @@ -539,3 +569,41 @@ pins_mmc1: mmc1 { bias-disable; }; }; + +&hdmi { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_hdmi_ddc>; + + hdmi-5v-supply = <&hdmi_power>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dw_hdmi_in: endpoint { + remote-endpoint = <&lcd_out>; + }; + }; + + port@1 { + reg = <1>; + dw_hdmi_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; +}; + +&lcdc0 { + status = "okay"; + + port { + lcd_out: endpoint { + remote-endpoint = <&dw_hdmi_in>; + }; + }; +}; -- 2.33.0
[PATCH v9 4/8] drm/ingenic: Add dw-hdmi driver for jz4780
From: Paul Boddie A specialisation of the generic Synopsys HDMI driver is employed for JZ4780 HDMI support. This requires a new driver, plus device tree and configuration modifications. Here we add Kconfig DRM_INGENIC_DW_HDMI, Makefile and driver code. Signed-off-by: Paul Boddie Signed-off-by: Ezequiel Garcia Signed-off-by: H. Nikolaus Schaller --- drivers/gpu/drm/ingenic/Kconfig | 9 ++ drivers/gpu/drm/ingenic/Makefile | 1 + drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c | 138 ++ 3 files changed, 148 insertions(+) create mode 100644 drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c diff --git a/drivers/gpu/drm/ingenic/Kconfig b/drivers/gpu/drm/ingenic/Kconfig index 3b57f8be007c4..4efc709d77b0a 100644 --- a/drivers/gpu/drm/ingenic/Kconfig +++ b/drivers/gpu/drm/ingenic/Kconfig @@ -25,4 +25,13 @@ config DRM_INGENIC_IPU The Image Processing Unit (IPU) will appear as a second primary plane. +config DRM_INGENIC_DW_HDMI + tristate "Ingenic specific support for Synopsys DW HDMI" + depends on MACH_JZ4780 + select DRM_DW_HDMI + help + Choose this option to enable Synopsys DesignWare HDMI based driver. + If you want to enable HDMI on Ingenic JZ4780 based SoC, you should + select this option.. + endif diff --git a/drivers/gpu/drm/ingenic/Makefile b/drivers/gpu/drm/ingenic/Makefile index d313326bdddbb..f10cc1c5a5f22 100644 --- a/drivers/gpu/drm/ingenic/Makefile +++ b/drivers/gpu/drm/ingenic/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_DRM_INGENIC) += ingenic-drm.o ingenic-drm-y = ingenic-drm-drv.o ingenic-drm-$(CONFIG_DRM_INGENIC_IPU) += ingenic-ipu.o +obj-$(CONFIG_DRM_INGENIC_DW_HDMI) += ingenic-dw-hdmi.o diff --git a/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c b/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c new file mode 100644 index 0..199e39c227d29 --- /dev/null +++ b/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. + * Copyright (C) 2019, 2020 Paul Boddie + * + * Derived from dw_hdmi-imx.c with i.MX portions removed. + * Probe and remove operations derived from rcar_dw_hdmi.c. + */ + +#include +#include +#include + +#include +#include +#include + +static const struct dw_hdmi_mpll_config ingenic_mpll_cfg[] = { + { 4525, { { 0x01e0, 0x }, { 0x21e1, 0x }, { 0x41e2, 0x } } }, + { 9250, { { 0x0140, 0x0005 }, { 0x2141, 0x0005 }, { 0x4142, 0x0005 } } }, + { 14850, { { 0x00a0, 0x000a }, { 0x20a1, 0x000a }, { 0x40a2, 0x000a } } }, + { 21600, { { 0x00a0, 0x000a }, { 0x2001, 0x000f }, { 0x4002, 0x000f } } }, + { ~0UL, { { 0x, 0x }, { 0x, 0x }, { 0x, 0x } } } +}; + +static const struct dw_hdmi_curr_ctrl ingenic_cur_ctr[] = { + /*pixelclk bpp8bpp10 bpp12 */ + { 5400, { 0x091c, 0x091c, 0x06dc } }, + { 5840, { 0x091c, 0x06dc, 0x06dc } }, + { 7200, { 0x06dc, 0x06dc, 0x091c } }, + { 7425, { 0x06dc, 0x0b5c, 0x091c } }, + { 11880, { 0x091c, 0x091c, 0x06dc } }, + { 21600, { 0x06dc, 0x0b5c, 0x091c } }, + { ~0UL, { 0x, 0x, 0x } }, +}; + +/* + * Resistance term 133Ohm Cfg + * PREEMP config 0.00 + * TX/CK level 10 + */ +static const struct dw_hdmi_phy_config ingenic_phy_config[] = { + /*pixelclk symbol term vlev */ + { 21600, 0x800d, 0x0005, 0x01ad}, + { ~0UL, 0x, 0x, 0x} +}; + +static enum drm_mode_status +ingenic_dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + if (mode->clock < 13500) + return MODE_CLOCK_LOW; + /* FIXME: Hardware is capable of 270MHz, but setup data is missing. */ + if (mode->clock > 216000) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + +static struct dw_hdmi_plat_data ingenic_dw_hdmi_plat_data = { + .mpll_cfg = ingenic_mpll_cfg, + .cur_ctr= ingenic_cur_ctr, + .phy_config = ingenic_phy_config, + .mode_valid = ingenic_dw_hdmi_mode_valid, + .output_port= 1, +}; + +static const struct of_device_id ingenic_dw_hdmi_dt_ids[] = { + { .compatible = "ingenic,jz4780-dw-hdmi" }, + { /* Sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ingenic_dw_hdmi_dt_ids); + +static void ingenic_dw_hdmi_cleanup(void *data) +{ + struct dw_hdmi *hdmi = (struct dw_hdmi *)data; + + dw_hdmi_remove(hdmi); +} + +static void ingenic_dw_hdmi_disable_regulator(void *data) +{ + struct regulator *regulator = (struct regulator *)data; + + regulator_disable(regulator); +} + +static int ingenic_dw_hdmi_probe(struct platform_device *pdev) +{ + struct dw_hdmi *hdmi; + struct regulator *regulator; + int ret; + + hdmi = dw_
[PATCH v9 2/8] drm/ingenic: Add support for JZ4780 and HDMI output
From: Paul Boddie Add support for the LCD controller present on JZ4780 SoCs. This SoC uses 8-byte descriptors which extend the current 4-byte descriptors used for other Ingenic SoCs. Tested on MIPS Creator CI20 board. Signed-off-by: Paul Boddie Signed-off-by: Ezequiel Garcia Signed-off-by: H. Nikolaus Schaller --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 53 +++ drivers/gpu/drm/ingenic/ingenic-drm.h | 38 2 files changed, 91 insertions(+) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 0bb590c3910d9..34089bc6e0fcd 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -6,6 +6,7 @@ #include "ingenic-drm.h" +#include #include #include #include @@ -49,6 +50,11 @@ struct ingenic_dma_hwdesc { u32 addr; u32 id; u32 cmd; + /* extended hw descriptor for jz4780 */ + u32 offsize; + u32 pagewidth; + u32 cpos; + u32 dessize; } __aligned(16); struct ingenic_dma_hwdescs { @@ -60,6 +66,7 @@ struct jz_soc_info { bool needs_dev_clk; bool has_osd; bool map_noncoherent; + bool use_extended_hwdesc; unsigned int max_width, max_height; const u32 *formats_f0, *formats_f1; unsigned int num_formats_f0, num_formats_f1; @@ -446,6 +453,9 @@ static int ingenic_drm_plane_atomic_check(struct drm_plane *plane, if (!crtc) return 0; + if (plane == &priv->f0) + return -EINVAL; + crtc_state = drm_atomic_get_existing_crtc_state(state, crtc); if (WARN_ON(!crtc_state)) @@ -662,6 +672,33 @@ static void ingenic_drm_plane_atomic_update(struct drm_plane *plane, hwdesc->cmd = JZ_LCD_CMD_EOF_IRQ | (width * height * cpp / 4); hwdesc->next = dma_hwdesc_addr(priv, next_id); + if (priv->soc_info->use_extended_hwdesc) { + hwdesc->cmd |= JZ_LCD_CMD_FRM_ENABLE; + + /* Extended 8-byte descriptor */ + hwdesc->cpos = 0; + hwdesc->offsize = 0; + hwdesc->pagewidth = 0; + + switch (newstate->fb->format->format) { + case DRM_FORMAT_XRGB1555: + hwdesc->cpos |= JZ_LCD_CPOS_RGB555; + fallthrough; + case DRM_FORMAT_RGB565: + hwdesc->cpos |= JZ_LCD_CPOS_BPP_15_16; + break; + case DRM_FORMAT_XRGB: + hwdesc->cpos |= JZ_LCD_CPOS_BPP_18_24; + break; + } + hwdesc->cpos |= (JZ_LCD_CPOS_COEFFICIENT_1 << +JZ_LCD_CPOS_COEFFICIENT_OFFSET); + hwdesc->dessize = + (0xff << JZ_LCD_DESSIZE_ALPHA_OFFSET) | + FIELD_PREP(JZ_LCD_DESSIZE_HEIGHT_MASK, height - 1) | + FIELD_PREP(JZ_LCD_DESSIZE_WIDTH_MASK, width - 1); + } + if (drm_atomic_crtc_needs_modeset(crtc_state)) { fourcc = newstate->fb->format->format; @@ -693,6 +730,9 @@ static void ingenic_drm_encoder_atomic_mode_set(struct drm_encoder *encoder, | JZ_LCD_CFG_SPL_DISABLE | JZ_LCD_CFG_REV_DISABLE; } + if (priv->soc_info->use_extended_hwdesc) + cfg |= JZ_LCD_CFG_DESCRIPTOR_8; + if (mode->flags & DRM_MODE_FLAG_NHSYNC) cfg |= JZ_LCD_CFG_HSYNC_ACTIVE_LOW; if (mode->flags & DRM_MODE_FLAG_NVSYNC) @@ -1468,10 +1508,23 @@ static const struct jz_soc_info jz4770_soc_info = { .num_formats_f0 = ARRAY_SIZE(jz4770_formats_f0), }; +static const struct jz_soc_info jz4780_soc_info = { + .needs_dev_clk = true, + .has_osd = true, + .use_extended_hwdesc = true, + .max_width = 4096, + .max_height = 2048, + .formats_f1 = jz4770_formats_f1, + .num_formats_f1 = ARRAY_SIZE(jz4770_formats_f1), + .formats_f0 = jz4770_formats_f0, + .num_formats_f0 = ARRAY_SIZE(jz4770_formats_f0), +}; + static const struct of_device_id ingenic_drm_of_match[] = { { .compatible = "ingenic,jz4740-lcd", .data = &jz4740_soc_info }, { .compatible = "ingenic,jz4725b-lcd", .data = &jz4725b_soc_info }, { .compatible = "ingenic,jz4770-lcd", .data = &jz4770_soc_info }, + { .compatible = "ingenic,jz4780-lcd", .data = &jz4780_soc_info }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, ingenic_drm_of_match); diff --git a/drivers/gpu/drm/ingenic/ingenic-drm.h b/drivers/gpu/drm/ingenic/ingenic-drm.h index 22654ac1dde1c..cb1d09b625881 100644
[PATCH v9 7/8] MIPS: defconfig: CI20: configure for DRM_DW_HDMI_JZ4780
Enable CONFIG options as modules. Signed-off-by: Ezequiel Garcia Signed-off-by: H. Nikolaus Schaller --- arch/mips/configs/ci20_defconfig | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index ab7ebb0668340..cc69b215854ea 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig @@ -98,7 +98,13 @@ CONFIG_RC_DEVICES=y CONFIG_IR_GPIO_CIR=m CONFIG_IR_GPIO_TX=m CONFIG_MEDIA_SUPPORT=m +CONFIG_DRM=m +CONFIG_DRM_INGENIC=m +CONFIG_DRM_INGENIC_DW_HDMI=m +CONFIG_DRM_DISPLAY_CONNECTOR=m # CONFIG_VGA_CONSOLE is not set +CONFIG_FB=y +CONFIG_FRAMEBUFFER_CONSOLE=y # CONFIG_HID is not set CONFIG_USB=y CONFIG_USB_STORAGE=y -- 2.33.0
[PATCH v9 1/8] drm/ingenic: prepare ingenic drm for later addition of JZ4780
This changes the way the regmap is allocated to prepare for the later addition of the JZ4780 which has more registers and bits than the others. Therefore we make the regmap as big as the reg property in the device tree tells. Suggested-by: Paul Cercueil Signed-off-by: H. Nikolaus Schaller --- drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index 462bc0f35f1bf..0bb590c3910d9 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -173,7 +173,6 @@ static const struct regmap_config ingenic_drm_regmap_config = { .val_bits = 32, .reg_stride = 4, - .max_register = JZ_REG_LCD_SIZE1, .writeable_reg = ingenic_drm_writeable_reg, }; @@ -1011,6 +1010,8 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) struct ingenic_drm_bridge *ib; struct drm_device *drm; void __iomem *base; + struct resource *res; + struct regmap_config regmap_config; long parent_rate; unsigned int i, clone_mask = 0; int ret, irq; @@ -1056,14 +1057,16 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) drm->mode_config.funcs = &ingenic_drm_mode_config_funcs; drm->mode_config.helper_private = &ingenic_drm_mode_config_helpers; - base = devm_platform_ioremap_resource(pdev, 0); + base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(base)) { dev_err(dev, "Failed to get memory resource\n"); return PTR_ERR(base); } + regmap_config = ingenic_drm_regmap_config; + regmap_config.max_register = res->end - res->start; priv->map = devm_regmap_init_mmio(dev, base, - &ingenic_drm_regmap_config); + ®map_config); if (IS_ERR(priv->map)) { dev_err(dev, "Failed to create regmap\n"); return PTR_ERR(priv->map); -- 2.33.0
[PATCH v9 5/8] MIPS: DTS: jz4780: Account for Synopsys HDMI driver and LCD controllers
From: Paul Boddie A specialisation of the generic Synopsys HDMI driver is employed for JZ4780 HDMI support. This requires a new driver, plus device tree and configuration modifications. Here we add jz4780 device tree setup. Signed-off-by: Paul Boddie Signed-off-by: H. Nikolaus Schaller --- arch/mips/boot/dts/ingenic/jz4780.dtsi | 40 ++ 1 file changed, 40 insertions(+) diff --git a/arch/mips/boot/dts/ingenic/jz4780.dtsi b/arch/mips/boot/dts/ingenic/jz4780.dtsi index b0a4e2e019c36..3f9ea47a10cd2 100644 --- a/arch/mips/boot/dts/ingenic/jz4780.dtsi +++ b/arch/mips/boot/dts/ingenic/jz4780.dtsi @@ -444,6 +444,46 @@ i2c4: i2c@10054000 { status = "disabled"; }; + hdmi: hdmi@1018 { + compatible = "ingenic,jz4780-dw-hdmi"; + reg = <0x1018 0x8000>; + reg-io-width = <4>; + + clocks = <&cgu JZ4780_CLK_AHB0>, <&cgu JZ4780_CLK_HDMI>; + clock-names = "iahb", "isfr"; + + interrupt-parent = <&intc>; + interrupts = <3>; + + status = "disabled"; + }; + + lcdc0: lcdc0@1305 { + compatible = "ingenic,jz4780-lcd"; + reg = <0x1305 0x1800>; + + clocks = <&cgu JZ4780_CLK_TVE>, <&cgu JZ4780_CLK_LCD0PIXCLK>; + clock-names = "lcd", "lcd_pclk"; + + interrupt-parent = <&intc>; + interrupts = <31>; + + status = "disabled"; + }; + + lcdc1: lcdc1@130a { + compatible = "ingenic,jz4780-lcd"; + reg = <0x130a 0x1800>; + + clocks = <&cgu JZ4780_CLK_TVE>, <&cgu JZ4780_CLK_LCD1PIXCLK>; + clock-names = "lcd", "lcd_pclk"; + + interrupt-parent = <&intc>; + interrupts = <23>; + + status = "disabled"; + }; + nemc: nemc@1341 { compatible = "ingenic,jz4780-nemc", "simple-mfd"; reg = <0x1341 0x1>; -- 2.33.0
[PATCH v9 3/8] dt-bindings: display: Add ingenic, jz4780-dw-hdmi DT Schema
From: Sam Ravnborg Add DT bindings for the hdmi driver for the Ingenic JZ4780 SoC. Based on .txt binding from Zubair Lutfullah Kakakhel We also add generic ddc-i2c-bus to synopsys,dw-hdmi.yaml Signed-off-by: Sam Ravnborg Signed-off-by: H. Nikolaus Schaller Cc: Rob Herring Cc: devicet...@vger.kernel.org --- .../display/bridge/ingenic,jz4780-hdmi.yaml | 76 +++ .../display/bridge/synopsys,dw-hdmi.yaml | 3 + 2 files changed, 79 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml new file mode 100644 index 0..9ab259ca2d849 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml @@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/bridge/ingenic,jz4780-hdmi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bindings for Ingenic JZ4780 HDMI Transmitter + +maintainers: + - H. Nikolaus Schaller + +description: | + The HDMI Transmitter in the Ingenic JZ4780 is a Synopsys DesignWare HDMI 1.4 + TX controller IP with accompanying PHY IP. + +allOf: + - $ref: bridge/synopsys,dw-hdmi.yaml# + +properties: + compatible: +const: ingenic,jz4780-dw-hdmi + + reg-io-width: +const: 4 + + clocks: +maxItems: 2 + + hdmi-5v-supply: +description: Optional regulator to provide +5V at the connector + + ports: +$ref: /schemas/graph.yaml#/properties/ports + +required: + - compatible + - clocks + - clock-names + - ports + - reg-io-width + +unevaluatedProperties: false + +examples: + - | +#include + +hdmi: hdmi@1018 { +compatible = "ingenic,jz4780-dw-hdmi"; +reg = <0x1018 0x8000>; +reg-io-width = <4>; +ddc-i2c-bus = <&i2c4>; +interrupt-parent = <&intc>; +interrupts = <3>; +clocks = <&cgu JZ4780_CLK_AHB0>, <&cgu JZ4780_CLK_HDMI>; +clock-names = "iahb", "isfr"; + +ports { +#address-cells = <1>; +#size-cells = <0>; +hdmi_in: port@0 { +reg = <0>; +dw_hdmi_in: endpoint { +remote-endpoint = <&jz4780_lcd_out>; +}; +}; +hdmi_out: port@1 { +reg = <1>; +dw_hdmi_out: endpoint { +remote-endpoint = <&hdmi_con>; +}; +}; +}; +}; + +... diff --git a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml index 9be44a682e67a..9cbeabaee0968 100644 --- a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml +++ b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml @@ -50,6 +50,9 @@ properties: interrupts: maxItems: 1 + ddc-i2c-bus: +description: An I2C interface if the internal DDC I2C driver is not to be used + additionalProperties: true ... -- 2.33.0
[PATCH v9 0/8] MIPS: JZ4780 and CI20 HDMI
PATCH V9 2021-11-24 22:29:14: - patch 6/8: remove optional <0> for assigned-clocks and unintentionally included "unwedge" setup (found by p...@crapouillou.net) - patch 4/8: some cosmetics make regulator enable/disable only if not NULL (found by p...@crapouillou.net) simplify/fix error handling and driver cleanup on remove (proposed by p...@crapouillou.net) - patch 3/8: fix #include path in example (found by p...@crapouillou.net) fix missing "i" in unevaluatedProperties (found by r...@kernel.org) fix 4 spaces indentation for required: property (found by r...@kernel.org) PATCH V8 2021-11-23 19:14:00: - fix a bad editing result from patch 2/8 (found by p...@crapouillou.net) PATCH V7 2021-11-23 18:46:23: - changed gpio polarity of hdmi_power to 0 (suggested by p...@crapouillou.net) - fixed LCD1 irq number (bug found by p...@crapouillou.net) - removed "- 4" for calculating max_register (suggested by p...@crapouillou.net) - use unevaluatedPropertes instead of additionalProperties (suggested by r...@kernel.org) - moved and renamed ingenic,jz4780-hdmi.yaml (suggested by r...@kernel.org) - adjusted assigned-clocks changes to upstream which added some for SSI (by h...@goldelico.com) - rebased and tested with v5.16-rc2 + patch set drm/ingenic by p...@crapouillou.net (by h...@goldelico.com) PATCH V6 2021-11-10 20:43:33: - changed CONFIG_DRM_INGENIC_DW_HDMI to "m" (by h...@goldelico.com) - made ingenic-dw-hdmi an independent platform driver which can be compiled as module and removed error patch fixes for IPU (suggested by p...@crapouillou.net) - moved assigned-clocks from jz4780.dtsi to ci20.dts (suggested by p...@crapouillou.net) - fixed reg property in jz4780.dtsi to cover all registers incl. gamma and vee (by h...@goldelico.com) - added a base patch to calculate regmap size from DTS reg property (requested by p...@crapouillou.net) - restored resetting all bits except one in LCDOSDC (requested by p...@crapouillou.net) - clarified setting of cpos (suggested by p...@crapouillou.net) - moved bindings definition for ddc-i2c-bus (suggested by p...@crapouillou.net) - simplified mask definitions for JZ_LCD_DESSIZE (requested by p...@crapouillou.net) - removed setting alpha premultiplication (suggested by p...@crapouillou.net) - removed some comments (suggested by p...@crapouillou.net) PATCH V5 2021-10-05 14:28:44: - dropped mode_fixup and timings support in dw-hdmi as it is no longer needed in this V5 (by h...@goldelico.com) - dropped "drm/ingenic: add some jz4780 specific features" (stimulated by p...@crapouillou.net) - fixed typo in commit subject: "synopsis" -> "synopsys" (by h...@goldelico.com) - swapped clocks in jz4780.dtsi to match synopsys,dw-hdmi.yaml (by h...@goldelico.com) - improved, simplified, fixed, dtbschecked ingenic-jz4780-hdmi.yaml and made dependent of bridge/synopsys,dw-hdmi.yaml (based on suggestions by max...@cerno.tech) - fixed binding vs. driver&DTS use of hdmi-5v regulator (suggested by max...@cerno.tech) - dropped "drm/bridge: synopsis: Fix to properly handle HPD" - was a no longer needed workaround for a previous version (suggested by max...@cerno.tech) PATCH V4 2021-09-27 18:44:38: - fix setting output_port = 1 (issue found by p...@crapouillou.net) - ci20.dts: convert to use hdmi-connector (by h...@goldelico.com) - add a hdmi-regulator to control +5V power (by h...@goldelico.com) - added a fix to dw-hdmi to call drm_kms_helper_hotplug_event on plugin event detection (by h...@goldelico.com) - always allocate extended descriptor but initialize only for jz4780 (by h...@goldelico.com) - updated to work on top of "[PATCH v3 0/6] drm/ingenic: Various improvements v3" (by p...@crapouillou.net) - rebased to v5.13-rc3 PATCH V3 2021-08-08 07:10:50: This series adds HDMI support for JZ4780 and CI20 board (and fixes one IPU related issue in registration error path) - [patch 1/8] switched from mode_fixup to atomic_check (suggested by robert.f...@linaro.org) - the call to the dw-hdmi specialization is still called mode_fixup - [patch 3/8] diverse fixes for ingenic-drm-drv (suggested by p...@crapouillou.net) - factor out some non-HDMI features of the jz4780 into a separate patch - multiple fixes around max height - do not change regmap config but a copy on stack - define some constants - factor out fixing of drm_init error path for IPU into separate patch - use FIELD_PREP() - [patch 8/8] conversion to component framework dropped (suggested by laurent.pinch...@ideasonboard.com and p...@crapouillou.net) PATCH V2 2021-08-05 16:08:05: - code and commit messages revisited for checkpatch warnings - rebased on v5.14-rc4 - include (failed, hence RFC 8/8) attempt to convert to component framework (was suggested by Paul Cercueil a while ago) This series adds HDMI support for JZ4780 and CI20 board H. Nikolaus Schaller (3): drm/ingenic: prepare ingenic drm for later addition of JZ4780 MIPS: defconfig: CI20:
Re: [PATCH v8 4/8] drm/ingenic: Add dw-hdmi driver for jz4780
Hi Paul, >>> You probably should disable the regulator (if not NULL) here. >> Indeed. Would it be ok to make struct regulator *regulator static >> or do we need dynamically allocated memory? > > static non-const is almost always a bad idea, so avoid it. Well some years ago it was a perfectly simple solution that still works... But I asked because I had a lot of doubt. > > You can either: > > - create a "ingenic_dw_hdmi" struct that will contain a pointer to dw_hdmi > and a pointer to the regulator. Instanciate it in the probe with > devm_kzalloc() and set the pointers, then set it as the driver data > (platform_set_drvdata). In the remove function you can then obtain the > pointer to your ingenic_dw_hdmi struct with platform_get_drvdata(), and you > can remove the dw_hdmi and unregister the regulator. > > - register cleanup functions, using devm_add_action_or_reset(dev, f, priv). > When it's time to cleanup, the kernel core will call f(priv) automatically. > So you can add a small wrapper around dw_hdmi_remove() and another one around > regulator_disable(), and those will be called automatically if your probe > function fails, or when the driver is removed. Then you can completely remove > the ".remove" callback. There are a few examples of these in the > ingenic-drm-drv.c if you want to take a look. The second one turned out to be cleaner to handle special cases like if there is no regulator. We just register the disabler only if there is a regulator and enable succeeds. So v9 is coming now. BR and thanks, Nikolaus
[pull] amdgpu, amdkfd drm-fixes-5.16
Hi Dave, Daniel, Fixes for 5.16. The following changes since commit 136057256686de39cc3a07c2e39ef6bc43003ff6: Linux 5.16-rc2 (2021-11-21 13:47:39 -0800) are available in the Git repository at: https://gitlab.freedesktop.org/agd5f/linux.git tags/amd-drm-fixes-5.16-2021-11-24 for you to fetch changes up to 692cd92e66ee10597676530573a495dc1d3bec6a: drm/amd/display: update bios scratch when setting backlight (2021-11-24 15:14:36 -0500) amd-drm-fixes-5.16-2021-11-24: amdgpu: - SRIOV fixes - dma-buf double free fix - Display fixes for GPU resets - Fix DSC powergating regression - GPU TSC fixes - Interrupt handler overflow fixes - Endian fix in IP discovery table handling - Aldebaran ASPM fix - Fix overclocking regression on older asics - Backlight/ACPI fix amdkfd: - SVM fixes - VMA removal race fix Alex Deucher (4): drm/amdgpu/gfx10: add wraparound gpu counter check for APUs as well drm/amdgpu/gfx9: switch to golden tsc registers for renoir+ drm/amdgpu/pm: fix powerplay OD interface drm/amd/display: update bios scratch when setting backlight Felix Kuehling (1): drm/amdgpu: Fix MMIO HDP flush on SRIOV Lijo Lazar (1): drm/amdgpu: Skip ASPM programming on aldebaran Nicholas Kazlauskas (3): drm/amd/display: Fix DPIA outbox timeout after GPU reset drm/amd/display: Set plane update flags for all planes in reset drm/amd/display: Reset link encoder assignments for GPU reset Philip Yang (6): drm/amdgpu: IH process reset count when restart drm/amdkfd: process exit and retry fault race drm/amdkfd: handle VMA remove race drm/amdkfd: simplify drain retry fault drm/amdgpu: enable Navi 48-bit IH timestamp counter drm/amdgpu: enable Navi retry fault wptr overflow Yang Wang (1): drm/amdgpu: fix byteorder error in amdgpu discovery Yi-Ling Chen (1): drm/amd/display: Fixed DSC would not PG after removing DSC stream shaoyunl (1): drm/amdgpu: move kfd post_reset out of reset_sriov function xinhui pan (1): drm/amdgpu: Fix double free of dmabuf drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c | 6 -- drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c | 12 +++ drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.h | 2 + drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 7 +- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 12 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 3 +- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 15 ++- drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 46 +++-- drivers/gpu/drm/amd/amdgpu/navi10_ih.c | 34 +++ drivers/gpu/drm/amd/amdgpu/nbio_v2_3.c | 4 + drivers/gpu/drm/amd/amdgpu/nbio_v6_1.c | 4 + drivers/gpu/drm/amd/amdgpu/nbio_v7_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/nbio_v7_2.c | 4 + drivers/gpu/drm/amd/amdgpu/nbio_v7_4.c | 7 +- drivers/gpu/drm/amd/amdgpu/nv.c| 8 +- drivers/gpu/drm/amd/amdgpu/soc15.c | 8 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_svm.c | 111 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 24 - .../drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 2 +- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c | 2 +- .../gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c | 20 ++-- .../gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c| 24 ++--- .../gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c| 6 +- .../gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c | 28 +++--- .../gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c | 10 +- .../gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c | 58 ++- 28 files changed, 279 insertions(+), 186 deletions(-)
Re: [PATCH v3 11/13] drm/msm/dsi: add mode valid callback for dsi_mgr
On 16/11/2021 09:22, Vinod Koul wrote: Add a mode valid callback for dsi_mgr for checking mode being valid in case of DSC. For DSC the height and width needs to be multiple of slice, so we check that here Signed-off-by: Vinod Koul Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi.h | 2 ++ drivers/gpu/drm/msm/dsi/dsi_host.c| 26 ++ drivers/gpu/drm/msm/dsi/dsi_manager.c | 12 3 files changed, 40 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 569c8ff062ba..e7affab2fc1e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -115,6 +115,8 @@ int msm_dsi_host_power_on(struct mipi_dsi_host *host, int msm_dsi_host_power_off(struct mipi_dsi_host *host); int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, const struct drm_display_mode *mode); +enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, + const struct drm_display_mode *mode); struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host); unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 30c1e299aa52..31d385d8d834 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -2588,6 +2588,32 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, return 0; } +enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, + const struct drm_display_mode *mode) +{ + struct msm_dsi_host *msm_host = to_msm_dsi_host(host); + struct msm_display_dsc_config *dsc = msm_host->dsc; + int pic_width = mode->hdisplay; + int pic_height = mode->vdisplay; + + if (!msm_host->dsc) + return MODE_OK; + + if (pic_width % dsc->drm->slice_width) { + pr_err("DSI: pic_width %d has to be multiple of slice %d\n", + pic_width, dsc->drm->slice_width); + return MODE_H_ILLEGAL; + } + + if (pic_height % dsc->drm->slice_height) { + pr_err("DSI: pic_height %d has to be multiple of slice %d\n", + pic_height, dsc->drm->slice_height); + return MODE_V_ILLEGAL; + } + + return MODE_OK; +} + struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host) { return of_drm_find_panel(to_msm_dsi_host(host)->device_node); diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 20c4d650fd80..0ad8a53aaa0e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -579,6 +579,17 @@ static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode); } +static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + int id = dsi_mgr_bridge_get_id(bridge); + struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); + struct mipi_dsi_host *host = msm_dsi->host; + + return msm_dsi_host_check_dsc(host, mode); +} + static const struct drm_connector_funcs dsi_mgr_connector_funcs = { .detect = dsi_mgr_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, @@ -600,6 +611,7 @@ static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = { .disable = dsi_mgr_bridge_disable, .post_disable = dsi_mgr_bridge_post_disable, .mode_set = dsi_mgr_bridge_mode_set, + .mode_valid = dsi_mgr_bridge_mode_valid, }; /* initialize connector when we're connected to a drm_panel */ -- With best wishes Dmitry
[PATCH] drm/gud: Fix descriptor magic check
le32_to_cpu() was put around the wrong operand in the descriptor magic value check. Fix this and put it around the descriptor value which is the one that is in little endian format. Fixes: 40e1a70 ("drm: Add GUD USB Display driver") Reported-by: kernel test robot Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/gud/gud_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index 3f9d4b9a1e3d..e6db478f1e49 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -92,7 +92,7 @@ static int gud_get_display_descriptor(struct usb_interface *intf, if (ret != sizeof(*desc)) return -EIO; - if (desc->magic != le32_to_cpu(GUD_DISPLAY_MAGIC)) + if (le32_to_cpu(desc->magic) != GUD_DISPLAY_MAGIC) return -ENODATA; DRM_DEV_DEBUG_DRIVER(&intf->dev, -- 2.33.0
Re: [PATCH v3] drm/msm/dp: employ bridge mechanism for display enable and disable
On 15/11/2021 21:48, Kuogee Hsieh wrote: Currently the msm_dp_*** functions implement the same sequence which would happen when drm_bridge is used. hence get rid of this intermediate layer and align with the drm_bridge usage to avoid customized implementation. Signed-off-by: Kuogee Hsieh Changes in v2: -- revise commit text -- rename dp_bridge to msm_dp_bridge -- delete empty functions Changes in 3: -- replace kzalloc() with devm_kzalloc() -- replace __dp_display_enable() with dp_display_enable() -- replace __dp_display_disable() with dp_display_disable() --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 21 --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 7 +++ drivers/gpu/drm/msm/dp/dp_display.c | 4 +- drivers/gpu/drm/msm/dp/dp_display.h | 1 + drivers/gpu/drm/msm/dp/dp_drm.c | 91 + drivers/gpu/drm/msm/msm_drv.h | 16 +++-- 6 files changed, 113 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 31050aa..c4e08c4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1003,9 +1003,6 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, trace_dpu_enc_mode_set(DRMID(drm_enc)); - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) - msm_dp_display_mode_set(dpu_enc->dp, drm_enc, mode, adj_mode); - list_for_each_entry(conn_iter, connector_list, head) if (conn_iter->encoder == drm_enc) conn = conn_iter; @@ -1181,14 +1178,6 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) _dpu_encoder_virt_enable_helper(drm_enc); - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) { - ret = msm_dp_display_enable(dpu_enc->dp, drm_enc); - if (ret) { - DPU_ERROR_ENC(dpu_enc, "dp display enable failed: %d\n", - ret); - goto out; - } - } dpu_enc->enabled = true; out: @@ -1214,11 +1203,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) /* wait for idle */ dpu_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE); - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) { - if (msm_dp_display_pre_disable(dpu_enc->dp, drm_enc)) - DPU_ERROR_ENC(dpu_enc, "dp display push idle failed\n"); - } - dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_PRE_STOP); for (i = 0; i < dpu_enc->num_phys_encs; i++) { @@ -1243,11 +1227,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); - if (drm_enc->encoder_type == DRM_MODE_ENCODER_TMDS) { - if (msm_dp_display_disable(dpu_enc->dp, drm_enc)) - DPU_ERROR_ENC(dpu_enc, "dp display disable failed\n"); - } - mutex_unlock(&dpu_enc->enc_lock); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 27d98b5..d16337f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -557,6 +557,13 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, encoder->base.id, rc); return rc; } + + rc = msm_dp_bridge_init(priv->dp[i], dev, encoder); + if (rc) { + DPU_ERROR("failed to setup DPU bridge %d: rc:%d\n", + encoder->base.id, rc); + return rc; + } There is no need to teach DPU driver about all the gory details of DP internals. Move this call to the msm_dp_modeset_init(). } return rc; diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 2f113ff..51770a4 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1674,8 +1674,8 @@ int msm_dp_display_disable(struct msm_dp *dp, struct drm_encoder *encoder) } void msm_dp_display_mode_set(struct msm_dp *dp, struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode) + const struct drm_display_mode *mode, + const struct drm_display_mode *adjusted_mode) { struct dp_display_private *dp_display; diff --git a/drivers/gpu/drm/msm/dp/dp_display.h b/drivers/gpu/drm/msm/dp/dp_display.h index 76f45f9..2237e80 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.h +++ b/drivers/gpu/drm/msm/dp/dp_display.h @@ -13,6 +13,7 @@ struct msm_dp { struct drm_device *drm_dev; struct device *codec_dev; +
Re: [PATCH] drm/amd/display: Fix warning comparing pointer to 0
On 2021-11-24 5:20 a.m., Jiapeng Chong wrote: Fix the following coccicheck warning: ./drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c:96:14-15: WARNING comparing pointer to 0. Reported-by: Abaci Robot Signed-off-by: Jiapeng Chong --- drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c index 122ba29..ec636d0 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dsc/rc_calc_fpu.c @@ -93,7 +93,7 @@ static void get_qp_set(qp_set qps, enum colour_mode cm, enum bits_per_comp bpc, TABLE_CASE(420, 12, min); } - if (table == 0) + if (!table) return; index = (bpp - table[0].bpp) * 2; Reviewed-by: Rodrigo Siqueira Applied to amd-staging-drm-next Thanks
Re: [PATCH 1/2] dt-bindings: display: bridge: Add TI DLPC3433 bindings
Hi Jagan, On Wed, Nov 24, 2021 at 2:26 PM Jagan Teki wrote: > > TI DLPC3433 is a MIPI DSI based display controller bridge > for processing high resolution DMD based projectors. > > It has a flexible configuration of MIPI DSI signal input > produces RGB565, RGB666, RGB888 output format with maximum > of 720p resolution in 60 and 120 Hz refresh rates. > > Add dt-bingings for it. > > Signed-off-by: Christopher Vollo > Signed-off-by: Jagan Teki > --- > .../bindings/display/bridge/ti,dlpc3433.yaml | 112 ++ > MAINTAINERS | 6 + Shouldn't the MAINTAINERS change be part of patch 2/2 instead?
[PATCH] drm/tegra: vic: Fix DMA API misuse
Upon failure, dma_alloc_coherent() returns NULL. If that does happen, passing some uninitialised stack contents to dma_mapping_error() - which belongs to a different API in the first place - has precious little chance of detecting it. Also include the correct header, because the fragile transitive inclusion currently providing it is going to break soon. Fixes: 20e7dce255e9 ("drm/tegra: Remove memory allocation from Falcon library") Signed-off-by: Robin Murphy --- It also doesn't appear to handle failure of the tegra_drm_alloc() path either, but that's a loose thread I have no desire to pull on... ;) --- drivers/gpu/drm/tegra/vic.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c index c02010ff2b7f..da4af5371991 100644 --- a/drivers/gpu/drm/tegra/vic.c +++ b/drivers/gpu/drm/tegra/vic.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -232,10 +233,8 @@ static int vic_load_firmware(struct vic *vic) if (!client->group) { virt = dma_alloc_coherent(vic->dev, size, &iova, GFP_KERNEL); - - err = dma_mapping_error(vic->dev, iova); - if (err < 0) - return err; + if (!virt) + return -ENOMEM; } else { virt = tegra_drm_alloc(tegra, size, &iova); } -- 2.28.0.dirty
Re: [PATCH] drm/bridge: megachips: Ensure both bridges are probed before registration
On Tue, 2021-11-23 at 16:18 +0100, Robert Foss wrote: > Hey Martyn, > > On Tue, 16 Nov 2021 at 13:28, Martyn Welch > wrote: > > > > In the configuration used by the b850v3, the STDP2690 is used to read > > EDID > > data whilst it's the STDP4028 which can detect when monitors are > > connected. > > > > This can result in problems at boot with monitors connected when the > > STDP4028 is probed first, a monitor is detected and an attempt is > > made to > > read the EDID data before the STDP2690 has probed: > > > > [ 3.795721] Unable to handle kernel NULL pointer dereference at > > virtual address 0018 > > [ 3.803845] pgd = (ptrval) > > [ 3.806581] [0018] *pgd= > > [ 3.810180] Internal error: Oops: 5 [#1] SMP ARM > > [ 3.814813] Modules linked in: > > [ 3.817879] CPU: 0 PID: 64 Comm: kworker/u4:1 Not tainted 5.15.0 > > #1 > > [ 3.824161] Hardware name: Freescale i.MX6 Quad/DualLite (Device > > Tree) > > [ 3.830705] Workqueue: events_unbound deferred_probe_work_func > > [ 3.836565] PC is at stdp2690_get_edid+0x44/0x19c > > [ 3.841286] LR is at ge_b850v3_lvds_get_modes+0x2c/0x5c > > [ 3.846526] pc : [<805eae10>] lr : [<805eb138>] psr: > > 8013 > > [ 3.852802] sp : 81c359d0 ip : 7dbb550b fp : 81c35a1c > > [ 3.858037] r10: 81c73840 r9 : 81c73894 r8 : 816d9800 > > [ 3.863270] r7 : r6 : 81c34000 r5 : r4 : > > 810c35f0 > > [ 3.869808] r3 : 80e3e294 r2 : 0080 r1 : 0cc0 r0 : > > 81401180 > > [ 3.876349] Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM > > Segment none > > [ 3.883499] Control: 10c5387d Table: 1000404a DAC: 0051 > > [ 3.889254] Register r0 information: slab kmem_cache start > > 81401180 pointer offset 0 > > [ 3.897034] Register r1 information: non-paged memory > > [ 3.902097] Register r2 information: non-paged memory > > [ 3.907160] Register r3 information: non-slab/vmalloc memory > > [ 3.912832] Register r4 information: non-slab/vmalloc memory > > [ 3.918503] Register r5 information: NULL pointer > > [ 3.923217] Register r6 information: non-slab/vmalloc memory > > [ 3.928887] Register r7 information: NULL pointer > > [ 3.933601] Register r8 information: slab kmalloc-1k start > > 816d9800 pointer offset 0 size 1024 > > [ 3.942244] Register r9 information: slab kmalloc-2k start > > 81c73800 pointer offset 148 size 2048 > > [ 3.951058] Register r10 information: slab kmalloc-2k start > > 81c73800 pointer offset 64 size 2048 > > [ 3.959873] Register r11 information: non-slab/vmalloc memory > > [ 3.965632] Register r12 information: non-paged memory > > [ 3.970781] Process kworker/u4:1 (pid: 64, stack limit = > > 0x(ptrval)) > > [ 3.977148] Stack: (0x81c359d0 to 0x81c36000) > > [ 3.981517] 59c0: 80b2b668 > > 80b2b5bc 02e2 034e > > [ 3.989712] 59e0: 81c35a8c 816d98e8 81c35a14 7dbb550b 805bfcd0 > > 810c35f0 81c73840 824addc0 > > [ 3.997906] 5a00: 1000 816d9800 81c73894 81c73840 81c35a34 > > 81c35a20 805eb138 805eadd8 > > [ 4.006099] 5a20: 810c35f0 0045 81c35adc 81c35a38 80594188 > > 805eb118 80d7c788 80dd1848 > > [ 4.014292] 5a40: 81c35a50 80dca950 811194d3 80dca7c4 > > 80dca944 80dca91c 816d9800 > > [ 4.022485] 5a60: 81c34000 81c760a8 816d9800 80c58c98 810c35f0 > > 816d98e8 1000 1000 > > [ 4.030678] 5a80: 8017712c 81c6 0002 > > 0001 > > [ 4.038870] 5aa0: 816d9900 816d9900 7dbb550b 805c700c > > 0008 826282c8 826282c8 > > [ 4.047062] 5ac0: 1000 81e1ce40 1000 0002 81c35bf4 > > 81c35ae0 805d9694 80593fc0 > > [ 4.055255] 5ae0: 8017a970 80179ad8 0179 81c35bcc > > 81c35b00 80177108 8017a950 > > [ 4.063447] 5b00: 81c35b10 81c34000 81004fd8 > > 81010a38 0059 > > [ 4.071639] 5b20: 816d98d4 81fbb718 0013 826282c8 8017a940 > > 81c35b40 81134448 0400 > > [ 4.079831] 5b40: 0178 e063b9c1 c249 > > 0040 0008 > > [ 4.088024] 5b60: 82628300 82628380 81c34000 > > 81fbb700 82628340 > > [ 4.096216] 5b80: 826283c0 1000 0010 816d9800 > > 826282c0 801766f8 > > [ 4.104408] 5ba0: 81004fd8 0049 > > 0001 80dcf940 80178de4 > > [ 4.112601] 5bc0: 81c35c0c 7dbb550b 80178de4 81fbb700 0010 > > 0010 810c35f4 81e1ce40 > > [ 4.120793] 5be0: 81c40908 000c 81c35c64 81c35bf8 805a7f18 > > 805d94a0 81c35c3c 816d9800 > > [ 4.128985] 5c00: 0010 81c34000 81c35c2c 81c35c18 8012fce0 > > 805be90c 81c35c3c 81c35c28 > > [ 4.137178] 5c20: 805be90c 80173210 81fbb600 81fbb6b4 81c35c5c > > 7dbb550b 81c35c64 81fbb700 > > [ 4.145370] 5c40: 816d9800 0010 810c35f4 81e1ce40 81c40908 > > 000c 81c35c84 81c35c68 > > [ 4.153565] 5c60: 805a8c78 805a7ed0 816d9800 81fbb700 0010 > > 81c35
Re: [PATCH v8 4/8] drm/ingenic: Add dw-hdmi driver for jz4780
Hi Nikolaus, Le mer., nov. 24 2021 at 17:13:30 +0100, H. Nikolaus Schaller a écrit : Am 23.11.2021 um 21:05 schrieb Paul Cercueil : Hi Nikolaus, I keep seeing a few things, sorry. no problem. Le mar., nov. 23 2021 at 19:13:57 +0100, H. Nikolaus Schaller a écrit : From: Paul Boddie A specialisation of the generic Synopsys HDMI driver is employed for JZ4780 HDMI support. This requires a new driver, plus device tree and configuration modifications. Here we add Kconfig DRM_INGENIC_DW_HDMI, Makefile and driver code. Signed-off-by: Paul Boddie Signed-off-by: Ezequiel Garcia Signed-off-by: H. Nikolaus Schaller --- drivers/gpu/drm/ingenic/Kconfig | 9 ++ drivers/gpu/drm/ingenic/Makefile | 1 + drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c | 129 ++ 3 files changed, 139 insertions(+) create mode 100644 drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c diff --git a/drivers/gpu/drm/ingenic/Kconfig b/drivers/gpu/drm/ingenic/Kconfig index 3b57f8be007c4..4efc709d77b0a 100644 --- a/drivers/gpu/drm/ingenic/Kconfig +++ b/drivers/gpu/drm/ingenic/Kconfig @@ -25,4 +25,13 @@ config DRM_INGENIC_IPU The Image Processing Unit (IPU) will appear as a second primary plane. +config DRM_INGENIC_DW_HDMI + tristate "Ingenic specific support for Synopsys DW HDMI" + depends on MACH_JZ4780 + select DRM_DW_HDMI + help + Choose this option to enable Synopsys DesignWare HDMI based driver. + If you want to enable HDMI on Ingenic JZ4780 based SoC, you should +select this option.. + endif diff --git a/drivers/gpu/drm/ingenic/Makefile b/drivers/gpu/drm/ingenic/Makefile index d313326bdddbb..f10cc1c5a5f22 100644 --- a/drivers/gpu/drm/ingenic/Makefile +++ b/drivers/gpu/drm/ingenic/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_DRM_INGENIC) += ingenic-drm.o ingenic-drm-y = ingenic-drm-drv.o ingenic-drm-$(CONFIG_DRM_INGENIC_IPU) += ingenic-ipu.o +obj-$(CONFIG_DRM_INGENIC_DW_HDMI) += ingenic-dw-hdmi.o diff --git a/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c b/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c new file mode 100644 index 0..c14890d6b9826 --- /dev/null +++ b/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. + * Copyright (C) 2019, 2020 Paul Boddie + * + * Derived from dw_hdmi-imx.c with i.MX portions removed. + * Probe and remove operations derived from rcar_dw_hdmi.c. + */ + +#include +#include +#include + +#include +#include +#include + +static const struct dw_hdmi_mpll_config ingenic_mpll_cfg[] = { + { 4525, { { 0x01e0, 0x }, { 0x21e1, 0x }, { 0x41e2, 0x } } }, + { 9250, { { 0x0140, 0x0005 }, { 0x2141, 0x0005 }, { 0x4142, 0x0005 } } }, + { 14850, { { 0x00a0, 0x000a }, { 0x20a1, 0x000a }, { 0x40a2, 0x000a } } }, + { 21600, { { 0x00a0, 0x000a }, { 0x2001, 0x000f }, { 0x4002, 0x000f } } }, + { ~0UL, { { 0x, 0x }, { 0x, 0x }, { 0x, 0x } } } +}; + +static const struct dw_hdmi_curr_ctrl ingenic_cur_ctr[] = { + /*pixelclk bpp8bpp10 bpp12 */ + { 5400, { 0x091c, 0x091c, 0x06dc } }, + { 5840, { 0x091c, 0x06dc, 0x06dc } }, + { 7200, { 0x06dc, 0x06dc, 0x091c } }, + { 7425, { 0x06dc, 0x0b5c, 0x091c } }, + { 11880, { 0x091c, 0x091c, 0x06dc } }, + { 21600, { 0x06dc, 0x0b5c, 0x091c } }, + { ~0UL, { 0x, 0x, 0x } }, +}; + +/* + * Resistance term 133Ohm Cfg + * PREEMP config 0.00 + * TX/CK level 10 + */ +static const struct dw_hdmi_phy_config ingenic_phy_config[] = { + /*pixelclk symbol term vlev */ + { 21600, 0x800d, 0x0005, 0x01ad}, + { ~0UL, 0x, 0x, 0x} +}; + +static enum drm_mode_status +ingenic_dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, + const struct drm_display_info *info, + const struct drm_display_mode *mode) +{ + if (mode->clock < 13500) + return MODE_CLOCK_LOW; + /* FIXME: Hardware is capable of 270MHz, but setup data is missing. */ + if (mode->clock > 216000) + return MODE_CLOCK_HIGH; + + return MODE_OK; +} + +static struct dw_hdmi_plat_data ingenic_dw_hdmi_plat_data = { + .mpll_cfg = ingenic_mpll_cfg, + .cur_ctr= ingenic_cur_ctr, + .phy_config = ingenic_phy_config, + .mode_valid = ingenic_dw_hdmi_mode_valid, + .output_port= 1, +}; + +static const struct of_device_id ingenic_dw_hdmi_dt_ids[] = { + { .compatible = "ingenic,jz4780-dw-hdmi" }, + { /* Sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, ingenic_dw_hdmi_dt_ids); + +static int ingenic_dw_hdmi_probe(struct platform_device *pdev) +{ + struct dw_hdmi *hdmi; + struct regulator *regulator; + int ret; + +
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
23.11.2021 01:21, Arnd Bergmann пишет: > From: Arnd Bergmann > > The DMA resource is never set up anywhere, and passing this as slave_id > has not been the proper procedure in a long time. > > As a preparation for removing all slave_id references from the ALSA code, > remove this one. > > According to Dmitry Osipenko, this driver has never been used and > the mechanism for configuring DMA would not work as it is implemented, > so this part will get rewritten when the driver gets put into use > again in the future. > > Signed-off-by: Arnd Bergmann > --- > sound/soc/tegra/tegra20_spdif.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c > index 9fdc82d58db3..1c3385da6f82 100644 > --- a/sound/soc/tegra/tegra20_spdif.c > +++ b/sound/soc/tegra/tegra20_spdif.c > @@ -284,7 +284,6 @@ static int tegra20_spdif_platform_probe(struct > platform_device *pdev) > spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; > spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; > spdif->playback_dma_data.maxburst = 4; > - spdif->playback_dma_data.slave_id = dmareq->start; > > pm_runtime_enable(&pdev->dev); > > Reviewed-by: Dmitry Osipenko
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
24.11.2021 19:47, Arnd Bergmann пишет: > On Wed, Nov 24, 2021 at 5:32 PM Dmitry Osipenko wrote: >> 23.11.2021 01:21, Arnd Bergmann пишет: >> >> The commit message is correct, however you could remove even more code >> here. But there is no need to make a v3 just because this patch because >> I already prepared patchset that revives this S/PDIF driver and enables >> HDMI audio on Tegra20. I'll take care of cleaning up the whole code of >> this driver. > > Ok, perfect, thanks for taking a closer look as well. > >> >> - dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0); >> - if (!dmareq) { >> - dev_err(&pdev->dev, "No DMA resource\n"); >> - return -ENODEV; >> - } >> - > > Right, I think I considered doing this at some point as well, not sure > why I left it in for the version I posted. Passing the IORESOURCE_DMA > values is clearly wrong by itself and needs to be removed, though > it's not obvious what the correct way of requesting the DMA channel > is for this driver either, without a DT binding or users. Yes, it's indeed not obvious.
Re: [PATCH v2] i2c: tegra: Add ACPI support
24.11.2021 19:40, Akhil R пишет: >> 24.11.2021 10:18, Akhil R пишет: *i2c_dev) > i2c_dev->is_vi = true; } How are you going to differentiate the VI I2C from a non-VI? This doesn't look right. >>> This patch adds the ACPI support to only non-VI I2C. The device_ids in >>> match table are added accordingly. I suppose, of_device_is_compatible >>> always returns false as there is no device tree. >>> Agree with the other comments. >> >> Will the VI I2C have a different ACPI ID or how it's going to work? > As there is a different compatible for VI I2C in device tree, I suppose the > ACPI > would have a different ID as well. I think the logic would also need an > update > if to have VI I2C using the ACPI. But that wasn't actually considered in this > patch. Thanks, you could reflected it in the commit message.
[PATCH 2/2] drm: bridge: Add TI DLPC3433
TI DLPC3433 is a MIPI DSI based display controller bridge for processing high resolution DMD based projectors. It has a flexible configuration of MIPI DSI signal input produces RGB565, RGB666, RGB888 output format with maximum of 720p resolution. Add bridge driver for it. Signed-off-by: Christopher Vollo Signed-off-by: Jagan Teki --- MAINTAINERS | 1 + drivers/gpu/drm/bridge/Kconfig | 13 + drivers/gpu/drm/bridge/Makefile | 1 + drivers/gpu/drm/bridge/ti-dlpc3433.c | 386 +++ 4 files changed, 401 insertions(+) create mode 100644 drivers/gpu/drm/bridge/ti-dlpc3433.c diff --git a/MAINTAINERS b/MAINTAINERS index a3019399dec0..36a63b4f96c3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6203,6 +6203,7 @@ M:Jagan Teki M: Christopher Vollo S: Maintained F: Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml +F: drivers/gpu/drm/bridge/ti-dlpc3433.c DRM DRIVER FOR TPO TPG110 PANELS M: Linus Walleij diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index 61db5a66b493..5fc51e537829 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -279,6 +279,19 @@ config DRM_TOSHIBA_TC358775 help Toshiba TC358775 DSI/LVDS bridge chip driver. +config DRM_TI_DLPC3433 + tristate "TI DLPC3433 Display controller" + depends on DRM && DRM_PANEL + depends on OF + select DRM_MIPI_DSI + help + TI DLPC3433 is a MIPI DSI based display controller bridge + for processing high resolution DMD based projectors. + + It has a flexible configuration of MIPI DSI signal input + produces RGB565, RGB666, RGB888 output format with maximum + of 720p resolution in 60 and 120 Hz refresh rates. + config DRM_TI_TFP410 tristate "TI TFP410 DVI/HDMI bridge" depends on OF diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index f2c73683cfcb..7ff4bf27e6b5 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o obj-$(CONFIG_DRM_TOSHIBA_TC358768) += tc358768.o obj-$(CONFIG_DRM_TOSHIBA_TC358775) += tc358775.o obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/ +obj-$(CONFIG_DRM_TI_DLPC3433) += ti-dlpc3433.o obj-$(CONFIG_DRM_TI_SN65DSI83) += ti-sn65dsi83.o obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o diff --git a/drivers/gpu/drm/bridge/ti-dlpc3433.c b/drivers/gpu/drm/bridge/ti-dlpc3433.c new file mode 100644 index ..557fa832a2fd --- /dev/null +++ b/drivers/gpu/drm/bridge/ti-dlpc3433.c @@ -0,0 +1,386 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 RenewOutReach + * Copyright (C) 2021 Amarula Solutions(India) + * + * Author: + * Jagan Teki + * Christopher Vollo + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +enum cmd_registers { + WR_INPUT_SOURCE = 0x05, /* Write Input Source Select */ + WR_EXT_SOURCE_FMT = 0x07, /* Write External Video Source Format */ + WR_IMAGE_CROP = 0x10, /* Write Image Crop */ + WR_DISPLAY_SIZE = 0x12, /* Write Display Size */ + WR_IMAGE_FREEZE = 0x1A, /* Write Image Freeze */ + WR_INPUT_IMAGE_SIZE = 0x2E, /* Write External Input Image Size */ + WR_RGB_LED_EN = 0x52, /* Write RGB LED Enable */ + WR_RGB_LED_CURRENT = 0x54, /* Write RGB LED Current */ + WR_RGB_LED_MAX_CURRENT = 0x5C, /* Write RGB LED Max Current */ + WR_DSI_HS_CLK = 0xBD, /* Write DSI HS Clock */ + RD_DEVICE_ID= 0xD4, /* Read Controller Device ID */ + WR_DSI_PORT_EN = 0xD7, /* Write DSI Port Enable */ +}; + +enum dev_id { + DLPC3430= 0x0, + DLPC3433, +}; + +enum input_source { + INPUT_EXTERNAL_VIDEO= 0, + INPUT_TEST_PATTERN, + INPUT_SPLASH_SCREEN, +}; + +#define DEV_ID_MASKGENMASK(3, 0) +#define IMAGE_FREESE_ENBIT(0) +#define DSI_PORT_EN0 +#define EXT_SOURCE_FMT_DSI 0 +#define RED_LED_EN BIT(0) +#define GREEN_LED_EN BIT(1) +#define BLUE_LED_ENBIT(2) +#define LED_MASK GENMASK(2, 0) +#define MAX_BYTE_SIZE 8 + +struct dlpc { + struct device *dev; + struct drm_bridge bridge; + struct drm_bridge *panel_bridge; + struct device_node *host_node; + struct mipi_dsi_device *dsi; + struct drm_display_mode mode; + + struct gpio_desc*enable_gpio; + struct regulator*vcc_intf; + struct regulator*vcc_flsh; + struct regmap *regmap; + unsigned intdsi_lanes; +}; + +static inline struct dlpc *bridge_to_dl
[PATCH 1/2] dt-bindings: display: bridge: Add TI DLPC3433 bindings
TI DLPC3433 is a MIPI DSI based display controller bridge for processing high resolution DMD based projectors. It has a flexible configuration of MIPI DSI signal input produces RGB565, RGB666, RGB888 output format with maximum of 720p resolution in 60 and 120 Hz refresh rates. Add dt-bingings for it. Signed-off-by: Christopher Vollo Signed-off-by: Jagan Teki --- .../bindings/display/bridge/ti,dlpc3433.yaml | 112 ++ MAINTAINERS | 6 + 2 files changed, 118 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml b/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml new file mode 100644 index ..3ade3a575c3e --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml @@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/ti,dlpc3433.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI DLPC3433 Display Controller + +maintainers: + - Jagan Teki + - Christopher Vollo + +description: | + The DLPC3433 or DLPC3438 controllers provide a convenient, + multi-functional interface between system electronics and + the DMD, enabling small form factor, low power, and high + resolution HD displays. + +properties: + compatible: +enum: + - ti,dlpc3433 + + reg: +maxItems: 1 +description: virtual channel number of a DSI peripheral + + enable-gpios: +description: PROJ_EN pin, chip powers up PROJ_EN is high. + + vcc_intf-supply: +description: A 1.8V/3.3V supply that power the Host I/O. + + vcc_flsh-supply: +description: A 1.8V/3.3V supply that power the Flash I/O. + + ports: +$ref: /schemas/graph.yaml#/properties/ports + +properties: + port@0: +$ref: /schemas/graph.yaml#/$defs/port-base +unevaluatedProperties: false +description: Video port for MIPI DSI input. + +properties: + endpoint: +$ref: /schemas/media/video-interfaces.yaml# +unevaluatedProperties: false + +properties: + data-lanes: +description: array of physical DSI data lane indexes. +minItems: 1 +items: + - const: 1 + - const: 2 + - const: 3 + - const: 4 + + port@1: +$ref: /schemas/graph.yaml#/properties/port +description: Video port for DPI output (DMD Projector). + +required: + - port@0 + - port@1 + +required: + - compatible + - reg + - enable-gpios + - ports + +additionalProperties: false + +examples: + - | +#include + +i2c1 { +#address-cells = <1>; +#size-cells = <0>; + +bridge@1d { +compatible = "ti,dlpc3433"; +reg = <0x1d>; +enable-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>; + +ports { +#address-cells = <1>; +#size-cells = <0>; + +port@0 { +reg = <0>; + +bridge_in_dsi: endpoint { +remote-endpoint = <&dsi_out_bridge>; +data-lanes = <1 2 3 4>; +}; +}; + +port@1 { +reg = <1>; + +bridge_out_panel: endpoint { +remote-endpoint = <&panel_out_bridge>; +}; +}; +}; +}; +}; diff --git a/MAINTAINERS b/MAINTAINERS index f32c7d733255..a3019399dec0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6198,6 +6198,12 @@ DRM DRIVER FOR TDFX VIDEO CARDS S: Orphan / Obsolete F: drivers/gpu/drm/tdfx/ +DRM DRIVER FOR TI DLPC3433 MIPI DSI DISPLAY CONTROLLER BRIDGE +M: Jagan Teki +M: Christopher Vollo +S: Maintained +F: Documentation/devicetree/bindings/display/bridge/ti,dlpc3433.yaml + DRM DRIVER FOR TPO TPG110 PANELS M: Linus Walleij S: Maintained -- 2.25.1
Re: [PATCH v3 13/13] drm/msm/dsi: Pass DSC params to drm_panel
On 16/11/2021 09:22, Vinod Koul wrote: When DSC is enabled, we need to pass the DSC parameters to panel driver as well, so add a dsc parameter in panel and set it when DSC is enabled Nit: I think patch description is a bit inaccurate, since we pass DSC parameters from panel to DSI host rather than other way around. Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/dsi/dsi_host.c | 16 +++- include/drm/drm_panel.h| 7 +++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 2c14c36f0b3d..3d5773fcf496 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -2159,11 +2159,25 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, struct msm_dsi_host *msm_host = to_msm_dsi_host(host); const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; struct msm_drm_private *priv; + struct drm_panel *panel; int ret; msm_host->dev = dev; + panel = msm_dsi_host_get_panel(&msm_host->base); priv = dev->dev_private; - priv->dsc = msm_host->dsc; + + if (panel && panel->dsc) { + struct msm_display_dsc_config *dsc = priv->dsc; + + if (!dsc) { + dsc = kzalloc(sizeof(*dsc), GFP_KERNEL); + if (!dsc) + return -ENOMEM; + dsc->drm = panel->dsc; + priv->dsc = dsc; + msm_host->dsc = dsc; + } + } ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K); if (ret) { diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 4602f833eb51..eb8ae9bf32ed 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -171,6 +171,13 @@ struct drm_panel { * Panel entry in registry. */ struct list_head list; + + /** +* @dsc: +* +* Panel DSC pps payload to be sent +*/ + struct drm_dsc_config *dsc; }; void drm_panel_init(struct drm_panel *panel, struct device *dev, -- With best wishes Dmitry
Re: [PATCH v8 0/8] MIPS: JZ4780 and CI20 HDMI
Hi Paul, > Am 23.11.2021 um 21:44 schrieb H. Nikolaus Schaller : > > Hi Paul, > >> Am 23.11.2021 um 21:12 schrieb Paul Cercueil : >> >> Hi Nikolaus, >> >> I think if you can fix the last few things I commented on, and I get an ACK >> from Rob for the Device Tree related patches, then it will be ready to merge. > > Fine! Especially for finding the NULL regulator risk. > > Will do in the next days. > For the unwedge pinmux I have to check if we need it at all. No. It is only needed by the driver to take care of for a special potential hardware hickup. The current code does nothing and I have removed it and everything still works as before. There remains only one question for a v9: can we store the (single) regulator reference in a static variable or should we define a struct and allocate memory in patch 4/8? BR and thanks, Nikolaus
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
On Wed, Nov 24, 2021 at 5:32 PM Dmitry Osipenko wrote: > 23.11.2021 01:21, Arnd Bergmann пишет: > > The commit message is correct, however you could remove even more code > here. But there is no need to make a v3 just because this patch because > I already prepared patchset that revives this S/PDIF driver and enables > HDMI audio on Tegra20. I'll take care of cleaning up the whole code of > this driver. Ok, perfect, thanks for taking a closer look as well. > > - dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0); > - if (!dmareq) { > - dev_err(&pdev->dev, "No DMA resource\n"); > - return -ENODEV; > - } > - Right, I think I considered doing this at some point as well, not sure why I left it in for the version I posted. Passing the IORESOURCE_DMA values is clearly wrong by itself and needs to be removed, though it's not obvious what the correct way of requesting the DMA channel is for this driver either, without a DT binding or users. Arnd
RE: [PATCH v2] i2c: tegra: Add ACPI support
> 24.11.2021 10:18, Akhil R пишет: > >> *i2c_dev) > >>> i2c_dev->is_vi = true; } > >> How are you going to differentiate the VI I2C from a non-VI? This > >> doesn't look right. > > This patch adds the ACPI support to only non-VI I2C. The device_ids in > > match table are added accordingly. I suppose, of_device_is_compatible > > always returns false as there is no device tree. > > Agree with the other comments. > > Will the VI I2C have a different ACPI ID or how it's going to work? As there is a different compatible for VI I2C in device tree, I suppose the ACPI would have a different ID as well. I think the logic would also need an update if to have VI I2C using the ACPI. But that wasn't actually considered in this patch. Best Regards, Akhil
Re: [PATCH v2 01/11] ASoC: tegra20-spdif: stop setting slave_id
23.11.2021 01:21, Arnd Bergmann пишет: > From: Arnd Bergmann > > The DMA resource is never set up anywhere, and passing this as slave_id > has not been the proper procedure in a long time. > > As a preparation for removing all slave_id references from the ALSA code, > remove this one. > > According to Dmitry Osipenko, this driver has never been used and > the mechanism for configuring DMA would not work as it is implemented, > so this part will get rewritten when the driver gets put into use > again in the future. > > Signed-off-by: Arnd Bergmann > --- > sound/soc/tegra/tegra20_spdif.c | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c > index 9fdc82d58db3..1c3385da6f82 100644 > --- a/sound/soc/tegra/tegra20_spdif.c > +++ b/sound/soc/tegra/tegra20_spdif.c > @@ -284,7 +284,6 @@ static int tegra20_spdif_platform_probe(struct > platform_device *pdev) > spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; > spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; > spdif->playback_dma_data.maxburst = 4; > - spdif->playback_dma_data.slave_id = dmareq->start; > > pm_runtime_enable(&pdev->dev); > > Thanks, Arnd! The commit message is correct, however you could remove even more code here. But there is no need to make a v3 just because this patch because I already prepared patchset that revives this S/PDIF driver and enables HDMI audio on Tegra20. I'll take care of cleaning up the whole code of this driver. diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c index 7751575cd6d6..1c3385da6f82 100644 --- a/sound/soc/tegra/tegra20_spdif.c +++ b/sound/soc/tegra/tegra20_spdif.c @@ -251,7 +251,7 @@ static const struct regmap_config tegra20_spdif_regmap_config = { static int tegra20_spdif_platform_probe(struct platform_device *pdev) { struct tegra20_spdif *spdif; - struct resource *mem, *dmareq; + struct resource *mem; void __iomem *regs; int ret; @@ -273,12 +273,6 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) if (IS_ERR(regs)) return PTR_ERR(regs); - dmareq = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmareq) { - dev_err(&pdev->dev, "No DMA resource\n"); - return -ENODEV; - } - spdif->regmap = devm_regmap_init_mmio(&pdev->dev, regs, &tegra20_spdif_regmap_config); if (IS_ERR(spdif->regmap)) { @@ -290,7 +284,6 @@ static int tegra20_spdif_platform_probe(struct platform_device *pdev) spdif->playback_dma_data.addr = mem->start + TEGRA20_SPDIF_DATA_OUT; spdif->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; spdif->playback_dma_data.maxburst = 4; - spdif->playback_dma_data.slave_id = dmareq->start; pm_runtime_enable(&pdev->dev);
Re: [PATCH v8 6/8] MIPS: DTS: CI20: Add DT nodes for HDMI setup
Hi Geert, > Am 24.11.2021 um 17:21 schrieb Geert Uytterhoeven : > > Hi Nikolaus, > > On Wed, Nov 24, 2021 at 5:19 PM H. Nikolaus Schaller > wrote: >>> Am 23.11.2021 um 21:10 schrieb Paul Cercueil : >>> Le mar., nov. 23 2021 at 19:13:59 +0100, H. Nikolaus Schaller >>> a écrit : +assigned-clock-rates = <4800>, <0>, <5400>, <0>, <2700>; }; &tcu { @@ -509,6 +534,19 @@ pins_i2c4: i2c4 { bias-disable; }; +pins_hdmi_ddc: hdmi_ddc { +function = "hdmi-ddc"; +groups = "hdmi-ddc"; +bias-disable; +}; + +/* switch to PF25 as gpio driving DDC_SDA low */ +pins_hdmi_ddc_unwedge: hdmi_ddc { +function = "hdmi-ddc"; +groups = "hdmi-ddc"; +bias-disable; +}; >>> >>> Your pins_hdmi_ddc and pins_hdmi_ddc_unwedge are the exact same? You could >>> just use the former and pass it to both pinctrl-0 and pinctrl-1. >> >> This was forgotten to remove. We do not make use of the unwedge feature >> because I could not find out how to use pinctrl to switch this to gpio25 and >> drive it low. > > Using gpio-hog? well, AFAIR it activates the gpio permanently and is a propery of the gpio controller and not of pinmux. The driver assumes it can use pinmux state switching to drive the DDC_SDA line low on demand. Since it is unlikely that we need it at all (and we have no test case that it works) I think we simply can leave this driver feature unused unless we get a test case. BR and thanks, Nikolaus
Re: [PATCH v3 13/13] drm/msm/dsi: Pass DSC params to drm_panel
On 16/11/2021 09:22, Vinod Koul wrote: When DSC is enabled, we need to pass the DSC parameters to panel driver as well, so add a dsc parameter in panel and set it when DSC is enabled Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/dsi/dsi_host.c | 16 +++- include/drm/drm_panel.h| 7 +++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 2c14c36f0b3d..3d5773fcf496 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -2159,11 +2159,25 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, struct msm_dsi_host *msm_host = to_msm_dsi_host(host); const struct msm_dsi_cfg_handler *cfg_hnd = msm_host->cfg_hnd; struct msm_drm_private *priv; + struct drm_panel *panel; int ret; msm_host->dev = dev; + panel = msm_dsi_host_get_panel(&msm_host->base); priv = dev->dev_private; - priv->dsc = msm_host->dsc; + + if (panel && panel->dsc) { + struct msm_display_dsc_config *dsc = priv->dsc; + + if (!dsc) { + dsc = kzalloc(sizeof(*dsc), GFP_KERNEL); devm_kzalloc()? Or even simpler: embed msm_display_dsc_config into struct msm_dsi_host and use it only if dsc->drm is set (IOW the panel provided DSC data)? + if (!dsc) + return -ENOMEM; + dsc->drm = panel->dsc; + priv->dsc = dsc; + msm_host->dsc = dsc; + } + } ret = cfg_hnd->ops->tx_buf_alloc(msm_host, SZ_4K); if (ret) { diff --git a/include/drm/drm_panel.h b/include/drm/drm_panel.h index 4602f833eb51..eb8ae9bf32ed 100644 --- a/include/drm/drm_panel.h +++ b/include/drm/drm_panel.h @@ -171,6 +171,13 @@ struct drm_panel { * Panel entry in registry. */ struct list_head list; + + /** +* @dsc: +* +* Panel DSC pps payload to be sent +*/ + struct drm_dsc_config *dsc; }; void drm_panel_init(struct drm_panel *panel, struct device *dev, -- With best wishes Dmitry
Re: [PATCH v3 12/13] drm/msm/dsi: Add support for DSC configuration
On 24/11/2021 19:21, Dmitry Baryshkov wrote: On 16/11/2021 09:22, Vinod Koul wrote: When DSC is enabled, we need to configure DSI registers accordingly and configure the respective stream compression registers. Add support to calculate the register setting based on DSC params and timing information and configure these registers. Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/dsi/dsi.xml.h | 10 +++ drivers/gpu/drm/msm/dsi/dsi_host.c | 113 - 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index 49b551ad1bff..c1c85df58c4b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -706,4 +706,14 @@ static inline uint32_t DSI_VERSION_MAJOR(uint32_t val) #define REG_DSI_CPHY_MODE_CTRL 0x02d4 +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL 0x029c + +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL2 0x02a0 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL 0x02a4 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2 0x02a8 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL3 0x02ac + #endif /* DSI_XML */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 31d385d8d834..2c14c36f0b3d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -908,6 +908,20 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0)); } +static int dsi_dsc_update_pic_dim(struct msm_display_dsc_config *dsc, + int pic_width, int pic_height) +{ + if (!dsc || !pic_width || !pic_height) { + pr_err("DSI: invalid input: pic_width: %d pic_height: %d\n", pic_width, pic_height); + return -EINVAL; + } + + dsc->drm->pic_width = pic_width; + dsc->drm->pic_height = pic_height; + + return 0; +} + static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { struct drm_display_mode *mode = msm_host->mode; @@ -940,7 +954,68 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) hdisplay /= 2; } + if (msm_host->dsc) { + struct msm_display_dsc_config *dsc = msm_host->dsc; + + /* update dsc params with timing params */ + dsi_dsc_update_pic_dim(dsc, mode->hdisplay, mode->vdisplay); + DBG("Mode Width- %d x Height %d\n", dsc->drm->pic_width, dsc->drm->pic_height); + + /* we do the calculations for dsc parameters here so that + * panel can use these parameters + */ + dsi_populate_dsc_params(dsc); + + /* Divide the display by 3 but keep back/font porch and + * pulse width same + */ + h_total -= hdisplay; + hdisplay /= 3; + h_total += hdisplay; + ha_end = ha_start + hdisplay; + } + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { + if (msm_host->dsc) { + struct msm_display_dsc_config *dsc = msm_host->dsc; + u32 reg, intf_width, slice_per_intf; + u32 total_bytes_per_intf; + + /* first calculate dsc parameters and then program + * compress mode registers + */ + intf_width = hdisplay; + slice_per_intf = DIV_ROUND_UP(intf_width, dsc->drm->slice_width); + + dsc->drm->slice_count = 1; + dsc->bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width * 8, 8); + total_bytes_per_intf = dsc->bytes_in_slice * slice_per_intf; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + dsc->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3); + dsc->bytes_per_pkt = dsc->bytes_in_slice * dsc->drm->slice_count; + dsc->pkt_per_line = slice_per_intf / dsc->drm->slice_count; + + reg = dsc->bytes_per_pkt << 16; + reg |= (0x0b << 8); /* dtype of compressed image */ + + /* pkt_per_line: + * 0 == 1 pkt + * 1 == 2 pkt + * 2 == 4 pkt + * 3 pkt is not supported + * above translates to ffs() - 1 + */ + reg |= (ffs(dsc->pkt_per_line) - 1) << 6; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + reg |= dsc->eol_byte_num << 4; + reg |= 1; + + dsi_write(msm_host, + REG_DSI_VIDEO_COMPRESSION_MODE_CTRL, reg); + } + dsi_write(msm_host, REG_DSI_ACTIVE_H, DSI_ACTIVE_H_START(ha_start) | DSI_ACTIVE_H_END(ha_end)); @@ -959,8 +1034,40 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); } else { /* command mode */ +
Re: [PATCH v8 3/8] dt-bindings: display: Add ingenic,jz4780-dw-hdmi DT Schema
> Am 24.11.2021 um 03:59 schrieb Rob Herring : > > On Tue, 23 Nov 2021 19:13:56 +0100, H. Nikolaus Schaller wrote: >> From: Sam Ravnborg >> >> Add DT bindings for the hdmi driver for the Ingenic JZ4780 SoC. >> Based on .txt binding from Zubair Lutfullah Kakakhel >> >> We also add generic ddc-i2c-bus to synopsys,dw-hdmi.yaml >> >> Signed-off-by: Sam Ravnborg >> Signed-off-by: H. Nikolaus Schaller >> Cc: Rob Herring >> Cc: devicet...@vger.kernel.org >> --- >> .../display/bridge/ingenic,jz4780-hdmi.yaml | 76 +++ >> .../display/bridge/synopsys,dw-hdmi.yaml | 3 + >> 2 files changed, 79 insertions(+) >> create mode 100644 >> Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml >> > > My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check' > on your patch (DT_CHECKER_FLAGS is new in v5.13): > > yamllint warnings/errors: > ./Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml:36:5: > [warning] wrong indentation: expected 2 but found 4 (indentation) ok, fixed. > > dtschema/dtc warnings/errors: > /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml: > 'unevaluatedPropertes' is not one of ['$id', '$schema', 'title', > 'description', 'examples', ah, that is a typo (missing i in ...ties). > 'required', 'allOf', 'anyOf', 'oneOf', 'definitions', '$defs', > 'additionalProperties', 'dependencies', 'dependentRequired', > 'dependentSchemas', 'patternProperties', 'properties', 'if', 'then', 'else', > 'unevaluatedProperties', 'deprecated', 'maintainers', 'select'] > from schema $id: http://devicetree.org/meta-schemas/base.yaml# > /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml: > 'oneOf' conditional failed, one must be fixed: > 'unevaluatedProperties' is a required property > 'additionalProperties' is a required property > hint: A schema with a "$ref" to another schema either can define all > properties used and use "additionalProperties" or can use > "unevaluatedProperties" > from schema $id: http://devicetree.org/meta-schemas/base.yaml# > Unknown file referenced: [Errno 2] No such file or directory: > '/usr/local/lib/python3.8/dist-packages/dtschema/schemas/bridge/bridge/synopsys,dw-hdmi.yaml' > xargs: dt-doc-validate: exited with status 255; aborting > /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml: > ignoring, error in schema: > warning: no schema found in file: > ./Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml > Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.example.dts:19:18: > fatal error: dt-bindings/clock/jz4780-cgu.h: No such file or directory > 19 | #include > | ^~~~ > compilation terminated. > make[1]: *** [scripts/Makefile.lib:373: > Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.example.dt.yaml] > Error 1 > make[1]: *** Waiting for unfinished jobs > make: *** [Makefile:1413: dt_binding_check] Error 2 > > doc reference errors (make refcheckdocs): > > See https://patchwork.ozlabs.org/patch/1558736 > > This check can fail if there are any dependencies. The base for a patch > series is generally the most recent rc1. > > If you already ran 'make dt_binding_check' and didn't see the above > error(s), then make sure 'yamllint' is installed and dt-schema is up to > date: > > pip3 install dtschema --upgrade > > Please check and re-submit. >
Re: [PATCH v8 6/8] MIPS: DTS: CI20: Add DT nodes for HDMI setup
Hi Nikolaus, On Wed, Nov 24, 2021 at 5:19 PM H. Nikolaus Schaller wrote: > > Am 23.11.2021 um 21:10 schrieb Paul Cercueil : > > Le mar., nov. 23 2021 at 19:13:59 +0100, H. Nikolaus Schaller > > a écrit : > >> +assigned-clock-rates = <4800>, <0>, <5400>, <0>, <2700>; > >> }; > >> &tcu { > >> @@ -509,6 +534,19 @@ pins_i2c4: i2c4 { > >> bias-disable; > >> }; > >> +pins_hdmi_ddc: hdmi_ddc { > >> +function = "hdmi-ddc"; > >> +groups = "hdmi-ddc"; > >> +bias-disable; > >> +}; > >> + > >> +/* switch to PF25 as gpio driving DDC_SDA low */ > >> +pins_hdmi_ddc_unwedge: hdmi_ddc { > >> +function = "hdmi-ddc"; > >> +groups = "hdmi-ddc"; > >> +bias-disable; > >> +}; > > > > Your pins_hdmi_ddc and pins_hdmi_ddc_unwedge are the exact same? You could > > just use the former and pass it to both pinctrl-0 and pinctrl-1. > > This was forgotten to remove. We do not make use of the unwedge feature > because I could not find out how to use pinctrl to switch this to gpio25 and > drive it low. Using gpio-hog? 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 v3 12/13] drm/msm/dsi: Add support for DSC configuration
On 16/11/2021 09:22, Vinod Koul wrote: When DSC is enabled, we need to configure DSI registers accordingly and configure the respective stream compression registers. Add support to calculate the register setting based on DSC params and timing information and configure these registers. Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/dsi/dsi.xml.h | 10 +++ drivers/gpu/drm/msm/dsi/dsi_host.c | 113 - 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index 49b551ad1bff..c1c85df58c4b 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -706,4 +706,14 @@ static inline uint32_t DSI_VERSION_MAJOR(uint32_t val) #define REG_DSI_CPHY_MODE_CTRL 0x02d4 +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL 0x029c + +#define REG_DSI_VIDEO_COMPRESSION_MODE_CTRL2 0x02a0 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL 0x02a4 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL2 0x02a8 + +#define REG_DSI_COMMAND_COMPRESSION_MODE_CTRL3 0x02ac + #endif /* DSI_XML */ diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 31d385d8d834..2c14c36f0b3d 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -908,6 +908,20 @@ static void dsi_ctrl_config(struct msm_dsi_host *msm_host, bool enable, dsi_write(msm_host, REG_DSI_CPHY_MODE_CTRL, BIT(0)); } +static int dsi_dsc_update_pic_dim(struct msm_display_dsc_config *dsc, + int pic_width, int pic_height) +{ + if (!dsc || !pic_width || !pic_height) { + pr_err("DSI: invalid input: pic_width: %d pic_height: %d\n", pic_width, pic_height); + return -EINVAL; + } + + dsc->drm->pic_width = pic_width; + dsc->drm->pic_height = pic_height; + + return 0; +} + static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) { struct drm_display_mode *mode = msm_host->mode; @@ -940,7 +954,68 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) hdisplay /= 2; } + if (msm_host->dsc) { + struct msm_display_dsc_config *dsc = msm_host->dsc; + + /* update dsc params with timing params */ + dsi_dsc_update_pic_dim(dsc, mode->hdisplay, mode->vdisplay); + DBG("Mode Width- %d x Height %d\n", dsc->drm->pic_width, dsc->drm->pic_height); + + /* we do the calculations for dsc parameters here so that +* panel can use these parameters +*/ + dsi_populate_dsc_params(dsc); + + /* Divide the display by 3 but keep back/font porch and +* pulse width same +*/ + h_total -= hdisplay; + hdisplay /= 3; + h_total += hdisplay; + ha_end = ha_start + hdisplay; + } + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { + if (msm_host->dsc) { + struct msm_display_dsc_config *dsc = msm_host->dsc; + u32 reg, intf_width, slice_per_intf; + u32 total_bytes_per_intf; + + /* first calculate dsc parameters and then program +* compress mode registers +*/ + intf_width = hdisplay; + slice_per_intf = DIV_ROUND_UP(intf_width, dsc->drm->slice_width); + + dsc->drm->slice_count = 1; + dsc->bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width * 8, 8); + total_bytes_per_intf = dsc->bytes_in_slice * slice_per_intf; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + dsc->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3); + dsc->bytes_per_pkt = dsc->bytes_in_slice * dsc->drm->slice_count; + dsc->pkt_per_line = slice_per_intf / dsc->drm->slice_count; + + reg = dsc->bytes_per_pkt << 16; + reg |= (0x0b << 8);/* dtype of compressed image */ + + /* pkt_per_line: +* 0 == 1 pkt +* 1 == 2 pkt +* 2 == 4 pkt +* 3 pkt is not supported +* above translates to ffs() - 1 +*/ + reg |= (ffs(dsc->pkt_per_line) - 1) << 6; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + reg |= dsc->eol_byte_num << 4; + reg |= 1; + +
Re: [PATCH v8 3/8] dt-bindings: display: Add ingenic,jz4780-dw-hdmi DT Schema
Hi Rob and Paul, > Am 24.11.2021 um 10:17 schrieb Paul Cercueil : > > Hi Nikolaus, > > Le mar., nov. 23 2021 at 19:13:56 +0100, H. Nikolaus Schaller > a écrit : >> From: Sam Ravnborg >> Add DT bindings for the hdmi driver for the Ingenic JZ4780 SoC. >> Based on .txt binding from Zubair Lutfullah Kakakhel >> We also add generic ddc-i2c-bus to synopsys,dw-hdmi.yaml >> Signed-off-by: Sam Ravnborg >> Signed-off-by: H. Nikolaus Schaller >> Cc: Rob Herring >> Cc: devicet...@vger.kernel.org >> --- >> .../display/bridge/ingenic,jz4780-hdmi.yaml | 76 +++ >> .../display/bridge/synopsys,dw-hdmi.yaml | 3 + >> 2 files changed, 79 insertions(+) >> create mode 100644 >> Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml >> diff --git >> a/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml >> b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml >> new file mode 100644 >> index 0..190ca4521b1d0 >> --- /dev/null >> +++ >> b/Documentation/devicetree/bindings/display/bridge/ingenic,jz4780-hdmi.yaml >> @@ -0,0 +1,76 @@ >> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) >> +%YAML 1.2 >> +--- >> +$id: http://devicetree.org/schemas/bridge/ingenic,jz4780-hdmi.yaml# >> +$schema: http://devicetree.org/meta-schemas/core.yaml# >> + >> +title: Bindings for Ingenic JZ4780 HDMI Transmitter >> + >> +maintainers: >> + - H. Nikolaus Schaller >> + >> +description: | >> + The HDMI Transmitter in the Ingenic JZ4780 is a Synopsys DesignWare HDMI >> 1.4 >> + TX controller IP with accompanying PHY IP. >> + >> +allOf: >> + - $ref: bridge/synopsys,dw-hdmi.yaml# >> + >> +properties: >> + compatible: >> +const: ingenic,jz4780-dw-hdmi >> + >> + reg-io-width: >> +const: 4 >> + >> + clocks: >> +maxItems: 2 >> + >> + hdmi-5v-supply: >> +description: Optional regulator to provide +5V at the connector >> + >> + ports: >> +$ref: /schemas/graph.yaml#/properties/ports >> + >> +required: >> +- compatible >> +- clocks >> +- clock-names >> +- ports >> +- reg-io-width >> + >> +unevaluatedPropertes: false >> + >> +examples: >> + - | >> +#include > > This include was moved in 5.16-rc1 to > . I see! > > Cheers, > -Paul > >> + >> +hdmi: hdmi@1018 { >> +compatible = "ingenic,jz4780-dw-hdmi"; >> +reg = <0x1018 0x8000>; >> +reg-io-width = <4>; >> +ddc-i2c-bus = <&i2c4>; >> +interrupt-parent = <&intc>; >> +interrupts = <3>; >> +clocks = <&cgu JZ4780_CLK_AHB0>, <&cgu JZ4780_CLK_HDMI>; >> +clock-names = "iahb", "isfr"; >> + >> +ports { >> +#address-cells = <1>; >> +#size-cells = <0>; >> +hdmi_in: port@0 { >> +reg = <0>; >> +dw_hdmi_in: endpoint { >> +remote-endpoint = <&jz4780_lcd_out>; >> +}; >> +}; >> +hdmi_out: port@1 { >> +reg = <1>; >> +dw_hdmi_out: endpoint { >> +remote-endpoint = <&hdmi_con>; >> +}; >> +}; >> +}; >> +}; >> + >> +... >> diff --git >> a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml >> b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml >> index 9be44a682e67a..9cbeabaee0968 100644 >> --- a/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml >> +++ b/Documentation/devicetree/bindings/display/bridge/synopsys,dw-hdmi.yaml >> @@ -50,6 +50,9 @@ properties: >> interrupts: >> maxItems: 1 >> + ddc-i2c-bus: >> +description: An I2C interface if the internal DDC I2C driver is not to >> be used >> + >> additionalProperties: true >> ... >> -- >> 2.33.0 > >
Re: [PATCH v8 6/8] MIPS: DTS: CI20: Add DT nodes for HDMI setup
> Am 23.11.2021 um 21:10 schrieb Paul Cercueil : > > Hi Nikolaus, > > Le mar., nov. 23 2021 at 19:13:59 +0100, H. Nikolaus Schaller > a écrit : >> From: Paul Boddie >> We need to hook up >> * HDMI connector >> * HDMI power regulator >> * JZ4780_CLK_HDMI @ 27 MHz >> * DDC pinmux >> * HDMI and LCDC endpoint connections >> Signed-off-by: Paul Boddie >> Signed-off-by: H. Nikolaus Schaller >> --- >> arch/mips/boot/dts/ingenic/ci20.dts | 83 +++-- >> 1 file changed, 80 insertions(+), 3 deletions(-) >> diff --git a/arch/mips/boot/dts/ingenic/ci20.dts >> b/arch/mips/boot/dts/ingenic/ci20.dts >> index b249a4f0f6b62..15cf03670693f 100644 >> --- a/arch/mips/boot/dts/ingenic/ci20.dts >> +++ b/arch/mips/boot/dts/ingenic/ci20.dts >> @@ -78,6 +78,18 @@ eth0_power: fixedregulator@0 { >> enable-active-high; >> }; >> +hdmi_out: connector { >> +compatible = "hdmi-connector"; >> +label = "HDMI OUT"; >> +type = "a"; >> + >> +port { >> +hdmi_con: endpoint { >> +remote-endpoint = <&dw_hdmi_out>; >> +}; >> +}; >> +}; >> + >> ir: ir { >> compatible = "gpio-ir-receiver"; >> gpios = <&gpe 3 GPIO_ACTIVE_LOW>; >> @@ -102,6 +114,17 @@ otg_power: fixedregulator@2 { >> gpio = <&gpf 14 GPIO_ACTIVE_LOW>; >> enable-active-high; >> }; >> + >> +hdmi_power: fixedregulator@3 { >> +compatible = "regulator-fixed"; >> + >> +regulator-name = "hdmi_power"; >> +regulator-min-microvolt = <500>; >> +regulator-max-microvolt = <500>; >> + >> +gpio = <&gpa 25 0>; >> +enable-active-high; >> +}; >> }; >> &ext { >> @@ -114,11 +137,13 @@ &cgu { >> * precision. >> */ >> assigned-clocks = <&cgu JZ4780_CLK_OTGPHY>, <&cgu JZ4780_CLK_RTC>, >> - <&cgu JZ4780_CLK_SSIPLL>, <&cgu JZ4780_CLK_SSI>; >> + <&cgu JZ4780_CLK_SSIPLL>, <&cgu JZ4780_CLK_SSI>, >> + <&cgu JZ4780_CLK_HDMI>; >> assigned-clock-parents = <0>, <&cgu JZ4780_CLK_RTCLK>, >> <&cgu JZ4780_CLK_MPLL>, >> - <&cgu JZ4780_CLK_SSIPLL>; >> -assigned-clock-rates = <4800>, <0>, <5400>; >> + <&cgu JZ4780_CLK_SSIPLL>, >> + <0>; > > Nit - you can remove the last <0>, it will be the default. Well, it might make life easier for the next addition but I've removed it. > >> +assigned-clock-rates = <4800>, <0>, <5400>, <0>, <2700>; >> }; >> &tcu { >> @@ -509,6 +534,19 @@ pins_i2c4: i2c4 { >> bias-disable; >> }; >> +pins_hdmi_ddc: hdmi_ddc { >> +function = "hdmi-ddc"; >> +groups = "hdmi-ddc"; >> +bias-disable; >> +}; >> + >> +/* switch to PF25 as gpio driving DDC_SDA low */ >> +pins_hdmi_ddc_unwedge: hdmi_ddc { >> +function = "hdmi-ddc"; >> +groups = "hdmi-ddc"; >> +bias-disable; >> +}; > > Your pins_hdmi_ddc and pins_hdmi_ddc_unwedge are the exact same? You could > just use the former and pass it to both pinctrl-0 and pinctrl-1. This was forgotten to remove. We do not make use of the unwedge feature because I could not find out how to use pinctrl to switch this to gpio25 and drive it low. And I always had a revert for this in my test tree and we haven't seen a stuck DDC so far. Therefore I remove it (and leave it as maybe-to-to in my tree). > > Cheers, > -Paul > >> + >> pins_nemc: nemc { >> function = "nemc"; >> groups = "nemc-data", "nemc-cle-ale", "nemc-rd-we", >> "nemc-frd-fwe"; >> @@ -539,3 +577,42 @@ pins_mmc1: mmc1 { >> bias-disable; >> }; >> }; >> + >> +&hdmi { >> +status = "okay"; >> + >> +pinctrl-names = "default", "unwedge"; >> +pinctrl-0 = <&pins_hdmi_ddc>; >> +pinctrl-1 = <&pins_hdmi_ddc_unwedge>; >> + >> +hdmi-5v-supply = <&hdmi_power>; >> + >> +ports { >> +#address-cells = <1>; >> +#size-cells = <0>; >> + >> +port@0 { >> +reg = <0>; >> +dw_hdmi_in: endpoint { >> +remote-endpoint = <&lcd_out>; >> +}; >> +}; >> + >> +port@1 { >> +reg = <1>; >> +dw_hdmi_out: endpoint { >> +remote-endpoint = <&hdmi_con>; >> +}; >> +}; >> +}; >> +}; >> + >> +&lcdc0 { >> +status = "okay"; >> + >> +port { >> +lcd_out: endpoint { >> +remote-endpoint = <&dw_hdmi_in>; >> +}; >> +}; >> +}; >> -- >> 2.33.0
Re: [PATCH v8 4/8] drm/ingenic: Add dw-hdmi driver for jz4780
> Am 23.11.2021 um 21:05 schrieb Paul Cercueil : > > Hi Nikolaus, > > I keep seeing a few things, sorry. no problem. > > > Le mar., nov. 23 2021 at 19:13:57 +0100, H. Nikolaus Schaller > a écrit : >> From: Paul Boddie >> A specialisation of the generic Synopsys HDMI driver is employed for >> JZ4780 HDMI support. This requires a new driver, plus device tree and >> configuration modifications. >> Here we add Kconfig DRM_INGENIC_DW_HDMI, Makefile and driver code. >> Signed-off-by: Paul Boddie >> Signed-off-by: Ezequiel Garcia >> Signed-off-by: H. Nikolaus Schaller >> --- >> drivers/gpu/drm/ingenic/Kconfig | 9 ++ >> drivers/gpu/drm/ingenic/Makefile | 1 + >> drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c | 129 ++ >> 3 files changed, 139 insertions(+) >> create mode 100644 drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c >> diff --git a/drivers/gpu/drm/ingenic/Kconfig >> b/drivers/gpu/drm/ingenic/Kconfig >> index 3b57f8be007c4..4efc709d77b0a 100644 >> --- a/drivers/gpu/drm/ingenic/Kconfig >> +++ b/drivers/gpu/drm/ingenic/Kconfig >> @@ -25,4 +25,13 @@ config DRM_INGENIC_IPU >>The Image Processing Unit (IPU) will appear as a second primary plane. >> +config DRM_INGENIC_DW_HDMI >> +tristate "Ingenic specific support for Synopsys DW HDMI" >> +depends on MACH_JZ4780 >> +select DRM_DW_HDMI >> +help >> + Choose this option to enable Synopsys DesignWare HDMI based driver. >> + If you want to enable HDMI on Ingenic JZ4780 based SoC, you should >> + select this option.. >> + >> endif >> diff --git a/drivers/gpu/drm/ingenic/Makefile >> b/drivers/gpu/drm/ingenic/Makefile >> index d313326bdddbb..f10cc1c5a5f22 100644 >> --- a/drivers/gpu/drm/ingenic/Makefile >> +++ b/drivers/gpu/drm/ingenic/Makefile >> @@ -1,3 +1,4 @@ >> obj-$(CONFIG_DRM_INGENIC) += ingenic-drm.o >> ingenic-drm-y = ingenic-drm-drv.o >> ingenic-drm-$(CONFIG_DRM_INGENIC_IPU) += ingenic-ipu.o >> +obj-$(CONFIG_DRM_INGENIC_DW_HDMI) += ingenic-dw-hdmi.o >> diff --git a/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c >> b/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c >> new file mode 100644 >> index 0..c14890d6b9826 >> --- /dev/null >> +++ b/drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c >> @@ -0,0 +1,129 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. >> + * Copyright (C) 2019, 2020 Paul Boddie >> + * >> + * Derived from dw_hdmi-imx.c with i.MX portions removed. >> + * Probe and remove operations derived from rcar_dw_hdmi.c. >> + */ >> + >> +#include >> +#include >> +#include >> + >> +#include >> +#include >> +#include >> + >> +static const struct dw_hdmi_mpll_config ingenic_mpll_cfg[] = { >> +{ 4525, { { 0x01e0, 0x }, { 0x21e1, 0x }, { 0x41e2, 0x >> } } }, >> +{ 9250, { { 0x0140, 0x0005 }, { 0x2141, 0x0005 }, { 0x4142, 0x0005 >> } } }, >> +{ 14850, { { 0x00a0, 0x000a }, { 0x20a1, 0x000a }, { 0x40a2, 0x000a >> } } }, >> +{ 21600, { { 0x00a0, 0x000a }, { 0x2001, 0x000f }, { 0x4002, 0x000f >> } } }, >> +{ ~0UL, { { 0x, 0x }, { 0x, 0x }, { 0x, 0x >> } } } >> +}; >> + >> +static const struct dw_hdmi_curr_ctrl ingenic_cur_ctr[] = { >> +/*pixelclk bpp8bpp10 bpp12 */ >> +{ 5400, { 0x091c, 0x091c, 0x06dc } }, >> +{ 5840, { 0x091c, 0x06dc, 0x06dc } }, >> +{ 7200, { 0x06dc, 0x06dc, 0x091c } }, >> +{ 7425, { 0x06dc, 0x0b5c, 0x091c } }, >> +{ 11880, { 0x091c, 0x091c, 0x06dc } }, >> +{ 21600, { 0x06dc, 0x0b5c, 0x091c } }, >> +{ ~0UL, { 0x, 0x, 0x } }, >> +}; >> + >> +/* >> + * Resistance term 133Ohm Cfg >> + * PREEMP config 0.00 >> + * TX/CK level 10 >> + */ >> +static const struct dw_hdmi_phy_config ingenic_phy_config[] = { >> +/*pixelclk symbol term vlev */ >> +{ 21600, 0x800d, 0x0005, 0x01ad}, >> +{ ~0UL, 0x, 0x, 0x} >> +}; >> + >> +static enum drm_mode_status >> +ingenic_dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, >> + const struct drm_display_info *info, >> + const struct drm_display_mode *mode) >> +{ >> +if (mode->clock < 13500) >> +return MODE_CLOCK_LOW; >> +/* FIXME: Hardware is capable of 270MHz, but setup data is missing. */ >> +if (mode->clock > 216000) >> +return MODE_CLOCK_HIGH; >> + >> +return MODE_OK; >> +} >> + >> +static struct dw_hdmi_plat_data ingenic_dw_hdmi_plat_data = { >> +.mpll_cfg = ingenic_mpll_cfg, >> +.cur_ctr= ingenic_cur_ctr, >> +.phy_config = ingenic_phy_config, >> +.mode_valid = ingenic_dw_hdmi_mode_valid, >> +.output_port= 1, >> +}; >> + >> +static const struct of_device_id ingenic_dw_hdmi_dt_ids[] = { >> +{ .compatible = "ingenic,jz4780-dw-hdmi" }, >> +{ /* Sentinel */ }, >> +}; >> +MODULE_DEVICE_TABLE(of, ingenic_dw_hdmi_dt_ids); >> + >> +static int ingenic_dw_hdm
Re: [PATCH v2] i2c: tegra: Add ACPI support
24.11.2021 10:18, Akhil R пишет: >> *i2c_dev) >>> i2c_dev->is_vi = true; >>> } >> How are you going to differentiate the VI I2C from a non-VI? This doesn't >> look >> right. > This patch adds the ACPI support to only non-VI I2C. The device_ids in match > table > are added accordingly. I suppose, of_device_is_compatible always returns > false as > there is no device tree. > Agree with the other comments. Will the VI I2C have a different ACPI ID or how it's going to work?
Re: [PATCH v3 10/13] drm/msm/disp/dpu1: Add DSC support in RM
On 16/11/2021 09:22, Vinod Koul wrote: This add the bits in RM to enable the DSC blocks Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 66 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 1 + 3 files changed, 68 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h index 775bcbda860f..fd6672efb096 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -146,6 +146,7 @@ struct dpu_global_state { uint32_t ctl_to_enc_id[CTL_MAX - CTL_0]; uint32_t intf_to_enc_id[INTF_MAX - INTF_0]; uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0]; + uint32_t dsc_to_enc_id[DSC_MAX - DSC_0]; }; struct dpu_global_state diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index f9c83d6e427a..c9d0fc765aaf 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -11,6 +11,7 @@ #include "dpu_hw_intf.h" #include "dpu_hw_dspp.h" #include "dpu_hw_merge3d.h" +#include "dpu_hw_dsc.h" #include "dpu_encoder.h" #include "dpu_trace.h" @@ -75,6 +76,14 @@ int dpu_rm_destroy(struct dpu_rm *rm) dpu_hw_intf_destroy(hw); } } + for (i = 0; i < ARRAY_SIZE(rm->dsc_blks); i++) { + struct dpu_hw_dsc *hw; + + if (rm->dsc_blks[i]) { + hw = to_dpu_hw_dsc(rm->dsc_blks[i]); + dpu_hw_dsc_destroy(hw); + } + } return 0; } @@ -221,6 +230,19 @@ int dpu_rm_init(struct dpu_rm *rm, rm->dspp_blks[dspp->id - DSPP_0] = &hw->base; } + for (i = 0; i < cat->dsc_count; i++) { + struct dpu_hw_dsc *hw; + const struct dpu_dsc_cfg *dsc = &cat->dsc[i]; + + hw = dpu_hw_dsc_init(dsc->id, mmio, cat); + if (IS_ERR_OR_NULL(hw)) { + rc = PTR_ERR(hw); + DPU_ERROR("failed dsc object creation: err %d\n", rc); + goto fail; + } + rm->dsc_blks[dsc->id - DSC_0] = &hw->base; + } + return 0; fail: @@ -476,6 +498,7 @@ static int _dpu_rm_reserve_intf( } global_state->intf_to_enc_id[idx] = enc_id; + return 0; } @@ -500,6 +523,38 @@ static int _dpu_rm_reserve_intf_related_hw( return ret; } +static int _dpu_rm_reserve_dsc(struct dpu_rm *rm, + struct dpu_global_state *global_state, + struct drm_encoder *enc, + const struct msm_display_topology *top) +{ + struct msm_drm_private *priv; + int num_dsc = top->num_dsc; + int i; + + priv = enc->dev->dev_private; + + if (!priv) + return -EIO; + + /* check if DSC is supported */ + if (!priv->dsc) + return 0; I don't think this check is necessary. If topology requests the DSC, just give away required amount of hw blocks. + + /* check if DSC required are allocated or not */ + for (i = 0; i < num_dsc; i++) { + if (global_state->dsc_to_enc_id[i]) { + DPU_ERROR("DSC %d is already allocated\n", i); + return -EIO; + } + } + + for (i = 0; i < num_dsc; i++) + global_state->dsc_to_enc_id[i] = enc->base.id; + + return 0; +} + static int _dpu_rm_make_reservation( struct dpu_rm *rm, struct dpu_global_state *global_state, @@ -526,6 +581,10 @@ static int _dpu_rm_make_reservation( if (ret) return ret; + ret = _dpu_rm_reserve_dsc(rm, global_state, enc, &reqs->topology); + if (ret) + return ret; + return ret; } @@ -567,6 +626,8 @@ void dpu_rm_release(struct dpu_global_state *global_state, ARRAY_SIZE(global_state->ctl_to_enc_id), enc->base.id); _dpu_rm_clear_mapping(global_state->intf_to_enc_id, ARRAY_SIZE(global_state->intf_to_enc_id), enc->base.id); + _dpu_rm_clear_mapping(global_state->dsc_to_enc_id, + ARRAY_SIZE(global_state->dsc_to_enc_id), enc->base.id); } int dpu_rm_reserve( @@ -640,6 +701,11 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm, hw_to_enc_id = global_state->dspp_to_enc_id; max_blks = ARRAY_SIZE(rm->dspp_blks); break; + case DPU_HW_BLK_DSC: + hw_blks = rm->dsc_blks; + hw_to_enc_id = global_state->dsc_to_enc_id; + max_blks = ARRAY_SIZE(rm->dsc_blks); + break; default: DPU_ERROR("blk type %d not managed by rm\n", type); return 0; diff --git a/drivers/gp
Re: [PATCH v3 09/13] drm/msm/disp/dpu1: Add support for DSC in topology
On 16/11/2021 09:22, Vinod Koul wrote: For DSC to work we typically need a 2,2,1 configuration. This should suffice for resolutions up to 4k. For more resolutions like 8k this won't work. Also, it is better to use 2 LMs and DSC instances as half width results in lesser power consumption as compared to single LM, DSC at full width. The panel has been tested only with 2,2,1 configuration, so for now we blindly create 2,2,1 topology when DSC is enabled Co-developed-by: Abhinav Kumar Signed-off-by: Abhinav Kumar Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 18 ++ drivers/gpu/drm/msm/msm_drv.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index f2ff8a504918..12f58de88ac7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -533,6 +533,8 @@ static struct msm_display_topology dpu_encoder_get_topology( struct drm_display_mode *mode) { struct msm_display_topology topology = {0}; + struct drm_encoder *drm_enc; + struct msm_drm_private *priv; int i, intf_count = 0; for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++) @@ -567,8 +569,24 @@ static struct msm_display_topology dpu_encoder_get_topology( topology.num_enc = 0; topology.num_intf = intf_count; + drm_enc = &dpu_enc->base; + priv = drm_enc->dev->dev_private; + if (priv && priv->dsc) { + /* In case of Display Stream Compression DSC, we would use +* 2 encoders, 2 line mixers and 1 interface +* this is power optimal and can drive up to (including) 4k +* screens +*/ + topology.num_enc = 2; + topology.num_dsc = 2; + topology.num_intf = 1; + topology.num_lm = 2; + priv->dsc->dsc_mask = BIT(0) | BIT(1); dsc_mask is still hardcoded here. We should use DSC indices returned from RM. + } + return topology; } + static int dpu_encoder_virt_atomic_check( struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index c4a588ad226e..d6b25d77700e 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h @@ -103,12 +103,14 @@ enum msm_event_wait { * @num_enc: number of compression encoder blocks used * @num_intf: number of interfaces the panel is mounted on * @num_dspp: number of dspp blocks used + * @num_dsc: number of Display Stream Compression (DSC) blocks used */ struct msm_display_topology { u32 num_lm; u32 num_enc; u32 num_intf; u32 num_dspp; + u32 num_dsc; }; /** -- With best wishes Dmitry
Re: [PATCH v3 07/13] drm/msm/disp/dpu1: Add support for DSC in encoder
On 16/11/2021 09:22, Vinod Koul wrote: We need to configure the encoder for DSC configuration and calculate DSC parameters for the given timing so this patch adds that support by adding dpu_encoder_prep_dsc() which is invoked when DSC is enabled. Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 140 +++- 1 file changed, 139 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index e7ee4cfb8461..f2ff8a504918 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -21,6 +21,7 @@ #include "dpu_hw_intf.h" #include "dpu_hw_ctl.h" #include "dpu_hw_dspp.h" +#include "dpu_hw_dsc.h" #include "dpu_formats.h" #include "dpu_encoder_phys.h" #include "dpu_crtc.h" @@ -136,6 +137,7 @@ enum dpu_enc_rc_states { * @cur_slave:As above but for the slave encoder. * @hw_pp:Handle to the pingpong blocks used for the display. No. *pingpong blocks can be different than num_phys_encs. + * @hw_dsc:Handle to the DSC blocks used for the display. * @intfs_swapped:Whether or not the phys_enc interfaces have been swapped *for partial update right-only cases, such as pingpong *split where virtual pingpong does not generate IRQs @@ -182,6 +184,7 @@ struct dpu_encoder_virt { struct dpu_encoder_phys *cur_master; struct dpu_encoder_phys *cur_slave; struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; bool intfs_swapped; @@ -972,7 +975,8 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL }; - int num_lm, num_ctl, num_pp; + struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; + int num_lm, num_ctl, num_pp, num_dsc; int i, j; if (!drm_enc) { @@ -1030,6 +1034,14 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) : NULL; + if (priv->dsc) { + num_dsc = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, + drm_enc->base.id, DPU_HW_BLK_DSC, + hw_dsc, ARRAY_SIZE(hw_dsc)); + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) + dpu_enc->hw_dsc[i] = i < num_dsc ? to_dpu_hw_dsc(hw_dsc[i]) : NULL; + } + cstate = to_dpu_crtc_state(drm_crtc->state); for (i = 0; i < num_lm; i++) { @@ -1772,10 +1784,132 @@ static void dpu_encoder_vsync_event_work_handler(struct kthread_work *work) nsecs_to_jiffies(ktime_to_ns(wakeup_time))); } +static void +dpu_encoder_dsc_pclk_param_calc(struct msm_display_dsc_config *dsc, u32 width) +{ + int slice_count, slice_per_intf; + int bytes_in_slice, total_bytes_per_intf; + + if (!dsc || !dsc->drm->slice_width || !dsc->drm->slice_count) { + DPU_ERROR("Invalid DSC/slices\n"); + return; + } + + slice_count = dsc->drm->slice_count; + slice_per_intf = DIV_ROUND_UP(width, dsc->drm->slice_width); + + /* +* If slice_count is greater than slice_per_intf then default to 1. +* This can happen during partial update. +*/ + if (slice_count > slice_per_intf) + slice_count = 1; + + bytes_in_slice = DIV_ROUND_UP(dsc->drm->slice_width * + dsc->drm->bits_per_pixel, 8); + total_bytes_per_intf = bytes_in_slice * slice_per_intf; + + dsc->eol_byte_num = total_bytes_per_intf % 3; + dsc->pclk_per_line = DIV_ROUND_UP(total_bytes_per_intf, 3); + dsc->bytes_in_slice = bytes_in_slice; + dsc->bytes_per_pkt = bytes_in_slice * slice_count; + dsc->pkt_per_line = slice_per_intf / slice_count; +} + +static void +dpu_encoder_dsc_initial_line_calc(struct msm_display_dsc_config *dsc, + u32 enc_ip_width) +{ + int ssm_delay, total_pixels, soft_slice_per_enc; + + soft_slice_per_enc = enc_ip_width / dsc->drm->slice_width; + + /* +* minimum number of initial line pixels is a sum of: +* 1. sub-stream multiplexer delay (83 groups for 8bpc, +*91 for 10 bpc) * 3 +* 2. for two soft slice cases, add extra sub-stream multiplexer * 3 +* 3. the initial xmit delay +* 4. total pipeline delay through the "lock step" of encoder (47) +* 5. 6 additional pixels as the output of the rate buffer is +*48
Re: [PATCH v3 05/13] drm/msm/disp/dpu1: Don't use DSC with mode_3d
On Wed, 24 Nov 2021 at 18:40, Dmitry Baryshkov wrote: > > On 16/11/2021 09:22, Vinod Koul wrote: > > We cannot enable mode_3d when we are using the DSC. So pass > > configuration to detect DSC is enabled and not enable mode_3d > > when we are using DSC > > > > We add a helper dpu_encoder_helper_get_dsc() to detect dsc > > enabled and pass this to .setup_intf_cfg() > > > > Signed-off-by: Vinod Koul > > --- > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 11 +++ > > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 2 ++ > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 ++- > > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 2 ++ > > 4 files changed, 17 insertions(+), 1 deletion(-) > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > > index e7270eb6b84b..efb85d595598 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h > > @@ -332,6 +332,17 @@ static inline enum dpu_3d_blend_mode > > dpu_encoder_helper_get_3d_blend_mode( > > return BLEND_3D_NONE; > > } > > > > +static inline bool dpu_encoder_helper_get_dsc(struct dpu_encoder_phys > > *phys_enc) Here you are returning the mask, so it should not be bool. > > +{ > > + struct drm_encoder *drm_enc = phys_enc->parent; > > + struct msm_drm_private *priv = drm_enc->dev->dev_private; > > + > > + if (priv->dsc) > > + return priv->dsc->dsc_mask; > > dsc_mask doesn't exist at this point, so the patch should be moved later > in the series. Please ignore this comment, dsc mask already exists. > > > + > > + return 0; > > +} > > + > > /** > >* dpu_encoder_helper_split_config - split display configuration helper > > function > >* This helper function may be used by physical encoders to configure > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > index 34a6940d12c5..f3f00f4d0193 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c > > @@ -70,6 +70,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( > > intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; > > intf_cfg.stream_sel = cmd_enc->stream_sel; > > intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); > > + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); > > + > > ctl->ops.setup_intf_cfg(ctl, &intf_cfg); > > } > > > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > index 64740ddb983e..36831457a91b 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > > @@ -519,7 +519,8 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, > > > > intf_cfg |= (cfg->intf & 0xF) << 4; > > > > - if (cfg->mode_3d) { > > + /* In DSC we can't set merge, so check for dsc too */ > > + if (cfg->mode_3d && !cfg->dsc) { > > intf_cfg |= BIT(19); > > intf_cfg |= (cfg->mode_3d - 0x1) << 20; > > } > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h > > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h > > index 806c171e5df2..9847c9c46d6f 100644 > > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h > > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h > > @@ -40,6 +40,7 @@ struct dpu_hw_stage_cfg { > >* @merge_3d: 3d merge block used > >* @intf_mode_sel: Interface mode, cmd / vid > >* @stream_sel:Stream selection for multi-stream interfaces > > + * @dsc: DSC BIT masks > >*/ > > struct dpu_hw_intf_cfg { > > enum dpu_intf intf; > > @@ -47,6 +48,7 @@ struct dpu_hw_intf_cfg { > > enum dpu_merge_3d merge_3d; > > enum dpu_ctl_mode_sel intf_mode_sel; > > int stream_sel; > > + unsigned int dsc; > > }; > > -- With best wishes Dmitry
Re: [PATCH v3 01/13] drm/msm/dsi: add support for dsc data
On 16/11/2021 09:22, Vinod Koul wrote: Display Stream Compression (DSC) parameters need to be calculated. Add helpers and struct msm_display_dsc_config in msm_drv for this msm_display_dsc_config uses drm_dsc_config for DSC parameters. Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/dsi/dsi_host.c | 132 + drivers/gpu/drm/msm/msm_drv.h | 20 + 2 files changed, 152 insertions(+) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index f69a125f9559..30c1e299aa52 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -31,6 +31,8 @@ #define DSI_RESET_TOGGLE_DELAY_MS 20 +static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc); + static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) { u32 ver; @@ -157,6 +159,7 @@ struct msm_dsi_host { struct regmap *sfpb; struct drm_display_mode *mode; + struct msm_display_dsc_config *dsc; /* connected device info */ struct device_node *device_node; @@ -1710,6 +1713,135 @@ static int dsi_host_parse_lane_data(struct msm_dsi_host *msm_host, return -EINVAL; } +static u32 dsi_dsc_rc_buf_thresh[DSC_NUM_BUF_RANGES - 1] = { + 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, + 0x69, 0x70, 0x77, 0x79, 0x7b, 0x7d, 0x7e +}; + +/* only 8bpc, 8bpp added */ +static char min_qp[DSC_NUM_BUF_RANGES] = { + 0, 0, 1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 7, 13 +}; + +static char max_qp[DSC_NUM_BUF_RANGES] = { + 4, 4, 5, 6, 7, 7, 7, 8, 9, 10, 11, 12, 13, 13, 15 +}; + +static char bpg_offset[DSC_NUM_BUF_RANGES] = { + 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 +}; + +static int dsi_populate_dsc_params(struct msm_display_dsc_config *dsc) +{ + int mux_words_size; + int groups_per_line, groups_total; + int min_rate_buffer_size; + int hrd_delay; + int pre_num_extra_mux_bits, num_extra_mux_bits; + int slice_bits; + int target_bpp_x16; + int data; + int final_value, final_scale; + int i; + + dsc->drm->rc_model_size = 8192; + dsc->drm->first_line_bpg_offset = 12; + dsc->drm->rc_edge_factor = 6; + dsc->drm->rc_tgt_offset_high = 3; + dsc->drm->rc_tgt_offset_low = 3; + dsc->drm->simple_422 = 0; + dsc->drm->convert_rgb = 1; + dsc->drm->vbr_enable = 0; + + /* handle only bpp = bpc = 8 */ + for (i = 0; i < DSC_NUM_BUF_RANGES - 1 ; i++) + dsc->drm->rc_buf_thresh[i] = dsi_dsc_rc_buf_thresh[i]; + + for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { + dsc->drm->rc_range_params[i].range_min_qp = min_qp[i]; + dsc->drm->rc_range_params[i].range_max_qp = max_qp[i]; + dsc->drm->rc_range_params[i].range_bpg_offset = bpg_offset[i]; + } + + dsc->drm->initial_offset = 6144; /* Not bpp 12 */ + if (dsc->drm->bits_per_pixel != 8) + dsc->drm->initial_offset = 2048; /* bpp = 12 */ + + mux_words_size = 48;/* bpc == 8/10 */ + if (dsc->drm->bits_per_component == 12) + mux_words_size = 64; + + dsc->drm->initial_xmit_delay = 512; + dsc->drm->initial_scale_value = 32; + dsc->drm->first_line_bpg_offset = 12; + dsc->drm->line_buf_depth = dsc->drm->bits_per_component + 1; + + /* bpc 8 */ + dsc->drm->flatness_min_qp = 3; + dsc->drm->flatness_max_qp = 12; + dsc->det_thresh_flatness = 7 + 2 * (dsc->drm->bits_per_component - 8); + dsc->drm->rc_quant_incr_limit0 = 11; + dsc->drm->rc_quant_incr_limit1 = 11; + dsc->drm->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC; + + /* FIXME: need to call drm_dsc_compute_rc_parameters() so that rest of +* params are calculated +*/ + dsc->slice_last_group_size = 3 - (dsc->drm->slice_width % 3); + groups_per_line = DIV_ROUND_UP(dsc->drm->slice_width, 3); + dsc->drm->slice_chunk_size = dsc->drm->slice_width * dsc->drm->bits_per_pixel / 8; + if ((dsc->drm->slice_width * dsc->drm->bits_per_pixel) % 8) + dsc->drm->slice_chunk_size++; + + /* rbs-min */ + min_rate_buffer_size = dsc->drm->rc_model_size - dsc->drm->initial_offset + + dsc->drm->initial_xmit_delay * dsc->drm->bits_per_pixel + + groups_per_line * dsc->drm->first_line_bpg_offset; + + hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->drm->bits_per_pixel); + + dsc->drm->initial_dec_delay = hrd_delay - dsc->drm->initial_xmit_delay; + + dsc->drm->initial_scale_value = 8 * dsc->drm->rc_model_size / + (dsc->drm->rc_model_size - dsc->drm->initial_offset); + + slice_bits = 8 * dsc->drm->slice_chunk_size * dsc->drm->slice_height; + + groups_total = groups_per_line * dsc->drm->slice_height; + + d
Re: [PATCH v3 05/13] drm/msm/disp/dpu1: Don't use DSC with mode_3d
On 16/11/2021 09:22, Vinod Koul wrote: We cannot enable mode_3d when we are using the DSC. So pass configuration to detect DSC is enabled and not enable mode_3d when we are using DSC We add a helper dpu_encoder_helper_get_dsc() to detect dsc enabled and pass this to .setup_intf_cfg() Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 11 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 2 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index e7270eb6b84b..efb85d595598 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -332,6 +332,17 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( return BLEND_3D_NONE; } +static inline bool dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc) +{ + struct drm_encoder *drm_enc = phys_enc->parent; + struct msm_drm_private *priv = drm_enc->dev->dev_private; + + if (priv->dsc) + return priv->dsc->dsc_mask; + + return 0; +} + /** * dpu_encoder_helper_split_config - split display configuration helper function *This helper function may be used by physical encoders to configure diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 34a6940d12c5..f3f00f4d0193 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -70,6 +70,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; intf_cfg.stream_sel = cmd_enc->stream_sel; intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); + You are going to hate me for the comments on this patch. But this chunk should also go into dpu_encoder_phys_vid.c, shouldn't it? ctl->ops.setup_intf_cfg(ctl, &intf_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 64740ddb983e..36831457a91b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -519,7 +519,8 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, intf_cfg |= (cfg->intf & 0xF) << 4; - if (cfg->mode_3d) { + /* In DSC we can't set merge, so check for dsc too */ + if (cfg->mode_3d && !cfg->dsc) { intf_cfg |= BIT(19); intf_cfg |= (cfg->mode_3d - 0x1) << 20; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 806c171e5df2..9847c9c46d6f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -40,6 +40,7 @@ struct dpu_hw_stage_cfg { * @merge_3d: 3d merge block used * @intf_mode_sel: Interface mode, cmd / vid * @stream_sel:Stream selection for multi-stream interfaces + * @dsc: DSC BIT masks */ struct dpu_hw_intf_cfg { enum dpu_intf intf; @@ -47,6 +48,7 @@ struct dpu_hw_intf_cfg { enum dpu_merge_3d merge_3d; enum dpu_ctl_mode_sel intf_mode_sel; int stream_sel; + unsigned int dsc; }; /** -- With best wishes Dmitry
Re: [PATCH v3 06/13] drm/msm/disp/dpu1: Add DSC support in hw_ctl
On 16/11/2021 09:22, Vinod Koul wrote: Later gens of hardware have DSC bits moved to hw_ctl, so configure these bits so that DSC would work there as well Signed-off-by: Vinod Koul Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 36831457a91b..66b0c44118d8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -25,6 +25,8 @@ #define CTL_MERGE_3D_ACTIVE 0x0E4 #define CTL_INTF_ACTIVE 0x0F4 #define CTL_MERGE_3D_FLUSH0x100 +#define CTL_DSC_ACTIVE0x0E8 +#define CTL_DSC_FLUSH0x104 #define CTL_INTF_FLUSH0x110 #define CTL_INTF_MASTER 0x134 #define CTL_FETCH_PIPE_ACTIVE 0x0FC @@ -34,6 +36,7 @@ #define DPU_REG_RESET_TIMEOUT_US2000 #define MERGE_3D_IDX 23 +#define DSC_IDX22 #define INTF_IDX 31 #define CTL_INVALID_BIT 0x @@ -120,7 +123,6 @@ static u32 dpu_hw_ctl_get_pending_flush(struct dpu_hw_ctl *ctx) static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) { - if (ctx->pending_flush_mask & BIT(MERGE_3D_IDX)) DPU_REG_WRITE(&ctx->hw, CTL_MERGE_3D_FLUSH, ctx->pending_merge_3d_flush_mask); @@ -498,6 +500,9 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, u32 intf_active = 0; u32 mode_sel = 0; + if (cfg->dsc) + DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, cfg->dsc); + if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD) mode_sel |= BIT(17); @@ -509,6 +514,10 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if (cfg->merge_3d) DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); + if (cfg->dsc) { + DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, cfg->dsc); + DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); + } } static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, -- With best wishes Dmitry
Re: [PATCH v3 05/13] drm/msm/disp/dpu1: Don't use DSC with mode_3d
On 16/11/2021 09:22, Vinod Koul wrote: We cannot enable mode_3d when we are using the DSC. So pass configuration to detect DSC is enabled and not enable mode_3d when we are using DSC We add a helper dpu_encoder_helper_get_dsc() to detect dsc enabled and pass this to .setup_intf_cfg() Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 11 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 2 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index e7270eb6b84b..efb85d595598 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -332,6 +332,17 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( return BLEND_3D_NONE; } +static inline bool dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc) +{ + struct drm_encoder *drm_enc = phys_enc->parent; + struct msm_drm_private *priv = drm_enc->dev->dev_private; + + if (priv->dsc) + return priv->dsc->dsc_mask; dsc_mask doesn't exist at this point, so the patch should be moved later in the series. + + return 0; +} + /** * dpu_encoder_helper_split_config - split display configuration helper function *This helper function may be used by physical encoders to configure diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 34a6940d12c5..f3f00f4d0193 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -70,6 +70,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; intf_cfg.stream_sel = cmd_enc->stream_sel; intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); + ctl->ops.setup_intf_cfg(ctl, &intf_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 64740ddb983e..36831457a91b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -519,7 +519,8 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, intf_cfg |= (cfg->intf & 0xF) << 4; - if (cfg->mode_3d) { + /* In DSC we can't set merge, so check for dsc too */ + if (cfg->mode_3d && !cfg->dsc) { intf_cfg |= BIT(19); intf_cfg |= (cfg->mode_3d - 0x1) << 20; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 806c171e5df2..9847c9c46d6f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -40,6 +40,7 @@ struct dpu_hw_stage_cfg { * @merge_3d: 3d merge block used * @intf_mode_sel: Interface mode, cmd / vid * @stream_sel:Stream selection for multi-stream interfaces + * @dsc: DSC BIT masks */ struct dpu_hw_intf_cfg { enum dpu_intf intf; @@ -47,6 +48,7 @@ struct dpu_hw_intf_cfg { enum dpu_merge_3d merge_3d; enum dpu_ctl_mode_sel intf_mode_sel; int stream_sel; + unsigned int dsc; }; /** -- With best wishes Dmitry
Re: [PATCH v3 05/13] drm/msm/disp/dpu1: Don't use DSC with mode_3d
On 16/11/2021 09:22, Vinod Koul wrote: We cannot enable mode_3d when we are using the DSC. So pass configuration to detect DSC is enabled and not enable mode_3d when we are using DSC We add a helper dpu_encoder_helper_get_dsc() to detect dsc enabled and pass this to .setup_intf_cfg() Signed-off-by: Vinod Koul --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 11 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c | 2 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 3 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index e7270eb6b84b..efb85d595598 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -332,6 +332,17 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( return BLEND_3D_NONE; } +static inline bool dpu_encoder_helper_get_dsc(struct dpu_encoder_phys *phys_enc) +{ + struct drm_encoder *drm_enc = phys_enc->parent; + struct msm_drm_private *priv = drm_enc->dev->dev_private; + + if (priv->dsc) + return priv->dsc->dsc_mask; + + return 0; +} + /** * dpu_encoder_helper_split_config - split display configuration helper function *This helper function may be used by physical encoders to configure diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 34a6940d12c5..f3f00f4d0193 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -70,6 +70,8 @@ static void _dpu_encoder_phys_cmd_update_intf_cfg( intf_cfg.intf_mode_sel = DPU_CTL_MODE_SEL_CMD; intf_cfg.stream_sel = cmd_enc->stream_sel; intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); + I'd prefer if we disable mode_3d here, rather than ignoring it in the dpu_hw_ctl_intf_cfg() ctl->ops.setup_intf_cfg(ctl, &intf_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 64740ddb983e..36831457a91b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -519,7 +519,8 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, intf_cfg |= (cfg->intf & 0xF) << 4; - if (cfg->mode_3d) { + /* In DSC we can't set merge, so check for dsc too */ + if (cfg->mode_3d && !cfg->dsc) { I think here'd better have WARN_ON(cfg->mode_3d && cfg->dsc) or similar dev_warn(). intf_cfg |= BIT(19); intf_cfg |= (cfg->mode_3d - 0x1) << 20; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index 806c171e5df2..9847c9c46d6f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -40,6 +40,7 @@ struct dpu_hw_stage_cfg { * @merge_3d: 3d merge block used * @intf_mode_sel: Interface mode, cmd / vid * @stream_sel:Stream selection for multi-stream interfaces + * @dsc: DSC BIT masks */ struct dpu_hw_intf_cfg { enum dpu_intf intf; @@ -47,6 +48,7 @@ struct dpu_hw_intf_cfg { enum dpu_merge_3d merge_3d; enum dpu_ctl_mode_sel intf_mode_sel; int stream_sel; + unsigned int dsc; }; /** -- With best wishes Dmitry
Re: [PATCH v3 02/13] drm/msm/disp/dpu1: Add support for DSC
On 16/11/2021 09:22, Vinod Koul wrote: Display Stream Compression (DSC) is one of the hw blocks in dpu, so add support by adding hw blocks for DSC Signed-off-by: Vinod Koul Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 + .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h| 13 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c| 210 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h| 77 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 13 ++ 5 files changed, 314 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 40577f8856d8..7d7058f1f5c1 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -59,6 +59,7 @@ msm-y := \ disp/dpu1/dpu_formats.o \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ + disp/dpu1/dpu_hw_dsc.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 4ade44bbd37e..65f43fadcda0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -553,6 +553,16 @@ struct dpu_merge_3d_cfg { const struct dpu_merge_3d_sub_blks *sblk; }; +/** + * struct dpu_dsc_cfg - information of DSC blocks + * @id enum identifying this block + * @base register offset of this block + * @features bit mask identifying sub-blocks/features + */ +struct dpu_dsc_cfg { + DPU_HW_BLK_INFO; +}; + /** * struct dpu_intf_cfg - information of timing engine blocks * @id enum identifying this block @@ -749,6 +759,9 @@ struct dpu_mdss_cfg { u32 merge_3d_count; const struct dpu_merge_3d_cfg *merge_3d; + u32 dsc_count; + struct dpu_dsc_cfg *dsc; + u32 intf_count; const struct dpu_intf_cfg *intf; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c new file mode 100644 index ..449d6f1dad28 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020-2021, Linaro Limited + */ + +#include "dpu_kms.h" +#include "dpu_hw_catalog.h" +#include "dpu_hwio.h" +#include "dpu_hw_mdss.h" +#include "dpu_hw_dsc.h" + +#define DSC_COMMON_MODE0x000 +#define DSC_ENC 0X004 +#define DSC_PICTURE 0x008 +#define DSC_SLICE 0x00C +#define DSC_CHUNK_SIZE 0x010 +#define DSC_DELAY 0x014 +#define DSC_SCALE_INITIAL 0x018 +#define DSC_SCALE_DEC_INTERVAL 0x01C +#define DSC_SCALE_INC_INTERVAL 0x020 +#define DSC_FIRST_LINE_BPG_OFFSET 0x024 +#define DSC_BPG_OFFSET 0x028 +#define DSC_DSC_OFFSET 0x02C +#define DSC_FLATNESS0x030 +#define DSC_RC_MODEL_SIZE 0x034 +#define DSC_RC 0x038 +#define DSC_RC_BUF_THRESH 0x03C +#define DSC_RANGE_MIN_QP0x074 +#define DSC_RANGE_MAX_QP0x0B0 +#define DSC_RANGE_BPG_OFFSET0x0EC + +static void dpu_hw_dsc_disable(struct dpu_hw_dsc *dsc) +{ + struct dpu_hw_blk_reg_map *c = &dsc->hw; + + DPU_REG_WRITE(c, DSC_COMMON_MODE, 0); +} + +static void dpu_hw_dsc_config(struct dpu_hw_dsc *hw_dsc, + struct msm_display_dsc_config *dsc, u32 mode) +{ + struct dpu_hw_blk_reg_map *c = &hw_dsc->hw; + u32 data, lsb, bpp; + u32 initial_lines = dsc->initial_lines; + bool is_cmd_mode = !(mode & DSC_MODE_VIDEO); + + DPU_REG_WRITE(c, DSC_COMMON_MODE, mode); + + if (is_cmd_mode) + initial_lines += 1; + + data = (initial_lines << 20); + data |= ((dsc->slice_last_group_size - 1) << 18); + /* bpp is 6.4 format, 4 LSBs bits are for fractional part */ + data |= dsc->drm->bits_per_pixel << 12; + lsb = dsc->drm->bits_per_pixel % 4; + bpp = dsc->drm->bits_per_pixel / 4; + bpp *= 4; + bpp <<= 4; + bpp |= lsb; + + data |= bpp << 8; + data |= (dsc->drm->block_pred_enable << 7); + data |= (dsc->drm->line_buf_depth << 3); + data |= (dsc->drm->simple_422 << 2); + data |= (dsc->drm->convert_rgb << 1); + data |= dsc->drm->bits_per_component; + + DPU_REG_WRITE(c, DSC_ENC, data); + + data = dsc->drm->pic_width << 16; + data |= dsc->drm->pic_height; + DPU_REG_WRITE(c, DSC_PICTURE, data); + + data = dsc->drm->slice_width << 16; + data |= dsc->drm->slice_height; +
Re: linux-next: Tree for Nov 24 (drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.o)
On 11/23/21 9:16 PM, Stephen Rothwell wrote: Hi all, Changes since 20211123: on i386: ld: drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.o: in function `dscc_compute_dsc_parameters': rc_calc_dpi.c:(.text+0x31f): undefined reference to `__udivdi3' -- ~Randy
Re: [PATCH] MAINTAINERS: Update email of Andrzej Hajda
On 18.10.2021 23:13, Andrzej Hajda wrote: > Beside updating email, the patch updates maintainers > of Samsung drivers. > > Signed-off-by: Andrzej Hajda > --- > .mailmap| 1 + > MAINTAINERS | 13 - > 2 files changed, 9 insertions(+), 5 deletions(-) > > diff --git a/.mailmap b/.mailmap > index 4f6e37da60589..4283a86f70d26 100644 > --- a/.mailmap > +++ b/.mailmap > @@ -40,6 +40,7 @@ Andrew Vasquez > Andrey Konovalov > Andrey Ryabinin > Andrey Ryabinin > +Andrzej Hajda > Andy Adamson > Antoine Tenart > Antoine Tenart > diff --git a/MAINTAINERS b/MAINTAINERS > index 54cd05d3aab65..e3fadb4ebced3 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -2546,7 +2546,7 @@ N: s3c64xx > N: s5pv210 > > ARM/SAMSUNG S5P SERIES 2D GRAPHICS ACCELERATION (G2D) SUPPORT > -M: Andrzej Hajda > +M: Łukasz Stelmach > L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers) > L: linux-me...@vger.kernel.org > S: Maintained > @@ -2570,7 +2570,8 @@ S: Maintained > F: drivers/media/platform/s5p-jpeg/ > > ARM/SAMSUNG S5P SERIES Multi Format Codec (MFC) SUPPORT > -M: Andrzej Hajda > +M: Marek Szyprowski > +M: Andrzej Hajda > L: linux-arm-ker...@lists.infradead.org (moderated for non-subscribers) > L: linux-me...@vger.kernel.org > S: Maintained > @@ -6254,7 +6255,7 @@ F: Documentation/devicetree/bindings/display/atmel/ > F: drivers/gpu/drm/atmel-hlcdc/ > > DRM DRIVERS FOR BRIDGE CHIPS > -M: Andrzej Hajda > +M: Andrzej Hajda > M: Neil Armstrong > M: Robert Foss > R: Laurent Pinchart > @@ -16748,13 +16749,15 @@ F: > Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml > F: drivers/nfc/s3fwrn5 > SAMSUNG S5C73M3 CAMERA DRIVER > -M: Andrzej Hajda > +M: Sylwester Nawrocki > +M: Andrzej Hajda > L: linux-me...@vger.kernel.org > S: Supported > F: drivers/media/i2c/s5c73m3/* > SAMSUNG S5K5BAF CAMERA DRIVER > -M: Andrzej Hajda > +M: Sylwester Nawrocki > +M: Andrzej Hajda > L: linux-me...@vger.kernel.org > S: Supported > F: drivers/media/i2c/s5k5baf.c Acked-by: Sylwester Nawrocki
Re: [Intel-gfx] [PATCH 1/3] drm/i915/gt: Spread virtual engines over idle engines
On Wed, Nov 24, 2021 at 08:55:39AM -0500, Rodrigo Vivi wrote: > On Wed, Nov 24, 2021 at 08:56:52AM +, Tvrtko Ursulin wrote: > > > > On 23/11/2021 19:52, Rodrigo Vivi wrote: > > > On Tue, Nov 23, 2021 at 09:39:25AM +, Tvrtko Ursulin wrote: > > > > > > > > On 17/11/2021 22:49, Vinay Belgaumkar wrote: > > > > > From: Chris Wilson > > > > > > > > > > Everytime we come to the end of a virtual engine's context, > > > > > re-randomise > > > > > it's siblings[]. As we schedule the siblings' tasklets in the order > > > > > they > > > > > are in the array, earlier entries are executed first (when idle) and > > > > > so > > > > > will be preferred when scheduling the next virtual request. Currently, > > > > > we only update the array when switching onto a new idle engine, so we > > > > > prefer to stick on the last execute engine, keeping the work compact. > > > > > However, it can be beneficial to spread the work out across idle > > > > > engines, so choose another sibling as our preferred target at the end > > > > > of > > > > > the context's execution. > > > > > > > > This partially brings back, from a different angle, the more dynamic > > > > scheduling behavior which has been lost since bugfix 90a987205c6c > > > > ("drm/i915/gt: Only swap to a random sibling once upon creation"). > > > > > > Shouldn't we use the Fixes tag here since this is targeting to fix one > > > of the performance regressions of this patch? > > > > Probably not but hard to say. Note that it wasn't a performance regression > > that was reported but power. > > > > And to go back to what we said elsewhere in the thread, I am actually with > > you in thinking that in the ideal world we need PnP testing across a variety > > of workloads and platforms. And "in the ideal world" should really be in the > > normal world. It is not professional to be reactive to isolated bug reports > > from users, without being able to see the overall picture. > > We surely need to address the bug report from users. I'm just asking to > address > that with the smallest fix that we can backport and fit to the products > milestones. > > Instead, we are creating another optimization feature on a rush. Without a > proper > validation. > > I believe it is too risk to add an algorithm like that without a broader test. > I see a big risk of introducing corner cases that will results in more bug > report > from other users in a near future. > > So, let's all be professionals and provide a smaller fix for a regression on > the load balancing scenario and provide a better validation with more data > to justify this new feature. Okay, after more IRC discussions I see that patch 2 is also part of the solution and probably safe. Let me be clear that my biggest complain and the risk is with race-to-idle in patch 3 on trying to predict the rc6 behavior and increasing the freq to try to complete job faster and then get to rc6 faster... That one would need a lot more validation. > > Thanks, > Rodrigo. > > > > > > > One day we could experiment with using engine busyness as criteria > > > > (instead > > > > of random). Back in the day busyness was kind of the best strategy, > > > > although > > > > sampled at submit, not at the trailing edge like here, but it still may > > > > be > > > > able to settle down to engine configuration better in some scenarios. > > > > Only > > > > testing could say. > > > > > > > > Still, from memory random also wasn't that bad so this should be okay > > > > for > > > > now. > > > > > > > > Reviewed-by: Tvrtko Ursulin > > > > > > Since you reviewed and it looks to be a middle ground point in terms > > > of when to balancing (always like in the initial implementation vs > > > only once like the in 90a987205c6c). > > > > > > If this one is really fixing the regression by itself: > > > Acked-by: Rodrigo Vivi > > > on this patch here. > > > > > > But I still don't want to take the risk with touching the freq with > > > race to idle, until not convinced that it is absolutely needed and > > > that we are not breaking the world out there. > > > > Yes agreed in principle, we have users with different priorities. > > > > However the RPS patches in the series, definitely the 1st one which looks at > > classes versus individual engines, sound plausible to me. Given the absence > > of automated PnP testing mentioned above, in the past it was usually Chris > > who was making the above and beyond effort to evaluate changes like these on > > as many platforms as he could, and with different workloads. Not sure who > > has the mandate and drive to fill that space but something will need to > > happen. > > > > Regards, > > > > Tvrtko > > > > > > > > > > Regards, > > > > > > > > Tvrtko > > > > > > > > > Signed-off-by: Chris Wilson > > > > > Cc: Vinay Belgaumkar > > > > > Cc: Tvrtko Ursulin > > > > > --- > > > > >.../drm/i915/gt/intel_execlists_submission.c | 80 > > > > > --- > > > > >1 file
[PATCH 6/6] drm: tiny: st7735r: Support DT initialization of controller
Add support for initializing the controller from device properties when the compatible is "sitronix,st7735r". The rotation property does not apply in this case since a matching ADDRESS_MODE/madctl value is necessary. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/tiny/st7735r.c | 87 +- 1 file changed, 75 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c index fc40dd10efa8..7f4d880b8702 100644 --- a/drivers/gpu/drm/tiny/st7735r.c +++ b/drivers/gpu/drm/tiny/st7735r.c @@ -58,6 +58,52 @@ struct st7735r_priv { static void st7735r_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) +{ + struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); + struct mipi_dbi *dbi = &dbidev->dbi; + int ret, idx; + + if (!drm_dev_enter(pipe->crtc.dev, &idx)) + return; + + DRM_DEBUG_KMS("\n"); + + ret = mipi_dbi_poweron_conditional_reset(dbidev); + if (ret < 0) + goto out_exit; + if (ret == 1) + goto out_enable; + + mipi_dbi_command(dbi, MIPI_DCS_EXIT_SLEEP_MODE); + msleep(120); + + mipi_dbi_command_from_property(dbi, ST7735R_FRMCTR1, "frmctr1", 3); + mipi_dbi_command_from_property(dbi, ST7735R_INVCTR, "invctr", 1); + mipi_dbi_command_from_property(dbi, ST7735R_PWCTR1, "pwctr1", 3); + mipi_dbi_command_from_property(dbi, ST7735R_PWCTR2, "pwctr2", 1); + mipi_dbi_command_from_property(dbi, ST7735R_PWCTR3, "pwctr3", 2); + mipi_dbi_command_from_property(dbi, ST7735R_VMCTR1, "vmctr1", 1); + mipi_dbi_command_from_property(dbi, MIPI_DCS_SET_ADDRESS_MODE, "madctl", 1); + mipi_dbi_command(dbi, MIPI_DCS_SET_PIXEL_FORMAT, MIPI_DCS_PIXEL_FMT_16BIT); + mipi_dbi_command_from_property(dbi, ST7735R_GAMCTRP1, "gamctrp1", 16); + mipi_dbi_command_from_property(dbi, ST7735R_GAMCTRN1, "gamctrn1", 16); + + mipi_dbi_command(dbi, MIPI_DCS_SET_DISPLAY_ON); +out_enable: + mipi_dbi_enable_flush(dbidev, crtc_state, plane_state); +out_exit: + drm_dev_exit(idx); +} + +static const struct drm_simple_display_pipe_funcs st7735r_pipe_funcs = { + .enable = st7735r_pipe_enable, + .disable= mipi_dbi_pipe_disable, + .update = mipi_dbi_pipe_update, +}; + +static void jd_t18003_t01_pipe_enable(struct drm_simple_display_pipe *pipe, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) { struct mipi_dbi_dev *dbidev = drm_to_mipi_dbi_dev(pipe->crtc.dev); struct st7735r_priv *priv = container_of(dbidev, struct st7735r_priv, @@ -132,8 +178,8 @@ static void st7735r_pipe_enable(struct drm_simple_display_pipe *pipe, drm_dev_exit(idx); } -static const struct drm_simple_display_pipe_funcs st7735r_pipe_funcs = { - .enable = st7735r_pipe_enable, +static const struct drm_simple_display_pipe_funcs jd_t18003_t01_pipe_funcs = { + .enable = jd_t18003_t01_pipe_enable, .disable= mipi_dbi_pipe_disable, .update = mipi_dbi_pipe_update, }; @@ -168,6 +214,7 @@ static const struct drm_driver st7735r_driver = { static const struct of_device_id st7735r_of_match[] = { { .compatible = "jianda,jd-t18003-t01", .data = &jd_t18003_t01_cfg }, { .compatible = "okaya,rh128128t", .data = &rh128128t_cfg }, + { .compatible = "sitronix,st7735r" }, { }, }; MODULE_DEVICE_TABLE(of, st7735r_of_match); @@ -180,6 +227,9 @@ MODULE_DEVICE_TABLE(spi, st7735r_id); static int st7735r_probe(struct spi_device *spi) { + const struct drm_simple_display_pipe_funcs *funcs; + const struct drm_display_mode *mode; + struct drm_display_mode dt_mode; struct device *dev = &spi->dev; const struct st7735r_cfg *cfg; struct mipi_dbi_dev *dbidev; @@ -191,8 +241,12 @@ static int st7735r_probe(struct spi_device *spi) int ret; cfg = device_get_match_data(&spi->dev); - if (!cfg) - cfg = (void *)spi_get_device_id(spi)->driver_data; + if (!cfg) { + const struct spi_device_id *spi_id = spi_get_device_id(spi); + + if (spi_id) + cfg = (struct st7735r_cfg *)spi_id->driver_data; + } priv = devm_drm_dev_alloc(dev, &st7735r_driver, struct st7735r_priv, dbidev.drm); @@ -217,20 +271,29 @@ static int st7735r_probe(struct spi_device *spi) if (IS_ERR(dbidev->backlight)) return PTR_ERR(dbidev->backlight); - device_property_read_u32(dev, "rotation", &rotation); - ret = mipi_dbi_spi_init(spi, dbi, dc); if (ret) return ret; -
[PATCH 0/6] drm/tiny/st7735r: Match up with staging/fbtft driver
Hi, This patchset adds a missing piece for decommissioning the staging/fbtft/fb_st7735r.c driver namely a way to configure the controller from Device Tree. All fbtft drivers have builtin support for one display panel and all other panels using that controller are configured using the Device Tree 'init' property. This property is supported by all fbtft drivers and provides a generic way to set register values or issue commands (depending on the type of controller). It is common for these types of displays to have a datasheet listing the necessary controller settings/commands or some example code doing the same. This is how the panel directly supported by the fb_st7735r staging driver is described using Device Tree with that driver: width = <160>; height = <128>; init = <0x101 0x296 0x111 0x2ff 0x1B1 0x01 0x2C 0x2D 0x1B4 0x07 0x1C0 0xA2 0x02 0x84 0x1C1 0xC5 0x1C2 0x0A 0x00 0x1C5 0x0E 0x13a 0x55 0x136 0x60 0x1E0 0x0F 0x1A 0x0F 0x18 0x2F 0x28 0x20 0x22 0x1F 0x1B 0x23 0x37 0x00 0x07 0x02 0x10 0x1E1 0x0F 0x1B 0x0F 0x17 0x33 0x2C 0x29 0x2E 0x30 0x30 0x39 0x3F 0x00 0x07 0x03 0x10 0x129 0x264>; This is how the same panel is described using the st7735r drm driver and this patchset: width = <160>; height = <128>; frmctr1 = [ 01 2C 2D ]; invctr = [ 07 ]; pwctr1 = [ A2 02 84 ]; pwctr2 = [ C5 ]; pwctr3 = [ 0A 00 ]; vmctr1 = [ 0E ]; madctl = [ 60 ]; gamctrp1 = [ 0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10 ]; gamctrn1 = [ 0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10 ]; Back when the fbtft drivers were added to staging I asked on the DT mailinglist if it was OK to use the 'init' property but it was turned down. In this patchset I'm trying the same approach used by the solomon,ssd1307fb.yaml binding in describing the attached panel. That binding prefixes the properties with the vendor name, not sure why that is and I think it looks strange so I try without it. Noralf. Noralf Trønnes (6): dt-bindings: display: sitronix,st7735r: Fix backlight in example dt-bindings: display: sitronix,st7735r: Make reset-gpios optional dt-bindings: display: sitronix,st7735r: Remove spi-max-frequency limit dt-bindings: display: sitronix,st7735r: Add initialization properties drm/mipi-dbi: Add device property functions drm: tiny: st7735r: Support DT initialization of controller .../bindings/display/sitronix,st7735r.yaml| 122 ++- drivers/gpu/drm/drm_mipi_dbi.c| 139 ++ drivers/gpu/drm/tiny/st7735r.c| 87 +-- include/drm/drm_mipi_dbi.h| 3 + 4 files changed, 334 insertions(+), 17 deletions(-) -- 2.33.0
[PATCH 5/6] drm/mipi-dbi: Add device property functions
Add helper functions for configuring a MIPI DBI controller from device properties. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/drm_mipi_dbi.c | 139 + include/drm/drm_mipi_dbi.h | 3 + 2 files changed, 142 insertions(+) diff --git a/drivers/gpu/drm/drm_mipi_dbi.c b/drivers/gpu/drm/drm_mipi_dbi.c index 71b646c4131f..41362e1d4231 100644 --- a/drivers/gpu/drm/drm_mipi_dbi.c +++ b/drivers/gpu/drm/drm_mipi_dbi.c @@ -137,6 +137,24 @@ int mipi_dbi_command_read(struct mipi_dbi *dbi, u8 cmd, u8 *val) } EXPORT_SYMBOL(mipi_dbi_command_read); +/** + * mipi_dbi_set_writeonly - Set the controller write only state + * @dbi: MIPI DBI structure + * @writeonly: If true the controller is not readable + * + * This function sets whether the controller can be read from or not (ie. MISO connected or not). + * It also checks the 'write-only' device property which overrides @writeonly. + * The controller is assumed to be readable by default. + */ +void mipi_dbi_set_writeonly(struct mipi_dbi *dbi, bool writeonly) +{ + struct device *dev = &dbi->spi->dev; + + if (writeonly || device_property_present(dev, "write-only")) + dbi->read_commands = NULL; +} +EXPORT_SYMBOL(mipi_dbi_set_writeonly); + /** * mipi_dbi_command_buf - MIPI DCS command with parameter(s) in an array * @dbi: MIPI DBI structure @@ -186,6 +204,40 @@ int mipi_dbi_command_stackbuf(struct mipi_dbi *dbi, u8 cmd, const u8 *data, } EXPORT_SYMBOL(mipi_dbi_command_stackbuf); +/** + * mipi_dbi_command_from_property - MIPI DCS command with parameter(s) from a device property + * @dbi: MIPI DBI structure + * @cmd: Command + * @propname: Name of the device property + * @len: Data length + * + * This function will execute @cmd with parameters from @propname if it exist. + * + * Returns: + * Zero on success, negative error code on failure. + */ +int mipi_dbi_command_from_property(struct mipi_dbi *dbi, u8 cmd, const char *propname, size_t len) +{ + struct device *dev = &dbi->spi->dev; + u8 data[64]; + int ret; + + if (WARN_ON_ONCE(len > sizeof(data))) + return -EINVAL; + + if (!device_property_present(dev, propname)) + return 0; + + ret = device_property_read_u8_array(dev, propname, data, len); + if (ret) { + dev_err(dev, "Failed to read property '%s', error=%d\n", propname, ret); + return ret; + } + + return mipi_dbi_command_stackbuf(dbi, cmd, data, len); +} +EXPORT_SYMBOL(mipi_dbi_command_from_property); + /** * mipi_dbi_buf_copy - Copy a framebuffer, transforming it if necessary * @dst: The destination buffer @@ -571,6 +623,93 @@ int mipi_dbi_dev_init(struct mipi_dbi_dev *dbidev, } EXPORT_SYMBOL(mipi_dbi_dev_init); +static int mipi_dbi_property_read_u32(struct device *dev, const char *propname, + unsigned int *retval, bool required) +{ + u32 val32; + int ret; + + if (!device_property_present(dev, propname)) { + if (required) { + dev_err(dev, "Missing required property '%s'\n", propname); + return -EINVAL; + } + + return 0; + } + + ret = device_property_read_u32(dev, propname, &val32); + if (ret) { + dev_err(dev, "Error reading property '%s', error=%d\n", propname, ret); + return ret; + } + + *retval = val32; + + return 0; +} + +static void mipi_dbi_simple_mode(struct drm_display_mode *mode, +unsigned int width, unsigned int height, +unsigned int width_mm, unsigned int height_mm) +{ + struct drm_display_mode simple_mode = { DRM_SIMPLE_MODE(width, height, width_mm, height_mm) }; + + *mode = simple_mode; +} + +/** + * mipi_dbi_read_device_properties - Read device properties + * @dbidev: MIPI DBI device structure + * @mode: Returned display mode + * + * This function reads device properties 'width', 'height', 'width_mm', 'height_mm' + * and returns them as a display mode in @mode. + * It also reads 'x-offset' and 'y-offset' whose values are set on @dbidev. + * + * The returned @mode can be passed on to mipi_dbi_dev_init(). + * + * Returns: + * Zero on success, negative error code on failure. + */ +int mipi_dbi_read_device_properties(struct mipi_dbi_dev *dbidev, struct drm_display_mode *mode) +{ + unsigned int width, height, width_mm = 0, height_mm = 0; + struct device *dev = dbidev->drm.dev; + int ret; + + ret = mipi_dbi_property_read_u32(dev, "width", &width, true); + if (ret) + return ret; + + ret = mipi_dbi_property_read_u32(dev, "height", &height, true); + if (ret) + return ret; + + if (device_property_present(dev, "width_mm") || device_property_present(dev, "height_mm")) { + ret = mipi_dbi_property_read
[PATCH 4/6] dt-bindings: display: sitronix, st7735r: Add initialization properties
Add initialization properties that are commonly used to initialize the controller for a specific display panel. It is common for displays to have a datasheet listing the necessary controller settings or some example code doing the same. These settings can be matched directly to the DT properties. The commands FRMCTR2, FRMCTR3, PWCTR4 and PWCTR5 are usually part of the setup examples but they are skipped here since they deal with partial and idle mode which are powersaving modes for very special use cases. dc-gpios is made optional because its absence indicates 3-line mode. Signed-off-by: Noralf Trønnes --- .../bindings/display/sitronix,st7735r.yaml| 118 +- 1 file changed, 116 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml index 157b1a7b18f9..2db1cfe6ae30 100644 --- a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml +++ b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml @@ -19,6 +19,10 @@ allOf: properties: compatible: oneOf: + - description: + Sitronix ST7735R 262K Color Single-Chip TFT Controller/Driver +items: + - const: sitronix,st7735r - description: Adafruit 1.8" 160x128 Color TFT LCD (Product ID 358 or 618) items: @@ -32,20 +36,99 @@ properties: - okaya,rh128128t - const: sitronix,st7715r + width: +description: + Width of display panel in pixels + + height: +description: + Height of display panel in pixels + + frmctr1: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Frame Rate Control (In normal mode/Full colors) (B1h) +minItems: 3 +maxItems: 3 + + invctr: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Display Inversion Control (B4h) +minItems: 1 +maxItems: 1 + + pwctr1: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Power Control 1 (C0h) +minItems: 3 +maxItems: 3 + + pwctr2: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Power Control 2 (C1h) +minItems: 1 +maxItems: 1 + + pwctr3: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Power Control 3 (in Normal mode/Full colors) (C2h) +minItems: 2 +maxItems: 2 + + vmctr1: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + VCOM Control 1 (C5h) +minItems: 1 +maxItems: 1 + + madctl: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Memory Data Access Control (36h) +minItems: 1 +maxItems: 1 + + gamctrp1: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Gamma Positive Polarity Correction Characteristics Setting (E0h) +minItems: 16 +maxItems: 16 + + gamctrn1: +$ref: /schemas/types.yaml#definitions/uint8-array +description: + Gamma Negative Polarity Correction Characteristics Setting (E1h) +minItems: 16 +maxItems: 16 + + write-only: +type: boolean +description: + Controller is not readable (ie. MISO is not wired up). + dc-gpios: maxItems: 1 -description: Display data/command selection (D/CX) +description: | + Controller data/command selection (D/CX) in 4-line SPI mode. + If not set, the controller is in 3-line SPI mode. backlight: true reg: true spi-max-frequency: true reset-gpios: true rotation: true + width-mm: true + height-mm: true required: - compatible - reg - - dc-gpios additionalProperties: false @@ -72,5 +155,36 @@ examples: backlight = <&backlight>; }; }; + - | +#include + +spi { +#address-cells = <1>; +#size-cells = <0>; + +sainsmart18@0{ +compatible = "sitronix,st7735r"; +reg = <0>; +spi-max-frequency = <4000>; + +width = <160>; +height = <128>; + +frmctr1 = [ 01 2C 2D ]; +invctr = [ 07 ]; +pwctr1 = [ A2 02 84 ]; +pwctr2 = [ C5 ]; +pwctr3 = [ 0A 00 ]; +vmctr1 = [ 0E ]; +madctl = [ 60 ]; +gamctrp1 = [ 0F 1A 0F 18 2F 28 20 22 1F 1B 23 37 00 07 02 10 ]; +gamctrn1 = [ 0F 1B 0F 17 33 2C 29 2E 30 30 39 3F 00 07 03 10 ]; + +dc-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; +reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; +write-only; +}; +}; + ... -- 2.33.0
[PATCH 3/6] dt-bindings: display: sitronix, st7735r: Remove spi-max-frequency limit
The datasheet lists the minimum Serial clock cycle (Write) as 66ns which is 15MHz. Mostly it can do much better than that and is in fact often run at 32MHz. With a clever driver that runs configuration commands at a low speed and only the pixel data at the maximum speed the configuration can't be messed up by transfer errors and the speed is only limited by the amount of pixel glitches that one is able to tolerate. Signed-off-by: Noralf Trønnes --- .../devicetree/bindings/display/sitronix,st7735r.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml index f81d0d0d51fe..157b1a7b18f9 100644 --- a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml +++ b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml @@ -32,15 +32,13 @@ properties: - okaya,rh128128t - const: sitronix,st7715r - spi-max-frequency: -maximum: 3200 - dc-gpios: maxItems: 1 description: Display data/command selection (D/CX) backlight: true reg: true + spi-max-frequency: true reset-gpios: true rotation: true -- 2.33.0
[PATCH 2/6] dt-bindings: display: sitronix, st7735r: Make reset-gpios optional
There are other ways than using a gpio to reset the controller so make this property optional. Signed-off-by: Noralf Trønnes --- Documentation/devicetree/bindings/display/sitronix,st7735r.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml index 419c3b2ac5a6..f81d0d0d51fe 100644 --- a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml +++ b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml @@ -48,7 +48,6 @@ required: - compatible - reg - dc-gpios - - reset-gpios additionalProperties: false -- 2.33.0
[PATCH 1/6] dt-bindings: display: sitronix, st7735r: Fix backlight in example
The backlight property was lost during conversion to yaml in commit abdd9e3705c8 ("dt-bindings: display: sitronix,st7735r: Convert to DT schema"). Put it back. Fixes: abdd9e3705c8 ("dt-bindings: display: sitronix,st7735r: Convert to DT schema") Signed-off-by: Noralf Trønnes --- Documentation/devicetree/bindings/display/sitronix,st7735r.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml index 0cebaaefda03..419c3b2ac5a6 100644 --- a/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml +++ b/Documentation/devicetree/bindings/display/sitronix,st7735r.yaml @@ -72,6 +72,7 @@ examples: dc-gpios = <&gpio 43 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio 80 GPIO_ACTIVE_HIGH>; rotation = <270>; +backlight = <&backlight>; }; }; -- 2.33.0
Re: [PATCH 1/2] drm: exynos: dsi: Convert to bridge driver
component_bind_all+0x16c/0x25c > >>>>>>> exynos_drm_bind+0x104/0x1bc > >>>>>>> try_to_bring_up_master+0x164/0x1d0 > >>>>>>> __component_add+0xa8/0x174 > >>>>>>> component_add+0x14/0x20 > >>>>>>> hdmi_probe+0x438/0x710 > >>>>>>> platform_probe+0x68/0xe0 > >>>>>>> really_probe.part.0+0x9c/0x31c > >>>>>>> __driver_probe_device+0x98/0x144 > >>>>>>> driver_probe_device+0xc8/0x160 > >>>>>>> __device_attach_driver+0xb8/0x120 > >>>>>>> bus_for_each_drv+0x78/0xd0 > >>>>>>> __device_attach+0xd8/0x180 > >>>>>>> device_initial_probe+0x14/0x20 > >>>>>>> bus_probe_device+0x9c/0xa4 > >>>>>>> deferred_probe_work_func+0x88/0xc4 > >>>>>>> process_one_work+0x288/0x6f0 > >>>>>>> worker_thread+0x74/0x470 > >>>>>>> kthread+0x188/0x194 > >>>>>>> ret_from_fork+0x10/0x20 > >>>>>>> Code: 11002042 f9481c61 531e7442 8b020021 (88dffc21) > >>>>>>> ---[ end trace d73aff585b108954 ]--- > >>>>>>> Kernel panic - not syncing: synchronous external abort: Fatal > >>>>>>> exception > >>>>>>> SMP: stopping secondary CPUs > >>>>>>> Kernel Offset: disabled > >>>>>>> CPU features: 0x2,300071c2,0846 > >>>>>>> Memory Limit: none > >>>>>>> ---[ end Kernel panic - not syncing: synchronous external abort: > >>>>>>> Fatal > >>>>>>> exception ]--- > >>>>>> Is this with Bridge or normal DSI panel? > >>>>> Can you apply this patch and check? > >>>>> https://protect2.fireeye.com/v1/url?k=aad62f08-f54d1627-aad7a447-0cc47a31cdf8-ea5858ddb7f0ecfe&q=1&e=2d730862-2c56-4988-a252-8febd02da578&u=https%3A%2F%2Fgithub.com%2Fopenedev%2Flinux%2Fcommit%2F412f226acd774356e8188c9e62b653672926ee0d > >>>>> > >>>> Any news on this? just asking in case if you missed it. > >>> It is somehow better. System doesn't crash, but the DRM is not bound: > >>> > >>> # cat /sys/kernel/debug/device_component/exynos-drm > >>> master namestatus > >>> - > >>> exynos-drm not bound > >>> > >>> device namestatus > >>> ----- > >>> 1380.decon not bound > >>> 1388.decon not bound > >>> 1393.micnot bound > >>> (unknown) not registered > >>> (unknown) not registered > >>> > >> Well, I also checked a much simpler case, the Samsung Trats board > >> (arch/arm/boot/dts/exynos4210-trats.dts). It has only Exynos FIMD > >> (CRTC), Exynos DSI (encoder) and s6e8aa0 panel. No bridges at all. With > >> only the $subject patch applied I got the following errors: > >> > >> exynos4-fb 11c0.fimd: Adding to iommu group 0 > >> OF: graph: no port node found in /soc/fimd@11c0 > >> [drm] Exynos DRM: using 11c0.fimd device for DMA mapping operations > >> exynos-drm exynos-drm: bound 11c0.fimd (ops fimd_component_ops) > >> [drm:drm_bridge_attach] *ERROR* failed to attach bridge > >> /soc/dsi@11c8 to encoder TMDS-50: -22 > >> exynos-drm exynos-drm: failed to bind 11c8.dsi (ops > >> exynos_dsi_component_ops): -22 > >> exynos-drm exynos-drm: master bind failed: -22 > >> exynos-drm: probe of exynos-drm failed with error -22 > >> lima 1300.gpu: gp - mali400 version major 1 minor 1 > >> lima 1300.gpu: pp0 - mali400 version major 1 minor 1 > >> lima 1300.gpu: pp1 - mali400 version major 1 minor 1 > >> lima 1300.gpu: pp2 - mali400 version major 1 minor 1 > >> lima 1300.gpu: pp3 - mali400 version major 1 minor 1 > >> lima 1300.gpu: l2 cache 128K, 4-way, 64byte cache line, 64bit > >> external bus > >> lima 1300.gpu: bus rate = 2 > >> lima 1300.gpu: mod rate = 1 > >> lima 1300.gpu: dev_pm_opp_set_regulators: no regulator (mali) found: > >> -19 > >> [drm] Initialized lima 1.1.0 20191231 for 1300.gpu on minor 0 > >> > >> > >> After applying "drm: exynos: dsi: Add component only once DSI device > >> attached" the Exynos DRM is not even tried to bind: > >> > >> # dmesg | grep drm > >> [2.495898] [drm] Initialized lima 1.1.0 20191231 for 1300.gpu on > >> minor 0 > > Can you confirm, does linux-next work with panel, downstream bridge devices? > > > > downstream bridge has, panel-simple out port (I2C based and non-I2C) > > What do you mean by downstream bridge devices? Bridge devices connected from Exynos Host. > > I've just checked and two mentioned in this thread boards: TM2e and > Trats properly display image with current (20211124) linux-next. > > However I've noticed that the Arndale board > (arch/arm/boot/dts/exynos5250-arndale.dts), which also uses Exynos DSI > with some bridges, gives no display with current next. I will try to > bisect and find when it got broken. I understand why it is broken. Would you please come irc for further discussion on this? #dri-devel jagan_ Thaks, Jagan.
Re: [PATCH 1/2] drm: exynos: dsi: Convert to bridge driver
really_probe.part.0+0x9c/0x31c >>>>>>> __driver_probe_device+0x98/0x144 >>>>>>> driver_probe_device+0xc8/0x160 >>>>>>> __device_attach_driver+0xb8/0x120 >>>>>>> bus_for_each_drv+0x78/0xd0 >>>>>>> __device_attach+0xd8/0x180 >>>>>>> device_initial_probe+0x14/0x20 >>>>>>> bus_probe_device+0x9c/0xa4 >>>>>>> deferred_probe_work_func+0x88/0xc4 >>>>>>> process_one_work+0x288/0x6f0 >>>>>>> worker_thread+0x74/0x470 >>>>>>> kthread+0x188/0x194 >>>>>>> ret_from_fork+0x10/0x20 >>>>>>> Code: 11002042 f9481c61 531e7442 8b020021 (88dffc21) >>>>>>> ---[ end trace d73aff585b108954 ]--- >>>>>>> Kernel panic - not syncing: synchronous external abort: Fatal >>>>>>> exception >>>>>>> SMP: stopping secondary CPUs >>>>>>> Kernel Offset: disabled >>>>>>> CPU features: 0x2,300071c2,0846 >>>>>>> Memory Limit: none >>>>>>> ---[ end Kernel panic - not syncing: synchronous external abort: >>>>>>> Fatal >>>>>>> exception ]--- >>>>>> Is this with Bridge or normal DSI panel? >>>>> Can you apply this patch and check? >>>>> https://protect2.fireeye.com/v1/url?k=aad62f08-f54d1627-aad7a447-0cc47a31cdf8-ea5858ddb7f0ecfe&q=1&e=2d730862-2c56-4988-a252-8febd02da578&u=https%3A%2F%2Fgithub.com%2Fopenedev%2Flinux%2Fcommit%2F412f226acd774356e8188c9e62b653672926ee0d >>>>> >>>> Any news on this? just asking in case if you missed it. >>> It is somehow better. System doesn't crash, but the DRM is not bound: >>> >>> # cat /sys/kernel/debug/device_component/exynos-drm >>> master namestatus >>> - >>> exynos-drm not bound >>> >>> device namestatus >>> - >>> 1380.decon not bound >>> 1388.decon not bound >>> 1393.mic not bound >>> (unknown) not registered >>> (unknown) not registered >>> >> Well, I also checked a much simpler case, the Samsung Trats board >> (arch/arm/boot/dts/exynos4210-trats.dts). It has only Exynos FIMD >> (CRTC), Exynos DSI (encoder) and s6e8aa0 panel. No bridges at all. With >> only the $subject patch applied I got the following errors: >> >> exynos4-fb 11c0.fimd: Adding to iommu group 0 >> OF: graph: no port node found in /soc/fimd@11c0 >> [drm] Exynos DRM: using 11c0.fimd device for DMA mapping operations >> exynos-drm exynos-drm: bound 11c0.fimd (ops fimd_component_ops) >> [drm:drm_bridge_attach] *ERROR* failed to attach bridge >> /soc/dsi@11c8 to encoder TMDS-50: -22 >> exynos-drm exynos-drm: failed to bind 11c8.dsi (ops >> exynos_dsi_component_ops): -22 >> exynos-drm exynos-drm: master bind failed: -22 >> exynos-drm: probe of exynos-drm failed with error -22 >> lima 1300.gpu: gp - mali400 version major 1 minor 1 >> lima 1300.gpu: pp0 - mali400 version major 1 minor 1 >> lima 1300.gpu: pp1 - mali400 version major 1 minor 1 >> lima 1300.gpu: pp2 - mali400 version major 1 minor 1 >> lima 1300.gpu: pp3 - mali400 version major 1 minor 1 >> lima 1300.gpu: l2 cache 128K, 4-way, 64byte cache line, 64bit >> external bus >> lima 1300.gpu: bus rate = 2 >> lima 1300.gpu: mod rate = 1 >> lima 1300.gpu: dev_pm_opp_set_regulators: no regulator (mali) found: -19 >> [drm] Initialized lima 1.1.0 20191231 for 1300.gpu on minor 0 >> >> >> After applying "drm: exynos: dsi: Add component only once DSI device >> attached" the Exynos DRM is not even tried to bind: >> >> # dmesg | grep drm >> [2.495898] [drm] Initialized lima 1.1.0 20191231 for 1300.gpu on >> minor 0 > Can you confirm, does linux-next work with panel, downstream bridge devices? > > downstream bridge has, panel-simple out port (I2C based and non-I2C) What do you mean by downstream bridge devices? I've just checked and two mentioned in this thread boards: TM2e and Trats properly display image with current (20211124) linux-next. However I've noticed that the Arndale board (arch/arm/boot/dts/exynos5250-arndale.dts), which also uses Exynos DSI with some bridges, gives no display with current next. I will try to bisect and find when it got broken. Best regards -- Marek Szyprowski, PhD Samsung R&D Institute Poland
[PATCH] drm/bridge: anx7625: fix an error code in anx7625_register_audio()
This code accidentally returns IS_ERR(), which is 1, instead of propagating the negative error code. The caller doesn't check for errors so it doesn't affect run time at all. Fixes: 566fef1226c1 ("drm/bridge: anx7625: add HDMI audio function") Signed-off-by: Dan Carpenter --- drivers/gpu/drm/bridge/analogix/anx7625.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/anx7625.c b/drivers/gpu/drm/bridge/analogix/anx7625.c index 001fb39d9919..f56e106b445d 100644 --- a/drivers/gpu/drm/bridge/analogix/anx7625.c +++ b/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1636,7 +1636,7 @@ static int anx7625_register_audio(struct device *dev, struct anx7625_data *ctx) sizeof(codec_data)); if (IS_ERR(ctx->audio_pdev)) - return IS_ERR(ctx->audio_pdev); + return PTR_ERR(ctx->audio_pdev); DRM_DEV_DEBUG_DRIVER(dev, "bound to %s", HDMI_CODEC_DRV_NAME); -- 2.20.1
[PATCH] drm/i915/gvt: Prevent integer overflow in intel_vgpu_emulate_cfg_write()
The "offset" is a u32 that comes from the user. The bug is that the "offset + bytes" operation can have an integer overflow problem which leads to an out of bounds access. Fixes: 4d60c5fd3f87 ("drm/i915/gvt: vGPU PCI configuration space virtualization") Signed-off-by: Dan Carpenter --- drivers/gpu/drm/i915/gvt/cfg_space.c | 4 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/i915/gvt/cfg_space.c b/drivers/gpu/drm/i915/gvt/cfg_space.c index b490e3db2e38..8a54dd3de91c 100644 --- a/drivers/gpu/drm/i915/gvt/cfg_space.c +++ b/drivers/gpu/drm/i915/gvt/cfg_space.c @@ -316,6 +316,10 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, if (drm_WARN_ON(&i915->drm, bytes > 4)) return -EINVAL; + if (drm_WARN_ON(&i915->drm, + offset > vgpu->gvt->device_info.cfg_space_size)) + return -EINVAL; + if (drm_WARN_ON(&i915->drm, offset + bytes > vgpu->gvt->device_info.cfg_space_size)) return -EINVAL; -- 2.20.1
Re: [PATCH v6 6/7] phy: phy-mtk-dp: Add driver for DP phy
Hi Chunfeng, Quoting Chunfeng Yun (2021-11-13 08:48:37) > On Wed, 2021-11-10 at 14:06 +0100, Guillaume Ranquet wrote: > > From: Markus Schneider-Pargmann > > > > This is a new driver that supports the integrated DisplayPort phy for > > mediatek SoCs, especially the mt8195. The phy is integrated into the > > DisplayPort controller and will be created by the mtk-dp driver. This > > driver expects a struct regmap to be able to work on the same > > registers > > as the DisplayPort controller. It sets the device data to be the > > struct > > phy so that the DisplayPort controller can easily work with it. > > > > The driver does not have any devicetree bindings because the > > datasheet > > does not list the controller and the phy as distinct units. > > > > The interaction with the controller can be covered by the configure > > callback of the phy framework and its displayport parameters. > > > > Signed-off-by: Markus Schneider-Pargmann > > Signed-off-by: Guillaume Ranquet > > --- > > MAINTAINERS | 1 + > > drivers/phy/mediatek/Kconfig | 8 ++ > > drivers/phy/mediatek/Makefile | 1 + > > drivers/phy/mediatek/phy-mtk-dp.c | 219 > > ++ > > 4 files changed, 229 insertions(+) > > create mode 100644 drivers/phy/mediatek/phy-mtk-dp.c > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index 170bbbeefc3f4..f9a71b6d2a4a9 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -6367,6 +6367,7 @@ L: linux-media...@lists.infradead.org > > (moderated for non-subscribers) > > S: Supported > > F: Documentation/devicetree/bindings/display/mediatek/ > > F: drivers/gpu/drm/mediatek/ > > +F: drivers/phy/mediatek/phy-mtk-dp.c > > F: drivers/phy/mediatek/phy-mtk-hdmi* > > F: drivers/phy/mediatek/phy-mtk-mipi* > > > > diff --git a/drivers/phy/mediatek/Kconfig > > b/drivers/phy/mediatek/Kconfig > > index 55f8e6c048ab3..f7ec860590492 100644 > > --- a/drivers/phy/mediatek/Kconfig > > +++ b/drivers/phy/mediatek/Kconfig > > @@ -55,3 +55,11 @@ config PHY_MTK_MIPI_DSI > > select GENERIC_PHY > > help > > Support MIPI DSI for Mediatek SoCs. > > + > > +config PHY_MTK_DP > > + tristate "MediaTek DP-PHY Driver" > > + depends on ARCH_MEDIATEK || COMPILE_TEST > > + depends on OF > > + select GENERIC_PHY > > + help > > + Support DisplayPort PHY for Mediatek SoCs. > > diff --git a/drivers/phy/mediatek/Makefile > > b/drivers/phy/mediatek/Makefile > > index ace660fbed3a1..4ba1e06504346 100644 > > --- a/drivers/phy/mediatek/Makefile > > +++ b/drivers/phy/mediatek/Makefile > > @@ -3,6 +3,7 @@ > > # Makefile for the phy drivers. > > # > > > > +obj-$(CONFIG_PHY_MTK_DP) += phy-mtk-dp.o > > obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o > > obj-$(CONFIG_PHY_MTK_UFS)+= phy-mtk-ufs.o > > obj-$(CONFIG_PHY_MTK_XSPHY) += phy-mtk-xsphy.o > > diff --git a/drivers/phy/mediatek/phy-mtk-dp.c > > b/drivers/phy/mediatek/phy-mtk-dp.c > > new file mode 100644 > > index 0..4f8d26ec0346b > > --- /dev/null > > +++ b/drivers/phy/mediatek/phy-mtk-dp.c > > @@ -0,0 +1,219 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (c) 2021 BayLibre > > + * Author: Markus Schneider-Pargmann > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#define PHY_OFFSET 0x1000 > Why not provide register base address in DTS? > I find that phy's platform device is registered by dp driver but the > one automatically created when parse dts? > This phy driver has no dt binding whatsoever, as it shares basically the same hardware as the DP driver, so everything has to be either hardcoded or passed through from the DP driver. > > + > > +#define MTK_DP_PHY_DIG_PLL_CTL_1 (PHY_OFFSET + 0x014) > > +# define TPLL_SSC_EN BIT(3) > > + > > +#define MTK_DP_PHY_DIG_BIT_RATE (PHY_OFFSET + > > 0x03C) > > +# define BIT_RATE_RBR0 > > +# define BIT_RATE_HBR1 > > +# define BIT_RATE_HBR2 2 > > +# define BIT_RATE_HBR3 3 > > + > > +#define MTK_DP_PHY_DIG_SW_RST(PHY_OFFSET + > > 0x038) > > +# define DP_GLB_SW_RST_PHYD BIT(0) > > + > > +#define MTK_DP_LANE0_DRIVING_PARAM_3 (PHY_OFFSET + 0x138) > > +#define MTK_DP_LANE1_DRIVING_PARAM_3 (PHY_OFFSET + 0x238) > > +#define MTK_DP_LANE2_DRIVING_PARAM_3 (PHY_OFFSET + 0x338) > > +#define MTK_DP_LANE3_DRIVING_PARAM_3 (PHY_OFFSET + 0x438) > > +# define XTP_LN_TX_LCTXC0_SW0_PRE0_DEFAULT 0x10 > > +# define XTP_LN_TX_LCTXC0_SW0_PRE1_DEFAULT (0x14 << 8) > > +# define XTP_LN_TX_LCTXC0_SW0_PRE2_DEFAULT (0x18 << 16) > > +# define XTP_LN_TX_LCTXC0_SW0_PRE3_DEFAULT (0x20 << 24) > > +# define DRIVING_PARAM_3_DEFAULT (XTP_LN_TX_LCTXC0_SW0_P > > RE
Re: [PATCH 1/9] gpu: host1x: Add missing DMA API include
On 2021-11-23 14:10, Robin Murphy wrote: Host1x seems to be relying on picking up dma-mapping.h transitively from iova.h, which has no reason to include it in the first place. Fix the former issue before we totally break things by fixing the latter one. CC: Thierry Reding CC: Mikko Perttunen CC: dri-devel@lists.freedesktop.org CC: linux-te...@vger.kernel.org Signed-off-by: Robin Murphy --- Feel free to pick this into drm-misc-next or drm-misc-fixes straight away if that suits - it's only to avoid a build breakage once the rest of the series gets queued. Bah, seems like tegra-vic needs the same treatment too, but wasn't in my local config. Should I squash that into a respin of this patch on the grounds of being vaguely related, or would you prefer it separate? (Either way I'll wait a little while to see if the buildbots uncover any more...) Cheers, Robin. drivers/gpu/host1x/bus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index 218e3718fd68..881fad5c3307 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include
Re: [Intel-gfx] [PATCH 1/3] drm/i915/gt: Spread virtual engines over idle engines
On Wed, Nov 24, 2021 at 08:56:52AM +, Tvrtko Ursulin wrote: > > On 23/11/2021 19:52, Rodrigo Vivi wrote: > > On Tue, Nov 23, 2021 at 09:39:25AM +, Tvrtko Ursulin wrote: > > > > > > On 17/11/2021 22:49, Vinay Belgaumkar wrote: > > > > From: Chris Wilson > > > > > > > > Everytime we come to the end of a virtual engine's context, re-randomise > > > > it's siblings[]. As we schedule the siblings' tasklets in the order they > > > > are in the array, earlier entries are executed first (when idle) and so > > > > will be preferred when scheduling the next virtual request. Currently, > > > > we only update the array when switching onto a new idle engine, so we > > > > prefer to stick on the last execute engine, keeping the work compact. > > > > However, it can be beneficial to spread the work out across idle > > > > engines, so choose another sibling as our preferred target at the end of > > > > the context's execution. > > > > > > This partially brings back, from a different angle, the more dynamic > > > scheduling behavior which has been lost since bugfix 90a987205c6c > > > ("drm/i915/gt: Only swap to a random sibling once upon creation"). > > > > Shouldn't we use the Fixes tag here since this is targeting to fix one > > of the performance regressions of this patch? > > Probably not but hard to say. Note that it wasn't a performance regression > that was reported but power. > > And to go back to what we said elsewhere in the thread, I am actually with > you in thinking that in the ideal world we need PnP testing across a variety > of workloads and platforms. And "in the ideal world" should really be in the > normal world. It is not professional to be reactive to isolated bug reports > from users, without being able to see the overall picture. We surely need to address the bug report from users. I'm just asking to address that with the smallest fix that we can backport and fit to the products milestones. Instead, we are creating another optimization feature on a rush. Without a proper validation. I believe it is too risk to add an algorithm like that without a broader test. I see a big risk of introducing corner cases that will results in more bug report from other users in a near future. So, let's all be professionals and provide a smaller fix for a regression on the load balancing scenario and provide a better validation with more data to justify this new feature. Thanks, Rodrigo. > > > > One day we could experiment with using engine busyness as criteria > > > (instead > > > of random). Back in the day busyness was kind of the best strategy, > > > although > > > sampled at submit, not at the trailing edge like here, but it still may be > > > able to settle down to engine configuration better in some scenarios. Only > > > testing could say. > > > > > > Still, from memory random also wasn't that bad so this should be okay for > > > now. > > > > > > Reviewed-by: Tvrtko Ursulin > > > > Since you reviewed and it looks to be a middle ground point in terms > > of when to balancing (always like in the initial implementation vs > > only once like the in 90a987205c6c). > > > > If this one is really fixing the regression by itself: > > Acked-by: Rodrigo Vivi > > on this patch here. > > > > But I still don't want to take the risk with touching the freq with > > race to idle, until not convinced that it is absolutely needed and > > that we are not breaking the world out there. > > Yes agreed in principle, we have users with different priorities. > > However the RPS patches in the series, definitely the 1st one which looks at > classes versus individual engines, sound plausible to me. Given the absence > of automated PnP testing mentioned above, in the past it was usually Chris > who was making the above and beyond effort to evaluate changes like these on > as many platforms as he could, and with different workloads. Not sure who > has the mandate and drive to fill that space but something will need to > happen. > > Regards, > > Tvrtko > > > > > > > Regards, > > > > > > Tvrtko > > > > > > > Signed-off-by: Chris Wilson > > > > Cc: Vinay Belgaumkar > > > > Cc: Tvrtko Ursulin > > > > --- > > > >.../drm/i915/gt/intel_execlists_submission.c | 80 > > > > --- > > > >1 file changed, 52 insertions(+), 28 deletions(-) > > > > > > > > diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > > > b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > > > index ca03880fa7e4..b95bbc8fb91a 100644 > > > > --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > > > +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c > > > > @@ -539,6 +539,41 @@ static void execlists_schedule_in(struct > > > > i915_request *rq, int idx) > > > > GEM_BUG_ON(intel_context_inflight(ce) != rq->engine); > > > >} > > > > +static void virtual_xfer_context(struct virtual_engine *ve, > > > > +struct intel_engine_cs *engine)
Re: [PATCH v6 7/7] drm/mediatek: Add mt8195 DisplayPort driver
Hi, Thanks for all your input, really appreciated. Quoting Maxime Ripard (2021-11-16 15:51:12) > Hi, > > On Mon, Nov 15, 2021 at 09:33:52AM -0500, Guillaume Ranquet wrote: > > Quoting Maxime Ripard (2021-11-15 11:11:29) > > > > The driver creates a child device for the phy. The child device will > > > > never exist without the parent being active. As they are sharing a > > > > register range, the parent passes a regmap pointer to the child so that > > > > both can work with the same register range. The phy driver sets device > > > > data that is read by the parent to get the phy device that can be used > > > > to control the phy properties. > > > > > > If the PHY is in the same register space than the DP controller, why do > > > you need a separate PHY driver in the first place? > > > > This has been asked by Chun-Kuang Hu in a previous revision of the series: > > > > https://lore.kernel.org/linux-mediatek/CAAOTY_-+T-wRCH2yw2XSm=zbabbqbq4eqpu2p0tf90gawqe...@mail.gmail.com/ > > It's a bit of a circular argument though :) > > It's a separate phy driver because it needs to go through another > maintainer's tree, but it needs to go through another maintainer's tree > because it's a separate phy driver. > > It doesn't explain why it needs to be a separate phy driver? Why can't > the phy setup be done directly in the DP driver, if it's essentially a > single device? > > That being said, usually what those kind of questions mean is that > you're missing a comment or something in the commit log to provide that > context in the first place, so it would be great to add that context > here. > > And it will avoid the situation we're now in where multiple reviewers > ask the same questions over and over again :) > At first I didn't understand your reply, then I realized I gave you the wrong link... my bad! I'm struggling a bit with mail reviews, but I'll get there eventually. The driver and phy were a single driver until v2 of this patch series and the phy setup was done directly in the driver (single driver, single C file). Here's the relevant link to the discussion between Chun-Kuang and Markus https://lore.kernel.org/linux-mediatek/caaoty__cjmqcaieeraj2sz4gi0zs-ainxz38_x7dpqea6hv...@mail.gmail.com/#t I'll try to find a way to make it clearer for v7. > > > > +static void mtk_dp_bridge_atomic_enable(struct drm_bridge *bridge, > > > > + struct drm_bridge_state > > > > *old_state) > > > > +{ > > > > + struct mtk_dp *mtk_dp = mtk_dp_from_bridge(bridge); > > > > + struct drm_connector *conn; > > > > + struct drm_connector_state *conn_state; > > > > + struct drm_crtc *crtc; > > > > + struct drm_crtc_state *crtc_state; > > > > + int ret = 0; > > > > + int i; > > > > + > > > > + conn = > > > > drm_atomic_get_new_connector_for_encoder(old_state->base.state, > > > > + bridge->encoder); > > > > + if (!conn) { > > > > + drm_err(mtk_dp->drm_dev, > > > > + "Can't enable bridge as connector is missing\n"); > > > > + return; > > > > + } > > > > + > > > > + memcpy(mtk_dp->connector_eld, conn->eld, MAX_ELD_BYTES); > > > > > > This should be protected by a mutex (just like any resource shared > > > between KMS and ALSA) > > > > Ok. > > I forgot to ask (even though checkpatch does mention it iirc), but since > you have multiple mutex it would be nice to have a comment for each > mutex stating exactly what it protects, and against what. > > It's hard otherwise to remember or figure out what the locks are here > for. > > > > > + ret = mtk_dp_dt_parse_pdata(mtk_dp, pdev); > > > > + if (ret) > > > > + return ret; > > > > > > pdata? > > > > > can you elaborate? > > Sorry, yeah, pdata is usually the abbreviation used in linux for the > platform_data mechanism, but you're using the DT to retrieve your > resources (and platform_data usually don't involve any parsing), so the > name is odd. > > > > > diff --git a/drivers/gpu/drm/mediatek/mtk_dpi.c > > > > b/drivers/gpu/drm/mediatek/mtk_dpi.c > > > > index 384074f69111b..e6e88e3cd811d 100644 > > > > --- a/drivers/gpu/drm/mediatek/mtk_dpi.c > > > > +++ b/drivers/gpu/drm/mediatek/mtk_dpi.c > > > > @@ -63,6 +63,14 @@ enum mtk_dpi_out_color_format { > > > > MTK_DPI_COLOR_FORMAT_YCBCR_422_FULL > > > > }; > > > > > > > > +enum TVDPLL_CLK { > > > > + TVDPLL_PLL = 0, > > > > + TVDPLL_D2 = 2, > > > > + TVDPLL_D4 = 4, > > > > + TVDPLL_D8 = 8, > > > > + TVDPLL_D16 = 16, > > > > +}; > > > > + > > > > struct mtk_dpi { > > > > struct drm_encoder encoder; > > > > struct drm_bridge bridge; > > > > @@ -71,8 +79,10 @@ struct mtk_dpi { > > > > void __iomem *regs; > > > > struct device *dev; > > > > struct clk *engine_clk; > > > > + struct clk *dpi_ck_cg; > > > > struct clk *pixel_clk; > > > > struct clk *tvd_clk; > > > > + struct clk *pcl
Re: [PATCH v2 6/8] inotify: simplify subdirectory registration with register_sysctl()
On Wed, Nov 24, 2021 at 10:44:09AM +0100, Jan Kara wrote: > On Tue 23-11-21 12:24:20, Luis Chamberlain wrote: > > From: Xiaoming Ni > > > > There is no need to user boiler plate code to specify a set of base > > directories we're going to stuff sysctls under. Simplify this by using > > register_sysctl() and specifying the directory path directly. > > > > Move inotify_user sysctl to inotify_user.c while at it to remove clutter > > from kernel/sysctl.c. > > > > Signed-off-by: Xiaoming Ni > > [mcgrof: update commit log to reflect new path we decided to take] > > Signed-off-by: Luis Chamberlain > > This looks fishy. You register inotify_table but not fanotify_table and > remove both... Indeed, the following was missing, I'll roll it in: diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 559bc1e9926d..a35693eb1f36 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -59,7 +59,7 @@ static int fanotify_max_queued_events __read_mostly; static long ft_zero = 0; static long ft_int_max = INT_MAX; -struct ctl_table fanotify_table[] = { +static struct ctl_table fanotify_table[] = { { .procname = "max_user_groups", .data = &init_user_ns.ucount_max[UCOUNT_FANOTIFY_GROUPS], @@ -88,6 +88,13 @@ struct ctl_table fanotify_table[] = { }, { } }; + +static void __init fanotify_sysctls_init(void) +{ + register_sysctl("fs/fanotify", fanotify_table); +} +#else +#define fanotify_sysctls_init() do { } while (0) #endif /* CONFIG_SYSCTL */ /* @@ -1685,6 +1692,7 @@ static int __init fanotify_user_setup(void) init_user_ns.ucount_max[UCOUNT_FANOTIFY_GROUPS] = FANOTIFY_DEFAULT_MAX_GROUPS; init_user_ns.ucount_max[UCOUNT_FANOTIFY_MARKS] = max_marks; + fanotify_sysctls_init(); return 0; } diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index 616af2ea20f3..556cc63c88ee 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h @@ -5,8 +5,6 @@ #include #include -extern struct ctl_table fanotify_table[]; /* for sysctl */ - #define FAN_GROUP_FLAG(group, flag) \ ((group)->fanotify_data.flags & (flag))
Re: [PATCH v2 12/63] thermal: intel: int340x_thermal: Use struct_group() for memcpy() region
On Wed, Nov 24, 2021 at 12:53 AM Srinivas Pandruvada wrote: > > On Tue, 2021-11-23 at 14:19 +0100, Rafael J. Wysocki wrote: > > On Wed, Aug 18, 2021 at 8:08 AM Kees Cook > > wrote: > > > > > > In preparation for FORTIFY_SOURCE performing compile-time and run- > > > time > > > field bounds checking for memcpy(), avoid intentionally writing > > > across > > > neighboring fields. > > > > > > Use struct_group() in struct art around members weight, and ac[0- > > > 9]_max, > > > so they can be referenced together. This will allow memcpy() and > > > sizeof() > > > to more easily reason about sizes, improve readability, and avoid > > > future > > > warnings about writing beyond the end of weight. > > > > > > "pahole" shows no size nor member offset changes to struct art. > > > "objdump -d" shows no meaningful object code changes (i.e. only > > > source > > > line number induced differences). > > > > > > Cc: Zhang Rui > > > Cc: Daniel Lezcano > > > Cc: Amit Kucheria > > > Cc: linux...@vger.kernel.org > > > Signed-off-by: Kees Cook > > > > Rui, Srinivas, any comments here? > Looks good. > Reviewed-by: Srinivas Pandruvada Applied as 5.17 material, thank you!
[Bug 211807] [drm:drm_dp_mst_dpcd_read] *ERROR* mstb 000000004e6288dd port 3: DPCD read on addr 0x60 for 1 bytes NAKed
https://bugzilla.kernel.org/show_bug.cgi?id=211807 Chatty (m...@chatty.de) changed: What|Removed |Added CC||m...@chatty.de --- Comment #17 from Chatty (m...@chatty.de) --- My setup: MS Surface Book 2 + AOC U2879G6 via Surface Dock via DisplayPort Tested kernels: 5.10.0 / 5.15.3 / 5.16.0-rc1 When connecting I get random results of: * monitor remains black * monitor exhibits 1080p@60 as max resolution * monitor exhibits 1440p@60 as max resolution * monitor exhibits 2160p@30 as max resolution * monitor exhibits 2160p@30 as max resolution <== desired On boot of 5.16.0-rc1 its initialized with: > i915 :00:02.0: [drm] Finished loading DMC firmware > i915/kbl_dmc_ver1_04.bin (v1.4) > [drm] Initialized i915 1.6.0 20201103 for :00:02.0 on minor 0 In the first case I see following dmesg output (black monitor): > i915 :00:02.0: [drm] *ERROR* mstb 09cd3ca6 port 1: DPCD read on > addr 0x4b0 for 1 bytes NAKed In the last case I see following dmesg output (despite monitor working): > i915 :00:02.0: [drm] *ERROR* mstb f4b4c9f1 port 1: DPCD read on > addr 0x4b0 for 1 bytes NAKed > i915 :00:02.0: [drm] *ERROR* mstb f4b4c9f1 port 1: DPCD read on > addr 0x4b0 for 1 bytes NAKed > i915 :00:02.0: [drm] *ERROR* mstb f4b4c9f1 port 1: DPCD read on > addr 0x4b0 for 1 bytes NAKed > i915 :00:02.0: [drm] *ERROR* mstb f4b4c9f1 port 1: DPCD read on > addr 0x4b0 for 1 bytes NAKed > i915 :00:02.0: [drm] *ERROR* mstb f4b4c9f1 port 1: DPCD read on > addr 0x4b0 for 1 bytes NAKed -- You may reply to this email to add a comment. You are receiving this mail because: You are watching the assignee of the bug.
[PATCH 5.15 247/279] drm/prime: Fix use after free in mmap with drm_gem_ttm_mmap
From: Anand K Mistry commit 8244a3bc27b3efd057da154b8d7e414670d5044f upstream. drm_gem_ttm_mmap() drops a reference to the gem object on success. If the gem object's refcount == 1 on entry to drm_gem_prime_mmap(), that drop will free the gem object, and the subsequent drm_gem_object_get() will be a UAF. Fix by grabbing a reference before calling the mmap helper. This issue was forseen when the reference dropping was adding in commit 9786b65bc61ac ("drm/ttm: fix mmap refcounting"): "For that to work properly the drm_gem_object_get() call in drm_gem_ttm_mmap() must be moved so it happens before calling obj->funcs->mmap(), otherwise the gem refcount would go down to zero." Signed-off-by: Anand K Mistry Fixes: 9786b65bc61a ("drm/ttm: fix mmap refcounting") Cc: Gerd Hoffmann Cc: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: # v5.5+ Signed-off-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20210930085932.1.I8043d61cc238e0168e2f4ca5f4783223434aa587@changeid Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_prime.c |6 -- 1 file changed, 4 insertions(+), 2 deletions(-) --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -719,11 +719,13 @@ int drm_gem_prime_mmap(struct drm_gem_ob if (obj->funcs && obj->funcs->mmap) { vma->vm_ops = obj->funcs->vm_ops; + drm_gem_object_get(obj); ret = obj->funcs->mmap(obj, vma); - if (ret) + if (ret) { + drm_gem_object_put(obj); return ret; + } vma->vm_private_data = obj; - drm_gem_object_get(obj); return 0; }
[PATCH 5.15 226/279] drm/cma-helper: Release non-coherent memory with dma_free_noncoherent()
From: Thomas Zimmermann commit 995f54ea962e03ec08b8bc6a4fe11a32b420edd3 upstream. The GEM CMA helpers allocate non-coherent (i.e., cached) backing storage with dma_alloc_noncoherent(), but release it with dma_free_wc(). Fix this with a call to dma_free_noncoherent(). Writecombining storage is still released with dma_free_wc(). Signed-off-by: Thomas Zimmermann Fixes: cf8ccbc72d61 ("drm: Add support for GEM buffers backed by non-coherent memory") Acked-by: Paul Cercueil Cc: Thomas Zimmermann Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: David Airlie Cc: Daniel Vetter Cc: dri-devel@lists.freedesktop.org Cc: # v5.14+ Link: https://patchwork.freedesktop.org/patch/msgid/20210708175146.10618-1-tzimmerm...@suse.de Signed-off-by: Greg Kroah-Hartman --- drivers/gpu/drm/drm_gem_cma_helper.c |9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -210,8 +210,13 @@ void drm_gem_cma_free_object(struct drm_ dma_buf_vunmap(gem_obj->import_attach->dmabuf, &map); drm_prime_gem_destroy(gem_obj, cma_obj->sgt); } else if (cma_obj->vaddr) { - dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, - cma_obj->vaddr, cma_obj->paddr); + if (cma_obj->map_noncoherent) + dma_free_noncoherent(gem_obj->dev->dev, cma_obj->base.size, +cma_obj->vaddr, cma_obj->paddr, +DMA_TO_DEVICE); + else + dma_free_wc(gem_obj->dev->dev, cma_obj->base.size, + cma_obj->vaddr, cma_obj->paddr); } drm_gem_object_release(gem_obj);
[PATCH 09/12] drm/amdgpu: use ttm_resource_manager_debug
Instead of calling the debug operation directly. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 9be56ecaf39a..62c328f23ff6 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -2082,7 +2082,7 @@ static int amdgpu_mm_vram_table_show(struct seq_file *m, void *unused) TTM_PL_VRAM); struct drm_printer p = drm_seq_file_printer(m); - man->func->debug(man, &p); + ttm_resource_manager_debug(man, &p); return 0; } @@ -2100,7 +2100,7 @@ static int amdgpu_mm_tt_table_show(struct seq_file *m, void *unused) TTM_PL_TT); struct drm_printer p = drm_seq_file_printer(m); - man->func->debug(man, &p); + ttm_resource_manager_debug(man, &p); return 0; } @@ -2111,7 +2111,7 @@ static int amdgpu_mm_gds_table_show(struct seq_file *m, void *unused) AMDGPU_PL_GDS); struct drm_printer p = drm_seq_file_printer(m); - man->func->debug(man, &p); + ttm_resource_manager_debug(man, &p); return 0; } @@ -2122,7 +2122,7 @@ static int amdgpu_mm_gws_table_show(struct seq_file *m, void *unused) AMDGPU_PL_GWS); struct drm_printer p = drm_seq_file_printer(m); - man->func->debug(man, &p); + ttm_resource_manager_debug(man, &p); return 0; } @@ -2133,7 +2133,7 @@ static int amdgpu_mm_oa_table_show(struct seq_file *m, void *unused) AMDGPU_PL_OA); struct drm_printer p = drm_seq_file_printer(m); - man->func->debug(man, &p); + ttm_resource_manager_debug(man, &p); return 0; } -- 2.25.1
[PATCH 12/12] drm/amdgpu: drop amdgpu_gtt_node
We have the BO pointer in the base structure now as well. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 49 - 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index ce5eeb3c1097..a55bbe1a154c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -26,23 +26,12 @@ #include "amdgpu.h" -struct amdgpu_gtt_node { - struct ttm_buffer_object *tbo; - struct ttm_range_mgr_node base; -}; - static inline struct amdgpu_gtt_mgr * to_gtt_mgr(struct ttm_resource_manager *man) { return container_of(man, struct amdgpu_gtt_mgr, manager); } -static inline struct amdgpu_gtt_node * -to_amdgpu_gtt_node(struct ttm_resource *res) -{ - return container_of(res, struct amdgpu_gtt_node, base.base); -} - /** * DOC: mem_info_gtt_total * @@ -107,9 +96,9 @@ const struct attribute_group amdgpu_gtt_mgr_attr_group = { */ bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *res) { - struct amdgpu_gtt_node *node = to_amdgpu_gtt_node(res); + struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res); - return drm_mm_node_allocated(&node->base.mm_nodes[0]); + return drm_mm_node_allocated(&node->mm_nodes[0]); } /** @@ -129,15 +118,14 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, { struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man); uint32_t num_pages = PFN_UP(tbo->base.size); - struct amdgpu_gtt_node *node; + struct ttm_range_mgr_node *node; int r; - node = kzalloc(struct_size(node, base.mm_nodes, 1), GFP_KERNEL); + node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL); if (!node) return -ENOMEM; - node->tbo = tbo; - ttm_resource_init(tbo, place, &node->base.base); + ttm_resource_init(tbo, place, &node->base); if (!(place->flags & TTM_PL_FLAG_TEMPORARY) && ttm_resource_manager_usage(man) > man->size) { r = -ENOSPC; @@ -146,8 +134,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, if (place->lpfn) { spin_lock(&mgr->lock); - r = drm_mm_insert_node_in_range(&mgr->mm, - &node->base.mm_nodes[0], + r = drm_mm_insert_node_in_range(&mgr->mm, &node->mm_nodes[0], num_pages, tbo->page_alignment, 0, place->fpfn, place->lpfn, DRM_MM_INSERT_BEST); @@ -155,18 +142,18 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, if (unlikely(r)) goto err_free; - node->base.base.start = node->base.mm_nodes[0].start; + node->base.start = node->mm_nodes[0].start; } else { - node->base.mm_nodes[0].start = 0; - node->base.mm_nodes[0].size = node->base.base.num_pages; - node->base.base.start = AMDGPU_BO_INVALID_OFFSET; + node->mm_nodes[0].start = 0; + node->mm_nodes[0].size = node->base.num_pages; + node->base.start = AMDGPU_BO_INVALID_OFFSET; } - *res = &node->base.base; + *res = &node->base; return 0; err_free: - ttm_resource_fini(man, &node->base.base); + ttm_resource_fini(man, &node->base); kfree(node); return r; } @@ -182,12 +169,12 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man, struct ttm_resource *res) { - struct amdgpu_gtt_node *node = to_amdgpu_gtt_node(res); + struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res); struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man); spin_lock(&mgr->lock); - if (drm_mm_node_allocated(&node->base.mm_nodes[0])) - drm_mm_remove_node(&node->base.mm_nodes[0]); + if (drm_mm_node_allocated(&node->mm_nodes[0])) + drm_mm_remove_node(&node->mm_nodes[0]); spin_unlock(&mgr->lock); ttm_resource_fini(man, res); @@ -204,16 +191,16 @@ static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man, int amdgpu_gtt_mgr_recover(struct ttm_resource_manager *man) { struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man); + struct ttm_range_mgr_node *node; struct amdgpu_device *adev; - struct amdgpu_gtt_node *node; struct drm_mm_node *mm_node; int r = 0; adev = container_of(mgr, typeof(*adev), mman.gtt_mgr); spin_lock(&mgr->lock); drm_mm_for_each_node(mm_node, &mgr->mm) { - node = container_of(mm_node, typeof(*node), base.mm_nodes[0]); -
[PATCH 11/12] drm/amdgpu: remove VRAM accounting
This is provided by TTM now. Also switch man->size to bytes instead of pages and fix the double printing of size and usage in debugfs. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 5 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 2 - drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 56 +++- 7 files changed, 26 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 7077f21f0021..4760fd82e6c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -531,9 +531,10 @@ int amdgpu_amdkfd_get_dmabuf_info(struct kgd_dev *kgd, int dma_buf_fd, uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd) { struct amdgpu_device *adev = (struct amdgpu_device *)kgd; - struct ttm_resource_manager *vram_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); + struct ttm_resource_manager *vram_man = + ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM); - return amdgpu_vram_mgr_usage(vram_man); + return ttm_resource_manager_usage(vram_man); } uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 413606d10080..797739ba5466 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -315,7 +315,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, } total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size); - used_vram = amdgpu_vram_mgr_usage(vram_man); + used_vram = ttm_resource_manager_usage(vram_man); free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram; spin_lock(&adev->mm_stats.lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 8d5d56d9d26d..6d21ee430f03 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -672,7 +672,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ui64 = atomic64_read(&adev->num_vram_cpu_page_faults); return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMDGPU_INFO_VRAM_USAGE: - ui64 = amdgpu_vram_mgr_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM)); + ui64 = ttm_resource_manager_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM)); return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMDGPU_INFO_VIS_VRAM_USAGE: ui64 = amdgpu_vram_mgr_vis_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM)); @@ -718,8 +718,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) mem.vram.usable_heap_size = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size) - AMDGPU_VM_RESERVED_VRAM; - mem.vram.heap_usage = - amdgpu_vram_mgr_usage(vram_man); + mem.vram.heap_usage = ttm_resource_manager_usage(vram_man); mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4; mem.cpu_accessible_vram.total_heap_size = diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 62c328f23ff6..b5a4f1311504 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1879,7 +1879,7 @@ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable) size = adev->gmc.real_vram_size; else size = adev->gmc.visible_vram_size; - man->size = size >> PAGE_SHIFT; + man->size = size; adev->mman.buffer_funcs_enabled = enable; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h index 2ac332cd4f59..f3eb4029bdcf 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h @@ -44,7 +44,6 @@ struct amdgpu_vram_mgr { spinlock_t lock; struct list_head reservations_pending; struct list_head reserved_pages; - atomic64_t usage; atomic64_t vis_usage; }; @@ -127,7 +126,6 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, void amdgpu_vram_mgr_free_sgt(struct device *dev, enum dma_data_direction dir, struct sg_table *sgt); -uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man); uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_res
[PATCH 03/12] drm/ttm: add a weak BO reference to the resource v3
Keep track for which BO a resource was allocated. This is necessary to move the LRU handling into the resources. A bit problematic is i915 since it tries to use the resource interface without a BO which is illegal from the conceptional point of view. v2: Document that this is a weak reference and add a workaround for i915 v3: further document that this is protected by ttm_device::lru_lock and clarify the i915 workaround Signed-off-by: Christian König --- drivers/gpu/drm/ttm/ttm_bo_util.c | 7 +-- drivers/gpu/drm/ttm/ttm_resource.c | 9 + include/drm/ttm/ttm_resource.h | 4 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 95de2691ee7c..a2e3a9626198 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -237,6 +237,11 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, if (bo->type != ttm_bo_type_sg) fbo->base.base.resv = &fbo->base.base._resv; + if (fbo->base.resource) { + ttm_resource_set_bo(fbo->base.resource, &fbo->base); + bo->resource = NULL; + } + dma_resv_init(&fbo->base.base._resv); fbo->base.base.dev = NULL; ret = dma_resv_trylock(&fbo->base.base._resv); @@ -512,7 +517,6 @@ static int ttm_bo_move_to_ghost(struct ttm_buffer_object *bo, ghost_obj->ttm = NULL; else bo->ttm = NULL; - bo->resource = NULL; dma_resv_unlock(&ghost_obj->base._resv); ttm_bo_put(ghost_obj); @@ -637,7 +641,6 @@ int ttm_bo_pipeline_gutting(struct ttm_buffer_object *bo) dma_resv_unlock(&ghost->base._resv); ttm_bo_put(ghost); bo->ttm = ttm; - bo->resource = NULL; ttm_bo_assign_mem(bo, sys_res); return 0; diff --git a/drivers/gpu/drm/ttm/ttm_resource.c b/drivers/gpu/drm/ttm/ttm_resource.c index 41e7bf195168..7fdd58b53c61 100644 --- a/drivers/gpu/drm/ttm/ttm_resource.c +++ b/drivers/gpu/drm/ttm/ttm_resource.c @@ -41,6 +41,7 @@ void ttm_resource_init(struct ttm_buffer_object *bo, res->bus.offset = 0; res->bus.is_iomem = false; res->bus.caching = ttm_cached; + res->bo = bo; } EXPORT_SYMBOL(ttm_resource_init); @@ -122,6 +123,14 @@ bool ttm_resource_compat(struct ttm_resource *res, } EXPORT_SYMBOL(ttm_resource_compat); +void ttm_resource_set_bo(struct ttm_resource *res, +struct ttm_buffer_object *bo) +{ + spin_lock(&bo->bdev->lru_lock); + res->bo = bo; + spin_unlock(&bo->bdev->lru_lock); +} + /** * ttm_resource_manager_init * diff --git a/include/drm/ttm/ttm_resource.h b/include/drm/ttm/ttm_resource.h index 6bf37383002b..69eea9d6399b 100644 --- a/include/drm/ttm/ttm_resource.h +++ b/include/drm/ttm/ttm_resource.h @@ -161,6 +161,7 @@ struct ttm_bus_placement { * @mem_type: Resource type of the allocation. * @placement: Placement flags. * @bus: Placement on io bus accessible to the CPU + * @bo: weak reference to the BO, protected by ttm_device::lru_lock * * Structure indicating the placement and space resources used by a * buffer object. @@ -171,6 +172,7 @@ struct ttm_resource { uint32_t mem_type; uint32_t placement; struct ttm_bus_placement bus; + struct ttm_buffer_object *bo; }; /** @@ -271,6 +273,8 @@ int ttm_resource_alloc(struct ttm_buffer_object *bo, void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource **res); bool ttm_resource_compat(struct ttm_resource *res, struct ttm_placement *placement); +void ttm_resource_set_bo(struct ttm_resource *res, +struct ttm_buffer_object *bo); void ttm_resource_manager_init(struct ttm_resource_manager *man, struct ttm_device *bdev, -- 2.25.1
[PATCH 10/12] drm/amdgpu: remove GTT accounting
This is provided by TTM now. Also switch man->size to bytes instead of pages and fix the double printing of size and usage in debugfs. Signed-off-by: Christian König --- drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c | 50 + drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 5 +-- drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h | 2 - 3 files changed, 12 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index 9e7685a4878c..ce5eeb3c1097 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -60,7 +60,7 @@ static ssize_t amdgpu_mem_info_gtt_total_show(struct device *dev, struct ttm_resource_manager *man; man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT); - return sysfs_emit(buf, "%llu\n", man->size * PAGE_SIZE); + return sysfs_emit(buf, "%llu\n", man->size); } /** @@ -80,7 +80,7 @@ static ssize_t amdgpu_mem_info_gtt_used_show(struct device *dev, struct ttm_resource_manager *man; man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT); - return sysfs_emit(buf, "%llu\n", amdgpu_gtt_mgr_usage(man)); + return sysfs_emit(buf, "%llu\n", ttm_resource_manager_usage(man)); } static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO, @@ -132,20 +132,17 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, struct amdgpu_gtt_node *node; int r; - if (!(place->flags & TTM_PL_FLAG_TEMPORARY) && - atomic64_add_return(num_pages, &mgr->used) > man->size) { - atomic64_sub(num_pages, &mgr->used); - return -ENOSPC; - } - node = kzalloc(struct_size(node, base.mm_nodes, 1), GFP_KERNEL); - if (!node) { - r = -ENOMEM; - goto err_out; - } + if (!node) + return -ENOMEM; node->tbo = tbo; ttm_resource_init(tbo, place, &node->base.base); + if (!(place->flags & TTM_PL_FLAG_TEMPORARY) && + ttm_resource_manager_usage(man) > man->size) { + r = -ENOSPC; + goto err_free; + } if (place->lpfn) { spin_lock(&mgr->lock); @@ -171,11 +168,6 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, err_free: ttm_resource_fini(man, &node->base.base); kfree(node); - -err_out: - if (!(place->flags & TTM_PL_FLAG_TEMPORARY)) - atomic64_sub(num_pages, &mgr->used); - return r; } @@ -198,27 +190,10 @@ static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man, drm_mm_remove_node(&node->base.mm_nodes[0]); spin_unlock(&mgr->lock); - if (!(res->placement & TTM_PL_FLAG_TEMPORARY)) - atomic64_sub(res->num_pages, &mgr->used); - ttm_resource_fini(man, res); kfree(node); } -/** - * amdgpu_gtt_mgr_usage - return usage of GTT domain - * - * @man: TTM memory type manager - * - * Return how many bytes are used in the GTT domain - */ -uint64_t amdgpu_gtt_mgr_usage(struct ttm_resource_manager *man) -{ - struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man); - - return atomic64_read(&mgr->used) * PAGE_SIZE; -} - /** * amdgpu_gtt_mgr_recover - re-init gart * @@ -265,9 +240,6 @@ static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man, spin_lock(&mgr->lock); drm_mm_print(&mgr->mm, printer); spin_unlock(&mgr->lock); - - drm_printf(printer, "man size:%llu pages, gtt used:%llu pages\n", - man->size, atomic64_read(&mgr->used)); } static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = { @@ -293,14 +265,12 @@ int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size) man->use_tt = true; man->func = &amdgpu_gtt_mgr_func; - ttm_resource_manager_init(man, &adev->mman.bdev, - gtt_size >> PAGE_SHIFT); + ttm_resource_manager_init(man, &adev->mman.bdev, gtt_size); start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS; size = (adev->gmc.gart_size >> PAGE_SHIFT) - start; drm_mm_init(&mgr->mm, start, size); spin_lock_init(&mgr->lock); - atomic64_set(&mgr->used, 0); ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager); ttm_resource_manager_set_used(man, true); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 651c7abfde03..8d5d56d9d26d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -678,7 +678,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) ui64 = amdgpu_vram_mgr_vis_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM)); return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0; case AMD