[drm-intel:for-linux-next-gt 1/4] drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c:2680 guc_context_policy_init_v70() warn: variable dereferenced before check 'ce' (see line 2663)
tree: git://anongit.freedesktop.org/drm-intel for-linux-next-gt head: 7ad6a8fae597af7fae5193efc73276609337c360 commit: cec82816d0d018f178b9b7f88fe4bf80d66954e9 [1/4] drm/i915/guc: Use context hints for GT frequency config: i386-randconfig-141-20240309 (https://download.01.org/0day-ci/archive/20240310/202403101225.7ahejhzj-...@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Reported-by: Dan Carpenter | Closes: https://lore.kernel.org/r/202403101225.7ahejhzj-...@intel.com/ New smatch warnings: drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c:2680 guc_context_policy_init_v70() warn: variable dereferenced before check 'ce' (see line 2663) vim +/ce +2680 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c 774ce1510e6ccb Daniele Ceraolo Spurio 2022-07-18 2661 static int guc_context_policy_init_v70(struct intel_context *ce, bool loop) 2584b3549f4c40 John Harrison 2022-04-12 2662 { 2584b3549f4c40 John Harrison 2022-04-12 @2663 struct intel_engine_cs *engine = ce->engine; ^^ Unchecked dereference 3f2f20da79b208 Andi Shyti 2023-12-29 2664 struct intel_guc *guc = gt_to_guc(engine->gt); 2584b3549f4c40 John Harrison 2022-04-12 2665 struct context_policy policy; 2584b3549f4c40 John Harrison 2022-04-12 2666 u32 execution_quantum; 2584b3549f4c40 John Harrison 2022-04-12 2667 u32 preemption_timeout; cec82816d0d018 Vinay Belgaumkar 2024-03-05 2668 u32 slpc_ctx_freq_req = 0; 2584b3549f4c40 John Harrison 2022-04-12 2669 unsigned long flags; 2584b3549f4c40 John Harrison 2022-04-12 2670 int ret; 3a4bfa091c46e9 Rahul Kumar Singh 2021-07-26 2671 7935785240508c John Harrison 2021-07-26 2672 /* NB: For both of these, zero means disabled. */ 568944af44e753 John Harrison 2022-10-06 2673 GEM_BUG_ON(overflows_type(engine->props.timeslice_duration_ms * 1000, 568944af44e753 John Harrison 2022-10-06 2674 execution_quantum)); 568944af44e753 John Harrison 2022-10-06 2675 GEM_BUG_ON(overflows_type(engine->props.preempt_timeout_ms * 1000, 568944af44e753 John Harrison 2022-10-06 2676 preemption_timeout)); 2584b3549f4c40 John Harrison 2022-04-12 2677 execution_quantum = engine->props.timeslice_duration_ms * 1000; 2584b3549f4c40 John Harrison 2022-04-12 2678 preemption_timeout = engine->props.preempt_timeout_ms * 1000; 2584b3549f4c40 John Harrison 2022-04-12 2679 cec82816d0d018 Vinay Belgaumkar 2024-03-05 @2680 if (ce && (ce->flags & BIT(CONTEXT_LOW_LATENCY))) ^^ NULL check is too late. cec82816d0d018 Vinay Belgaumkar 2024-03-05 2681 slpc_ctx_freq_req |= SLPC_CTX_FREQ_REQ_IS_COMPUTE; cec82816d0d018 Vinay Belgaumkar 2024-03-05 2682 2584b3549f4c40 John Harrison 2022-04-12 2683 __guc_context_policy_start_klv(, ce->guc_id.id); 2584b3549f4c40 John Harrison 2022-04-12 2684 2584b3549f4c40 John Harrison 2022-04-12 2685 __guc_context_policy_add_priority(, ce->guc_state.prio); 2584b3549f4c40 John Harrison 2022-04-12 2686 __guc_context_policy_add_execution_quantum(, execution_quantum); 2584b3549f4c40 John Harrison 2022-04-12 2687 __guc_context_policy_add_preemption_timeout(, preemption_timeout); cec82816d0d018 Vinay Belgaumkar 2024-03-05 2688 __guc_context_policy_add_slpc_ctx_freq_req(, slpc_ctx_freq_req); 2584b3549f4c40 John Harrison 2022-04-12 2689 2584b3549f4c40 John Harrison 2022-04-12 2690 if (engine->flags & I915_ENGINE_WANT_FORCED_PREEMPTION) 2584b3549f4c40 John Harrison 2022-04-12 2691 __guc_context_policy_add_preempt_to_idle(, 1); 2584b3549f4c40 John Harrison 2022-04-12 2692 2584b3549f4c40 John Harrison 2022-04-12 2693 ret = __guc_context_set_context_policies(guc, , loop); 2584b3549f4c40 John Harrison 2022-04-12 2694 2584b3549f4c40 John Harrison 2022-04-12 2695 spin_lock_irqsave(>guc_state.lock, flags); 6c82c75230b87d Daniele Ceraolo Spurio 2022-07-27 2696 if (ret != 0) 2584b3549f4c40 John Harrison 2022-04-12 2697 set_context_policy_required(ce); 2584b3549f4c40 John Harrison 2022-04-12 2698 else 2584b
Re: [RFC PATCH 0/5] Add support for suppressing warning backtraces
On Tue, Mar 05, 2024 at 10:40:28AM -0800, Guenter Roeck wrote: > Some unit tests intentionally trigger warning backtraces by passing bad > parameters to kernel API functions. Such unit tests typically check the > return value from such calls, not the existence of the warning backtrace. > > Such intentionally generated warning backtraces are neither desirable > nor useful for a number of reasons. > - They can result in overlooked real problems. > - A warning that suddenly starts to show up in unit tests needs to be > investigated and has to be marked to be ignored, for example by > adjusting filter scripts. Such filters are ad-hoc because there is > no real standard format for warnings. On top of that, such filter > scripts would require constant maintenance. > > One option to address problem would be to add messages such as "expected > warning backtraces start / end here" to the kernel log. However, that > would again require filter scripts, it might result in missing real > problematic warning backtraces triggered while the test is running, and > the irrelevant backtrace(s) would still clog the kernel log. > > Solve the problem by providing a means to identify and suppress specific > warning backtraces while executing test code. Support suppressing multiple > backtraces while at the same time limiting changes to generic code to the > absolute minimum. Architecture specific changes are kept at minimum by > retaining function names only if both CONFIG_DEBUG_BUGVERBOSE and > CONFIG_KUNIT are enabled. > > The first patch of the series introduces the necessary infrastructure. > The second patch marks the warning message in drm_calc_scale() in the DRM > subsystem as intentional where warranted. This patch is intended to serve > as an example for the use of the functionality introduced with this series. > The last three patches in the series introduce the necessary architecture > specific changes for x86, arm64, and loongarch. > > This series is based on the RFC patch and subsequent discussion at > https://patchwork.kernel.org/project/linux-kselftest/patch/02546e59-1afe-4b08-ba81-d94f3b691c9a@moroto.mountain/ > and offers a more comprehensive solution of the problem discussed there. > > Checkpatch note: > Remaining checkpatch errors and warnings were deliberately ignored. > Some are triggered by matching coding style or by comments interpreted > as code, others by assembler macros which are disliked by checkpatch. > Suggestions for improvements are welcome. > > Some questions: > > - Is the general approach promising ? If not, are there other possible > solutions ? > - Function pointers are only added to the __bug_table section if both > CONFIG_KUNIT and CONFIG_DEBUG_BUGVERBOSE are enabled. This avoids image > size increases if CONFIG_KUNIT=n. Downside is slightly more complex > architecture specific assembler code. If function pointers were always > added to the __bug_table section, vmlinux image size would increase by > approximately 0.6-0.7%. Is the increased complexity in assembler code > worth the reduced image size ? I think so, but I would like to hear > other opinions. > - There are additional possibilities associated with storing the bug > function name in the __bug_table section. It could be independent of > KUNIT, it could be a configuration flag, and/or it could be used to > display the name of the offending function in BUG/WARN messages. > Is any of those of interest ? > I am ready to send a full version of this series with support for all affected architectures. I am undecided if I should send it now, based on v6.8, and send v2 after rebasing it to v6.9-rc1, or if I should just wait for v6.9-rc1. I understand that some maintainers dislike getting new patch series while the commit window is is open. On the ther side, I tested the series thoroughly on top of v6.8-rc7, and initial v6.9 release candidates may have their own problems. Given that, I tend to send the series now. Any thoughts ? Unless there is strong negative feedback, I'll likely do that in a day or two. Thanks, Guenter
Re: [RFC PATCH net-next v6 01/15] queue_api: define queue api
On 3/8/24 4:47 PM, David Wei wrote: > > I'm working to port bnxt over to using this API. What are your thoughts > on maybe pulling this out and use bnxt to drive it? > I would love to see a second nic implementation; this patch set and overall design is driven by GVE limitations.
Re: [PATCH] drm/sun4i: tcon: Support keeping dclk rate upon ancestor clock changes
Hello Frank, On Sun, Mar 10, 2024 at 02:32:29PM +0100, Frank Oltmanns wrote: > +static int sun4i_rate_reset_notifier_cb(struct notifier_block *nb, > + unsigned long event, void *data) > +{ > + struct sun4i_rate_reset_nb *rate_reset = to_sun4i_rate_reset_nb(nb); > + > + if (event == POST_RATE_CHANGE) > + schedule_delayed_work(_reset->reset_rate_work, > msecs_to_jiffies(100)); If you get multiple reset notifier calls within 100ms of the first one, the delay from the last one will not be 100ms, so this may violate expectations you're describing in the commit message. schedule_delayed_work doesn't re-schedule the work if it's already pending. Kind regards, o.
[drm-misc:drm-misc-next 1/1] drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c:843:6: error: variable 'out' set but not used
tree: git://anongit.freedesktop.org/drm/drm-misc drm-misc-next head: b219865715e419435ad49dc2300fe3f85c79d3f6 commit: d6eb77731c45caf6ee7b18d907e9bc44be760e8c [1/1] Merge drm/drm-next into drm-misc-next config: x86_64-allyesconfig (https://download.01.org/0day-ci/archive/20240311/202403110614.law3uing-...@intel.com/config) compiler: clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240311/202403110614.law3uing-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202403110614.law3uing-...@intel.com/ All errors (new ones prefixed by >>): >> drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c:843:6: error: variable 'out' set >> but not used [-Werror,-Wunused-but-set-variable] 843 | u64 out = dumper->iova + A6XX_CD_DATA_OFFSET; | ^ 1 error generated. vim +/out +843 drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c 64d6255650d4e0 Connor Abbott 2024-01-25 834 1707add815519d Jordan Crouse 2018-11-02 835 /* Read a shader / debug block from the HLSQ aperture with the crashdumper */ 1707add815519d Jordan Crouse 2018-11-02 836 static void a6xx_get_shader_block(struct msm_gpu *gpu, d6852b4b2d0140 Jordan Crouse 2018-11-02 837struct a6xx_gpu_state *a6xx_state, 1707add815519d Jordan Crouse 2018-11-02 838const struct a6xx_shader_block *block, 1707add815519d Jordan Crouse 2018-11-02 839struct a6xx_gpu_state_obj *obj, 1707add815519d Jordan Crouse 2018-11-02 840struct a6xx_crashdumper *dumper) 1707add815519d Jordan Crouse 2018-11-02 841 { 1707add815519d Jordan Crouse 2018-11-02 842u64 *in = dumper->ptr; 64d6255650d4e0 Connor Abbott 2024-01-25 @843u64 out = dumper->iova + A6XX_CD_DATA_OFFSET; 1707add815519d Jordan Crouse 2018-11-02 844size_t datasize = block->size * A6XX_NUM_SHADER_BANKS * sizeof(u32); 1707add815519d Jordan Crouse 2018-11-02 845int i; 1707add815519d Jordan Crouse 2018-11-02 846 1707add815519d Jordan Crouse 2018-11-02 847if (WARN_ON(datasize > A6XX_CD_DATA_SIZE)) 1707add815519d Jordan Crouse 2018-11-02 848return; 1707add815519d Jordan Crouse 2018-11-02 849 1707add815519d Jordan Crouse 2018-11-02 850for (i = 0; i < A6XX_NUM_SHADER_BANKS; i++) { 1707add815519d Jordan Crouse 2018-11-02 851in += CRASHDUMP_WRITE(in, REG_A6XX_HLSQ_DBG_READ_SEL, 1707add815519d Jordan Crouse 2018-11-02 852(block->type << 8) | i); 1707add815519d Jordan Crouse 2018-11-02 853 1707add815519d Jordan Crouse 2018-11-02 854in += CRASHDUMP_READ(in, REG_A6XX_HLSQ_DBG_AHB_READ_APERTURE, 1707add815519d Jordan Crouse 2018-11-02 855block->size, dumper->iova + A6XX_CD_DATA_OFFSET); 64d6255650d4e0 Connor Abbott 2024-01-25 856 64d6255650d4e0 Connor Abbott 2024-01-25 857out += block->size * sizeof(u32); 1707add815519d Jordan Crouse 2018-11-02 858} 1707add815519d Jordan Crouse 2018-11-02 859 1707add815519d Jordan Crouse 2018-11-02 860CRASHDUMP_FINI(in); 1707add815519d Jordan Crouse 2018-11-02 861 1707add815519d Jordan Crouse 2018-11-02 862if (a6xx_crashdumper_run(gpu, dumper)) 1707add815519d Jordan Crouse 2018-11-02 863return; 1707add815519d Jordan Crouse 2018-11-02 864 1707add815519d Jordan Crouse 2018-11-02 865obj->handle = block; d6852b4b2d0140 Jordan Crouse 2018-11-02 866obj->data = state_kmemdup(a6xx_state, dumper->ptr + A6XX_CD_DATA_OFFSET, d6852b4b2d0140 Jordan Crouse 2018-11-02 867datasize); 1707add815519d Jordan Crouse 2018-11-02 868 } 1707add815519d Jordan Crouse 2018-11-02 869 :: The code at line 843 was first introduced by commit :: 64d6255650d4e0ff816cd303a43685f65c5a0dbb drm/msm: More fully implement devcoredump for a7xx :: TO: Connor Abbott :: CC: Rob Clark -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
[PATCH RESEND] drm: panel-orientation-quirks: Add quirk for Aya Neo KUN
From: Tobias Jakobi Similar to the other Aya Neo devices this one features again a portrait screen, here with a native resolution of 1600x2560. Signed-off-by: Tobias Jakobi --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index 3d92f66e550c..5d3fb11fd45f 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -196,6 +196,12 @@ static const struct dmi_system_id orientation_data[] = { DMI_MATCH(DMI_BOARD_NAME, "NEXT"), }, .driver_data = (void *)_rightside_up, + }, {/* AYA NEO KUN */ + .matches = { + DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AYANEO"), + DMI_MATCH(DMI_BOARD_NAME, "KUN"), + }, + .driver_data = (void *)_rightside_up, }, {/* Chuwi HiBook (CWI514) */ .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), -- 2.43.0
[PATCH] drm: Don't return unsupported formats in drm_mode_legacy_fb_format
This patch changes drm_mode_legacy_fb_format() to only return formats which are supported by the current drm-device. The motivation for this change is to fix a regression introduced by commit c91acda3a380 ("drm/gem: Check for valid formats") which stops the Xorg modesetting driver from working on the Beagleboard Black (it uses the tilcdc kernel driver). When the Xorg modesetting driver starts up, it tries to determine the default bpp for the device. It does this by allocating a dumb 32bpp frame buffer (using DRM_IOCTL_MODE_CREATE_DUMB) and then calling drmModeAddFB() with that frame buffer asking for a 24-bit depth and 32 bpp. As the modesetting driver uses drmModeAddFB() which doesn't supply a format, the kernel's drm_mode_legacy_fb_format() is called to provide a format matching the requested depth and bpp. If the drmModeAddFB() call fails, it forces both depth and bpp to 24. If drmModeAddFB() succeeds, depth is assumed to be 24 and bpp 32. The dummy frame buffer is then removed (using drmModeRmFB()). If the modesetting driver finds that both the default bpp and depth are 24, it forces the use of a 32bpp shadow buffer and a 24bpp front buffer. Following this, the driver reads the user-specified color depth option and tries to create a framebuffer of that depth, but if the use of a shadow buffer has been forced, the bpp and depth of it overrides the user-supplied option. The Xorg modesetting driver on top of the tilcdc kernel driver used to work on the Beagleboard Black if a 16 bit color depth was configured. The hardware in the Beagleboard Black supports the RG16, BG24, and XB24 formats. When drm_mode_legacy_fb_format() was called to request a format for a 24-bit depth and 32 bpp, it would return the unsupported RG24 format which drmModeAddFB() would happily accept (as there was no check for a valid format). As a shadow buffer wasn't forced, the modesetting driver would try the user specified 16 bit color depth and drm_mode_legacy_fb_format() would return RG16 which is supported by the hardware. Color depths of 24 bits were not supported, as the unsupported RG24 would be detected when drmModeSetCrtc() was called. Following commit c91acda3a380 ("drm/gem: Check for valid formats"), which adds a check for a valid (supported by the hardware) format to the code path for the kernel part of drmModeAddFB(), the modesetting driver fails to configure and add a frame buffer. This is because the call to create a 24-bit depth and 32 bpp framebuffer during detection of the default bpp will now fail and a 24-bit depth and 24 bpp front buffer will be forced. As drm_mode_legacy_fb_format() will return RG24 which isn't supported, the creation of that framebuffer will also fail. To fix the regression, this patch extends drm_mode_legacy_fb_format() to list all formats with a particular bpp and color depth known to the kernel, and have it probe the current drm-device for a supported format. This fixes the regression and, as a bonus, a color depth of 24 bits on the Beagleboard Black is now working. As this patch changes drm_mode_legacy_fb_format() which is used by other drivers, it has, in addition to the Beagleboard Black, also been tested with the nouveau and modesetting drivers on a NVIDIA NV96, and with the intel and modesetting drivers on an intel HD Graphics 4000 chipset. Signed-off-by: Frej Drejhammar Fixes: c91acda3a380 ("drm/gem: Check for valid formats") Cc: sta...@vger.kernel.org Cc: Russell King Cc: David Airlie Cc: Daniel Vetter Cc: Maarten Lankhorst Cc: Maxime Ripard Cc: Thomas Zimmermann Cc: Krzysztof Kozlowski Cc: Patrik Jakobsson Cc: Rob Clark Cc: Abhinav Kumar Cc: Dmitry Baryshkov Cc: Tomi Valkeinen Cc: Javier Martinez Canillas Cc: "Maíra Canal" Cc: "Ville Syrjälä" Cc: dri-devel@lists.freedesktop.org --- drivers/gpu/drm/armada/armada_fbdev.c | 2 +- drivers/gpu/drm/drm_fb_helper.c | 2 +- drivers/gpu/drm/drm_fbdev_dma.c | 3 +- drivers/gpu/drm/drm_fbdev_generic.c | 3 +- drivers/gpu/drm/drm_fourcc.c | 91 --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 +- drivers/gpu/drm/gma500/fbdev.c| 2 +- drivers/gpu/drm/i915/display/intel_fbdev_fb.c | 3 +- drivers/gpu/drm/msm/msm_fbdev.c | 3 +- drivers/gpu/drm/omapdrm/omap_fbdev.c | 2 +- drivers/gpu/drm/radeon/radeon_fbdev.c | 3 +- drivers/gpu/drm/tegra/fbdev.c | 3 +- drivers/gpu/drm/tiny/ofdrm.c | 6 +- drivers/gpu/drm/xe/display/intel_fbdev_fb.c | 3 +- include/drm/drm_fourcc.h | 3 +- 15 files changed, 104 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/armada/armada_fbdev.c b/drivers/gpu/drm/armada/armada_fbdev.c index d223176912b6..82f312f76980 100644 --- a/drivers/gpu/drm/armada/armada_fbdev.c +++ b/drivers/gpu/drm/armada/armada_fbdev.c @@ -54,7 +54,7 @@ static int armada_fbdev_create(struct drm_fb_helper *fbh,
[PATCH v4 2/2] backlight: Add new lm3509 backlight driver
This is a general driver for LM3509 backlight chip of TI. LM3509 is High Efficiency Boost for White LEDs and/or OLED Displays with Dual Current Sinks. This driver supports OLED/White LED select, brightness control and sub/main control. The datasheet can be found at http://www.ti.com/product/lm3509. Signed-off-by: Patrick Gansterer --- drivers/video/backlight/Kconfig | 7 + drivers/video/backlight/Makefile| 1 + drivers/video/backlight/lm3509_bl.c | 338 3 files changed, 346 insertions(+) create mode 100644 drivers/video/backlight/lm3509_bl.c diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index ea2d0d69bd8c..96ad5dc584b6 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -366,6 +366,13 @@ config BACKLIGHT_AAT2870 If you have a AnalogicTech AAT2870 say Y to enable the backlight driver. +config BACKLIGHT_LM3509 + tristate "Backlight Driver for LM3509" + depends on I2C + select REGMAP_I2C + help + This supports TI LM3509 Backlight Driver + config BACKLIGHT_LM3630A tristate "Backlight Driver for LM3630A" depends on I2C && PWM diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 06966cb20459..51a4ac5d0530 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO) += ipaq_micro_bl.o obj-$(CONFIG_BACKLIGHT_KTD253) += ktd253-backlight.o obj-$(CONFIG_BACKLIGHT_KTZ8866)+= ktz8866.o +obj-$(CONFIG_BACKLIGHT_LM3509) += lm3509_bl.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o obj-$(CONFIG_BACKLIGHT_LM3630A)+= lm3630a_bl.o obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o diff --git a/drivers/video/backlight/lm3509_bl.c b/drivers/video/backlight/lm3509_bl.c new file mode 100644 index ..696ec8aab6aa --- /dev/null +++ b/drivers/video/backlight/lm3509_bl.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#include +#include +#include +#include +#include +#include + +#define LM3509_NAME "lm3509_bl" + +#define LM3509_SINK_MAIN 0 +#define LM3509_SINK_SUB 1 +#define LM3509_NUM_SINKS 2 + +#define LM3509_DEF_BRIGHTNESS 0x12 +#define LM3509_MAX_BRIGHTNESS 0x1F + +#define REG_GP 0x10 +#define REG_BMAIN 0xA0 +#define REG_BSUB 0xB0 +#define REG_MAX 0xFF + +enum { + REG_GP_ENM_BIT = 0, + REG_GP_ENS_BIT, + REG_GP_UNI_BIT, + REG_GP_RMP0_BIT, + REG_GP_RMP1_BIT, + REG_GP_OLED_BIT, +}; + +struct lm3509_bl { + struct regmap *regmap; + struct backlight_device *bl_main; + struct backlight_device *bl_sub; + struct gpio_desc *reset_gpio; +}; + +struct lm3509_bl_led_pdata { + const char *label; + int led_sources; + u32 brightness; + u32 max_brightness; +}; + +static void lm3509_reset(struct lm3509_bl *data) +{ + if (data->reset_gpio) { + gpiod_set_value(data->reset_gpio, 1); + udelay(1); + gpiod_set_value(data->reset_gpio, 0); + udelay(10); + } +} + +static int lm3509_update_status(struct backlight_device *bl, + unsigned int en_mask, unsigned int br_reg) +{ + struct lm3509_bl *data = bl_get_data(bl); + int ret; + bool en; + + ret = regmap_write(data->regmap, br_reg, backlight_get_brightness(bl)); + if (ret < 0) + return ret; + + en = !backlight_is_blank(bl); + return regmap_update_bits(data->regmap, REG_GP, en_mask, + en ? en_mask : 0); +} + +static int lm3509_main_update_status(struct backlight_device *bl) +{ + return lm3509_update_status(bl, BIT(REG_GP_ENM_BIT), REG_BMAIN); +} + +static const struct backlight_ops lm3509_main_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = lm3509_main_update_status, +}; + +static int lm3509_sub_update_status(struct backlight_device *bl) +{ + return lm3509_update_status(bl, BIT(REG_GP_ENS_BIT), REG_BSUB); +} + +static const struct backlight_ops lm3509_sub_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = lm3509_sub_update_status, +}; + +static struct backlight_device * +lm3509_backlight_register(struct device *dev, const char *name_suffix, + struct lm3509_bl *data, + const struct backlight_ops *ops, + const struct lm3509_bl_led_pdata *pdata) + +{ + struct backlight_device *bd; + struct backlight_properties props; + const char *label = pdata->label; + char name[64]; + + memset(, 0, sizeof(props)); + props.type = BACKLIGHT_RAW; + props.brightness = pdata->brightness; + props.max_brightness = pdata->max_brightness; + +
[PATCH v4 1/2] dt-bindings: backlight: Add Texas Instruments LM3509
Add Device Tree bindings for Texas Instruments LM3509 - a High Efficiency Boost for White LED's and/or OLED Displays Signed-off-by: Patrick Gansterer Reviewed-by: Krzysztof Kozlowski --- Changes in v4: Use backlight_*() to access backlight_device Do not set backlight_properties.power v3: https://lore.kernel.org/all/20240309132521.1290173-1-par...@paroga.com/ Changes in v3: Improved device tree bindings documentation v2: https://lore.kernel.org/all/20240308215617.1729664-1-par...@paroga.com/ Changes in v2: Add device tree nodes for each output Addressed multiple smaller review comments v1: https://lore.kernel.org/all/20240302212757.1871164-1-par...@paroga.com/ .../bindings/leds/backlight/ti,lm3509.yaml| 139 ++ 1 file changed, 139 insertions(+) create mode 100644 Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml diff --git a/Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml b/Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml new file mode 100644 index ..b67f67648852 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/backlight/ti,lm3509.yaml @@ -0,0 +1,139 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/backlight/ti,lm3509.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI LM3509 High Efficiency Boost for White LED's and/or OLED Displays + +maintainers: + - Patrick Gansterer + +description: + The LM3509 current mode boost converter offers two separate outputs. + https://www.ti.com/product/LM3509 + +properties: + compatible: +const: ti,lm3509 + + reg: +maxItems: 1 + + "#address-cells": +const: 1 + + "#size-cells": +const: 0 + + reset-gpios: +maxItems: 1 + + ti,brightness-rate-of-change-us: +description: Brightness Rate of Change in microseconds. +enum: [51, 13000, 26000, 52000] + + ti,oled-mode: +description: Enable OLED mode. +type: boolean + +patternProperties: + "^led@[01]$": +type: object +description: Properties for a string of connected LEDs. + +allOf: + - $ref: common.yaml# + +properties: + reg: +description: + The control register that is used to program the two current sinks. + The LM3509 has two registers (BMAIN and BSUB) and are represented + as 0 or 1 in this property. The two current sinks can be controlled + independently with both registers, or register BMAIN can be + configured to control both sinks with the led-sources property. +minimum: 0 +maximum: 1 + + label: true + + led-sources: +allOf: + - minItems: 1 +maxItems: 2 +items: + minimum: 0 + maximum: 1 + + default-brightness: +minimum: 0 +maximum: 31 +default: 18 + + max-brightness: +minimum: 0 +maximum: 31 +default: 31 + +required: + - reg + +additionalProperties: false + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | +#include +i2c { +#address-cells = <1>; +#size-cells = <0>; + +backlight@36 { +compatible = "ti,lm3509"; +reg = <0x36>; +reset-gpios = < 5 GPIO_ACTIVE_LOW>; + +ti,oled-mode; +ti,brightness-rate-of-change-us = <52000>; + +#address-cells = <1>; +#size-cells = <0>; + +led@0 { +reg = <0>; +led-sources = <0 1>; +label = "lcd-backlight"; +default-brightness = <12>; +max-brightness = <31>; +}; +}; +}; + - | +i2c { +#address-cells = <1>; +#size-cells = <0>; + +backlight@36 { +compatible = "ti,lm3509"; +reg = <0x36>; + +#address-cells = <1>; +#size-cells = <0>; + +led@0 { +reg = <0>; +default-brightness = <12>; +}; + +led@1 { +reg = <1>; +default-brightness = <15>; +}; +}; +}; -- 2.44.0
[PATCH] drm/sun4i: tcon: Support keeping dclk rate upon ancestor clock changes
Allow the dclk to reset its rate when a rate change is initiated from an ancestor clock. This makes it possible to no longer to get an exclusive lock. As a consequence, it is now possible to set new rates if necessary, e.g. when an external display is connected. The first user of this functionality is the A64 because PLL-VIDEO0 is an ancestor for both HDMI and TCON0. This allows to select an optimal rate for TCON0 as long as there is no external HDMI connection. Once a change in PLL-VIDEO0 is performed when an HDMI connection is established, TCON0 can react gracefully and select an optimal rate based on this the new constraint. Signed-off-by: Frank Oltmanns --- I would like to make the Allwinner A64's data-clock keep its rate when its ancestor's (pll-video0) rate changes. Keeping data-clock's rate is required, to let the A64 drive both an LCD and HDMI display at the same time, because both have pll-video0 as an ancestor. TCONs that use this flag store the ideal rate for their data-clock and subscribe to be notified when data-clock changes. When rate setting has finished (indicated by a POST_RATE_CHANGE event) the call back function schedules delayed work to set the data-clock's rate to the initial value after 100 ms. Using delayed work maks sure that the clock setting is finished. I've implemented this functionality as a quirk, so that it is possible to use it only for the A64. This patch supersedes [1]. This work is inspired by an out-of-tree patchset [2] [3] [4]. Unfortunately, the patchset uses clk_set_rate() directly in a notifier callback, which the following comment on clk_notifier_register() forbids: "The callbacks associated with the notifier must not re-enter into the clk framework by calling any top-level clk APIs." [5] Furthermore, that out-of-tree patchset no longer works since 6.6, because setting pll-mipi is now also resetting pll-video0 and therefore causes a race condition. Thank you for considering this contribution, Frank [1] https://lore.kernel.org/lkml/20230825-pll-mipi_keep_rate-v1-0-35bc43570...@oltmanns.dev/ [2] https://codeberg.org/megi/linux/commit/a37cda2fff41a67a2bacf82b1594e10335d0bd8a [3] https://codeberg.org/megi/linux/commit/24dc09128d2c8efc6ddf19249420e9798e967a46 [4] https://codeberg.org/megi/linux/commit/728a93d46f99f0eb231ed6fa8971a45f97c7182c [5] https://elixir.bootlin.com/linux/v6.7.9/source/drivers/clk/clk.c#L4669 --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 70 ++ drivers/gpu/drm/sun4i/sun4i_tcon.h | 12 +++ 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index a1a2c845ade0..b880bd44049a 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -108,9 +108,11 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel, if (enabled) { clk_prepare_enable(clk); - clk_rate_exclusive_get(clk); + if (!tcon->quirks->restores_rate) + clk_rate_exclusive_get(clk); } else { - clk_rate_exclusive_put(clk); + if (!tcon->quirks->restores_rate) + clk_rate_exclusive_put(clk); clk_disable_unprepare(clk); } } @@ -343,6 +345,53 @@ static void sun4i_tcon0_mode_set_dithering(struct sun4i_tcon *tcon, regmap_write(tcon->regs, SUN4I_TCON_FRM_CTL_REG, val); } +static void sun4i_rate_reset_notifier_delayed_update(struct work_struct *work) +{ + struct sun4i_rate_reset_nb *rate_reset = container_of(work, struct sun4i_rate_reset_nb, + reset_rate_work.work); + + clk_set_rate(rate_reset->target_clk, rate_reset->saved_rate); +} + +static int sun4i_rate_reset_notifier_cb(struct notifier_block *nb, + unsigned long event, void *data) +{ + struct sun4i_rate_reset_nb *rate_reset = to_sun4i_rate_reset_nb(nb); + + if (event == POST_RATE_CHANGE) + schedule_delayed_work(_reset->reset_rate_work, msecs_to_jiffies(100)); + + return NOTIFY_DONE; +} + +static void sun4i_rate_reset_notifier_register(struct sun4i_rate_reset_nb *rate_reset_nb) +{ + if (rate_reset_nb->is_registered) + return; + + rate_reset_nb->clk_nb.notifier_call = sun4i_rate_reset_notifier_cb; + + INIT_DELAYED_WORK(_reset_nb->reset_rate_work, + sun4i_rate_reset_notifier_delayed_update); + + if (!clk_notifier_register(rate_reset_nb->target_clk, + _reset_nb->clk_nb)) + rate_reset_nb->is_registered = true; +} + +static struct sun4i_rate_reset_nb tcon_rate_reset_tcon0_nb; + +static void sun4i_tcon0_set_dclk_rate(struct sun4i_tcon *tcon, unsigned long rate) +{ + clk_set_rate(tcon->dclk, rate); + + if (tcon->quirks->restores_rate) {
[PATCH v4 5/5] arm64: dts: allwinner: a64: Run GPU at 432 MHz
The Allwinner A64's GPU has currently three operating points. However, the BSP runs the GPU fixed at 432 MHz. In addition, at least one of the devices using that SoC - the pinephone - shows unstabilities (see link) that can be circumvented by running the GPU at a fixed rate. Therefore, remove the other two operating points from the GPU OPP table, so that the GPU runs at a fixed rate of 432 MHz. Link: https://gitlab.com/postmarketOS/pmaports/-/issues/805 Acked-by: Erico Nunes Signed-off-by: Frank Oltmanns --- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 8 1 file changed, 8 deletions(-) diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 57ac18738c99..c810380aab6d 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -107,14 +107,6 @@ de: display-engine { gpu_opp_table: opp-table-gpu { compatible = "operating-points-v2"; - opp-12000 { - opp-hz = /bits/ 64 <12000>; - }; - - opp-31200 { - opp-hz = /bits/ 64 <31200>; - }; - opp-43200 { opp-hz = /bits/ 64 <43200>; }; -- 2.44.0
[PATCH v4 4/5] clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate
The Allwinner A64 manual lists the following constraints for the PLL-MIPI clock: - M/N <= 3 - (PLL_VIDEO0)/M >= 24MHz Use these constraints. Reviewed-by: Jernej Skrabec Signed-off-by: Frank Oltmanns --- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 12 +++- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 6a4b2b9ef30a..07796c79a23e 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -171,11 +171,13 @@ static struct ccu_nkm pll_mipi_clk = { * user manual, and by experiments the PLL doesn't work without * these bits toggled. */ - .enable = BIT(31) | BIT(23) | BIT(22), - .lock = BIT(28), - .n = _SUNXI_CCU_MULT(8, 4), - .k = _SUNXI_CCU_MULT_MIN(4, 2, 2), - .m = _SUNXI_CCU_DIV(0, 4), + .enable = BIT(31) | BIT(23) | BIT(22), + .lock = BIT(28), + .n = _SUNXI_CCU_MULT(8, 4), + .k = _SUNXI_CCU_MULT_MIN(4, 2, 2), + .m = _SUNXI_CCU_DIV(0, 4), + .max_m_n_ratio = 3, + .min_parent_m_ratio = 2400, .common = { .reg= 0x040, .hw.init= CLK_HW_INIT("pll-mipi", "pll-video0", -- 2.44.0
[PATCH v4 2/5] clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI
When the Allwinner A64's TCON0 searches the ideal rate for the connected panel, it may happen that it requests a rate from its parent PLL-MIPI which PLL-MIPI does not support. This happens for example on the Olimex TERES-I laptop where TCON0 requests PLL-MIPI to change to a rate of several GHz which causes the panel to stay blank. It also happens on the pinephone where a rate of less than 500 MHz is requested which causes instabilities on some phones. Set the minimum and maximum rate of Allwinner A64's PLL-MIPI according to the Allwinner User Manual. Fixes: ca1170b69968 ("clk: sunxi-ng: a64: force select PLL_MIPI in TCON0 mux") Reported-by: Diego Roversi Closes: https://groups.google.com/g/linux-sunxi/c/Rh-Uqqa66bw Tested-by: Diego Roversi Cc: sta...@vger.kernel.org Reviewed-by: Maxime Ripard Signed-off-by: Frank Oltmanns --- drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c index 8951ffc14ff5..6a4b2b9ef30a 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.c +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.c @@ -182,6 +182,8 @@ static struct ccu_nkm pll_mipi_clk = { _nkm_ops, CLK_SET_RATE_UNGATE | CLK_SET_RATE_PARENT), .features = CCU_FEATURE_CLOSEST_RATE, + .min_rate = 5, + .max_rate = 14, }, }; -- 2.44.0
[PATCH v4 3/5] clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate
The Allwinner A64 manual lists the following constraints for the PLL-MIPI clock: - M/N <= 3 - (PLL_VIDEO0)/M >= 24MHz The PLL-MIPI clock is implemented as ccu_nkm. Therefore, add support for these constraints. Reviewed-by: Jernej Skrabec Signed-off-by: Frank Oltmanns --- drivers/clk/sunxi-ng/ccu_nkm.c | 21 + drivers/clk/sunxi-ng/ccu_nkm.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 853f84398e2b..1168d894d636 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -16,6 +16,20 @@ struct _ccu_nkm { unsigned long m, min_m, max_m; }; +static bool ccu_nkm_is_valid_rate(struct ccu_common *common, unsigned long parent, + unsigned long n, unsigned long m) +{ + struct ccu_nkm *nkm = container_of(common, struct ccu_nkm, common); + + if (nkm->max_m_n_ratio && (m > nkm->max_m_n_ratio * n)) + return false; + + if (nkm->min_parent_m_ratio && (parent < nkm->min_parent_m_ratio * m)) + return false; + + return true; +} + static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common, struct clk_hw *parent_hw, unsigned long *parent, unsigned long rate, @@ -31,6 +45,10 @@ static unsigned long ccu_nkm_find_best_with_parent_adj(struct ccu_common *common unsigned long tmp_rate, tmp_parent; tmp_parent = clk_hw_round_rate(parent_hw, rate * _m / (_n * _k)); + + if (!ccu_nkm_is_valid_rate(common, tmp_parent, _n, _m)) + continue; + tmp_rate = tmp_parent * _n * _k / _m; if (ccu_is_better_rate(common, rate, tmp_rate, best_rate) || @@ -64,6 +82,9 @@ static unsigned long ccu_nkm_find_best(unsigned long parent, unsigned long rate, for (_k = nkm->min_k; _k <= nkm->max_k; _k++) { for (_n = nkm->min_n; _n <= nkm->max_n; _n++) { for (_m = nkm->min_m; _m <= nkm->max_m; _m++) { + if (!ccu_nkm_is_valid_rate(common, parent, _n, _m)) + continue; + unsigned long tmp_rate; tmp_rate = parent * _n * _k / _m; diff --git a/drivers/clk/sunxi-ng/ccu_nkm.h b/drivers/clk/sunxi-ng/ccu_nkm.h index 6601defb3f38..c409212ee40e 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.h +++ b/drivers/clk/sunxi-ng/ccu_nkm.h @@ -27,6 +27,8 @@ struct ccu_nkm { struct ccu_mux_internal mux; unsigned intfixed_post_div; + unsigned long max_m_n_ratio; + unsigned long min_parent_m_ratio; struct ccu_common common; }; -- 2.44.0
[PATCH v4 1/5] clk: sunxi-ng: common: Support minimum and maximum rate
The Allwinner SoC's typically have an upper and lower limit for their clocks' rates. Up until now, support for that has been implemented separately for each clock type. Implement that functionality in the sunxi-ng's common part making use of the CCF rate liming capabilities, so that it is available for all clock types. Suggested-by: Maxime Ripard Signed-off-by: Frank Oltmanns Cc: sta...@vger.kernel.org --- drivers/clk/sunxi-ng/ccu_common.c | 19 +++ drivers/clk/sunxi-ng/ccu_common.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index 8babce55302f..ac0091b4ce24 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -44,6 +44,16 @@ bool ccu_is_better_rate(struct ccu_common *common, unsigned long current_rate, unsigned long best_rate) { + unsigned long min_rate, max_rate; + + clk_hw_get_rate_range(>hw, _rate, _rate); + + if (current_rate > max_rate) + return false; + + if (current_rate < min_rate) + return false; + if (common->features & CCU_FEATURE_CLOSEST_RATE) return abs(current_rate - target_rate) < abs(best_rate - target_rate); @@ -122,6 +132,7 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, for (i = 0; i < desc->hw_clks->num ; i++) { struct clk_hw *hw = desc->hw_clks->hws[i]; + struct ccu_common *common = hw_to_ccu_common(hw); const char *name; if (!hw) @@ -136,6 +147,14 @@ static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev, pr_err("Couldn't register clock %d - %s\n", i, name); goto err_clk_unreg; } + + if (common->max_rate) + clk_hw_set_rate_range(hw, common->min_rate, + common->max_rate); + else + WARN(common->min_rate, +"No max_rate, ignoring min_rate of clock %d - %s\n", +i, name); } ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, diff --git a/drivers/clk/sunxi-ng/ccu_common.h b/drivers/clk/sunxi-ng/ccu_common.h index 942a72c09437..329734f8cf42 100644 --- a/drivers/clk/sunxi-ng/ccu_common.h +++ b/drivers/clk/sunxi-ng/ccu_common.h @@ -31,6 +31,9 @@ struct ccu_common { u16 lock_reg; u32 prediv; + unsigned long min_rate; + unsigned long max_rate; + unsigned long features; spinlock_t *lock; struct clk_hw hw; -- 2.44.0
[PATCH v4 0/5] Pinephone video out fixes (flipping between two frames)
On some pinephones the video output sometimes freezes (flips between two frames) [1]. It seems to be that the reason for this behaviour is that PLL-MIPI is outside its limits, and the GPU is not running at a fixed rate. In this patch series I propose the following changes: 1. sunxi-ng: Adhere to the following constraints given in the Allwinner A64 Manual regarding PLL-MIPI: * M/N <= 3 * (PLL_VIDEO0)/M >= 24MHz * 500MHz <= clockrate <= 1400MHz 2. Remove two operating points from the A64 DTS OPPs, so that the GPU runs at a fixed rate of 432 MHz. Note, that when pinning the GPU to 432 MHz the issue [1] completely disappears for me. I've searched the BSP and could not find any indication that supports the idea of having the three OPPs. The only frequency I found in the BPSs for A64 is 432 MHz, which has also proven stable for me. I very much appreciate your feedback! [1] https://gitlab.com/postmarketOS/pmaports/-/issues/805 Signed-off-by: Frank Oltmanns --- Changes in v4: - sunxi-ng: common: Address review comments. - Link to v3: https://lore.kernel.org/r/20240304-pinephone-pll-fixes-v3-0-94ab828f2...@oltmanns.dev Changes in v3: - dts: Pin GPU to 432 MHz. - nkm and a64: Move minimum and maximum rate handling to the common part of the sunxi-ng driver. - Removed st7703 patch from series. - Link to v2: https://lore.kernel.org/r/20240205-pinephone-pll-fixes-v2-0-96a46a2d8...@oltmanns.dev Changes in v2: - dts: Increase minimum GPU frequency to 192 MHz. - nkm and a64: Add minimum and maximum rate for PLL-MIPI. - nkm: Use the same approach for skipping invalid rates in ccu_nkm_find_best() as in ccu_nkm_find_best_with_parent_adj(). - nkm: Improve names for ratio struct members and hence get rid of describing comments. - nkm and a64: Correct description in the commit messages: M/N <= 3 - Remove patches for nm as they were not needed. - st7703: Rework the commit message to cover more background for the change. - Link to v1: https://lore.kernel.org/r/20231218-pinephone-pll-fixes-v1-0-e238b6ed6...@oltmanns.dev --- Frank Oltmanns (5): clk: sunxi-ng: common: Support minimum and maximum rate clk: sunxi-ng: a64: Set minimum and maximum rate for PLL-MIPI clk: sunxi-ng: nkm: Support constraints on m/n ratio and parent rate clk: sunxi-ng: a64: Add constraints on PLL-MIPI's n/m ratio and parent rate arm64: dts: allwinner: a64: Run GPU at 432 MHz arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 8 drivers/clk/sunxi-ng/ccu-sun50i-a64.c | 14 +- drivers/clk/sunxi-ng/ccu_common.c | 19 +++ drivers/clk/sunxi-ng/ccu_common.h | 3 +++ drivers/clk/sunxi-ng/ccu_nkm.c| 21 + drivers/clk/sunxi-ng/ccu_nkm.h| 2 ++ 6 files changed, 54 insertions(+), 13 deletions(-) --- base-commit: dcb6c8ee6acc6c347caec1e73fb900c0f4ff9806 change-id: 20231218-pinephone-pll-fixes-0ccdfde273e4 Best regards, -- Frank Oltmanns
[PATCH v9 6/6] Documentation: iio: Document high-speed DMABUF based API
Document the new DMABUF based API. Signed-off-by: Paul Cercueil Signed-off-by: Nuno Sa --- v2: - Explicitly state that the new interface is optional and is not implemented by all drivers. - The IOCTLs can now only be called on the buffer FD returned by IIO_BUFFER_GET_FD_IOCTL. - Move the page up a bit in the index since it is core stuff and not driver-specific. v3: Update the documentation to reflect the new API. v5: Use description lists for the documentation of the three new IOCTLs instead of abusing subsections. v8: Renamed dmabuf_api.rst -> iio_dmabuf_api.rst, and updated index.rst whose format changed in iio/togreg. --- Documentation/iio/iio_dmabuf_api.rst | 54 Documentation/iio/index.rst | 1 + 2 files changed, 55 insertions(+) create mode 100644 Documentation/iio/iio_dmabuf_api.rst diff --git a/Documentation/iio/iio_dmabuf_api.rst b/Documentation/iio/iio_dmabuf_api.rst new file mode 100644 index ..1cd6cd51a582 --- /dev/null +++ b/Documentation/iio/iio_dmabuf_api.rst @@ -0,0 +1,54 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=== +High-speed DMABUF interface for IIO +=== + +1. Overview +=== + +The Industrial I/O subsystem supports access to buffers through a +file-based interface, with read() and write() access calls through the +IIO device's dev node. + +It additionally supports a DMABUF based interface, where the userspace +can attach DMABUF objects (externally created) to a IIO buffer, and +subsequently use them for data transfers. + +A userspace application can then use this interface to share DMABUF +objects between several interfaces, allowing it to transfer data in a +zero-copy fashion, for instance between IIO and the USB stack. + +The userspace application can also memory-map the DMABUF objects, and +access the sample data directly. The advantage of doing this vs. the +read() interface is that it avoids an extra copy of the data between the +kernel and userspace. This is particularly useful for high-speed devices +which produce several megabytes or even gigabytes of data per second. +It does however increase the userspace-kernelspace synchronization +overhead, as the DMA_BUF_SYNC_START and DMA_BUF_SYNC_END IOCTLs have to +be used for data integrity. + +2. User API +=== + +As part of this interface, three new IOCTLs have been added. These three +IOCTLs have to be performed on the IIO buffer's file descriptor, +obtained using the IIO_BUFFER_GET_FD_IOCTL() ioctl. + + ``IIO_BUFFER_DMABUF_ATTACH_IOCTL(int)`` +Attach the DMABUF object, identified by its file descriptor, to the +IIO buffer. Returns zero on success, and a negative errno value on +error. + + ``IIO_BUFFER_DMABUF_DETACH_IOCTL(int)`` +Detach the given DMABUF object, identified by its file descriptor, +from the IIO buffer. Returns zero on success, and a negative errno +value on error. + +Note that closing the IIO buffer's file descriptor will +automatically detach all previously attached DMABUF objects. + + ``IIO_BUFFER_DMABUF_ENQUEUE_IOCTL(struct iio_dmabuf *iio_dmabuf)`` +Enqueue a previously attached DMABUF object to the buffer queue. +Enqueued DMABUFs will be read from (if output buffer) or written to +(if input buffer) as long as the buffer is enabled. diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 30b09eefe75e..feb50b61aac0 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -9,6 +9,7 @@ Industrial I/O iio_configfs iio_devbuf + iio_dmabuf_api Industrial I/O Kernel Drivers = -- 2.43.0
[PATCH v9 5/6] iio: buffer-dmaengine: Support new DMABUF based userspace API
Use the functions provided by the buffer-dma core to implement the DMABUF userspace API in the buffer-dmaengine IIO buffer implementation. Since we want to be able to transfer an arbitrary number of bytes and not necesarily the full DMABUF, the associated scatterlist is converted to an array of DMA addresses + lengths, which is then passed to dmaengine_prep_slave_dma_array(). Signed-off-by: Paul Cercueil Signed-off-by: Nuno Sa --- v3: Use the new dmaengine_prep_slave_dma_array(), and adapt the code to work with the new functions introduced in industrialio-buffer-dma.c. v5: - Use the new dmaengine_prep_slave_dma_vec(). - Restrict to input buffers, since output buffers are not yet supported by IIO buffers. v6: - Populate .lock_queue / .unlock_queue callbacks - Switch to atomic memory allocations in .submit_queue, because of the dma_fence critical section - Make sure that the size of the scatterlist is enough v7: Adapted patch for the changes made in patch 1. --- .../buffer/industrialio-buffer-dmaengine.c| 59 +-- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index a18c1da292af..3b7b649f0a89 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -64,15 +64,55 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, struct dmaengine_buffer *dmaengine_buffer = iio_buffer_to_dmaengine_buffer(>buffer); struct dma_async_tx_descriptor *desc; + struct scatterlist *sgl; + struct dma_vec *vecs; dma_cookie_t cookie; + size_t len_total; + size_t max_size; + unsigned int i; + int nents; - block->bytes_used = min(block->size, dmaengine_buffer->max_size); - block->bytes_used = round_down(block->bytes_used, - dmaengine_buffer->align); + if (queue->buffer.direction != IIO_BUFFER_DIRECTION_IN) { + /* We do not yet support output buffers. */ + return -EINVAL; + } - desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, - block->phys_addr, block->bytes_used, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT); + if (block->sg_table) { + sgl = block->sg_table->sgl; + nents = sg_nents_for_len(sgl, block->bytes_used); + if (nents < 0) + return nents; + + vecs = kmalloc_array(nents, sizeof(*vecs), GFP_ATOMIC); + if (!vecs) + return -ENOMEM; + + len_total = block->bytes_used; + + for (i = 0; i < nents; i++) { + vecs[i].addr = sg_dma_address(sgl); + vecs[i].len = min(sg_dma_len(sgl), len_total); + len_total -= vecs[i].len; + + sgl = sg_next(sgl); + } + + desc = dmaengine_prep_peripheral_dma_vec(dmaengine_buffer->chan, +vecs, nents, +DMA_DEV_TO_MEM, +DMA_PREP_INTERRUPT, 0); + kfree(vecs); + } else { + max_size = min(block->size, dmaengine_buffer->max_size); + max_size = round_down(max_size, dmaengine_buffer->align); + block->bytes_used = max_size; + + desc = dmaengine_prep_slave_single(dmaengine_buffer->chan, + block->phys_addr, + block->bytes_used, + DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT); + } if (!desc) return -ENOMEM; @@ -120,6 +160,13 @@ static const struct iio_buffer_access_funcs iio_dmaengine_buffer_ops = { .data_available = iio_dma_buffer_data_available, .release = iio_dmaengine_buffer_release, + .enqueue_dmabuf = iio_dma_buffer_enqueue_dmabuf, + .attach_dmabuf = iio_dma_buffer_attach_dmabuf, + .detach_dmabuf = iio_dma_buffer_detach_dmabuf, + + .lock_queue = iio_dma_buffer_lock_queue, + .unlock_queue = iio_dma_buffer_unlock_queue, + .modes = INDIO_BUFFER_HARDWARE, .flags = INDIO_BUFFER_FLAG_FIXED_WATERMARK, }; -- 2.43.0
[PATCH v9 4/6] iio: buffer-dma: Enable support for DMABUFs
Implement iio_dma_buffer_attach_dmabuf(), iio_dma_buffer_detach_dmabuf() and iio_dma_buffer_transfer_dmabuf(), which can then be used by the IIO DMA buffer implementations. Signed-off-by: Paul Cercueil Signed-off-by: Nuno Sa --- v3: Update code to provide the functions that will be used as callbacks for the new IOCTLs. v6: - Update iio_dma_buffer_enqueue_dmabuf() to take a dma_fence pointer - Pass that dma_fence pointer along to iio_buffer_signal_dmabuf_done() - Add iio_dma_buffer_lock_queue() / iio_dma_buffer_unlock_queue() - Do not lock the queue in iio_dma_buffer_enqueue_dmabuf(). The caller will ensure that it has been locked already. - Replace "int += bool;" by "if (bool) int++;" - Use dma_fence_begin/end_signalling in the dma_fence critical sections - Use one "num_dmabufs" fields instead of one "num_blocks" and one "num_fileio_blocks". Make it an atomic_t, which makes it possible to decrement it atomically in iio_buffer_block_release() without having to lock the queue mutex; and in turn, it means that we don't need to use iio_buffer_block_put_atomic() everywhere to avoid locking the queue mutex twice. - Use cleanup.h guard(mutex) when possible - Explicitely list all states in the switch in iio_dma_can_enqueue_block() - Rename iio_dma_buffer_fileio_mode() to iio_dma_buffer_can_use_fileio(), and add a comment explaining why it cannot race vs. DMABUF. --- drivers/iio/buffer/industrialio-buffer-dma.c | 181 +-- include/linux/iio/buffer-dma.h | 31 2 files changed, 201 insertions(+), 11 deletions(-) diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c index 5610ba67925e..c0f539af98f9 100644 --- a/drivers/iio/buffer/industrialio-buffer-dma.c +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -4,6 +4,8 @@ * Author: Lars-Peter Clausen */ +#include +#include #include #include #include @@ -14,6 +16,8 @@ #include #include #include +#include +#include #include #include @@ -94,13 +98,18 @@ static void iio_buffer_block_release(struct kref *kref) { struct iio_dma_buffer_block *block = container_of(kref, struct iio_dma_buffer_block, kref); + struct iio_dma_buffer_queue *queue = block->queue; - WARN_ON(block->state != IIO_BLOCK_STATE_DEAD); + WARN_ON(block->fileio && block->state != IIO_BLOCK_STATE_DEAD); - dma_free_coherent(block->queue->dev, PAGE_ALIGN(block->size), - block->vaddr, block->phys_addr); + if (block->fileio) { + dma_free_coherent(queue->dev, PAGE_ALIGN(block->size), + block->vaddr, block->phys_addr); + } else { + atomic_dec(>num_dmabufs); + } - iio_buffer_put(>queue->buffer); + iio_buffer_put(>buffer); kfree(block); } @@ -163,7 +172,7 @@ static struct iio_dma_buffer_queue *iio_buffer_to_queue(struct iio_buffer *buf) } static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( - struct iio_dma_buffer_queue *queue, size_t size) + struct iio_dma_buffer_queue *queue, size_t size, bool fileio) { struct iio_dma_buffer_block *block; @@ -171,13 +180,16 @@ static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( if (!block) return NULL; - block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size), - >phys_addr, GFP_KERNEL); - if (!block->vaddr) { - kfree(block); - return NULL; + if (fileio) { + block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size), + >phys_addr, GFP_KERNEL); + if (!block->vaddr) { + kfree(block); + return NULL; + } } + block->fileio = fileio; block->size = size; block->state = IIO_BLOCK_STATE_DONE; block->queue = queue; @@ -186,6 +198,9 @@ static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( iio_buffer_get(>buffer); + if (!fileio) + atomic_inc(>num_dmabufs); + return block; } @@ -206,13 +221,21 @@ void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) { struct iio_dma_buffer_queue *queue = block->queue; unsigned long flags; + bool cookie; + + cookie = dma_fence_begin_signalling(); spin_lock_irqsave(>list_lock, flags); _iio_dma_buffer_block_done(block); spin_unlock_irqrestore(>list_lock, flags); + if (!block->fileio) + iio_buffer_signal_dmabuf_done(block->fence, 0); + iio_buffer_block_put_atomic(block); wake_up_interruptible_poll(>buffer.pollq, EPOLLIN | EPOLLRDNORM); + +
[PATCH v9 3/6] iio: core: Add new DMABUF interface infrastructure
Add the necessary infrastructure to the IIO core to support a new optional DMABUF based interface. With this new interface, DMABUF objects (externally created) can be attached to a IIO buffer, and subsequently used for data transfer. A userspace application can then use this interface to share DMABUF objects between several interfaces, allowing it to transfer data in a zero-copy fashion, for instance between IIO and the USB stack. The userspace application can also memory-map the DMABUF objects, and access the sample data directly. The advantage of doing this vs. the read() interface is that it avoids an extra copy of the data between the kernel and userspace. This is particularly userful for high-speed devices which produce several megabytes or even gigabytes of data per second. As part of the interface, 3 new IOCTLs have been added: IIO_BUFFER_DMABUF_ATTACH_IOCTL(int fd): Attach the DMABUF object identified by the given file descriptor to the buffer. IIO_BUFFER_DMABUF_DETACH_IOCTL(int fd): Detach the DMABUF object identified by the given file descriptor from the buffer. Note that closing the IIO buffer's file descriptor will automatically detach all previously attached DMABUF objects. IIO_BUFFER_DMABUF_ENQUEUE_IOCTL(struct iio_dmabuf *): Request a data transfer to/from the given DMABUF object. Its file descriptor, as well as the transfer size and flags are provided in the "iio_dmabuf" structure. These three IOCTLs have to be performed on the IIO buffer's file descriptor, obtained using the IIO_BUFFER_GET_FD_IOCTL() ioctl. Signed-off-by: Paul Cercueil Signed-off-by: Nuno Sa --- v2: Only allow the new IOCTLs on the buffer FD created with IIO_BUFFER_GET_FD_IOCTL(). v3: - Get rid of the old IOCTLs. The IIO subsystem does not create or manage DMABUFs anymore, and only attaches/detaches externally created DMABUFs. - Add IIO_BUFFER_DMABUF_CYCLIC to the supported flags. v5: - Use dev_err() instead of pr_err() - Inline to_iio_dma_fence() - Add comment to explain why we unref twice when detaching dmabuf - Remove TODO comment. It is actually safe to free the file's private data even when transfers are still pending because it won't be accessed. - Fix documentation of new fields in struct iio_buffer_access_funcs - iio_dma_resv_lock() does not need to be exported, make it static v6: - Remove dead code in iio_dma_resv_lock() - Fix non-block actually blocking - Cache dma_buf_attachment instead of mapping/unmapping it for every transfer - Return -EINVAL instead of IIO_IOCTL_UNHANDLED for unknown ioctl - Make .block_enqueue() callback take a dma_fence pointer, which will be passed to iio_buffer_signal_dmabuf_done() instead of the dma_buf_attachment; and remove the backpointer from the priv structure to the dma_fence. - Use dma_fence_begin/end_signalling in the dma_fence critical sections - Unref dma_fence and dma_buf_attachment in worker, because they might try to lock the dma_resv, which would deadlock. - Add buffer ops to lock/unlock the queue. This is motivated by the fact that once the dma_fence has been installed, we cannot lock anything anymore - so the queue must be locked before the dma_fence is installed. - Use 'long retl' variable to handle the return value of dma_resv_wait_timeout() - Protect dmabufs list access with a mutex - Rework iio_buffer_find_attachment() to use the internal dmabufs list, instead of messing with dmabufs private data. - Add an atomically-increasing sequence number for fences v8 - Fix swapped fence direction - Simplify fence wait mechanism - Remove "Buffer closed with active transfers" print, as it was dead code - Un-export iio_buffer_dmabuf_{get,put}. They are not used anywhere else so they can even be static. - Prevent attaching already-attached DMABUFs v9: - Select DMA_SHARED_BUFFER in Kconfig - Remove useless forward declaration of 'iio_dma_fence' - Import DMA-BUF namespace - Add missing __user tag to iio_buffer_detach_dmabuf() argument --- drivers/iio/Kconfig | 1 + drivers/iio/industrialio-buffer.c | 462 ++ include/linux/iio/buffer_impl.h | 30 ++ include/uapi/linux/iio/buffer.h | 22 ++ 4 files changed, 515 insertions(+) diff --git a/drivers/iio/Kconfig b/drivers/iio/Kconfig index 9c351ffc7bed..661127aed2f9 100644 --- a/drivers/iio/Kconfig +++ b/drivers/iio/Kconfig @@ -14,6 +14,7 @@ if IIO config IIO_BUFFER bool "Enable buffer support within IIO" + select DMA_SHARED_BUFFER help Provide core support for various buffer based data acquisition methods. diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index b581a7e80566..a987654f82fc 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -9,14 +9,19
[PATCH v9 2/6] dmaengine: dma-axi-dmac: Implement device_prep_peripheral_dma_vec
Add implementation of the .device_prep_peripheral_dma_vec() callback. Signed-off-by: Paul Cercueil Signed-off-by: Nuno Sa --- v3: New patch v5: Implement .device_prep_slave_dma_vec() instead of v3's .device_prep_slave_dma_array(). v6: Use new prototype for axi_dmac_alloc_desc() as it changed upstream. v7: Adapted patch for the changes made in patch 1. --- drivers/dma/dma-axi-dmac.c | 40 ++ 1 file changed, 40 insertions(+) diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index 4e339c04fc1e..d03cbf1d28e8 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c @@ -620,6 +620,45 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan, return sg; } +static struct dma_async_tx_descriptor * +axi_dmac_prep_peripheral_dma_vec(struct dma_chan *c, const struct dma_vec *vecs, +size_t nb, enum dma_transfer_direction direction, +unsigned long prep_flags, unsigned long flags) +{ + struct axi_dmac_chan *chan = to_axi_dmac_chan(c); + struct axi_dmac_desc *desc; + unsigned int num_sgs = 0; + struct axi_dmac_sg *dsg; + size_t i; + + if (direction != chan->direction) + return NULL; + + for (i = 0; i < nb; i++) + num_sgs += DIV_ROUND_UP(vecs[i].len, chan->max_length); + + desc = axi_dmac_alloc_desc(chan, num_sgs); + if (!desc) + return NULL; + + dsg = desc->sg; + + for (i = 0; i < nb; i++) { + if (!axi_dmac_check_addr(chan, vecs[i].addr) || + !axi_dmac_check_len(chan, vecs[i].len)) { + kfree(desc); + return NULL; + } + + dsg = axi_dmac_fill_linear_sg(chan, direction, vecs[i].addr, 1, + vecs[i].len, dsg); + } + + desc->cyclic = false; + + return vchan_tx_prep(>vchan, >vdesc, prep_flags); +} + static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg( struct dma_chan *c, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, @@ -1055,6 +1094,7 @@ static int axi_dmac_probe(struct platform_device *pdev) dma_dev->device_tx_status = dma_cookie_status; dma_dev->device_issue_pending = axi_dmac_issue_pending; dma_dev->device_prep_slave_sg = axi_dmac_prep_slave_sg; + dma_dev->device_prep_peripheral_dma_vec = axi_dmac_prep_peripheral_dma_vec; dma_dev->device_prep_dma_cyclic = axi_dmac_prep_dma_cyclic; dma_dev->device_prep_interleaved_dma = axi_dmac_prep_interleaved; dma_dev->device_terminate_all = axi_dmac_terminate_all; -- 2.43.0
[PATCH v9 1/6] dmaengine: Add API function dmaengine_prep_peripheral_dma_vec()
This function can be used to initiate a scatter-gather DMA transfer, where the address and size of each segment is located in one entry of the dma_vec array. The major difference with dmaengine_prep_slave_sg() is that it supports specifying the lengths of each DMA transfer; as trying to override the length of the transfer with dmaengine_prep_slave_sg() is a very tedious process. The introduction of a new API function is also justified by the fact that scatterlists are on their way out. Note that dmaengine_prep_interleaved_dma() is not helpful either in that case, as it assumes that the address of each segment will be higher than the one of the previous segment, which we just cannot guarantee in case of a scatter-gather transfer. Signed-off-by: Paul Cercueil Signed-off-by: Nuno Sa --- v3: New patch v5: Replace with function dmaengine_prep_slave_dma_vec(), and struct 'dma_vec'. Note that at some point we will need to support cyclic transfers using dmaengine_prep_slave_dma_vec(). Maybe with a new "flags" parameter to the function? v7: - Renamed *device_prep_slave_dma_vec() -> device_prep_peripheral_dma_vec(); - Added a new flag parameter to the function as agreed between Paul and Vinod. I renamed the first parameter to prep_flags as it's supposed to be used (I think) with enum dma_ctrl_flags. I'm not really sure how that API can grow but I was thinking in just having a bool cyclic parameter (as the first intention of the flags is to support cyclic transfers) but ended up "respecting" the previously agreed approach. --- include/linux/dmaengine.h | 27 +++ 1 file changed, 27 insertions(+) diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 752dbde4cec1..856df8cd9a4e 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -160,6 +160,16 @@ struct dma_interleaved_template { struct data_chunk sgl[]; }; +/** + * struct dma_vec - DMA vector + * @addr: Bus address of the start of the vector + * @len: Length in bytes of the DMA vector + */ +struct dma_vec { + dma_addr_t addr; + size_t len; +}; + /** * enum dma_ctrl_flags - DMA flags to augment operation preparation, * control completion, and communicate status. @@ -910,6 +920,10 @@ struct dma_device { struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( struct dma_chan *chan, unsigned long flags); + struct dma_async_tx_descriptor *(*device_prep_peripheral_dma_vec)( + struct dma_chan *chan, const struct dma_vec *vecs, + size_t nents, enum dma_transfer_direction direction, + unsigned long prep_flags, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_slave_sg)( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction direction, @@ -973,6 +987,19 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_single( dir, flags, NULL); } +static inline struct dma_async_tx_descriptor *dmaengine_prep_peripheral_dma_vec( + struct dma_chan *chan, const struct dma_vec *vecs, size_t nents, + enum dma_transfer_direction dir, unsigned long prep_flags, + unsigned long flags) +{ + if (!chan || !chan->device || !chan->device->device_prep_peripheral_dma_vec) + return NULL; + + return chan->device->device_prep_peripheral_dma_vec(chan, vecs, nents, + dir, prep_flags, + flags); +} + static inline struct dma_async_tx_descriptor *dmaengine_prep_slave_sg( struct dma_chan *chan, struct scatterlist *sgl, unsigned int sg_len, enum dma_transfer_direction dir, unsigned long flags) -- 2.43.0
[PATCH v9 0/6] iio: new DMABUF based API
Hi Jonathan, Here's the final-er version of the IIO DMABUF patchset. This v9 fixes the few issues reported by the kernel bot. This was based on next-20240308. Changelog: - [3/6]: - Select DMA_SHARED_BUFFER in Kconfig - Remove useless forward declaration of 'iio_dma_fence' - Import DMA-BUF namespace - Add missing __user tag to iio_buffer_detach_dmabuf() argument Cheers, -Paul Paul Cercueil (6): dmaengine: Add API function dmaengine_prep_peripheral_dma_vec() dmaengine: dma-axi-dmac: Implement device_prep_peripheral_dma_vec iio: core: Add new DMABUF interface infrastructure iio: buffer-dma: Enable support for DMABUFs iio: buffer-dmaengine: Support new DMABUF based userspace API Documentation: iio: Document high-speed DMABUF based API Documentation/iio/iio_dmabuf_api.rst | 54 ++ Documentation/iio/index.rst | 1 + drivers/dma/dma-axi-dmac.c| 40 ++ drivers/iio/Kconfig | 1 + drivers/iio/buffer/industrialio-buffer-dma.c | 181 ++- .../buffer/industrialio-buffer-dmaengine.c| 59 ++- drivers/iio/industrialio-buffer.c | 462 ++ include/linux/dmaengine.h | 27 + include/linux/iio/buffer-dma.h| 31 ++ include/linux/iio/buffer_impl.h | 30 ++ include/uapi/linux/iio/buffer.h | 22 + 11 files changed, 891 insertions(+), 17 deletions(-) create mode 100644 Documentation/iio/iio_dmabuf_api.rst -- 2.43.0
Re: [PATCH v8 0/6] iio: new DMABUF based API
On Fri, 8 Mar 2024 18:00:40 +0100 Paul Cercueil wrote: > Hi Jonathan, > > Here's the final(tm) version of the IIO DMABUF patchset. > > This v8 fixes the remaining few issues that Christian reported. > > I also updated the documentation patch as there has been changes to > index.rst. > > This was based on next-20240308. > > Changelog: > > - [3/6]: > - Fix swapped fence direction > - Simplify fence wait mechanism > - Remove "Buffer closed with active transfers" print, as it was dead > code > - Un-export iio_buffer_dmabuf_{get,put}. They are not used anywhere > else so they can even be static. > - Prevent attaching already-attached DMABUFs > - [6/6]: > Renamed dmabuf_api.rst -> iio_dmabuf_api.rst, and updated index.rst > whose format changed in iio/togreg. > > Cheers, > -Paul Given nature of the build bug issues reported, I'm guessing you never built this as a module :( Not sure how one instance of a missing user marking got through but also easy to fix. Anyhow, no need to wait before sending a v9 with those sorted. 0-day does it's job again - even better is that it's whilst it's still your problem and not mine :) Jonathan > > Paul Cercueil (6): > dmaengine: Add API function dmaengine_prep_peripheral_dma_vec() > dmaengine: dma-axi-dmac: Implement device_prep_peripheral_dma_vec > iio: core: Add new DMABUF interface infrastructure > iio: buffer-dma: Enable support for DMABUFs > iio: buffer-dmaengine: Support new DMABUF based userspace API > Documentation: iio: Document high-speed DMABUF based API > > Documentation/iio/iio_dmabuf_api.rst | 54 ++ > Documentation/iio/index.rst | 1 + > drivers/dma/dma-axi-dmac.c| 40 ++ > drivers/iio/buffer/industrialio-buffer-dma.c | 181 ++- > .../buffer/industrialio-buffer-dmaengine.c| 59 ++- > drivers/iio/industrialio-buffer.c | 462 ++ > include/linux/dmaengine.h | 27 + > include/linux/iio/buffer-dma.h| 31 ++ > include/linux/iio/buffer_impl.h | 30 ++ > include/uapi/linux/iio/buffer.h | 22 + > 10 files changed, 890 insertions(+), 17 deletions(-) > create mode 100644 Documentation/iio/iio_dmabuf_api.rst >
Re: [PATCH v2 14/28] sparc32: Drop unused mmu models
Hi kernel test robot et al. On Sun, Mar 10, 2024 at 06:37:53PM +0800, kernel test robot wrote: > Hi Sam, > > kernel test robot noticed the following build warnings: > > [auto build test WARNING on 84b76d05828a1909e20d0f66553b876b801f98c8] > > url: > https://github.com/intel-lab-lkp/linux/commits/Sam-Ravnborg-via-B4-Relay/sparc32-Update-defconfig-to-LEON-SMP/20240310-021717 > base: 84b76d05828a1909e20d0f66553b876b801f98c8 > patch link: > https://lore.kernel.org/r/20240309-sunset-v2-14-f09912574d2c%40ravnborg.org > patch subject: [PATCH v2 14/28] sparc32: Drop unused mmu models > config: sparc-randconfig-r113-20240310 > (https://download.01.org/0day-ci/archive/20240310/202403101854.z94sau13-...@intel.com/config) > compiler: sparc-linux-gcc (GCC) 13.2.0 > reproduce: > (https://download.01.org/0day-ci/archive/20240310/202403101854.z94sau13-...@intel.com/reproduce) > > If you fix the issue in a separate patch/commit (i.e. not just a new version > of > the same patch/commit), kindly add following tags > | Reported-by: kernel test robot > | Closes: > https://lore.kernel.org/oe-kbuild-all/202403101854.z94sau13-...@intel.com/ > > sparse warnings: (new ones prefixed by >>) > >> arch/sparc/mm/srmmu.c:49:5: sparse: sparse: symbol 'vac_line_size' was not > >> declared. Should it be static? > > vim +/vac_line_size +49 arch/sparc/mm/srmmu.c > > accf032cfa582e Sam Ravnborg 2012-05-19 46 > ^1da177e4c3f41 Linus Torvalds 2005-04-16 47 int vac_cache_size; > 9d262d95114cf2 Guenter Roeck 2017-04-01 48 EXPORT_SYMBOL(vac_cache_size); > ^1da177e4c3f41 Linus Torvalds 2005-04-16 @49 int vac_line_size; > ^1da177e4c3f41 Linus Torvalds 2005-04-16 50 vac_line_size is no longer used and can be deleted. vac_cache_size is never written to and can be deleted too. vac_cache_size is used in shmparam_32.h like this: #define SHMLBA (vac_cache_size ? vac_cache_size : PAGE_SIZE) The same file has: #define __ARCH_FORCE_SHMLBA 1 If I understand it right then when SHMLBA equals PAGE_SIZE then there is no need to define __ARCH_FORCE_SHMLBA and sparc32 can use the asm-generic variant of shmparam.h I will do this change in v3. Sam
Re: [PATCH v8 3/6] iio: core: Add new DMABUF interface infrastructure
Hi Paul, kernel test robot noticed the following build errors: [auto build test ERROR on jic23-iio/togreg] [also build test ERROR on vkoul-dmaengine/next lwn/docs-next linus/master v6.8-rc7 next-20240308] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Paul-Cercueil/dmaengine-Add-API-function-dmaengine_prep_peripheral_dma_vec/20240309-010421 base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg patch link: https://lore.kernel.org/r/20240308170046.92899-4-paul%40crapouillou.net patch subject: [PATCH v8 3/6] iio: core: Add new DMABUF interface infrastructure config: um-randconfig-002-20240310 (https://download.01.org/0day-ci/archive/20240310/202403101928.wwsqwfdg-...@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240310/202403101928.wwsqwfdg-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202403101928.wwsqwfdg-...@intel.com/ All errors (new ones prefixed by >>): /usr/bin/ld: drivers/iio/industrialio-buffer.o: in function `iio_buffer_dmabuf_release': >> industrialio-buffer.c:(.text+0xec6): undefined reference to >> `dma_buf_unmap_attachment' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xf96): undefined reference to >> `dma_buf_detach' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xfa5): undefined reference to >> `dma_buf_put' /usr/bin/ld: drivers/iio/industrialio-buffer.o: in function `iio_buffer_signal_dmabuf_done': >> industrialio-buffer.c:(.text+0x4a56): undefined reference to >> `dma_fence_signal' /usr/bin/ld: drivers/iio/industrialio-buffer.o: in function `iio_buffer_cleanup': >> industrialio-buffer.c:(.text+0x64f2): undefined reference to >> `dma_fence_release' /usr/bin/ld: drivers/iio/industrialio-buffer.o: in function `iio_buffer_attach_dmabuf.isra.0': >> industrialio-buffer.c:(.text+0x9dbf): undefined reference to >> `dma_fence_context_alloc' >> /usr/bin/ld: industrialio-buffer.c:(.text+0x9df7): undefined reference to >> `dma_buf_get' >> /usr/bin/ld: industrialio-buffer.c:(.text+0x9e38): undefined reference to >> `dma_buf_attach' >> /usr/bin/ld: industrialio-buffer.c:(.text+0x9efe): undefined reference to >> `dma_buf_map_attachment' /usr/bin/ld: industrialio-buffer.c:(.text+0xa2c1): undefined reference to `dma_buf_detach' /usr/bin/ld: industrialio-buffer.c:(.text+0xa2cd): undefined reference to `dma_buf_put' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xa34d): undefined reference to >> `dma_buf_unmap_attachment' /usr/bin/ld: drivers/iio/industrialio-buffer.o: in function `iio_buffer_enqueue_dmabuf': >> industrialio-buffer.c:(.text+0xa949): undefined reference to `dma_buf_get' /usr/bin/ld: industrialio-buffer.c:(.text+0xa997): undefined reference to `dma_buf_put' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xac84): undefined reference to >> `dma_fence_init' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xad4b): undefined reference to >> `dma_resv_wait_timeout' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xadec): undefined reference to >> `dma_resv_reserve_fences' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xae2c): undefined reference to >> `dma_resv_add_fence' >> /usr/bin/ld: industrialio-buffer.c:(.text+0xb0da): undefined reference to >> `dma_fence_release' /usr/bin/ld: drivers/iio/industrialio-buffer.o: in function `iio_buffer_chrdev_ioctl': industrialio-buffer.c:(.text+0xb833): undefined reference to `dma_buf_get' /usr/bin/ld: industrialio-buffer.c:(.text+0xbad0): undefined reference to `dma_buf_put' collect2: error: ld returned 1 exit status -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH v2 14/28] sparc32: Drop unused mmu models
Hi Sam, kernel test robot noticed the following build warnings: [auto build test WARNING on 84b76d05828a1909e20d0f66553b876b801f98c8] url: https://github.com/intel-lab-lkp/linux/commits/Sam-Ravnborg-via-B4-Relay/sparc32-Update-defconfig-to-LEON-SMP/20240310-021717 base: 84b76d05828a1909e20d0f66553b876b801f98c8 patch link: https://lore.kernel.org/r/20240309-sunset-v2-14-f09912574d2c%40ravnborg.org patch subject: [PATCH v2 14/28] sparc32: Drop unused mmu models config: sparc-randconfig-r113-20240310 (https://download.01.org/0day-ci/archive/20240310/202403101854.z94sau13-...@intel.com/config) compiler: sparc-linux-gcc (GCC) 13.2.0 reproduce: (https://download.01.org/0day-ci/archive/20240310/202403101854.z94sau13-...@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202403101854.z94sau13-...@intel.com/ sparse warnings: (new ones prefixed by >>) >> arch/sparc/mm/srmmu.c:49:5: sparse: sparse: symbol 'vac_line_size' was not >> declared. Should it be static? vim +/vac_line_size +49 arch/sparc/mm/srmmu.c accf032cfa582e Sam Ravnborg 2012-05-19 46 ^1da177e4c3f41 Linus Torvalds 2005-04-16 47 int vac_cache_size; 9d262d95114cf2 Guenter Roeck 2017-04-01 48 EXPORT_SYMBOL(vac_cache_size); ^1da177e4c3f41 Linus Torvalds 2005-04-16 @49 int vac_line_size; ^1da177e4c3f41 Linus Torvalds 2005-04-16 50 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH v3 2/2] backlight: Add new lm3509 backlight driver
Hi Patrick, a few comments in the following. Sam On Sat, Mar 09, 2024 at 02:24:56PM +0100, Patrick Gansterer wrote: > This is a general driver for LM3509 backlight chip of TI. > LM3509 is High Efficiency Boost for White LEDs and/or OLED Displays with > Dual Current Sinks. This driver supports OLED/White LED select, brightness > control and sub/main control. > The datasheet can be found at http://www.ti.com/product/lm3509. > > Signed-off-by: Patrick Gansterer > --- > drivers/video/backlight/Kconfig | 7 + > drivers/video/backlight/Makefile| 1 + > drivers/video/backlight/lm3509_bl.c | 340 > 3 files changed, 348 insertions(+) > create mode 100644 drivers/video/backlight/lm3509_bl.c > > diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig > index ea2d0d69bd8c..96ad5dc584b6 100644 > --- a/drivers/video/backlight/Kconfig > +++ b/drivers/video/backlight/Kconfig > @@ -366,6 +366,13 @@ config BACKLIGHT_AAT2870 > If you have a AnalogicTech AAT2870 say Y to enable the > backlight driver. > > +config BACKLIGHT_LM3509 > + tristate "Backlight Driver for LM3509" > + depends on I2C > + select REGMAP_I2C > + help > + This supports TI LM3509 Backlight Driver > + > config BACKLIGHT_LM3630A > tristate "Backlight Driver for LM3630A" > depends on I2C && PWM > diff --git a/drivers/video/backlight/Makefile > b/drivers/video/backlight/Makefile > index 06966cb20459..51a4ac5d0530 100644 > --- a/drivers/video/backlight/Makefile > +++ b/drivers/video/backlight/Makefile > @@ -35,6 +35,7 @@ obj-$(CONFIG_BACKLIGHT_HP700) += > jornada720_bl.o > obj-$(CONFIG_BACKLIGHT_IPAQ_MICRO) += ipaq_micro_bl.o > obj-$(CONFIG_BACKLIGHT_KTD253) += ktd253-backlight.o > obj-$(CONFIG_BACKLIGHT_KTZ8866) += ktz8866.o > +obj-$(CONFIG_BACKLIGHT_LM3509) += lm3509_bl.o > obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_bl.o > obj-$(CONFIG_BACKLIGHT_LM3630A) += lm3630a_bl.o > obj-$(CONFIG_BACKLIGHT_LM3639) += lm3639_bl.o > diff --git a/drivers/video/backlight/lm3509_bl.c > b/drivers/video/backlight/lm3509_bl.c > new file mode 100644 > index ..bfad0aaffa0d > --- /dev/null > +++ b/drivers/video/backlight/lm3509_bl.c > @@ -0,0 +1,340 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define LM3509_NAME "lm3509_bl" > + > +#define LM3509_SINK_MAIN 0 > +#define LM3509_SINK_SUB 1 > +#define LM3509_NUM_SINKS 2 > + > +#define LM3509_DEF_BRIGHTNESS 0x12 > +#define LM3509_MAX_BRIGHTNESS 0x1F > + > +#define REG_GP 0x10 > +#define REG_BMAIN 0xA0 > +#define REG_BSUB 0xB0 > +#define REG_MAX 0xFF > + > +enum { > + REG_GP_ENM_BIT = 0, > + REG_GP_ENS_BIT, > + REG_GP_UNI_BIT, > + REG_GP_RMP0_BIT, > + REG_GP_RMP1_BIT, > + REG_GP_OLED_BIT, > +}; > + > +struct lm3509_bl { > + struct regmap *regmap; > + struct backlight_device *bl_main; > + struct backlight_device *bl_sub; > + struct gpio_desc *reset_gpio; > +}; > + > +struct lm3509_bl_led_pdata { > + const char *label; > + int led_sources; > + u32 brightness; > + u32 max_brightness; > +}; > + > +static void lm3509_reset(struct lm3509_bl *data) > +{ > + if (data->reset_gpio) { > + gpiod_set_value(data->reset_gpio, 1); > + udelay(1); > + gpiod_set_value(data->reset_gpio, 0); > + udelay(10); > + } > +} > + > +static int lm3509_update_status(struct backlight_device *bl, > + unsigned int en_mask, unsigned int br_reg) > +{ > + struct lm3509_bl *data = bl_get_data(bl); > + int ret; > + bool en; > + > + ret = regmap_write(data->regmap, br_reg, bl->props.brightness); Here you can use backlight_get_brightness() thus avoiding direct access to backlight internal properties. > + if (ret < 0) > + return ret; > + > + en = bl->props.power <= FB_BLANK_NORMAL; Use backlight_is_blank() here. Sam > + return regmap_update_bits(data->regmap, REG_GP, en_mask, > + en ? en_mask : 0); > +} > + > +static int lm3509_main_update_status(struct backlight_device *bl) > +{ > + return lm3509_update_status(bl, BIT(REG_GP_ENM_BIT), REG_BMAIN); > +} > + > +static const struct backlight_ops lm3509_main_ops = { > + .options = BL_CORE_SUSPENDRESUME, > + .update_status = lm3509_main_update_status, > +}; > + > +static int lm3509_sub_update_status(struct backlight_device *bl) > +{ > + return lm3509_update_status(bl, BIT(REG_GP_ENS_BIT), REG_BSUB); > +} > + > +static const struct backlight_ops lm3509_sub_ops = { > + .options = BL_CORE_SUSPENDRESUME, > + .update_status = lm3509_sub_update_status, > +}; > + > +static struct backlight_device * > +lm3509_backlight_register(struct device *dev, const char
Re: [PATCH v3 1/2] dt-bindings: backlight: Add Texas Instruments LM3509
On 09/03/2024 14:24, Patrick Gansterer wrote: > Add Device Tree bindings for Texas Instruments LM3509 - a > High Efficiency Boost for White LED's and/or OLED Displays > > Signed-off-by: Patrick Gansterer > --- Reviewed-by: Krzysztof Kozlowski Best regards, Krzysztof
Re: [PATCH v3 1/2] dt-bindings: backlight: Add Texas Instruments LM3509
On 09/03/2024 14:24, Patrick Gansterer wrote: > Add Device Tree bindings for Texas Instruments LM3509 - a > High Efficiency Boost for White LED's and/or OLED Displays > > Signed-off-by: Patrick Gansterer > --- > Changes in v3: > Improved device tree bindings documentation style That's way too generic. Everything can be called style. If you only improved style, then my comments regarding real issues like missing defaults were not implemented? Best regards, Krzysztof