Re: [PATCH 0/1] add support for enum module parameters
+ linux-wireless, netdev Jani Nikula writes: > On Thu, 14 Apr 2022, Greg Kroah-Hartman wrote: >> On Thu, Apr 14, 2022 at 03:30:32PM +0300, Jani Nikula wrote: >>> Hey, I've sent this before, ages ago, but haven't really followed >>> through with it. I still think it would be useful for many scenarios >>> where a plain number is a clumsy interface for a module param. >>> >>> Thoughts? >> >> We should not be adding new module parameters anyway (they operate on >> code, not data/devices), so what would this be used for? > > I think it's just easier to use names than random values, and this also > gives you range check on the input. > > I also keep telling people not to add new module parameters, but it's > not like they're going away anytime soon. > > If there's a solution to being able to pass device specific debug > parameters at probe time, I'm all ears. At least i915 has a bunch of > things which can't really be changed after probe, when debugfs for the > device is around. Module parameters aren't ideal, but debugfs doesn't > work for this. Wireless drivers would also desperately need to pass device specific parameters at (or before) probe time. And not only debug parameters but also configuration parameters, for example firmware memory allocations schemes (optimise for features vs number of clients etc) and whatnot. Any ideas how to implement that? Is there any prior work for anything like this? This is pretty hard limiting usability of upstream wireless drivers and I really want to find a proper solution. -- https://patchwork.kernel.org/project/linux-wireless/list/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
[PATCH v2] drm/vmwgfx: Fix gem refcounting and memory evictions
From: Zack Rusin v2: Add the last part of the ref count fix which was spotted by Philipp Sieweck where the ref count of cpu writers is off due to ERESTARTSYS or EBUSY during bo waits. The initial GEM port broke refcounting on shareable (prime) surfaces and memory evictions. The prime surfaces broke because the parent surfaces weren't increasing the ref count on GEM surfaces, which meant that the memory backing textures could have been deleted while the texture was still accessible. The evictions broke due to a typo, the code was supposed to exit if the passed buffers were not vmw_buffer_object not if they were. They're tied because the evictions depend on having memory to actually evict. This fixes crashes with XA state tracker which is used for xrender acceleration on xf86-video-vmware, apps/tests which use a lot of memory (a good test being the piglit's streaming-texture-leak) and desktops. Signed-off-by: Zack Rusin Fixes: 8afa13a0583f ("drm/vmwgfx: Implement DRIVER_GEM") Reported-by: Philipp Sieweck Cc: # v5.17+ Reviewed-by: Maaz Mombasawala --- drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 43 - drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 8 ++--- drivers/gpu/drm/vmwgfx/vmwgfx_surface.c | 7 +++- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index 31aecc46624b..04c8a378aeed 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -46,6 +46,21 @@ vmw_buffer_object(struct ttm_buffer_object *bo) return container_of(bo, struct vmw_buffer_object, base); } +/** + * bo_is_vmw - check if the buffer object is a _buffer_object + * @bo: ttm buffer object to be checked + * + * Uses destroy function associated with the object to determine if this is + * a _buffer_object. + * + * Returns: + * true if the object is of _buffer_object type, false if not. + */ +static bool bo_is_vmw(struct ttm_buffer_object *bo) +{ + return bo->destroy == _bo_bo_free || + bo->destroy == _gem_destroy; +} /** * vmw_bo_pin_in_placement - Validate a buffer to placement. @@ -615,8 +630,9 @@ int vmw_user_bo_synccpu_ioctl(struct drm_device *dev, void *data, ret = vmw_user_bo_synccpu_grab(vbo, arg->flags); vmw_bo_unreference(); - if (unlikely(ret != 0 && ret != -ERESTARTSYS && -ret != -EBUSY)) { + if (unlikely(ret != 0)) { + if (ret == -ERESTARTSYS || ret == -EBUSY) + return -EBUSY; DRM_ERROR("Failed synccpu grab on handle 0x%08x.\n", (unsigned int) arg->handle); return ret; @@ -798,7 +814,7 @@ int vmw_dumb_create(struct drm_file *file_priv, void vmw_bo_swap_notify(struct ttm_buffer_object *bo) { /* Is @bo embedded in a struct vmw_buffer_object? */ - if (vmw_bo_is_vmw_bo(bo)) + if (!bo_is_vmw(bo)) return; /* Kill any cached kernel maps before swapout */ @@ -822,7 +838,7 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, struct vmw_buffer_object *vbo; /* Make sure @bo is embedded in a struct vmw_buffer_object? */ - if (vmw_bo_is_vmw_bo(bo)) + if (!bo_is_vmw(bo)) return; vbo = container_of(bo, struct vmw_buffer_object, base); @@ -843,22 +859,3 @@ void vmw_bo_move_notify(struct ttm_buffer_object *bo, if (mem->mem_type != VMW_PL_MOB && bo->resource->mem_type == VMW_PL_MOB) vmw_resource_unbind_list(vbo); } - -/** - * vmw_bo_is_vmw_bo - check if the buffer object is a _buffer_object - * @bo: buffer object to be checked - * - * Uses destroy function associated with the object to determine if this is - * a _buffer_object. - * - * Returns: - * true if the object is of _buffer_object type, false if not. - */ -bool vmw_bo_is_vmw_bo(struct ttm_buffer_object *bo) -{ - if (bo->destroy == _bo_bo_free || - bo->destroy == _gem_destroy) - return true; - - return false; -} diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 72a17618ba0a..0c12faa4e533 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1018,13 +1018,10 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) goto out_no_fman; } - drm_vma_offset_manager_init(_priv->vma_manager, - DRM_FILE_PAGE_OFFSET_START, - DRM_FILE_PAGE_OFFSET_SIZE); ret = ttm_device_init(_priv->bdev, _bo_driver, dev_priv->drm.dev, dev_priv->drm.anon_inode->i_mapping, - _priv->vma_manager, + dev_priv->drm.vma_offset_manager,
Re: [PATCH 03/15] dma-buf & drm/amdgpu: remove dma_resv workaround
On Thu, 2022-04-07 at 10:59 +0200, Christian König wrote: > Rework the internals of the dma_resv object to allow adding more than > one > write fence and remember for each fence what purpose it had. > > This allows removing the workaround from amdgpu which used a container > for > this instead. > > Signed-off-by: Christian König > Reviewed-by: Daniel Vetter > Cc: amd-...@lists.freedesktop.org afaict this change broke vmwgfx which now kernel oops right after boot. I haven't had the time to look into it yet, so I'm not sure what's the problem. I'll look at this tomorrow, but just in case you have some clues, the backtrace follows: [ cut here ] kernel BUG at drivers/dma-buf/dma-resv.c:306! invalid opcode: [#1] PREEMPT SMP PTI CPU: 1 PID: 1608 Comm: gnome-shell Not tainted 5.18.0-rc1-vmwgfx #18 Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 RIP: 0010:dma_resv_add_fence+0x2ed/0x300 Code: ff ff be 01 00 00 00 e8 31 7d d9 ff e9 80 fd ff ff be 03 00 00 00 e8 22 7d d9 ff e9 ee fe ff ff 0f 1f 44 00 00 e9 bc fe ff ff <0f> 0b e8 4c cc 45 00 66 6> RSP: 0018:a1e6846c3ab0 EFLAGS: 00010246 RAX: RBX: 94c5c5507138 RCX: 902bc24e7b7c70ae RDX: 902bc24e7b7c70ae RSI: aaf7f437 RDI: aaffde66 RBP: a1e6846c3b08 R08: R09: 0001 R10: 0004 R11: R12: 94c5cba90578 R13: R14: 94c5cba8bc00 R15: FS: 7f9a17c6e600() GS:94c6f9e4() knlGS: CS: 0010 DS: ES: CR0: 80050033 CR2: 7f9a14113000 CR3: 0144c003 CR4: 003706e0 Call Trace: ttm_eu_fence_buffer_objects+0x54/0x110 [ttm] vmw_execbuf_process+0xcae/0x12a0 [vmwgfx] ? vmw_execbuf_release_pinned_bo+0x60/0x60 [vmwgfx] vmw_execbuf_ioctl+0xfb/0x160 [vmwgfx] ? vmw_execbuf_release_pinned_bo+0x60/0x60 [vmwgfx] drm_ioctl_kernel+0xba/0x150 [drm] ? __might_fault+0x77/0x80 drm_ioctl+0x247/0x460 [drm] ? vmw_execbuf_release_pinned_bo+0x60/0x60 [vmwgfx] ? find_held_lock+0x31/0x90 ? __fget_files+0xc5/0x190 ? __this_cpu_preempt_check+0x13/0x20 ? lock_release+0x142/0x2f0 ? drm_ioctl_kernel+0x150/0x150 [drm] vmw_generic_ioctl+0xa3/0x110 [vmwgfx] vmw_unlocked_ioctl+0x15/0x20 [vmwgfx] __x64_sys_ioctl+0x91/0xc0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x7f9a1af1aaff Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <41> 89 c0 3d 00 f0 ff ff 7> RSP: 002b:7ffd833696c0 EFLAGS: 0246 ORIG_RAX: 0010 RAX: ffda RBX: 7ffd83369780 RCX: 7f9a1af1aaff RDX: 7ffd83369780 RSI: 4028644c RDI: 000d RBP: 4028644c R08: 1248 R09: 7ffd83369808 R10: 0008 R11: 0246 R12: 7ffd83369808 R13: 000d R14: 55719cb629c0 R15: 7ffd83369808 Modules linked in: overlay snd_ens1371 intel_rapl_msr snd_ac97_codec intel_rapl_common ac97_bus vsock_loopback vmw_vsock_virtio_transport_common vmw_vsock_vmci> ---[ end trace ]--- z
Re: [PATCH v5 09/10] arm64: dts: qcom: sc7180: Add support for HDCP in dp-controller
On Mon 11 Apr 13:47 PDT 2022, Sean Paul wrote: > From: Sean Paul > > This patch adds the register ranges required for HDCP key injection and > HDCP TrustZone interaction as described in the dt-bindings for the > sc7180 dp controller. Can you please mention why this is only done for trogdor and not sc7180 as a whole? > Now that these are supported, change the compatible string to > "dp-hdcp". > I don't see this change in the patch. > Signed-off-by: Sean Paul > Link: > https://patchwork.freedesktop.org/patch/msgid/20210913175747.47456-15-s...@poorly.run > #v1 > Link: > https://patchwork.freedesktop.org/patch/msgid/20210915203834.1439-14-s...@poorly.run > #v2 > Link: > https://patchwork.freedesktop.org/patch/msgid/20211001151145.55916-14-s...@poorly.run > #v3 > Link: > https://patchwork.freedesktop.org/patch/msgid/20211105030434.2828845-14-s...@poorly.run > #v4 > > Changes in v3: > -Split off into a new patch containing just the dts change (Stephen) > -Add hdcp compatible string (Stephen) > Changes in v4: > -Rebase on Bjorn's multi-dp patchset > Changes in v5: > -Put the tz register offsets in trogdor dtsi (Rob C) > --- > arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi | 8 > arch/arm64/boot/dts/qcom/sc7180.dtsi | 6 +- > 2 files changed, 13 insertions(+), 1 deletion(-) > > diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi > b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi > index 732e1181af48..c3559253aefc 100644 > --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi > +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor.dtsi > @@ -815,6 +815,14 @@ _dp { > data-lanes = <0 1>; > vdda-1p2-supply = <_usb_ss_dp_1p2>; > vdda-0p9-supply = <_usb_ss_dp_core>; > + > + reg = <0 0x0ae9 0 0x200>, > + <0 0x0ae90200 0 0x200>, > + <0 0x0ae90400 0 0xc00>, > + <0 0x0ae91000 0 0x400>, > + <0 0x0ae91400 0 0x400>, > + <0 0x0aed1000 0 0x175>, > + <0 0x0aee1000 0 0x2c>; > }; > > _adc { > diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi > b/arch/arm64/boot/dts/qcom/sc7180.dtsi > index e1c46b80f14a..3c3eef7a7d52 100644 > --- a/arch/arm64/boot/dts/qcom/sc7180.dtsi > +++ b/arch/arm64/boot/dts/qcom/sc7180.dtsi > @@ -3089,7 +3089,11 @@ mdss_dp: displayport-controller@ae9 { > compatible = "qcom,sc7180-dp"; > status = "disabled"; > > - reg = <0 0x0ae9 0 0x1400>; > + reg = <0 0x0ae9 0 0x200>, > + <0 0x0ae90200 0 0x200>, > + <0 0x0ae90400 0 0xc00>, > + <0 0x0ae91000 0 0x400>, > + <0 0x0ae91400 0 0x400>; This hunk stands on its own, following the DT binding changes I did earlier. Would you mind spinning it off so I can merge it separately? Thanks, Bjorn > > interrupt-parent = <>; > interrupts = <12>; > -- > Sean Paul, Software Engineer, Google / Chromium OS >
Re: [PATCH v7 4/4] drm/vc4: change vc4 driver to use drm_writeback_connector_init_with_encoder()
I am dropping this change because originally I had made this only to show usage of drm_writeback_connector_init_with_encoder(). For writeback functionality, vc4 doesnt need this and this seems redundant. To show the usage of drm_writeback_connector_init_with_encoder(), I have posted the MSM writeback driver changes here [1]. [1] https://patchwork.freedesktop.org/series/99724/ Thanks Abhinav On 4/8/2022 5:53 PM, Abhinav Kumar wrote: vc4 driver currently embeds the drm_encoder into struct vc4_txp and later on uses container_of to retrieve the vc4_txp from the drm_encoder. Make vc4 driver use the new API so that the embedded encoder model can be retained in the driver and there is no change in functionality. changes in v7: - remove the drm core changes to previous patch in the series Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/vc4/vc4_txp.c | 32 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index 7e063a9..0d461df 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -151,6 +151,8 @@ struct vc4_txp { struct platform_device *pdev; + struct drm_encoder drm_enc; + struct drm_writeback_connector connector; void __iomem *regs; @@ -159,7 +161,7 @@ struct vc4_txp { static inline struct vc4_txp *encoder_to_vc4_txp(struct drm_encoder *encoder) { - return container_of(encoder, struct vc4_txp, connector.internal_encoder); + return container_of(encoder, struct vc4_txp, drm_enc); } static inline struct vc4_txp *connector_to_vc4_txp(struct drm_connector *conn) @@ -368,6 +370,10 @@ static const struct drm_encoder_helper_funcs vc4_txp_encoder_helper_funcs = { .disable = vc4_txp_encoder_disable, }; +static const struct drm_encoder_funcs vc4_txp_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + static int vc4_txp_enable_vblank(struct drm_crtc *crtc) { return 0; @@ -467,6 +473,7 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) struct vc4_txp *txp; struct drm_crtc *crtc; struct drm_encoder *encoder; + struct drm_writeback_connector *wb_conn; int ret, irq; irq = platform_get_irq(pdev, 0); @@ -492,16 +499,25 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) txp->regset.regs = txp_regs; txp->regset.nregs = ARRAY_SIZE(txp_regs); - drm_connector_helper_add(>connector.base, -_txp_connector_helper_funcs); - ret = drm_writeback_connector_init(drm, >connector, - _txp_connector_funcs, - _txp_encoder_helper_funcs, - drm_fmts, ARRAY_SIZE(drm_fmts), - 0); + wb_conn = >connector; + + drm_encoder_helper_add(>drm_enc, _txp_encoder_helper_funcs); + + ret = drm_encoder_init(drm, >drm_enc, _txp_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, NULL); if (ret) return ret; + drm_connector_helper_add(_conn->base, _txp_connector_helper_funcs); + + ret = drm_writeback_connector_init_with_encoder(drm, wb_conn, >drm_enc, + _txp_connector_funcs, drm_fmts, ARRAY_SIZE(drm_fmts)); + + if (ret) { + drm_encoder_cleanup(>drm_enc); + return ret; + } + ret = vc4_crtc_init(drm, vc4_crtc, _txp_crtc_funcs, _txp_crtc_helper_funcs); if (ret)
[PATCH v2 10/17] drm/msm/dpu: make changes to dpu_encoder to support virtual encoder
Make changes to dpu_encoder to support virtual encoder needed to support writeback for dpu. changes in v2: - add the writeback parts to dpu_encoder_helper_phys_cleanup - rebase on tip of msm-next and fix related dependencies - get the writeback blocks directly from RM Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 71 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 3 + 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 0e31ad3..06b8631 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -928,6 +928,7 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; int num_lm, num_ctl, num_pp, num_dsc; unsigned int dsc_mask = 0; + enum dpu_hw_blk_type blk_type; int i; if (!drm_enc) { @@ -1009,12 +1010,21 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = dpu_enc->hw_pp[i]; phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); - if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) - phys->hw_intf = dpu_rm_get_intf(_kms->rm, phys->intf_idx); + if (dpu_encoder_get_intf_mode(_enc->base) == INTF_MODE_WB_LINE) + blk_type = DPU_HW_BLK_WB; + else + blk_type = DPU_HW_BLK_INTF; + + if (phys->intf_idx >= INTF_0 && phys->intf_idx < INTF_MAX) { + if (blk_type == DPU_HW_BLK_INTF) + phys->hw_intf = dpu_rm_get_intf(_kms->rm, phys->intf_idx); + else if (blk_type == DPU_HW_BLK_WB) + phys->hw_wb = dpu_rm_get_wb(_kms->rm, phys->intf_idx); + } - if (!phys->hw_intf) { + if (!phys->hw_intf && !phys->hw_wb) { DPU_ERROR_ENC(dpu_enc, - "no intf block assigned at idx: %d\n", i); + "no intf ow wb block assigned at idx: %d\n", i); return; } @@ -1157,15 +1167,22 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) mutex_unlock(_enc->enc_lock); } -static enum dpu_intf dpu_encoder_get_intf(struct dpu_mdss_cfg *catalog, +static enum dpu_intf dpu_encoder_get_intf_or_wb(struct dpu_mdss_cfg *catalog, enum dpu_intf_type type, u32 controller_id) { int i = 0; - for (i = 0; i < catalog->intf_count; i++) { - if (catalog->intf[i].type == type - && catalog->intf[i].controller_id == controller_id) { - return catalog->intf[i].id; + if (type != INTF_WB) { + for (i = 0; i < catalog->intf_count; i++) { + if (catalog->intf[i].type == type + && catalog->intf[i].controller_id == controller_id) { + return catalog->intf[i].id; + } + } + } else { + for (i = 0; i < catalog->wb_count; i++) { + if (catalog->wb[i].id == controller_id) + return catalog->wb[i].id; } } @@ -1886,16 +1903,27 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) dpu_encoder_helper_reset_mixers(phys_enc); - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - if (dpu_enc->phys_encs[i] && phys_enc->hw_intf->ops.bind_pingpong_blk) - phys_enc->hw_intf->ops.bind_pingpong_blk( - dpu_enc->phys_encs[i]->hw_intf, false, - dpu_enc->phys_encs[i]->hw_pp->idx); + if (phys_enc->hw_wb) { + /* disable the PP block */ + if (phys_enc->hw_wb->ops.bind_pingpong_blk) + phys_enc->hw_wb->ops.bind_pingpong_blk(phys_enc->hw_wb, false, + phys_enc->hw_pp->idx); - /* mark INTF flush as pending */ - if (phys_enc->hw_ctl->ops.update_pending_flush_intf) - phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl, - dpu_enc->phys_encs[i]->hw_intf->idx); + /* mark WB flush as pending */ + if (phys_enc->hw_ctl->ops.update_pending_flush_wb) + phys_enc->hw_ctl->ops.update_pending_flush_wb(ctl, phys_enc->hw_wb->idx); + } else { + for (i = 0; i < dpu_enc->num_phys_encs; i++) { + if (dpu_enc->phys_encs[i] &&
[PATCH v2 11/17] drm/msm/dpu: add encoder operations to prepare/cleanup wb job
add dpu encoder APIs to prepare and cleanup writeback job for the writeback encoder. These shall be invoked from the prepare_wb_job/cleanup_wb_job hooks of the drm_writeback framework. changes in v2: - rebased on tip of msm-next Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 34 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 16 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 5 3 files changed, 55 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 06b8631..b117cad 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -912,6 +912,40 @@ static int dpu_encoder_resource_control(struct drm_encoder *drm_enc, return 0; } +void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc, + struct drm_writeback_job *job) +{ + struct dpu_encoder_virt *dpu_enc; + int i; + + dpu_enc = to_dpu_encoder_virt(drm_enc); + + for (i = 0; i < dpu_enc->num_phys_encs; i++) { + struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; + + if (phys->ops.prepare_wb_job) + phys->ops.prepare_wb_job(phys, job); + + } +} + +void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc, + struct drm_writeback_job *job) +{ + struct dpu_encoder_virt *dpu_enc; + int i; + + dpu_enc = to_dpu_encoder_virt(drm_enc); + + for (i = 0; i < dpu_enc->num_phys_encs; i++) { + struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; + + if (phys->ops.cleanup_wb_job) + phys->ops.cleanup_wb_job(phys, job); + + } +} + static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 2903e65..6ceec1d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -180,4 +180,20 @@ bool dpu_encoder_is_widebus_enabled(const struct drm_encoder *drm_enc); */ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc); +/** + * dpu_encoder_prepare_wb_job - prepare writeback job for the encoder. + * @drm_enc:Pointer to previously created drm encoder structure + * @job:Pointer to the current drm writeback job + */ +void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc, + struct drm_writeback_job *job); + +/** + * dpu_encoder_cleanup_wb_job - cleanup writeback job for the encoder. + * @drm_enc:Pointer to previously created drm encoder structure + * @job:Pointer to the current drm writeback job + */ +void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc, + struct drm_writeback_job *job); + #endif /* __DPU_ENCODER_H__ */ 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 0b80af4..00951f3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -7,6 +7,7 @@ #ifndef __DPU_ENCODER_PHYS_H__ #define __DPU_ENCODER_PHYS_H__ +#include #include #include "dpu_kms.h" @@ -137,6 +138,10 @@ struct dpu_encoder_phys_ops { void (*restore)(struct dpu_encoder_phys *phys); int (*get_line_count)(struct dpu_encoder_phys *phys); int (*get_frame_count)(struct dpu_encoder_phys *phys); + void (*prepare_wb_job)(struct dpu_encoder_phys *phys_enc, + struct drm_writeback_job *job); + void (*cleanup_wb_job)(struct dpu_encoder_phys *phys_enc, + struct drm_writeback_job *job); }; /** -- 2.7.4
[PATCH v2 16/17] drm/msm/dpu: gracefully handle null fb commits for writeback
kms_writeback test cases also verify with a null fb for the writeback connector job. In addition there are also other commit paths which can result in kickoffs without a valid framebuffer like while closing the fb which results in the callback to drm_atomic_helper_dirtyfb() which internally triggers a commit. Add protection in the dpu driver to ensure that commits for writeback encoders without a valid fb are gracefully skipped. changes in v2: - rename dpu_encoder_has_valid_fb to dpu_encoder_is_valid_for_commit Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c| 9 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 21 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 6 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h| 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 12 5 files changed, 49 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 7763558..d65e124 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -869,6 +869,13 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) DPU_ATRACE_BEGIN("crtc_commit"); + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc->state->encoder_mask) { + if (!dpu_encoder_is_valid_for_commit(encoder)) { + DRM_DEBUG_ATOMIC("invalid FB not kicking off crtc\n"); + goto end; + } + } /* * Encoder will flush/start now, unless it has a tx pending. If so, it * may delay and flush at an irq event (e.g. ppdone) @@ -891,6 +898,8 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) dpu_encoder_kickoff(encoder); reinit_completion(_crtc->frame_done_comp); + +end: DPU_ATRACE_END("crtc_commit"); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index b1475dd..d07e3ee 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1850,6 +1850,27 @@ void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) dpu_encoder_prep_dsc(dpu_enc, dpu_enc->dsc); } +bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc) +{ + struct dpu_encoder_virt *dpu_enc; + unsigned int i; + struct dpu_encoder_phys *phys; + + dpu_enc = to_dpu_encoder_virt(drm_enc); + + if (drm_enc->encoder_type == DRM_MODE_ENCODER_VIRTUAL) { + for (i = 0; i < dpu_enc->num_phys_encs; i++) { + phys = dpu_enc->phys_encs[i]; + if (phys->ops.is_valid_for_commit && !phys->ops.is_valid_for_commit(phys)) { + DPU_DEBUG("invalid FB not kicking off\n"); + return false; + } + } + } + + return true; +} + void dpu_encoder_kickoff(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 6ceec1d..781d41c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -196,4 +196,10 @@ void dpu_encoder_prepare_wb_job(struct drm_encoder *drm_enc, void dpu_encoder_cleanup_wb_job(struct drm_encoder *drm_enc, struct drm_writeback_job *job); +/** + * dpu_encoder_is_valid_for_commit - check if encode has valid parameters for commit. + * @drm_enc:Pointer to drm encoder structure + */ +bool dpu_encoder_is_valid_for_commit(struct drm_encoder *drm_enc); + #endif /* __DPU_ENCODER_H__ */ 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 5452f98..04d037e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -142,6 +142,7 @@ struct dpu_encoder_phys_ops { struct drm_writeback_job *job); void (*cleanup_wb_job)(struct dpu_encoder_phys *phys_enc, struct drm_writeback_job *job); + bool (*is_valid_for_commit)(struct dpu_encoder_phys *phys_enc); }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 128317fe..9acbce0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -667,6 +667,16 @@ static void dpu_encoder_phys_wb_cleanup_wb_job(struct dpu_encoder_phys *phys_enc wb_enc->wb_conn = NULL; } +static bool dpu_encoder_phys_wb_is_valid_for_commit(struct dpu_encoder_phys *phys_enc) +{ + struct dpu_encoder_phys_wb *wb_enc = to_dpu_encoder_phys_wb(phys_enc); + +
[PATCH v2 05/17] drm/msm/dpu: add reset_intf_cfg operation for dpu_hw_ctl
Add a reset_intf_cfg operation for dpu_hw_ctl to reset the entire CTL path by disabling each component namely layer mixer, 3d-merge and interface blocks. Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 32 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 8 2 files changed, 40 insertions(+) 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 dc27579..524f024 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -563,6 +563,37 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, DPU_REG_WRITE(c, CTL_TOP, intf_cfg); } +static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, + struct dpu_hw_intf_cfg *cfg) +{ + struct dpu_hw_blk_reg_map *c = >hw; + u32 intf_active = 0; + u32 merge3d_active = 0; + + /* +* This API resets each portion of the CTL path namely, +* clearing the sspps staged on the lm, merge_3d block, +* interfaces etc to ensure clean teardown of the pipeline. +* This will be used for writeback to begin with to have a +* proper teardown of the writeback session but upon further +* validation, this can be extended to all interfaces. +*/ + if (cfg->merge_3d) { + merge3d_active = DPU_REG_READ(c, CTL_MERGE_3D_ACTIVE); + merge3d_active &= ~BIT(cfg->merge_3d - MERGE_3D_0); + DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, + merge3d_active); + } + + dpu_hw_ctl_clear_all_blendstages(ctx); + + if (cfg->intf) { + intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); + intf_active &= ~BIT(cfg->intf - INTF_0); + DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); + } +} + static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, unsigned long *fetch_active) { @@ -586,6 +617,7 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, if (cap & BIT(DPU_CTL_ACTIVE_CFG)) { ops->trigger_flush = dpu_hw_ctl_trigger_flush_v1; ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg_v1; + ops->reset_intf_cfg = dpu_hw_ctl_reset_intf_cfg_v1; ops->update_pending_flush_intf = dpu_hw_ctl_update_pending_flush_intf_v1; ops->update_pending_flush_merge_3d = 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 97f326d..c61a8fd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -140,6 +140,14 @@ struct dpu_hw_ctl_ops { void (*setup_intf_cfg)(struct dpu_hw_ctl *ctx, struct dpu_hw_intf_cfg *cfg); + /** +* reset ctl_path interface config +* @ctx: ctl path ctx pointer +* @cfg: interface config structure pointer +*/ + void (*reset_intf_cfg)(struct dpu_hw_ctl *ctx, + struct dpu_hw_intf_cfg *cfg); + int (*reset)(struct dpu_hw_ctl *c); /* -- 2.7.4
[PATCH v2 13/17] drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback
Introduce the dpu_encoder_phys_* for the writeback interface to handle writeback specific hardware programming. changes in v2: - rebase on msm-next and fix related dependencies namely the irq cleanup - move cdp_cfg, aspace out of dpu_encoder_phys_wb - leave a comment about wb master - start using _dpu_hw_get_qos_lut from dpu_hw_util - replace hw_pp->merge_3d check with DPU_CTL_ACTIVE_CFG Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 30 + .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 751 + 3 files changed, 782 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index ca779c1..0387f22 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -60,6 +60,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_encoder.o \ disp/dpu1/dpu_encoder_phys_cmd.o \ disp/dpu1/dpu_encoder_phys_vid.o \ + disp/dpu1/dpu_encoder_phys_wb.o \ disp/dpu1/dpu_formats.o \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ 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 00951f3..5452f98 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -150,6 +150,7 @@ struct dpu_encoder_phys_ops { * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel * @INTR_IDX_RDPTR:Readpointer done unterrupt for cmd mode panel + * @INTR_IDX_WB_DONE: Writeback fone interrupt for virtual connector */ enum dpu_intr_idx { INTR_IDX_VSYNC, @@ -157,6 +158,7 @@ enum dpu_intr_idx { INTR_IDX_UNDERRUN, INTR_IDX_CTL_START, INTR_IDX_RDPTR, + INTR_IDX_WB_DONE, INTR_IDX_MAX, }; @@ -224,6 +226,27 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) } /** + * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to handle command + * mode specific operations + * @base: Baseclass physical encoder structure + * @wbirq_refcount: Reference count of writeback interrupt + * @wb_done_timeout_cnt: number of wb done irq timeout errors + * @wb_cfg: writeback block config to store fb related details + * @wb_conn: backpointer to writeback connector + * @wb_job: backpointer to current writeback job + * @dest: dpu buffer layout for current writeback output buffer + */ +struct dpu_encoder_phys_wb { + struct dpu_encoder_phys base; + atomic_t wbirq_refcount; + int wb_done_timeout_cnt; + struct dpu_hw_wb_cfg wb_cfg; + struct drm_writeback_connector *wb_conn; + struct drm_writeback_job *wb_job; + struct dpu_hw_fmt_layout dest; +}; + +/** * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command * mode specific operations * @base: Baseclass physical encoder structure @@ -291,6 +314,13 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( struct dpu_enc_phys_init_params *p); /** + * dpu_encoder_phys_wb_init - initialize writeback encoder + * @init: Pointer to init info structure with initialization params + */ +struct dpu_encoder_phys *dpu_encoder_phys_wb_init( + struct dpu_enc_phys_init_params *p); + +/** * dpu_encoder_helper_trigger_start - control start helper function * This helper function may be optionally specified by physical * encoders if they require ctl_start triggering. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c new file mode 100644 index 000..128317fe --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -0,0 +1,751 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__ + +#include + +#include "dpu_encoder_phys.h" +#include "dpu_formats.h" +#include "dpu_hw_top.h" +#include "dpu_hw_wb.h" +#include "dpu_hw_lm.h" +#include "dpu_hw_blk.h" +#include "dpu_hw_merge3d.h" +#include "dpu_hw_interrupts.h" +#include "dpu_core_irq.h" +#include "dpu_vbif.h" +#include "dpu_crtc.h" +#include "disp/msm_disp_snapshot.h" + +#define DEFAULT_MAX_WRITEBACK_WIDTH 2048 + +#define to_dpu_encoder_phys_wb(x) \ + container_of(x, struct dpu_encoder_phys_wb, base) + +/** + * dpu_encoder_phys_wb_is_master - report wb always as master encoder + */ +static bool dpu_encoder_phys_wb_is_master(struct dpu_encoder_phys *phys_enc) +{ + /* there is only one physical enc for dpu_writeback */ + return true; +} + +/** + *
[PATCH v2 04/17] drm/msm/dpu: add writeback blocks to the sm8250 DPU catalog
Add writeback blocks to the sm8250 DPU hardware catalog. Other chipsets support writeback too but add it to sm8250 to prototype the feature so that it can be easily extended to other chipsets. changes in v2: - none Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 74 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 66 ++- 2 files changed, 138 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index b0a0ef7..bcb5273 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt)"[drm:%s:%d] " fmt, __func__, __LINE__ @@ -120,6 +121,16 @@ BIT(MDP_AD4_0_INTR) | \ BIT(MDP_AD4_1_INTR)) +#define WB_SM8250_MASK (BIT(DPU_WB_LINE_MODE) | \ +BIT(DPU_WB_UBWC) | \ +BIT(DPU_WB_YUV_CONFIG) | \ +BIT(DPU_WB_PIPE_ALPHA) | \ +BIT(DPU_WB_XY_ROI_OFFSET) | \ +BIT(DPU_WB_QOS) | \ +BIT(DPU_WB_QOS_8LVL) | \ +BIT(DPU_WB_CDP) | \ +BIT(DPU_WB_INPUT_CTRL)) + #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024) #define DEFAULT_DPU_LINE_WIDTH 2048 #define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560 @@ -211,6 +222,40 @@ static const u32 rotation_v2_formats[] = { /* TODO add formats after validation */ }; +static const uint32_t wb2_formats[] = { + DRM_FORMAT_RGB565, + DRM_FORMAT_BGR565, + DRM_FORMAT_RGB888, + DRM_FORMAT_ARGB, + DRM_FORMAT_RGBA, + DRM_FORMAT_ABGR, + DRM_FORMAT_XRGB, + DRM_FORMAT_RGBX, + DRM_FORMAT_XBGR, + DRM_FORMAT_ARGB1555, + DRM_FORMAT_RGBA5551, + DRM_FORMAT_XRGB1555, + DRM_FORMAT_RGBX5551, + DRM_FORMAT_ARGB, + DRM_FORMAT_RGBA, + DRM_FORMAT_RGBX, + DRM_FORMAT_XRGB, + DRM_FORMAT_BGR565, + DRM_FORMAT_BGR888, + DRM_FORMAT_ABGR, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRX, + DRM_FORMAT_XBGR, + DRM_FORMAT_ABGR1555, + DRM_FORMAT_BGRA5551, + DRM_FORMAT_XBGR1555, + DRM_FORMAT_BGRX5551, + DRM_FORMAT_ABGR, + DRM_FORMAT_BGRA, + DRM_FORMAT_BGRX, + DRM_FORMAT_XBGR, +}; + /* * DPU sub blocks config */ @@ -448,6 +493,8 @@ static const struct dpu_mdp_cfg sm8250_mdp[] = { .reg_off = 0x2C4, .bit_off = 8}, .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2BC, .bit_off = 20}, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { + .reg_off = 0x3B8, .bit_off = 24}, }, }; @@ -1235,6 +1282,29 @@ static const struct dpu_intf_cfg qcm2290_intf[] = { }; /* + * Writeback blocks config + */ +#define WB_BLK(_name, _id, _base, _features, _clk_ctrl, \ + __xin_id, vbif_id, _reg, _wb_done_bit) \ + { \ + .name = _name, .id = _id, \ + .base = _base, .len = 0x2c8, \ + .features = _features, \ + .format_list = wb2_formats, \ + .num_formats = ARRAY_SIZE(wb2_formats), \ + .clk_ctrl = _clk_ctrl, \ + .xin_id = __xin_id, \ + .vbif_idx = vbif_id, \ + .maxlinewidth = DEFAULT_DPU_LINE_WIDTH, \ + .intr_wb_done = DPU_IRQ_IDX(_reg, _wb_done_bit) \ + } + +static const struct dpu_wb_cfg sm8250_wb[] = { + WB_BLK("wb_2", WB_2, 0x65000, WB_SM8250_MASK, DPU_CLK_CTRL_WB2, 6, + VBIF_RT, MDP_SSPP_TOP0_INTR, 4), +}; + +/* * VBIF sub blocks config */ /* VBIF QOS remap */ @@ -1832,6 +1902,8 @@ static void sm8250_cfg_init(struct dpu_mdss_cfg *dpu_cfg) .intf = sm8150_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), .vbif = sdm845_vbif, + .wb_count = ARRAY_SIZE(sm8250_wb), + .wb = sm8250_wb, .reg_dma_count = 1, .dma_cfg = sm8250_regdma, .perf = sm8250_perf_data, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
[PATCH v2 09/17] drm/msm/dpu: add an API to reset the encoder related hw blocks
Add an API to reset the encoder related hw blocks to ensure a proper teardown of the pipeline. At the moment this is being used only for the writeback encoder but eventually we can start using this for all interfaces. changes in v2: - split the writeback part to another commit Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 82 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 7 ++ 2 files changed, 89 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 4523693..0e31ad3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -22,6 +23,7 @@ #include "dpu_hw_ctl.h" #include "dpu_hw_dspp.h" #include "dpu_hw_dsc.h" +#include "dpu_hw_merge3d.h" #include "dpu_formats.h" #include "dpu_encoder_phys.h" #include "dpu_crtc.h" @@ -1838,6 +1840,86 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc) DPU_ATRACE_END("encoder_kickoff"); } +static void dpu_encoder_helper_reset_mixers(struct dpu_encoder_phys *phys_enc) +{ + struct dpu_hw_mixer_cfg mixer; + int i, num_lm; + u32 flush_mask = 0; + struct dpu_global_state *global_state; + struct dpu_hw_blk *hw_lm[2]; + struct dpu_hw_mixer *hw_mixer[2]; + struct dpu_hw_ctl *ctl = phys_enc->hw_ctl; + + memset(, 0, sizeof(mixer)); + + /* reset all mixers for this encoder */ + if (phys_enc->hw_ctl->ops.clear_all_blendstages) + phys_enc->hw_ctl->ops.clear_all_blendstages(phys_enc->hw_ctl); + + global_state = dpu_kms_get_existing_global_state(phys_enc->dpu_kms); + + num_lm = dpu_rm_get_assigned_resources(_enc->dpu_kms->rm, global_state, + phys_enc->parent->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); + + for (i = 0; i < num_lm; i++) { + hw_mixer[i] = to_dpu_hw_mixer(hw_lm[i]); + flush_mask = phys_enc->hw_ctl->ops.get_bitmask_mixer(ctl, hw_mixer[i]->idx); + if (phys_enc->hw_ctl->ops.update_pending_flush) + phys_enc->hw_ctl->ops.update_pending_flush(ctl, flush_mask); + + /* clear all blendstages */ + if (phys_enc->hw_ctl->ops.setup_blendstage) + phys_enc->hw_ctl->ops.setup_blendstage(ctl, hw_mixer[i]->idx, NULL); + } +} + +void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) +{ + struct dpu_hw_ctl *ctl = phys_enc->hw_ctl; + struct dpu_hw_intf_cfg intf_cfg = { 0 }; + int i; + struct dpu_encoder_virt *dpu_enc; + + dpu_enc = to_dpu_encoder_virt(phys_enc->parent); + + phys_enc->hw_ctl->ops.reset(ctl); + + dpu_encoder_helper_reset_mixers(phys_enc); + + for (i = 0; i < dpu_enc->num_phys_encs; i++) { + if (dpu_enc->phys_encs[i] && phys_enc->hw_intf->ops.bind_pingpong_blk) + phys_enc->hw_intf->ops.bind_pingpong_blk( + dpu_enc->phys_encs[i]->hw_intf, false, + dpu_enc->phys_encs[i]->hw_pp->idx); + + /* mark INTF flush as pending */ + if (phys_enc->hw_ctl->ops.update_pending_flush_intf) + phys_enc->hw_ctl->ops.update_pending_flush_intf(phys_enc->hw_ctl, + dpu_enc->phys_encs[i]->hw_intf->idx); + } + + /* reset the merge 3D HW block */ + if (phys_enc->hw_pp->merge_3d) { + phys_enc->hw_pp->merge_3d->ops.setup_3d_mode(phys_enc->hw_pp->merge_3d, + BLEND_3D_NONE); + if (phys_enc->hw_ctl->ops.update_pending_flush_merge_3d) + phys_enc->hw_ctl->ops.update_pending_flush_merge_3d(ctl, + phys_enc->hw_pp->merge_3d->idx); + } + + intf_cfg.stream_sel = 0; /* Don't care value for video mode */ + intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); + if (phys_enc->hw_pp->merge_3d) + intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; + + if (ctl->ops.reset_intf_cfg) + ctl->ops.reset_intf_cfg(ctl, _cfg); + + ctl->ops.trigger_flush(ctl); + ctl->ops.trigger_start(ctl); + ctl->ops.clear_pending_flush(ctl); +} + void dpu_encoder_prepare_commit(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; 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 706b566..544a9a4 100644 ---
[PATCH v2 12/17] drm/msm/dpu: move _dpu_plane_get_qos_lut to dpu_hw_util file
_dpu_plane_get_qos_lut() is not specific to just dpu_plane. It can take any fill level and return the LUT matching it. This can be used even for other modules like dpu_writeback. Move _dpu_plane_get_qos_lut() to the common dpu_hw_util file and rename it to _dpu_hw_get_qos_lut(). Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c | 25 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h | 4 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 27 +-- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index aad8511..512316f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -422,3 +422,28 @@ void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, DPU_REG_WRITE(c, csc_reg_off + 0x3c, data->csc_post_bv[1]); DPU_REG_WRITE(c, csc_reg_off + 0x40, data->csc_post_bv[2]); } + +/** + * _dpu_hw_get_qos_lut - get LUT mapping based on fill level + * @tbl: Pointer to LUT table + * @total_fl: fill level + * Return: LUT setting corresponding to the fill level + */ +u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, + u32 total_fl) +{ + int i; + + if (!tbl || !tbl->nentry || !tbl->entries) + return 0; + + for (i = 0; i < tbl->nentry; i++) + if (total_fl <= tbl->entries[i].fl) + return tbl->entries[i].lut; + + /* if last fl is zero, use as default */ + if (!tbl->entries[i-1].fl) + return tbl->entries[i-1].lut; + + return 0; +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h index 3913475..529a6e0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -9,6 +9,7 @@ #include #include #include "dpu_hw_mdss.h" +#include "dpu_hw_catalog.h" #define REG_MASK(n) ((BIT(n)) - 1) @@ -324,4 +325,7 @@ void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c, u32 csc_reg_off, const struct dpu_csc_cfg *data, bool csc10); +u64 _dpu_hw_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, + u32 total_fl); + #endif /* _DPU_HW_UTIL_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index c77c3d9d..730f0a3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -280,31 +280,6 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane, } /** - * _dpu_plane_get_qos_lut - get LUT mapping based on fill level - * @tbl: Pointer to LUT table - * @total_fl: fill level - * Return: LUT setting corresponding to the fill level - */ -static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, - u32 total_fl) -{ - int i; - - if (!tbl || !tbl->nentry || !tbl->entries) - return 0; - - for (i = 0; i < tbl->nentry; i++) - if (total_fl <= tbl->entries[i].fl) - return tbl->entries[i].lut; - - /* if last fl is zero, use as default */ - if (!tbl->entries[i-1].fl) - return tbl->entries[i-1].lut; - - return 0; -} - -/** * _dpu_plane_set_qos_lut - set QoS LUT of the given plane * @plane: Pointer to drm plane * @fb:Pointer to framebuffer associated with the given plane @@ -333,7 +308,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, lut_usage = DPU_QOS_LUT_USAGE_MACROTILE; } - qos_lut = _dpu_plane_get_qos_lut( + qos_lut = _dpu_hw_get_qos_lut( >catalog->perf.qos_lut_tbl[lut_usage], total_fl); trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0, -- 2.7.4
[PATCH v2 17/17] drm/msm/dpu: add writeback blocks to the display snapshot
Add writeback block information while capturing the display snapshot. Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 0a50509..86c98db 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -944,6 +944,11 @@ static void dpu_kms_mdp_snapshot(struct msm_disp_state *disp_state, struct msm_k msm_disp_snapshot_add_block(disp_state, cat->mixer[i].len, dpu_kms->mmio + cat->mixer[i].base, "lm_%d", i); + /* dump WB sub-blocks HW regs info */ + for (i = 0; i < cat->wb_count; i++) + msm_disp_snapshot_add_block(disp_state, cat->wb[i].len, + dpu_kms->mmio + cat->wb[i].base, "wb_%d", i); + msm_disp_snapshot_add_block(disp_state, top->hw.length, dpu_kms->mmio + top->hw.blk_off, "top"); -- 2.7.4
[PATCH v2 07/17] drm/msm/dpu: add writeback blocks to DPU RM
Add writeback blocks to DPU resource manager so that the encoders can directly request them through RM. changes in v2: - stop global tracking of WB blocks similar to INTF - align usage of hw_wb to be similar to that of hw_intf Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 22 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 12 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 0e6634b..bb01d31 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -9,6 +9,7 @@ #include "dpu_hw_ctl.h" #include "dpu_hw_pingpong.h" #include "dpu_hw_intf.h" +#include "dpu_hw_wb.h" #include "dpu_hw_dspp.h" #include "dpu_hw_merge3d.h" #include "dpu_hw_dsc.h" @@ -87,6 +88,9 @@ int dpu_rm_destroy(struct dpu_rm *rm) } } + for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++) + dpu_hw_wb_destroy(rm->hw_wb[i]); + return 0; } @@ -186,6 +190,24 @@ int dpu_rm_init(struct dpu_rm *rm, rm->hw_intf[intf->id - INTF_0] = hw; } + for (i = 0; i < cat->wb_count; i++) { + struct dpu_hw_wb *hw; + const struct dpu_wb_cfg *wb = >wb[i]; + + if (wb->id < WB_0 || wb->id >= WB_MAX) { + DPU_ERROR("skip intf %d with invalid id\n", wb->id); + continue; + } + + hw = dpu_hw_wb_init(wb->id, mmio, cat); + if (IS_ERR_OR_NULL(hw)) { + rc = PTR_ERR(hw); + DPU_ERROR("failed wb object creation: err %d\n", rc); + goto fail; + } + rm->hw_wb[wb->id - WB_0] = hw; + } + for (i = 0; i < cat->ctl_count; i++) { struct dpu_hw_ctl *hw; const struct dpu_ctl_cfg *ctl = >ctl[i]; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index 32e0d8a..ba82e54 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -19,6 +19,7 @@ struct dpu_global_state; * @mixer_blks: array of layer mixer hardware resources * @ctl_blks: array of ctl hardware resources * @hw_intf: array of intf hardware resources + * @hw_wb: array of wb hardware resources * @dspp_blks: array of dspp hardware resources */ struct dpu_rm { @@ -26,6 +27,7 @@ struct dpu_rm { struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0]; struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0]; struct dpu_hw_intf *hw_intf[INTF_MAX - INTF_0]; + struct dpu_hw_wb *hw_wb[WB_MAX - WB_0]; struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0]; struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0]; struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0]; @@ -96,5 +98,15 @@ static inline struct dpu_hw_intf *dpu_rm_get_intf(struct dpu_rm *rm, enum dpu_in return rm->hw_intf[intf_idx - INTF_0]; } +/** + * dpu_rm_get_wb - Return a struct dpu_hw_wb instance given it's index. + * @rm: DPU Resource Manager handle + * @wb_idx: WB index + */ +static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_intf wb_idx) +{ + return rm->hw_wb[wb_idx - WB_0]; +} + #endif /* __DPU_RM_H__ */ -- 2.7.4
[PATCH v2 15/17] drm/msm/dpu: initialize dpu encoder and connector for writeback
Initialize dpu encoder and connector for writeback if the target supports it in the catalog. changes in v2: - start initialing the encoder for writeback since we have migrated to using drm_writeback_connector_init_with_encoder() - instead of checking for WB_2 inside _dpu_kms_initialize_writeback call it only when its WB_2 - rebase on tip of msm-next and remove usage of priv->encoders Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 27 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 58 + 2 files changed, 78 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index b117cad..b1475dd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2085,7 +2085,7 @@ static void dpu_encoder_early_unregister(struct drm_encoder *encoder) } static int dpu_encoder_virt_add_phys_encs( - u32 display_caps, + struct msm_display_info *disp_info, struct dpu_encoder_virt *dpu_enc, struct dpu_enc_phys_init_params *params) { @@ -2104,7 +2104,7 @@ static int dpu_encoder_virt_add_phys_encs( return -EINVAL; } - if (display_caps & MSM_DISPLAY_CAP_VID_MODE) { + if (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE) { enc = dpu_encoder_phys_vid_init(params); if (IS_ERR_OR_NULL(enc)) { @@ -2117,7 +2117,7 @@ static int dpu_encoder_virt_add_phys_encs( ++dpu_enc->num_phys_encs; } - if (display_caps & MSM_DISPLAY_CAP_CMD_MODE) { + if (disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) { enc = dpu_encoder_phys_cmd_init(params); if (IS_ERR_OR_NULL(enc)) { @@ -2130,6 +2130,19 @@ static int dpu_encoder_virt_add_phys_encs( ++dpu_enc->num_phys_encs; } + if (disp_info->intf_type == DRM_MODE_ENCODER_VIRTUAL) { + enc = dpu_encoder_phys_wb_init(params); + + if (IS_ERR_OR_NULL(enc)) { + DPU_ERROR_ENC(dpu_enc, "failed to init wb enc: %ld\n", + PTR_ERR(enc)); + return enc == NULL ? -EINVAL : PTR_ERR(enc); + } + + dpu_enc->phys_encs[dpu_enc->num_phys_encs] = enc; + ++dpu_enc->num_phys_encs; + } + if (params->split_role == ENC_ROLE_SLAVE) dpu_enc->cur_slave = enc; else @@ -2220,9 +2233,8 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, } if (!ret) { - ret = dpu_encoder_virt_add_phys_encs(disp_info->capabilities, - dpu_enc, - _params); + ret = dpu_encoder_virt_add_phys_encs(disp_info, + dpu_enc, _params); if (ret) DPU_ERROR_ENC(dpu_enc, "failed to add phys encs\n"); } @@ -2339,8 +2351,9 @@ struct drm_encoder *dpu_encoder_init(struct drm_device *dev, if (!dpu_enc) return ERR_PTR(-ENOMEM); + rc = drm_encoder_init(dev, _enc->base, _encoder_funcs, - drm_enc_mode, NULL); + drm_enc_mode, NULL); if (rc) { devm_kfree(dev->dev, dpu_enc); return ERR_PTR(rc); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index c683cab..0a50509 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -15,6 +16,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_mmu.h" @@ -29,6 +31,7 @@ #include "dpu_kms.h" #include "dpu_plane.h" #include "dpu_vbif.h" +#include "dpu_writeback.h" #define CREATE_TRACE_POINTS #include "dpu_trace.h" @@ -648,6 +651,45 @@ static int _dpu_kms_initialize_displayport(struct drm_device *dev, return 0; } +static int _dpu_kms_initialize_writeback(struct drm_device *dev, + struct msm_drm_private *priv, struct dpu_kms *dpu_kms, + const u32 *wb_formats, int n_formats) +{ + struct drm_encoder *encoder = NULL; + struct msm_display_info info; + int rc; + + encoder = dpu_encoder_init(dev,
[PATCH v2 14/17] drm/msm/dpu: add the writeback connector layer
Introduce the dpu_writeback module which serves as the interface between dpu operations and the drm_writeback. This module manages the connector related operations for dpu writeback. changes in v2: - start using drm_writeback_connector_init_with_encoder() - drop unnecessary arguments from dpu_writeback_init() - rebase on msm-next tip and remove usage of priv->connectors Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c | 68 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h | 25 ++ 3 files changed, 94 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 0387f22..66395ee 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -80,6 +80,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_plane.o \ disp/dpu1/dpu_rm.o \ disp/dpu1/dpu_vbif.o \ + disp/dpu1/dpu_writeback.o msm-$(CONFIG_DRM_MSM_MDSS) += \ msm_mdss.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c new file mode 100644 index 000..526d884 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "dpu_writeback.h" + +static int dpu_wb_conn_get_modes(struct drm_connector *connector) +{ + struct drm_device *dev = connector->dev; + + return drm_add_modes_noedid(connector, dev->mode_config.max_width, + dev->mode_config.max_height); +} + +static const struct drm_connector_funcs dpu_wb_conn_funcs = { + .reset = drm_atomic_helper_connector_reset, + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static int dpu_wb_conn_prepare_job(struct drm_writeback_connector *connector, + struct drm_writeback_job *job) +{ + if (!job->fb) + return 0; + + dpu_encoder_prepare_wb_job(connector->encoder, job); + + return 0; +} + +static void dpu_wb_conn_cleanup_job(struct drm_writeback_connector *connector, + struct drm_writeback_job *job) +{ + if (!job->fb) + return; + + dpu_encoder_cleanup_wb_job(connector->encoder, job); +} + +static const struct drm_connector_helper_funcs dpu_wb_conn_helper_funcs = { + .get_modes = dpu_wb_conn_get_modes, + .prepare_writeback_job = dpu_wb_conn_prepare_job, + .cleanup_writeback_job = dpu_wb_conn_cleanup_job, +}; + +int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc, + const u32 *format_list, u32 num_formats) +{ + struct dpu_wb_connector *dpu_wb_conn; + int rc = 0; + + dpu_wb_conn = devm_kzalloc(dev->dev, sizeof(*dpu_wb_conn), GFP_KERNEL); + + drm_connector_helper_add(_wb_conn->base.base, _wb_conn_helper_funcs); + + /* DPU initializes the encoder and sets it up completely for writeback +* cases and hence should use the new API drm_writeback_connector_init_with_encoder +* to initialize the writeback connector +*/ + rc = drm_writeback_connector_init_with_encoder(dev, _wb_conn->base, enc, + _wb_conn_funcs, format_list, num_formats); + + return rc; +} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h new file mode 100644 index 000..05aff05 --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _DPU_WRITEBACK_H +#define _DPU_WRITEBACK_H + +#include +#include +#include +#include + +#include "msm_drv.h" +#include "dpu_kms.h" +#include "dpu_encoder_phys.h" + +struct dpu_wb_connector { + struct drm_writeback_connector base; +}; + +int dpu_writeback_init(struct drm_device *dev, struct drm_encoder *enc, + const u32 *format_list, u32 num_formats); + +#endif /*_DPU_WRITEBACK_H */ -- 2.7.4
[PATCH v2 02/17] drm: introduce drm_writeback_connector_init_with_encoder() API
For vendors drivers which pass an already allocated and initialized encoder especially for cases where the encoder hardware is shared OR the writeback encoder shares the resources with the rest of the display pipeline introduce a new API, drm_writeback_connector_init_with_encoder() which expects an initialized encoder as a parameter and only sets up the writeback connector. changes in v4: - removed the possible_crtcs part changes in v5: - reorder this change to come before in the series to avoid incorrect functionality in subsequent changes - continue using struct drm_encoder instead of struct drm_encoder * and switch it in next change changes in v6: - remove drm_writeback_connector_setup() and instead directly call drm_writeback_connector_init_with_encoder() - fix a drm_writeback_connector typo and function doc which incorrectly shows that the function accepts enc_helper_funcs - pass encoder as a parameter explicitly to the new API for better readability changes in v7: - fix the function doc slightly as suggested by Liviu Reviewed-by: Liviu Dudau Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/drm_writeback.c | 72 + include/drm/drm_writeback.h | 6 2 files changed, 64 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index 9e0b845..92658ad 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -178,6 +178,62 @@ int drm_writeback_connector_init(struct drm_device *dev, const u32 *formats, int n_formats, u32 possible_crtcs) { + int ret = 0; + + drm_encoder_helper_add(_connector->encoder, enc_helper_funcs); + + wb_connector->encoder.possible_crtcs = possible_crtcs; + + ret = drm_encoder_init(dev, _connector->encoder, + _writeback_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, NULL); + if (ret) + return ret; + + ret = drm_writeback_connector_init_with_encoder(dev, wb_connector, _connector->encoder, + con_funcs, formats, n_formats); + + if (ret) + drm_encoder_cleanup(_connector->encoder); + + return ret; +} +EXPORT_SYMBOL(drm_writeback_connector_init); + +/** + * drm_writeback_connector_init_with_encoder - Initialize a writeback connector and its properties + * using the encoder which already assigned and initialized + * + * @dev: DRM device + * @wb_connector: Writeback connector to initialize + * @enc: handle to the already initialized drm encoder + * @con_funcs: Connector funcs vtable + * @formats: Array of supported pixel formats for the writeback engine + * @n_formats: Length of the formats array + * + * This function creates the writeback-connector-specific properties if they + * have not been already created, initializes the connector as + * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property + * values. + * + * This function assumes that the drm_writeback_connector's encoder has already been + * created and initialized before invoking this function. + * + * In addition, this function also assumes that callers of this API will manage + * assigning the encoder helper functions, possible_crtcs and any other encoder + * specific operation. + * + * Drivers should always use this function instead of drm_connector_init() to + * set up writeback connectors if they want to manage themselves the lifetime of the + * associated encoder. + * + * Returns: 0 on success, or a negative error code + */ +int drm_writeback_connector_init_with_encoder(struct drm_device *dev, + struct drm_writeback_connector *wb_connector, struct drm_encoder *enc, + const struct drm_connector_funcs *con_funcs, const u32 *formats, + int n_formats) +{ struct drm_property_blob *blob; struct drm_connector *connector = _connector->base; struct drm_mode_config *config = >mode_config; @@ -191,15 +247,6 @@ int drm_writeback_connector_init(struct drm_device *dev, if (IS_ERR(blob)) return PTR_ERR(blob); - drm_encoder_helper_add(_connector->encoder, enc_helper_funcs); - - wb_connector->encoder.possible_crtcs = possible_crtcs; - - ret = drm_encoder_init(dev, _connector->encoder, - _writeback_encoder_funcs, - DRM_MODE_ENCODER_VIRTUAL, NULL); - if (ret) - goto fail; connector->interlace_allowed = 0; @@ -208,8 +255,7 @@ int drm_writeback_connector_init(struct drm_device *dev, if (ret) goto connector_fail; - ret = drm_connector_attach_encoder(connector, -
[PATCH v2 08/17] drm/msm/dpu: add changes to support writeback in hw_ctl
Add changes to support writeback module in the dpu_hw_ctl interface. changes in v2: - keep only the wb specific changes to reset_intf_cfg - use cfg->intf / cfg->wb to identify intf or wb - use bit-wise OR for the wb bits while programming Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 43 +++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 15 ++- 2 files changed, 53 insertions(+), 5 deletions(-) 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 524f024..495a9cd 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #include @@ -23,10 +24,12 @@ #define CTL_SW_RESET 0x030 #define CTL_LAYER_EXTN_OFFSET 0x40 #define CTL_MERGE_3D_ACTIVE 0x0E4 +#define CTL_WB_ACTIVE 0x0EC #define CTL_INTF_ACTIVE 0x0F4 #define CTL_MERGE_3D_FLUSH0x100 #define CTL_DSC_ACTIVE0x0E8 #define CTL_DSC_FLUSH0x104 +#define CTL_WB_FLUSH 0x108 #define CTL_INTF_FLUSH0x110 #define CTL_INTF_MASTER 0x134 #define CTL_FETCH_PIPE_ACTIVE 0x0FC @@ -38,6 +41,7 @@ #define MERGE_3D_IDX 23 #define DSC_IDX22 #define INTF_IDX 31 +#define WB_IDX 16 #define CTL_INVALID_BIT 0x #define CTL_DEFAULT_GROUP_ID 0xf @@ -135,6 +139,9 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) if (ctx->pending_flush_mask & BIT(INTF_IDX)) DPU_REG_WRITE(>hw, CTL_INTF_FLUSH, ctx->pending_intf_flush_mask); + if (ctx->pending_flush_mask & BIT(WB_IDX)) + DPU_REG_WRITE(>hw, CTL_WB_FLUSH, + ctx->pending_wb_flush_mask); DPU_REG_WRITE(>hw, CTL_FLUSH, ctx->pending_flush_mask); } @@ -255,6 +262,13 @@ static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx, } } +static void dpu_hw_ctl_update_pending_flush_wb_v1(struct dpu_hw_ctl *ctx, + enum dpu_wb wb) +{ + ctx->pending_wb_flush_mask |= BIT(wb - WB_0); + ctx->pending_flush_mask |= BIT(WB_IDX); +} + static void dpu_hw_ctl_update_pending_flush_intf_v1(struct dpu_hw_ctl *ctx, enum dpu_intf intf) { @@ -504,6 +518,7 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, { struct dpu_hw_blk_reg_map *c = >hw; u32 intf_active = 0; + u32 wb_active = 0; u32 mode_sel = 0; /* CTL_TOP[31:28] carries group_id to collate CTL paths @@ -519,11 +534,20 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD) mode_sel |= BIT(17); - intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); - intf_active |= BIT(cfg->intf - INTF_0); + if (cfg->intf) { + intf_active = DPU_REG_READ(c, CTL_INTF_ACTIVE); + intf_active |= BIT(cfg->intf - INTF_0); + } + + if (cfg->wb) { + wb_active = DPU_REG_READ(c, CTL_WB_ACTIVE); + wb_active |= BIT(cfg->wb - WB_0); + } DPU_REG_WRITE(c, CTL_TOP, mode_sel); DPU_REG_WRITE(c, CTL_INTF_ACTIVE, intf_active); + DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); + if (cfg->merge_3d) DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); @@ -546,6 +570,9 @@ static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, intf_cfg |= (cfg->mode_3d - 0x1) << 20; } + if (cfg->wb) + intf_cfg |= (cfg->wb & 0x3) + 2; + switch (cfg->intf_mode_sel) { case DPU_CTL_MODE_SEL_VID: intf_cfg &= ~BIT(17); @@ -568,12 +595,13 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, { struct dpu_hw_blk_reg_map *c = >hw; u32 intf_active = 0; + u32 wb_active = 0; u32 merge3d_active = 0; /* * This API resets each portion of the CTL path namely, * clearing the sspps staged on the lm, merge_3d block, -* interfaces etc to ensure clean teardown of the pipeline. +* interfaces , writeback etc to ensure clean teardown of the pipeline. * This will be used for writeback to begin with to have a * proper teardown of the writeback session but upon further * validation, this can be extended to all interfaces. @@ -592,6 +620,12 @@ static void
[PATCH v2 06/17] drm/msm/dpu: add dpu_hw_wb abstraction for writeback blocks
Add the dpu_hw_wb abstraction to program registers related to the writeback block. These will be invoked once all the configuration is set and ready to be programmed to the registers. changes in v2: - remove multiple empty lines at the end of the file - change dpu_hw_wb_bind_pingpong_blk to preserve upper bits Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 273 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 131 ++ 3 files changed, 405 insertions(+) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index d5ca2e6..ca779c1 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -74,6 +74,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_top.o \ disp/dpu1/dpu_hw_util.o \ disp/dpu1/dpu_hw_vbif.o \ + disp/dpu1/dpu_hw_wb.o \ disp/dpu1/dpu_kms.o \ disp/dpu1/dpu_plane.o \ disp/dpu1/dpu_rm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c new file mode 100644 index 000..afa8aab --- /dev/null +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved + */ + +#include "dpu_hw_mdss.h" +#include "dpu_hwio.h" +#include "dpu_hw_catalog.h" +#include "dpu_hw_wb.h" +#include "dpu_formats.h" +#include "dpu_kms.h" + +#define WB_DST_FORMAT 0x000 +#define WB_DST_OP_MODE0x004 +#define WB_DST_PACK_PATTERN 0x008 +#define WB_DST0_ADDR 0x00C +#define WB_DST1_ADDR 0x010 +#define WB_DST2_ADDR 0x014 +#define WB_DST3_ADDR 0x018 +#define WB_DST_YSTRIDE0 0x01C +#define WB_DST_YSTRIDE1 0x020 +#define WB_DST_YSTRIDE1 0x020 +#define WB_DST_DITHER_BITDEPTH0x024 +#define WB_DST_MATRIX_ROW00x030 +#define WB_DST_MATRIX_ROW10x034 +#define WB_DST_MATRIX_ROW20x038 +#define WB_DST_MATRIX_ROW30x03C +#define WB_DST_WRITE_CONFIG 0x048 +#define WB_ROTATION_DNSCALER 0x050 +#define WB_ROTATOR_PIPE_DOWNSCALER0x054 +#define WB_N16_INIT_PHASE_X_C03 0x060 +#define WB_N16_INIT_PHASE_X_C12 0x064 +#define WB_N16_INIT_PHASE_Y_C03 0x068 +#define WB_N16_INIT_PHASE_Y_C12 0x06C +#define WB_OUT_SIZE 0x074 +#define WB_ALPHA_X_VALUE 0x078 +#define WB_DANGER_LUT 0x084 +#define WB_SAFE_LUT 0x088 +#define WB_QOS_CTRL 0x090 +#define WB_CREQ_LUT_0 0x098 +#define WB_CREQ_LUT_1 0x09C +#define WB_UBWC_STATIC_CTRL 0x144 +#define WB_MUX0x150 +#define WB_CROP_CTRL 0x154 +#define WB_CROP_OFFSET0x158 +#define WB_CSC_BASE 0x260 +#define WB_DST_ADDR_SW_STATUS 0x2B0 +#define WB_CDP_CNTL 0x2B4 +#define WB_OUT_IMAGE_SIZE 0x2C0 +#define WB_OUT_XY 0x2C4 + +/* WB_QOS_CTRL */ +#define WB_QOS_CTRL_DANGER_SAFE_ENBIT(0) + +static const struct dpu_wb_cfg *_wb_offset(enum dpu_wb wb, + const struct dpu_mdss_cfg *m, void __iomem *addr, + struct dpu_hw_blk_reg_map *b) +{ + int i; + + for (i = 0; i < m->wb_count; i++) { + if (wb == m->wb[i].id) { + b->base_off = addr; + b->blk_off = m->wb[i].base; + b->length = m->wb[i].len; + b->hwversion = m->hwversion; + return >wb[i]; + } + } + return ERR_PTR(-EINVAL); +} + +static void dpu_hw_wb_setup_outaddress(struct dpu_hw_wb *ctx, + struct dpu_hw_wb_cfg *data) +{ + struct dpu_hw_blk_reg_map *c = >hw; + + DPU_REG_WRITE(c, WB_DST0_ADDR, data->dest.plane_addr[0]); + DPU_REG_WRITE(c, WB_DST1_ADDR, data->dest.plane_addr[1]); + DPU_REG_WRITE(c, WB_DST2_ADDR, data->dest.plane_addr[2]); + DPU_REG_WRITE(c, WB_DST3_ADDR, data->dest.plane_addr[3]); +} + +static void dpu_hw_wb_setup_format(struct dpu_hw_wb *ctx, + struct dpu_hw_wb_cfg *data) +{ + struct dpu_hw_blk_reg_map *c = >hw; + const struct dpu_format *fmt =
[PATCH v2 03/17] drm: allow real encoder to be passed for drm_writeback_connector
For some vendor driver implementations, display hardware can be shared between the encoder used for writeback and the physical display. In addition resources such as clocks and interrupts can also be shared between writeback and the real encoder. To accommodate such vendor drivers and hardware, allow real encoder to be passed for drm_writeback_connector. For existing clients, drm_writeback_connector_init() will use an internal_encoder under the hood and hence no changes will be needed. changes in v7: - move this change before the vc4 change in the series to minimize the changes to vendor drivers in drm core changes Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/drm_writeback.c | 18 -- drivers/gpu/drm/vc4/vc4_txp.c | 4 ++-- include/drm/drm_writeback.h | 22 -- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index 92658ad..0538674 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -180,21 +180,21 @@ int drm_writeback_connector_init(struct drm_device *dev, { int ret = 0; - drm_encoder_helper_add(_connector->encoder, enc_helper_funcs); + drm_encoder_helper_add(_connector->internal_encoder, enc_helper_funcs); - wb_connector->encoder.possible_crtcs = possible_crtcs; + wb_connector->internal_encoder.possible_crtcs = possible_crtcs; - ret = drm_encoder_init(dev, _connector->encoder, + ret = drm_encoder_init(dev, _connector->internal_encoder, _writeback_encoder_funcs, DRM_MODE_ENCODER_VIRTUAL, NULL); if (ret) return ret; - ret = drm_writeback_connector_init_with_encoder(dev, wb_connector, _connector->encoder, - con_funcs, formats, n_formats); + ret = drm_writeback_connector_init_with_encoder(dev, wb_connector, + _connector->internal_encoder, con_funcs, formats, n_formats); if (ret) - drm_encoder_cleanup(_connector->encoder); + drm_encoder_cleanup(_connector->internal_encoder); return ret; } @@ -239,6 +239,12 @@ int drm_writeback_connector_init_with_encoder(struct drm_device *dev, struct drm_mode_config *config = >mode_config; int ret = create_writeback_properties(dev); + /* +* Assign the encoder passed to this API to the wb_connector's encoder. +* For drm_writeback_connector_init(), this shall be the internal_encoder +*/ + wb_connector->encoder = enc; + if (ret != 0) return ret; diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index 3447eb6..7e063a9 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -159,7 +159,7 @@ struct vc4_txp { static inline struct vc4_txp *encoder_to_vc4_txp(struct drm_encoder *encoder) { - return container_of(encoder, struct vc4_txp, connector.encoder); + return container_of(encoder, struct vc4_txp, connector.internal_encoder); } static inline struct vc4_txp *connector_to_vc4_txp(struct drm_connector *conn) @@ -507,7 +507,7 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; - encoder = >connector.encoder; + encoder = txp->connector.encoder; encoder->possible_crtcs = drm_crtc_mask(crtc); ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0, diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h index bb306fa..3fbae9d 100644 --- a/include/drm/drm_writeback.h +++ b/include/drm/drm_writeback.h @@ -25,13 +25,31 @@ struct drm_writeback_connector { struct drm_connector base; /** -* @encoder: Internal encoder used by the connector to fulfill +* @encoder: handle to drm_encoder used by the connector to fulfill * the DRM framework requirements. The users of the * @drm_writeback_connector control the behaviour of the @encoder * by passing the @enc_funcs parameter to drm_writeback_connector_init() * function. +* +* For some vendor drivers, the hardware resources are shared between +* writeback encoder and rest of the display pipeline. +* To accommodate such cases, encoder is a handle to the real encoder +* hardware. +* +* For current existing writeback users, this shall continue to be the +* embedded encoder for the writeback connector. +*/ + struct drm_encoder *encoder; + + /** +* @internal_encoder: internal encoder used by writeback when +* drm_writeback_connector_init() is used. +* @encoder will be assigned to this for those cases +* +* This will be unused when
[PATCH v2 01/17] drm: allow passing possible_crtcs to drm_writeback_connector_init()
Clients of drm_writeback_connector_init() initialize the possible_crtcs and then invoke the call to this API. To simplify things, allow passing possible_crtcs as a parameter to drm_writeback_connector_init() and make changes to the other drm drivers to make them compatible with this change. changes in v2: - split the changes according to their functionality changes in v3: - allow passing possible_crtcs for existing users of drm_writeback_connector_init() - squash the vendor changes into the same commit so that each patch in the series can compile individually changes in v4: - keep only changes related to possible_crtcs - add line breaks after ARRAY_SIZE - stop using temporary variables for possible_crtcs changes in v5: - None changes in v6: - None changes in v7: - wrap long lines to match the coding style of existing drivers - Fix indentation and remove parenthesis where not needed - use u32 instead of uint32_t for possible_crtcs Signed-off-by: Abhinav Kumar Acked-by: Liviu Dudau Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c | 4 ++-- drivers/gpu/drm/arm/malidp_mw.c | 4 ++-- drivers/gpu/drm/drm_writeback.c | 7 ++- drivers/gpu/drm/rcar-du/rcar_du_writeback.c | 4 ++-- drivers/gpu/drm/vc4/vc4_txp.c| 3 ++- drivers/gpu/drm/vkms/vkms_writeback.c| 4 ++-- include/drm/drm_writeback.h | 3 ++- 7 files changed, 18 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c index e465cc4..ce4b760 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c @@ -155,7 +155,6 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, kwb_conn->wb_layer = kcrtc->master->wb_layer; wb_conn = _conn->base; - wb_conn->encoder.possible_crtcs = BIT(drm_crtc_index(>base)); formats = komeda_get_layer_fourcc_list(>fmt_tbl, kwb_conn->wb_layer->layer_type, @@ -164,7 +163,8 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, err = drm_writeback_connector_init(>base, wb_conn, _wb_connector_funcs, _wb_encoder_helper_funcs, - formats, n_formats); + formats, n_formats, + BIT(drm_crtc_index(>base))); komeda_put_fourcc_list(formats); if (err) { kfree(kwb_conn); diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c index f5847a7..204c869 100644 --- a/drivers/gpu/drm/arm/malidp_mw.c +++ b/drivers/gpu/drm/arm/malidp_mw.c @@ -212,7 +212,6 @@ int malidp_mw_connector_init(struct drm_device *drm) if (!malidp->dev->hw->enable_memwrite) return 0; - malidp->mw_connector.encoder.possible_crtcs = 1 << drm_crtc_index(>crtc); drm_connector_helper_add(>mw_connector.base, _mw_connector_helper_funcs); @@ -223,7 +222,8 @@ int malidp_mw_connector_init(struct drm_device *drm) ret = drm_writeback_connector_init(drm, >mw_connector, _mw_connector_funcs, _mw_encoder_helper_funcs, - formats, n_formats); + formats, n_formats, + 1 << drm_crtc_index(>crtc)); kfree(formats); if (ret) return ret; diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index dccf4504..9e0b845 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -157,6 +157,7 @@ static const struct drm_encoder_funcs drm_writeback_encoder_funcs = { * @enc_helper_funcs: Encoder helper funcs vtable to be used by the internal encoder * @formats: Array of supported pixel formats for the writeback engine * @n_formats: Length of the formats array + * @possible_crtcs: possible crtcs for the internal writeback encoder * * This function creates the writeback-connector-specific properties if they * have not been already created, initializes the connector as @@ -174,7 +175,8 @@ int drm_writeback_connector_init(struct drm_device *dev, struct drm_writeback_connector *wb_connector, const struct drm_connector_funcs *con_funcs, const struct drm_encoder_helper_funcs *enc_helper_funcs, -
[PATCH v2 00/17] Add writeback block support for DPU
This series adds support for writeback block on DPU. Writeback block is extremely useful to validate boards having no physical displays in addition to many other use-cases where we want to get the output of the display pipeline to examine whether issue is with the display pipeline or with the panel. These changes have been validated on SM8250 RB5 boards with IGT KMS writeback test-suite thereby further increasing the IGT test coverage for DPU. I am sharing the test results below. root@linaro-developer:~/igt_repo/igt-gpu-tools/build/tests# ./kms_writeback [ 35.066157] Console: switching to colour dummy device 80x25 [ 35.071964] [IGT] kms_writeback: executing IGT-Version: 1.26-gae2eb9e1 (aarch64) (Linux: 5.16.0-rc2-62171-g132577e2697b aarch64) [ 35.611418] [IGT] kms_writeback: starting subtest writeback-pixel-formats Starting subtest: writeback-pixel-formats [ 35.618528] [IGT] kms_writeback: starting subtest writeback-invalid-parameters Subtest writeback-pixel-formats: SUCCESS (0.000s) Starting subtest: writeback-invalid-parameters Subtest writeback-invalid-parameters: SUCCESS (0.028s) 35.657437] [IGT] kms_writeback: starting subtest writeback-fb-id Starting subtest: writeback-fb-id Subtest writeback-fb-id: SUCCESS (0.030s) [ 35.698957] [IGT] kms_writeback: starting subtest writeback-check-output Starting subtest: writeback-check-output [ 35.852834] [IGT] kms_writeback: exiting, ret=0 Subtest writeback-check-output: SUCCESS (0.142s) [ 35.861291] Console: switching to colour frame buffer device 240x67 root@linaro-developer:~/igt_repo/igt-gpu-tools/build/tests# The changes can easily be extended to support any other chipset using the DPU driver by adding the support in the catalog. Writeback block supports various formats and features. The support for all of them can be incrementally added on top of this framework when validation is improved and the test frameworks are extended to validate them. changes in v2: - rebase on tip of msm-next and address related dependencies - fix review comments from Dmitry - absorb the DRM writeback core changes which have been acked in this series so that it can be landed together Abhinav Kumar (17): drm: allow passing possible_crtcs to drm_writeback_connector_init() drm: introduce drm_writeback_connector_init_with_encoder() API drm: allow real encoder to be passed for drm_writeback_connector drm/msm/dpu: add writeback blocks to the sm8250 DPU catalog drm/msm/dpu: add reset_intf_cfg operation for dpu_hw_ctl drm/msm/dpu: add dpu_hw_wb abstraction for writeback blocks drm/msm/dpu: add writeback blocks to DPU RM drm/msm/dpu: add changes to support writeback in hw_ctl drm/msm/dpu: add an API to reset the encoder related hw blocks drm/msm/dpu: make changes to dpu_encoder to support virtual encoder drm/msm/dpu: add encoder operations to prepare/cleanup wb job drm/msm/dpu: move _dpu_plane_get_qos_lut to dpu_hw_util file drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback drm/msm/dpu: add the writeback connector layer drm/msm/dpu: initialize dpu encoder and connector for writeback drm/msm/dpu: gracefully handle null fb commits for writeback drm/msm/dpu: add writeback blocks to the display snapshot .../drm/arm/display/komeda/komeda_wb_connector.c | 4 +- drivers/gpu/drm/arm/malidp_mw.c| 4 +- drivers/gpu/drm/drm_writeback.c| 79 ++- drivers/gpu/drm/msm/Makefile | 3 + drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 9 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 217 +- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h| 22 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 46 ++ .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c| 763 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 74 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 66 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 73 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 23 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c| 25 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h| 4 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c | 273 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.h | 131 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c| 63 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 27 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 22 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h | 12 + drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.c | 68 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_writeback.h | 25 + drivers/gpu/drm/rcar-du/rcar_du_writeback.c| 4 +- drivers/gpu/drm/vc4/vc4_txp.c | 7 +- drivers/gpu/drm/vkms/vkms_writeback.c | 4 +- include/drm/drm_writeback.h| 31 +- 27 files changed, 2003 insertions(+), 76
Re: [PATCH] Staging: fbtft: Fix style problem in header
Hi Ian, Thank you for the patch! Yet something to improve: [auto build test ERROR on staging/staging-testing] url: https://github.com/intel-lab-lkp/linux/commits/Ian-Cowan/Staging-fbtft-Fix-style-problem-in-header/20220420-040428 base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git bed6d200f8ca38e1ecbdd8fb7e0564884002abd1 config: ia64-allmodconfig (https://download.01.org/0day-ci/archive/20220420/202204200954.tbobwakp-...@intel.com/config) compiler: ia64-linux-gcc (GCC) 11.2.0 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 # https://github.com/intel-lab-lkp/linux/commit/77c04f63df8342cff035e42cda5606c2c87d33db git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Ian-Cowan/Staging-fbtft-Fix-style-problem-in-header/20220420-040428 git checkout 77c04f63df8342cff035e42cda5606c2c87d33db # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.2.0 make.cross W=1 O=build_dir ARCH=ia64 SHELL=/bin/bash drivers/staging/ If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All errors (new ones prefixed by >>): In file included from drivers/staging/fbtft/fb_agm1264k-fl.c:15: >> drivers/staging/fbtft/fbtft.h:284:1: error: expected ',' or ';' before >> 'static' 284 | static int fbtft_driver_probe_spi(struct spi_device *spi) \ | ^~ drivers/staging/fbtft/fbtft.h:323:1: note: in expansion of macro 'FBTFT_SPI_DRIVER' 323 | FBTFT_SPI_DRIVER(_name, _compatible, _display, NULL) \ | ^~~~ drivers/staging/fbtft/fb_agm1264k-fl.c:435:1: note: in expansion of macro 'FBTFT_REGISTER_DRIVER' 435 | FBTFT_REGISTER_DRIVER(DRVNAME, "displaytronic,fb_agm1264k-fl", ); | ^ >> drivers/staging/fbtft/fbtft.h:302:18: error: 'fbtft_driver_probe_spi' >> undeclared here (not in a function); did you mean 'fbtft_driver_remove_spi'? 302 | .probe = fbtft_driver_probe_spi, \ | ^~ drivers/staging/fbtft/fbtft.h:323:1: note: in expansion of macro 'FBTFT_SPI_DRIVER' 323 | FBTFT_SPI_DRIVER(_name, _compatible, _display, NULL) \ | ^~~~ drivers/staging/fbtft/fb_agm1264k-fl.c:435:1: note: in expansion of macro 'FBTFT_REGISTER_DRIVER' 435 | FBTFT_REGISTER_DRIVER(DRVNAME, "displaytronic,fb_agm1264k-fl", ); | ^ -- In file included from drivers/staging/fbtft/fb_bd663474.c:17: >> drivers/staging/fbtft/fbtft.h:284:1: error: expected ',' or ';' before >> 'static' 284 | static int fbtft_driver_probe_spi(struct spi_device *spi) \ | ^~ drivers/staging/fbtft/fbtft.h:323:1: note: in expansion of macro 'FBTFT_SPI_DRIVER' 323 | FBTFT_SPI_DRIVER(_name, _compatible, _display, NULL) \ | ^~~~ drivers/staging/fbtft/fb_bd663474.c:162:1: note: in expansion of macro 'FBTFT_REGISTER_DRIVER' 162 | FBTFT_REGISTER_DRIVER(DRVNAME, "hitachi,bd663474", ); | ^ >> drivers/staging/fbtft/fbtft.h:302:18: error: 'fbtft_driver_probe_spi' >> undeclared here (not in a function); did you mean 'fbtft_driver_remove_spi'? 302 | .probe = fbtft_driver_probe_spi, \ | ^~ drivers/staging/fbtft/fbtft.h:323:1: note: in expansion of macro 'FBTFT_SPI_DRIVER' 323 | FBTFT_SPI_DRIVER(_name, _compatible, _display, NULL) \ | ^~~~ drivers/staging/fbtft/fb_bd663474.c:162:1: note: in expansion of macro 'FBTFT_REGISTER_DRIVER' 162 | FBTFT_REGISTER_DRIVER(DRVNAME, "hitachi,bd663474", ); | ^ -- In file included from drivers/staging/fbtft/fb_hx8340bn.c:21: >> drivers/staging/fbtft/fbtft.h:284:1: error: expected ',' or ';' before >> 'static' 284 | static int fbtft_driver_probe_spi(struct spi_device *spi) \ | ^~ drivers/staging/fbtft/fbtft.h:323:1: note: in expansion of macro 'FBTFT_SPI_DRIVER' 323 | FBTFT_SPI_DRIVER(_name, _compatible, _display, NULL) \ | ^~~~ drivers/staging/fbtft/fb_hx8340bn.c:216:1: note: in expansion of macro 'FBTFT_REGISTER_DRIVER' 216 | FBTFT_REGISTER_DRIVER(DRVNAME, "himax,hx8340bn", ); | ^ >> drivers/staging/fbtft/fbtft.h:302:18: error: 'fbtft_driver_probe_spi' >> undeclared here (not in a function); did you mean 'fbtft_driver_remove_spi'? 302 |
[PATCH v2] drm/bridge: Fix error handling in analogix_dp_probe
In the error handling path, the clk_prepare_enable() function call should be balanced by a corresponding 'clk_disable_unprepare()' call , as already done in the remove function. Fixes: 3424e3a4f844 ("drm: bridge: analogix/dp: split exynos dp driver to bridge directory") Signed-off-by: Miaoqian Lin --- changes in v2: - remove the wrong return statement. --- .../gpu/drm/bridge/analogix/analogix_dp_core.c | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index eb590fb8e8d0..474ef88015ae 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1698,8 +1698,10 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dp->reg_base = devm_ioremap_resource(>dev, res); - if (IS_ERR(dp->reg_base)) - return ERR_CAST(dp->reg_base); + if (IS_ERR(dp->reg_base)) { + ret = PTR_ERR(dp->reg_base); + goto err_disable_clk; + } dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); @@ -1711,7 +1713,8 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) if (IS_ERR(dp->hpd_gpiod)) { dev_err(dev, "error getting HDP GPIO: %ld\n", PTR_ERR(dp->hpd_gpiod)); - return ERR_CAST(dp->hpd_gpiod); + ret = PTR_ERR(dp->hpd_gpiod); + goto err_disable_clk; } if (dp->hpd_gpiod) { @@ -1731,7 +1734,8 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) if (dp->irq == -ENXIO) { dev_err(>dev, "failed to get irq\n"); - return ERR_PTR(-ENODEV); + ret = -ENODEV; + goto err_disable_clk; } ret = devm_request_threaded_irq(>dev, dp->irq, @@ -1740,11 +1744,15 @@ analogix_dp_probe(struct device *dev, struct analogix_dp_plat_data *plat_data) irq_flags, "analogix-dp", dp); if (ret) { dev_err(>dev, "failed to request irq\n"); - return ERR_PTR(ret); + goto err_disable_clk; } disable_irq(dp->irq); return dp; + +err_disable_clk: + clk_disable_unprepare(dp->clock); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(analogix_dp_probe); -- 2.17.1
[PATCH 2/2] drm/panel: simple: Add Startek KD070WVFPA043-C069A panel support
From: Heiko Schocher Add Startek KD070WVFPA043-C069A 7" TFT LCD panel support. Signed-off-by: Heiko Schocher Signed-off-by: Fabio Estevam --- drivers/gpu/drm/panel/panel-simple.c | 33 1 file changed, 33 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index a34f4198a534..ca8cd017821d 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -3311,6 +3311,36 @@ static const struct panel_desc tsd_tst043015cmhx = { .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE, }; +static const struct display_timing startek_kd070wvfpa_mode = { + .pixelclock = { 2520, 2720, 3050 }, + .hactive = { 800, 800, 800 }, + .hfront_porch = { 19, 44, 115 }, + .hback_porch = { 5, 16, 101 }, + .hsync_len = { 1, 2, 100 }, + .vactive = { 480, 480, 480 }, + .vfront_porch = { 5, 43, 67 }, + .vback_porch = { 5, 5, 67 }, + .vsync_len = { 1, 2, 66 }, +}; + +static const struct panel_desc startek_kd070wvfpa = { + .timings = _kd070wvfpa_mode, + .num_timings = 1, + .bpc = 8, + .size = { + .width = 152, + .height = 91, + }, + .delay = { + .prepare = 20, + .enable = 200, + .disable = 200, + }, + .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .connector_type = DRM_MODE_CONNECTOR_DPI, +}; + static const struct drm_display_mode tfc_s9700rtwv43tr_01b_mode = { .clock = 3, .hdisplay = 800, @@ -3990,6 +4020,9 @@ static const struct of_device_id platform_of_match[] = { }, { .compatible = "starry,kr070pe2t", .data = _kr070pe2t, + }, { + .compatible = "startek,kd070wvfpa", + .data = _kd070wvfpa, }, { .compatible = "team-source-display,tst043015cmhx", .data = _tst043015cmhx, -- 2.25.1
[PATCH 1/2] dt-bindings: display: simple: Add Startek KD070WVFPA043-C069A panel
From: Fabio Estevam Add Startek KD070WVFPA043-C069A 7" TFT LCD panel compatible string. Signed-off-by: Fabio Estevam --- .../devicetree/bindings/display/panel/panel-simple.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml index 1eb9dd4f8f58..e190eef66872 100644 --- a/Documentation/devicetree/bindings/display/panel/panel-simple.yaml +++ b/Documentation/devicetree/bindings/display/panel/panel-simple.yaml @@ -294,6 +294,8 @@ properties: - starry,kr070pe2t # Starry 12.2" (1920x1200 pixels) TFT LCD panel - starry,kr122ea0sra +# Startek KD070WVFPA043-C069A 7" TFT LCD panel + - startek,kd070wvfpa # Team Source Display Technology TST043015CMHX 4.3" WQVGA TFT LCD panel - team-source-display,tst043015cmhx # Tianma Micro-electronics TM070JDHG30 7.0" WXGA TFT LCD panel -- 2.25.1
[PATCH v2] drm/vc4: Fix pm_runtime_get_sync() usage
If the device is already in a runtime PM enabled state pm_runtime_get_sync() will return 1, so a test for negative value should be used to check for errors. Also, we need to call pm_runtime_put_noidle() when pm_runtime_get_sync() fails, so use pm_runtime_resume_and_get() instead. this function will handle this. Fixes: 4078f5757144 ("drm/vc4: Add DSI driver") Signed-off-by: Miaoqian Lin --- change in v2: - switch to pm_runtime_resume_and_get() to fix refcount leak. --- drivers/gpu/drm/vc4/vc4_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_dsi.c b/drivers/gpu/drm/vc4/vc4_dsi.c index 752f921735c6..9d7ffaf6bc70 100644 --- a/drivers/gpu/drm/vc4/vc4_dsi.c +++ b/drivers/gpu/drm/vc4/vc4_dsi.c @@ -846,8 +846,8 @@ static void vc4_dsi_encoder_enable(struct drm_encoder *encoder) unsigned long phy_clock; int ret; - ret = pm_runtime_get_sync(dev); - if (ret) { + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { DRM_ERROR("Failed to runtime PM enable on DSI%d\n", dsi->variant->port); return; } -- 2.17.1
[PATCH] drm/i915: Fix race in __i915_vma_remove_closed
i915_vma_reopen checked if the vma is closed before without taking the lock. So multiple threads could attempt removing the vma. Instead the lock needs to be taken before actually checking. Cc: Chris Wilson Cc: intel-...@lists.freedesktop.org Cc: dri-devel@lists.freedesktop.org Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5732 Signed-off-by: Karol Herbst --- drivers/gpu/drm/i915/i915_vma.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 162e8d83691b..bb3b6e4bee8b 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -1615,17 +1615,17 @@ void i915_vma_close(struct i915_vma *vma) static void __i915_vma_remove_closed(struct i915_vma *vma) { - struct intel_gt *gt = vma->vm->gt; - - spin_lock_irq(>closed_lock); list_del_init(>closed_link); - spin_unlock_irq(>closed_lock); } void i915_vma_reopen(struct i915_vma *vma) { + struct intel_gt *gt = vma->vm->gt; + + spin_lock_irq(>closed_lock); if (i915_vma_is_closed(vma)) __i915_vma_remove_closed(vma); + spin_unlock_irq(>closed_lock); } static void force_unbind(struct i915_vma *vma) @@ -1651,7 +1651,11 @@ static void release_references(struct i915_vma *vma, bool vm_ddestroy) spin_unlock(>vma.lock); + struct intel_gt *gt = vma->vm->gt; + + spin_lock_irq(>closed_lock); __i915_vma_remove_closed(vma); + spin_unlock_irq(>closed_lock); if (vm_ddestroy) i915_vm_resv_put(vma->vm); -- 2.35.1
Re: [PATCH v3] drm/gma500: depend on framebuffer
On Tue, Apr 12, 2022 at 3:30 AM Patrik Jakobsson wrote: > > On Tue, Apr 12, 2022 at 3:48 AM James Hilliard > wrote: > > > > On Mon, Apr 11, 2022 at 3:27 AM Patrik Jakobsson > > wrote: > > > > > > On Sun, Apr 10, 2022 at 10:05 PM James Hilliard > > > wrote: > > > > > > > > On Sun, Apr 10, 2022 at 1:52 PM Patrik Jakobsson > > > > wrote: > > > > > > > > > > On Sun, Apr 10, 2022 at 9:40 PM James Hilliard > > > > > wrote: > > > > > > > > > > > > On Sun, Apr 10, 2022 at 1:36 PM Patrik Jakobsson > > > > > > wrote: > > > > > > > > > > > > > > On Sat, Apr 9, 2022 at 6:23 AM James Hilliard > > > > > > > wrote: > > > > > > > > > > > > > > > > Select the efi framebuffer if efi is enabled. > > > > > > > > > > > > > > > > This appears to be needed for video output to function > > > > > > > > correctly. > > > > > > > > > > > > > > > > Signed-off-by: James Hilliard > > > > > > > > > > > > > > Hi James, > > > > > > > EFI_FB is its own driver and not needed by gma500 to drive its > > > > > > > hardware. What makes you think it's required? > > > > > > > > > > > > I wasn't getting any HDMI video output without it enabled for some > > > > > > reason, > > > > > > I assume it is doing some sort of initialization needed by gma500 > > > > > > during startup. > > > > > > > > > > Then it sounds like you might just be using EFI_FB and not gma500. Can > > > > > you provide the kernel log with drm.debug=0x1f set on kernel > > > > > command-line. > > > > > > > > Seems efifb loads first and then hands off to gma500 > > > > > > That is how it normally works but efifb shouldn't change the state of > > > the currently set mode so shouldn't affect gma500. > > > From the logs I can see that you have LVDS (internal panel), HDMI and > > > DP (3 displays in total) connected. This sounds wrong. Your version of > > > gma500 (Cedarview) doesn't support more than 2 crtcs/pipes. This might > > > be a problem. > > > > Yeah, there's a bug there with the connector status, only DVI-D-1 is > > actually > > connected, I have DP-2 and LVDS-1 turned off in weston. > > Ok, but are the connectors physically connected to anything? There is one HDMI cable physically connected to the board > Regardless of what you do in Weston, the connectors shouldn't be > getting modes if they aren't used. Yeah, it seems there's a bug there, not sure if that's related to the output failure when efifb isn't available. > LVDS might be from VBIOS but I'm > not sure where the DP modes come from. It would help if you also > provide kernel logs with drm.debug=0x1f when the outputs doesn't work > so I have something to compare with. Log with efifb/fb not enabled in kernel build which causes no HDMI output: [0.00] Linux version 5.17.3 (buildroot@james-x399) (x86_64-buildroot-linux-gnu-gcc.br_real (Buildroot 2022.02-533-g95bc9df0b3) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #1 SMP PREEMPT Tue Apr 19 15:14:53 MDT 2022 [0.00] Command line: root=PARTUUID=dea0d091-16af-704f-977c-1a5475cf261c rootwait drm.debug=0x1f console=tty1 [0.00] Disabled fast string operations [0.00] x86/fpu: x87 FPU will use FXSAVE [0.00] signal: max sigframe size: 1440 [0.00] BIOS-provided physical RAM map: [0.00] BIOS-e820: [mem 0x-0x0009] usable [0.00] BIOS-e820: [mem 0x000a-0x000f] reserved [0.00] BIOS-e820: [mem 0x0010-0xcf32cfff] usable [0.00] BIOS-e820: [mem 0xcf32d000-0xcf374fff] ACPI NVS [0.00] BIOS-e820: [mem 0xcf375000-0xcf385fff] reserved [0.00] BIOS-e820: [mem 0xcf386000-0xcf38dfff] ACPI data [0.00] BIOS-e820: [mem 0xcf38e000-0xcf3b5fff] reserved [0.00] BIOS-e820: [mem 0xcf3b6000-0xcf3b6fff] ACPI NVS [0.00] BIOS-e820: [mem 0xcf3b7000-0xcf3c6fff] reserved [0.00] BIOS-e820: [mem 0xcf3c7000-0xcf3d2fff] ACPI NVS [0.00] BIOS-e820: [mem 0xcf3d3000-0xcf3f7fff] reserved [0.00] BIOS-e820: [mem 0xcf3f8000-0xcf43afff] ACPI NVS [0.00] BIOS-e820: [mem 0xcf43b000-0xcf5bafff] usable [0.00] BIOS-e820: [mem 0xcf5bb000-0xcf6e6fff] reserved [0.00] BIOS-e820: [mem 0xcf6e7000-0xcf6e] usable [0.00] BIOS-e820: [mem 0xcf6f-0xcfff] reserved [0.00] BIOS-e820: [mem 0xe000-0xefff] reserved [0.00] BIOS-e820: [mem 0xfec0-0xfec00fff] reserved [0.00] BIOS-e820: [mem 0xfed0-0xfed00fff] reserved [0.00] BIOS-e820: [mem 0xfed14000-0xfed19fff] reserved [0.00] BIOS-e820: [mem 0xfed1c000-0xfed8] reserved [0.00] BIOS-e820: [mem 0xfee0-0xfee00fff] reserved [0.00] BIOS-e820: [mem
[PATCH v5 1/5] dt-bindings: display: ssd1307fb: Deprecate "-i2c" compatible strings
The current compatible strings for SSD130x I2C controllers contain both an "fb" and "-i2c" suffixes. It seems to indicate that are for a fbdev driver and also that are for devices that can be accessed over an I2C bus. But a DT is supposed to describe the hardware and not Linux implementation details. So let's deprecate those compatible strings and add new ones that only contain the vendor and device name, without any of these suffixes. These will just describe the device and can be matched by both I2C and SPI DRM drivers. The required properties should still be enforced for old ones. While being there, just drop the "sinowealth,sh1106-i2c" compatible string since that was never present in a released Linux version. Signed-off-by: Javier Martinez Canillas Acked-by: Mark Brown Reviewed-by: Geert Uytterhoeven --- (no changes since v3) Changes in v3: - Drop the "sinowealth,sh1106-i2c", wasn't in a released version (Chen-Yu Tsai) - Continue enforcing required properties for deprecated strings (Maxime Ripard) Changes in v2: - Drop the -i2c suffixes from the compatible strings too (Geert Uytterhoeven) .../bindings/display/solomon,ssd1307fb.yaml | 44 +-- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml index ade61d502edd..7653b6c3fcb6 100644 --- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml @@ -12,12 +12,22 @@ maintainers: properties: compatible: -enum: - - sinowealth,sh1106-i2c - - solomon,ssd1305fb-i2c - - solomon,ssd1306fb-i2c - - solomon,ssd1307fb-i2c - - solomon,ssd1309fb-i2c +oneOf: + # Deprecated compatible strings + - items: + - enum: + - solomon,ssd1305fb-i2c + - solomon,ssd1306fb-i2c + - solomon,ssd1307fb-i2c + - solomon,ssd1309fb-i2c +deprecated: true + - items: + - enum: + - sinowealth,sh1106 + - solomon,ssd1305 + - solomon,ssd1306 + - solomon,ssd1307 + - solomon,ssd1309 reg: maxItems: 1 @@ -136,7 +146,7 @@ allOf: properties: compatible: contains: -const: sinowealth,sh1106-i2c +const: sinowealth,sh1106 then: properties: solomon,dclk-div: @@ -148,7 +158,9 @@ allOf: properties: compatible: contains: -const: solomon,ssd1305fb-i2c +enum: + - solomon,ssd1305-i2c + - solomon,ssd1305 then: properties: solomon,dclk-div: @@ -160,7 +172,9 @@ allOf: properties: compatible: contains: -const: solomon,ssd1306fb-i2c +enum: + - solomon,ssd1306-i2c + - solomon,ssd1306 then: properties: solomon,dclk-div: @@ -172,7 +186,9 @@ allOf: properties: compatible: contains: -const: solomon,ssd1307fb-i2c +enum: + - solomon,ssd1307-i2c + - solomon,ssd1307 then: properties: solomon,dclk-div: @@ -186,7 +202,9 @@ allOf: properties: compatible: contains: -const: solomon,ssd1309fb-i2c +enum: + - solomon,ssd1309-i2c + - solomon,ssd1309 then: properties: solomon,dclk-div: @@ -203,14 +221,14 @@ examples: #size-cells = <0>; ssd1307: oled@3c { -compatible = "solomon,ssd1307fb-i2c"; +compatible = "solomon,ssd1307"; reg = <0x3c>; pwms = < 4 3000>; reset-gpios = < 7>; }; ssd1306: oled@3d { -compatible = "solomon,ssd1306fb-i2c"; +compatible = "solomon,ssd1306"; reg = <0x3c>; pwms = < 4 3000>; reset-gpios = < 7>; -- 2.35.1
[PATCH v5 5/5] drm/solomon: Add SSD130x OLED displays SPI support
The ssd130x driver only provides the core support for these devices but it does not have any bus transport logic. Add a driver to interface over SPI. There is a difference in the communication protocol when using 4-wire SPI instead of I2C. For the latter, a control byte that contains a D/C# field has to be sent. This field tells the controller whether the data has to be written to the command register or to the graphics display data memory. But for 4-wire SPI that control byte is not used, instead a real D/C# line must be pulled HIGH for commands data and LOW for graphics display data. For this reason the standard SPI regmap can't be used and a custom .write bus handler is needed. Signed-off-by: Javier Martinez Canillas Acked-by: Mark Brown Reviewed-by: Geert Uytterhoeven --- Changes in v5: - Remove cast by just using u8 *reg instead of void *data (Geert Uytterhoeven). - Add Geert Uytterhoeven's Reviewed-by tag to patch 5/5. Changes in v4: - Use MODULE_IMPORT_NS(DRM_SSD130X) in the ssd130x-spi driver (Andy Shevchenko) Changes in v3: - Drop ssd130x_spi_get_dc() helper and open code it (Geert Uytterhoeven) - Export variants array and use [ID] in device table (Andy Shevchenko) Changes in v2: - Add the same compatible strings than I2C (Geert Uytterhoeven) drivers/gpu/drm/solomon/Kconfig | 9 ++ drivers/gpu/drm/solomon/Makefile | 1 + drivers/gpu/drm/solomon/ssd130x-spi.c | 178 ++ 3 files changed, 188 insertions(+) create mode 100644 drivers/gpu/drm/solomon/ssd130x-spi.c diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index 8c0a0c788385..e170716d976b 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -20,3 +20,12 @@ config DRM_SSD130X_I2C I2C bus. If M is selected the module will be called ssd130x-i2c. + +config DRM_SSD130X_SPI + tristate "DRM support for Solomon SSD130X OLED displays (SPI bus)" + depends on DRM_SSD130X && SPI + select REGMAP + help + Say Y here if the SSD130x OLED display is connected via SPI bus. + + If M is selected the module will be called ssd130x-spi. diff --git a/drivers/gpu/drm/solomon/Makefile b/drivers/gpu/drm/solomon/Makefile index 4bfc5acb0447..b5fc792257d7 100644 --- a/drivers/gpu/drm/solomon/Makefile +++ b/drivers/gpu/drm/solomon/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_DRM_SSD130X) += ssd130x.o obj-$(CONFIG_DRM_SSD130X_I2C) += ssd130x-i2c.o +obj-$(CONFIG_DRM_SSD130X_SPI) += ssd130x-spi.o diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c new file mode 100644 index ..43722adab1f8 --- /dev/null +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DRM driver for Solomon SSD130X OLED displays (SPI bus) + * + * Copyright 2022 Red Hat Inc. + * Authors: Javier Martinez Canillas + */ +#include +#include + +#include "ssd130x.h" + +#define DRIVER_NAME"ssd130x-spi" +#define DRIVER_DESC"DRM driver for Solomon SSD130X OLED displays (SPI)" + +struct ssd130x_spi_transport { + struct spi_device *spi; + struct gpio_desc *dc; +}; + +static const struct regmap_config ssd130x_spi_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +/* + * The regmap bus .write handler, it is just a wrapper around spi_write() + * but toggling the Data/Command control pin (D/C#). Since for 4-wire SPI + * a D/C# pin is used, in contrast with I2C where a control byte is sent, + * prior to every data byte, that contains a bit with the D/C# value. + * + * These control bytes are considered registers by the ssd130x core driver + * and can be used by the ssd130x SPI driver to determine if the data sent + * is for a command register or for the Graphic Display Data RAM (GDDRAM). + */ +static int ssd130x_spi_write(void *context, const void *data, size_t count) +{ + struct ssd130x_spi_transport *t = context; + struct spi_device *spi = t->spi; + const u8 *reg = data; + + if (*reg == SSD130X_COMMAND) + gpiod_set_value_cansleep(t->dc, 0); + + if (*reg == SSD130X_DATA) + gpiod_set_value_cansleep(t->dc, 1); + + /* Remove control byte since is not used in a 4-wire SPI interface */ + return spi_write(spi, reg + 1, count - 1); +} + +/* The ssd130x driver does not read registers but regmap expects a .read */ +static int ssd130x_spi_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + return -EOPNOTSUPP; +} + +/* + * A custom bus is needed due the special write that toggles a D/C# pin, + * another option could be to just have a .reg_write() callback but that + * will prevent to do data writes in bulk. + * + * Once the regmap API is extended to support defining a bulk write handler + * in the struct regmap_config, this can be simplified and the bus dropped. + */
[PATCH v5 3/5] drm/solomon: Add ssd130x new compatible strings and deprecate old ones.
The current compatible strings for SSD130x I2C controllers contain an "fb" and "-i2c" suffixes. These have been deprecated and more correct ones were added, that don't encode a subsystem or bus used to interface the devices. Signed-off-by: Javier Martinez Canillas Acked-by: Mark Brown Reviewed-by: Geert Uytterhoeven --- (no changes since v3) Changes in v3: - Drop the "sinowealth,sh1106-i2c", wasn't in a released version (Chen-Yu Tsai) Changes in v2: - Use the compatible strings that don't have "fb-i2c" (Geert Uytterhoeven). drivers/gpu/drm/solomon/ssd130x-i2c.c | 19 ++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index d099b241dd3f..45867ef2bc8b 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -88,9 +88,26 @@ static struct ssd130x_deviceinfo ssd130x_ssd1309_deviceinfo = { static const struct of_device_id ssd130x_of_match[] = { { - .compatible = "sinowealth,sh1106-i2c", + .compatible = "sinowealth,sh1106", .data = _sh1106_deviceinfo, }, + { + .compatible = "solomon,ssd1305", + .data = _ssd1305_deviceinfo, + }, + { + .compatible = "solomon,ssd1306", + .data = _ssd1306_deviceinfo, + }, + { + .compatible = "solomon,ssd1307", + .data = _ssd1307_deviceinfo, + }, + { + .compatible = "solomon,ssd1309", + .data = _ssd1309_deviceinfo, + }, + /* Deprecated but kept for backward compatibility */ { .compatible = "solomon,ssd1305fb-i2c", .data = _ssd1305_deviceinfo, -- 2.35.1
[PATCH v5 4/5] drm/solomon: Move device info from ssd130x-i2c to the core driver
These are declared in the ssd130x-i2c transport driver but the information is not I2C specific, and could be used by other SSD130x transport drivers. Move them to the ssd130x core driver and just set the OF device entries to an ID that could be used to lookup the correct device info from an array. While being there, also move the SSD130X_DATA and SSD130X_COMMAND control bytes. Since even though they are used by the I2C interface, they could also be useful for other transport protocols such as SPI. Suggested-by: Chen-Yu Tsai Signed-off-by: Javier Martinez Canillas Acked-by: Mark Brown Reviewed-by: Geert Uytterhoeven --- Changes in v5: - Remove unnecessary blank line added by mistake in v4 (Andy Shevchenko). Changes in v4: - Export ssd13x_variants array using EXPORT_SYMBOL_NS_GPL() (Andy Shevchenko) - Use MODULE_IMPORT_NS(DRM_SSD130X) in the ssd130x-i2c driver (Andy Shevchenko) Changes in v3: - s/it/they in the commit description (Geert Uytterhoeven) - Drop unnecessary blank line (Geert Uytterhoeven) - Export variants array and use [ID] in device table (Andy Shevchenko) Changes in v2: - Drop ssd13x_variant_to_info() and just use the array index (Neil Armstrong). drivers/gpu/drm/solomon/ssd130x-i2c.c | 52 ++- drivers/gpu/drm/solomon/ssd130x.c | 35 -- drivers/gpu/drm/solomon/ssd130x.h | 14 3 files changed, 56 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index 45867ef2bc8b..d6835ec71c39 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -53,76 +53,43 @@ static void ssd130x_i2c_shutdown(struct i2c_client *client) ssd130x_shutdown(ssd130x); } -static struct ssd130x_deviceinfo ssd130x_sh1106_deviceinfo = { - .default_vcomh = 0x40, - .default_dclk_div = 1, - .default_dclk_frq = 5, - .page_mode_only = 1, -}; - -static struct ssd130x_deviceinfo ssd130x_ssd1305_deviceinfo = { - .default_vcomh = 0x34, - .default_dclk_div = 1, - .default_dclk_frq = 7, -}; - -static struct ssd130x_deviceinfo ssd130x_ssd1306_deviceinfo = { - .default_vcomh = 0x20, - .default_dclk_div = 1, - .default_dclk_frq = 8, - .need_chargepump = 1, -}; - -static struct ssd130x_deviceinfo ssd130x_ssd1307_deviceinfo = { - .default_vcomh = 0x20, - .default_dclk_div = 2, - .default_dclk_frq = 12, - .need_pwm = 1, -}; - -static struct ssd130x_deviceinfo ssd130x_ssd1309_deviceinfo = { - .default_vcomh = 0x34, - .default_dclk_div = 1, - .default_dclk_frq = 10, -}; - static const struct of_device_id ssd130x_of_match[] = { { .compatible = "sinowealth,sh1106", - .data = _sh1106_deviceinfo, + .data = _variants[SH1106_ID], }, { .compatible = "solomon,ssd1305", - .data = _ssd1305_deviceinfo, + .data = _variants[SSD1305_ID], }, { .compatible = "solomon,ssd1306", - .data = _ssd1306_deviceinfo, + .data = _variants[SSD1306_ID], }, { .compatible = "solomon,ssd1307", - .data = _ssd1307_deviceinfo, + .data = _variants[SSD1307_ID], }, { .compatible = "solomon,ssd1309", - .data = _ssd1309_deviceinfo, + .data = _variants[SSD1309_ID], }, /* Deprecated but kept for backward compatibility */ { .compatible = "solomon,ssd1305fb-i2c", - .data = _ssd1305_deviceinfo, + .data = _variants[SSD1305_ID], }, { .compatible = "solomon,ssd1306fb-i2c", - .data = _ssd1306_deviceinfo, + .data = _variants[SSD1306_ID], }, { .compatible = "solomon,ssd1307fb-i2c", - .data = _ssd1307_deviceinfo, + .data = _variants[SSD1307_ID], }, { .compatible = "solomon,ssd1309fb-i2c", - .data = _ssd1309_deviceinfo, + .data = _variants[SSD1309_ID], }, { /* sentinel */ } }; @@ -142,3 +109,4 @@ module_i2c_driver(ssd130x_i2c_driver); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_AUTHOR("Javier Martinez Canillas "); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(DRM_SSD130X); diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index a7e784518c69..ba2de93d00f0 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -39,9 +39,6 @@ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 -#define SSD130X_DATA 0x40 -#define SSD130X_COMMAND0x80 - #define SSD130X_PAGE_COL_START_LOW 0x00 #define SSD130X_PAGE_COL_START_HIGH
[PATCH v5 2/5] dt-bindings: display: ssd1307fb: Extend schema for SPI controllers
The Solomon SSD130x OLED displays can either have an I2C or SPI interface, add to the schema the properties and examples for OLED devices under SPI. Signed-off-by: Javier Martinez Canillas Acked-by: Mark Brown Reviewed-by: Geert Uytterhoeven --- (no changes since v4) Changes in v4: - Add a description for the dc-gpios property for SPI (Geert Uytterhoeven) Changes in v3: - Add a comment to the properties required for SPI (Geert Uytterhoeven) Changes in v2: - Don't add compatible strings with an "-spi" suffix (Geert Uytterhoeven) .../bindings/display/solomon,ssd1307fb.yaml | 42 ++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml index 7653b6c3fcb6..3fbd87c2c120 100644 --- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml @@ -38,9 +38,20 @@ properties: reset-gpios: maxItems: 1 + # Only required for SPI + dc-gpios: +description: + GPIO connected to the controller's D/C# (Data/Command) pin, + that is needed for 4-wire SPI to tell the controller if the + data sent is for a command register or the display data RAM +maxItems: 1 + vbat-supply: description: The supply for VBAT + # Only required for SPI + spi-max-frequency: true + solomon,height: $ref: /schemas/types.yaml#/definitions/uint32 default: 16 @@ -220,14 +231,14 @@ examples: #address-cells = <1>; #size-cells = <0>; -ssd1307: oled@3c { +ssd1307_i2c: oled@3c { compatible = "solomon,ssd1307"; reg = <0x3c>; pwms = < 4 3000>; reset-gpios = < 7>; }; -ssd1306: oled@3d { +ssd1306_i2c: oled@3d { compatible = "solomon,ssd1306"; reg = <0x3c>; pwms = < 4 3000>; @@ -238,3 +249,30 @@ examples: solomon,lookup-table = /bits/ 8 <0x3f 0x3f 0x3f 0x3f>; }; }; + - | +spi { +#address-cells = <1>; +#size-cells = <0>; + +ssd1307_spi: oled@0 { +compatible = "solomon,ssd1307"; +reg = <0x0>; +pwms = < 4 3000>; +reset-gpios = < 7>; +dc-gpios = < 8>; +spi-max-frequency = <1000>; +}; + +ssd1306_spi: oled@1 { +compatible = "solomon,ssd1306"; +reg = <0x1>; +pwms = < 4 3000>; +reset-gpios = < 7>; +dc-gpios = < 8>; +spi-max-frequency = <1000>; +solomon,com-lrremap; +solomon,com-invdir; +solomon,com-offset = <32>; +solomon,lookup-table = /bits/ 8 <0x3f 0x3f 0x3f 0x3f>; +}; +}; -- 2.35.1
[PATCH v5 0/5] drm/solomon: Add SSD130x OLED displays SPI support
Hello, This series adds a ssd130x-spi driver that provides a 4-wire SPI transport support for SSD130x OLED controllers that can be accessed over a SPI bus. The driver is quite similar to existing ssd130x-i2c driver that is used by I2C controllers, but there is a difference in the protocol used by SSD130x depending on the transport used. The details are in patch #4 description. Patch #1 just makes the current ssd130x-i2c compatible strings in the DT binding to be deprecated, and add new ones that don't have an "fb-i2c". Patch #2 extends the DT binding with the properties needed to support SPI. Patch #3 adds the new compatible strings to the OF device ID table in the ssd130x-i2c DRM driver and deprecate the old ones. Patch #4 moves the device info for the different SSD130x variants from the ssd130x-i2c transport driver to the ssd130x core driver. Finally patch #5 adds the ssd130x-spi DRM driver for the OLED controllers that come with a 4-wire SPI interface, instead of an I2C interface. This is a v5 that addresses the issues pointed out in v4. Best regards, Javier Changes in v5: - Remove unnecessary blank line added by mistake in v4 (Andy Shevchenko). - Remove cast by just using u8 *reg instead of void *data (Geert Uytterhoeven). - Add Geert Uytterhoeven's Reviewed-by tag to patch 5/5. Changes in v4: - Add a description for the dc-gpios property for SPI (Geert Uytterhoeven) - Export ssd13x_variants array using EXPORT_SYMBOL_NS_GPL() (Andy Shevchenko) - Use MODULE_IMPORT_NS(DRM_SSD130X) in the ssd130x-i2c driver (Andy Shevchenko) - Use MODULE_IMPORT_NS(DRM_SSD130X) in the ssd130x-spi driver (Andy Shevchenko) Changes in v3: - Drop the "sinowealth,sh1106-i2c", wasn't in a released version (Chen-Yu Tsai) - Continue enforcing required properties for deprecated strings (Maxime Ripard) - Add a comment to the properties required for SPI (Geert Uytterhoeven) - Drop the "sinowealth,sh1106-i2c", wasn't in a released version (Chen-Yu Tsai) - s/it/they in the commit description (Geert Uytterhoeven) - Drop unnecessary blank line (Geert Uytterhoeven) - Export variants array and use [ID] in device table (Andy Shevchenko) - Drop ssd130x_spi_get_dc() helper and open code it (Geert Uytterhoeven) - Export variants array and use [ID] in device table (Andy Shevchenko) - Add Geert Uytterhoeven's Reviewed-by tag to patches. Changes in v2: - Drop the -i2c suffixes from the compatible strings too (Geert Uytterhoeven) - Don't add compatible strings with an "-spi" suffix (Geert Uytterhoeven) - Use the compatible strings that don't have "fb-i2c" (Geert Uytterhoeven). - Drop ssd13x_variant_to_info() and just use the array index (Neil Armstrong). - Add the same compatible strings than I2C (Geert Uytterhoeven) - Add Mark Brown's Acked-by tag to all patches. Javier Martinez Canillas (5): dt-bindings: display: ssd1307fb: Deprecate "-i2c" compatible strings dt-bindings: display: ssd1307fb: Extend schema for SPI controllers drm/solomon: Add ssd130x new compatible strings and deprecate old ones. drm/solomon: Move device info from ssd130x-i2c to the core driver drm/solomon: Add SSD130x OLED displays SPI support .../bindings/display/solomon,ssd1307fb.yaml | 86 +++-- drivers/gpu/drm/solomon/Kconfig | 9 + drivers/gpu/drm/solomon/Makefile | 1 + drivers/gpu/drm/solomon/ssd130x-i2c.c | 63 +++ drivers/gpu/drm/solomon/ssd130x-spi.c | 178 ++ drivers/gpu/drm/solomon/ssd130x.c | 35 +++- drivers/gpu/drm/solomon/ssd130x.h | 14 ++ 7 files changed, 329 insertions(+), 57 deletions(-) create mode 100644 drivers/gpu/drm/solomon/ssd130x-spi.c -- 2.35.1
Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems
Hi Paul, On 4/14/2022 2:52 AM, Paul Menzel wrote: [Cc: -kernel test robot ] Dear Alex, dear Richard, Am 13.04.22 um 15:00 schrieb Alex Deucher: On Wed, Apr 13, 2022 at 3:43 AM Paul Menzel wrote: Thank you for sending out v4. Am 12.04.22 um 23:50 schrieb Richard Gong: Active State Power Management (ASPM) feature is enabled since kernel 5.14. There are some AMD GFX cards (such as WX3200 and RX640) that won't work with ASPM-enabled Intel Alder Lake based systems. Using these GFX cards as video/display output, Intel Alder Lake based systems will hang during suspend/resume. I am still not clear, what “hang during suspend/resume” means. I guess suspending works fine? During resume (S3 or S0ix?), where does it hang? The system is functional, but there are only display problems? System freeze after suspend/resume. The issue was initially reported on one system (Dell Precision 3660 with BIOS version 0.14.81), but was later confirmed to affect at least 4 Alder Lake based systems. Add extra check to disable ASPM on Intel Alder Lake based systems. Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default") Link: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885data=04%7C01%7Crichard.gong%40amd.com%7Ce7febed5d6a441c3a58008da1debb99c%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637855195670542145%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000sdata=7cEnE%2BSM9e5IGFxSLloCLtCOxovBpaPz0Ns0Ta2vVlc%3Dreserved=0 Reported-by: kernel test robot This tag is a little confusing. Maybe clarify that it was for an issue in a previous patch iteration? I did describe in change-list version 3 below, which corrected the build error with W=1 option. It is not good idea to add the description for that to the commit message, this is why I add descriptions on change-list version 3. Signed-off-by: Richard Gong --- v4: s/CONFIG_X86_64/CONFIG_X86 enhanced check logic v3: s/intel_core_asom_chk/aspm_support_quirk_check correct build error with W=1 option v2: correct commit description move the check from chip family to problematic platform --- drivers/gpu/drm/amd/amdgpu/vi.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 039b90cdc3bc..b33e0a9bee65 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -81,6 +81,10 @@ #include "mxgpu_vi.h" #include "amdgpu_dm.h" +#if IS_ENABLED(CONFIG_X86) +#include +#endif + #define ixPCIE_LC_L1_PM_SUBSTATE 0x100100C6 #define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 0x0001L #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 0x0002L @@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct amdgpu_device *adev) WREG32_PCIE(ixPCIE_LC_CNTL, data); } +static bool aspm_support_quirk_check(void) +{ + if (IS_ENABLED(CONFIG_X86)) { + struct cpuinfo_x86 *c = _data(0); + + return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE); + } + + return true; +} + static void vi_program_aspm(struct amdgpu_device *adev) { u32 data, data1, orig; bool bL1SS = false; bool bClkReqSupport = true; - if (!amdgpu_device_should_use_aspm(adev)) + if (!amdgpu_device_should_use_aspm(adev) || !aspm_support_quirk_check()) return; Can users still forcefully enable ASPM with the parameter `amdgpu.aspm`? As Mario mentioned in a separate reply, we can't forcefully enable ASPM with the parameter 'amdgpu.aspm'. if (adev->flags & AMD_IS_APU || If I remember correctly, there were also newer cards, where ASPM worked with Intel Alder Lake, right? Can only the problematic generations for WX3200 and RX640 be excluded from ASPM? This patch only disables it for the generation that was problematic. Could that please be made clear in the commit message summary, and message? Are you ok with the commit messages below? Active State Power Management (ASPM) feature is enabled since kernel 5.14. There are some AMD GFX cards (such as WX3200 and RX640) that won't work with ASPM-enabled Intel Alder Lake based systems. Using these GFX cards as video/display output, Intel Alder Lake based systems will freeze after suspend/resume. The issue was initially reported on one system (Dell Precision 3660 with BIOS version 0.14.81), but was later confirmed to affect at least 4 Alder Lake based systems. Add extra check to disable ASPM on Intel Alder Lake based systems with problematic generation GFX cards. Loosely related, is there a public (or internal issue) to analyze how to get ASPM working for VI generation devices with Intel Alder Lake? As Alex mentioned, we need support from Intel. We don't have any update on that. Regards, Richard
Re: [PATCH] drm/msm/dsi: fixup DSC support for the cases when there is no pannel attached
typo in the subject pannel --> panel Otherwise, Reviewed-by: Abhinav Kumar On 4/19/2022 2:37 PM, Dmitry Baryshkov wrote: Unable to handle kernel paging request at virtual address fe2b Mem abort info: ESR = 0x9604 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x0004 CM = 0, WnR = 0 swapper pgtable: 4k pages, 48-bit VAs, pgdp=a1a39000 [fe2b] pgd=, p4d= Internal error: Oops: 9604 [#1] SMP Modules linked in: CPU: 7 PID: 8 Comm: kworker/u16:0 Not tainted 5.18.0-rc3-00055-g3120774492e8 #672 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Workqueue: events_unbound deferred_probe_work_func pstate: 6045 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : msm_dsi_host_modeset_init+0x30/0xcc lr : msm_dsi_host_modeset_init+0x28/0xcc sp : 88093640 x29: 88093640 x28: 0757131ef080 x27: x26: a1d966bca440 x25: x24: 0001 x23: 0757131e6880 x22: 075700dc9c00 x21: a1d965d40f60 x20: fdfb x19: 0757131ea480 x18: x17: a1d966c51b10 x16: 03e8 x15: 075713989287 x14: x13: 075713989284 x12: 07587effaf90 x11: 07587effaf70 x10: 000b4220 x9 : 0003 x8 : 0101010101010101 x7 : 0003 x6 : 1d150c11f5f38080 x5 : x4 : 0757001f63c0 x3 : a1d966bc02b8 x2 : x1 : 0757001f63c0 x0 : fdfb Call trace: msm_dsi_host_modeset_init+0x30/0xcc msm_dsi_modeset_init+0x40/0x1e4 _dpu_kms_drm_obj_init.isra.0+0xdc/0x5c0 dpu_kms_hw_init+0x338/0x590 msm_drm_bind+0x1d8/0x5f0 try_to_bring_up_aggregate_device+0x164/0x1d0 __component_add+0xa4/0x170 component_add+0x14/0x20 dsi_dev_attach+0x20/0x30 dsi_host_attach+0x94/0x150 devm_mipi_dsi_attach+0x34/0xb0 lt9611uxc_attach_dsi.isra.0+0x84/0x100 lt9611uxc_probe+0x538/0x5e0 i2c_device_probe+0x2ac/0x2f0 really_probe.part.0+0x9c/0x28c __driver_probe_device+0x98/0x144 driver_probe_device+0x40/0x140 __device_attach_driver+0xb4/0x120 bus_for_each_drv+0x78/0xd0 __device_attach+0xdc/0x184 device_initial_probe+0x14/0x20 bus_probe_device+0x9c/0xa4 deferred_probe_work_func+0x88/0xc0 process_one_work+0x1ec/0x444 worker_thread+0x294/0x4dc kthread+0xfc/0x100 ret_from_fork+0x10/0x20 Code: f940e675 97fdc7ba b4c0 aa0003f4 (f9401800) Signed-off-by: Dmitry Baryshkov --- Note: I'm going to squash this fix into the respective patch from the DSC series --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 03921649bd28..c983698d1384 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -2167,7 +2167,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, msm_host->dev = dev; panel = msm_dsi_host_get_panel(_host->base); - if (panel && panel->dsc) { + if (!IS_ERR(panel) && panel->dsc) { struct msm_display_dsc_config *dsc = msm_host->dsc; if (!dsc) {
[PATCH] drm/msm/dsi: fixup DSC support for the cases when there is no pannel attached
Unable to handle kernel paging request at virtual address fe2b Mem abort info: ESR = 0x9604 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x0004 CM = 0, WnR = 0 swapper pgtable: 4k pages, 48-bit VAs, pgdp=a1a39000 [fe2b] pgd=, p4d= Internal error: Oops: 9604 [#1] SMP Modules linked in: CPU: 7 PID: 8 Comm: kworker/u16:0 Not tainted 5.18.0-rc3-00055-g3120774492e8 #672 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Workqueue: events_unbound deferred_probe_work_func pstate: 6045 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : msm_dsi_host_modeset_init+0x30/0xcc lr : msm_dsi_host_modeset_init+0x28/0xcc sp : 88093640 x29: 88093640 x28: 0757131ef080 x27: x26: a1d966bca440 x25: x24: 0001 x23: 0757131e6880 x22: 075700dc9c00 x21: a1d965d40f60 x20: fdfb x19: 0757131ea480 x18: x17: a1d966c51b10 x16: 03e8 x15: 075713989287 x14: x13: 075713989284 x12: 07587effaf90 x11: 07587effaf70 x10: 000b4220 x9 : 0003 x8 : 0101010101010101 x7 : 0003 x6 : 1d150c11f5f38080 x5 : x4 : 0757001f63c0 x3 : a1d966bc02b8 x2 : x1 : 0757001f63c0 x0 : fdfb Call trace: msm_dsi_host_modeset_init+0x30/0xcc msm_dsi_modeset_init+0x40/0x1e4 _dpu_kms_drm_obj_init.isra.0+0xdc/0x5c0 dpu_kms_hw_init+0x338/0x590 msm_drm_bind+0x1d8/0x5f0 try_to_bring_up_aggregate_device+0x164/0x1d0 __component_add+0xa4/0x170 component_add+0x14/0x20 dsi_dev_attach+0x20/0x30 dsi_host_attach+0x94/0x150 devm_mipi_dsi_attach+0x34/0xb0 lt9611uxc_attach_dsi.isra.0+0x84/0x100 lt9611uxc_probe+0x538/0x5e0 i2c_device_probe+0x2ac/0x2f0 really_probe.part.0+0x9c/0x28c __driver_probe_device+0x98/0x144 driver_probe_device+0x40/0x140 __device_attach_driver+0xb4/0x120 bus_for_each_drv+0x78/0xd0 __device_attach+0xdc/0x184 device_initial_probe+0x14/0x20 bus_probe_device+0x9c/0xa4 deferred_probe_work_func+0x88/0xc0 process_one_work+0x1ec/0x444 worker_thread+0x294/0x4dc kthread+0xfc/0x100 ret_from_fork+0x10/0x20 Code: f940e675 97fdc7ba b4c0 aa0003f4 (f9401800) Signed-off-by: Dmitry Baryshkov --- Note: I'm going to squash this fix into the respective patch from the DSC series --- drivers/gpu/drm/msm/dsi/dsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 03921649bd28..c983698d1384 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -2167,7 +2167,7 @@ int msm_dsi_host_modeset_init(struct mipi_dsi_host *host, msm_host->dev = dev; panel = msm_dsi_host_get_panel(_host->base); - if (panel && panel->dsc) { + if (!IS_ERR(panel) && panel->dsc) { struct msm_display_dsc_config *dsc = msm_host->dsc; if (!dsc) { -- 2.35.1
Re: [PATCH] drm/msm: Revert "drm/msm: Stop using iommu_present()"
On 2022-04-19 22:08, Dmitry Baryshkov wrote: On 20/04/2022 00:04, Robin Murphy wrote: On 2022-04-19 14:04, Dmitry Baryshkov wrote: This reverts commit e2a88eabb02410267519b838fb9b79f5206769be. The commit in question makes msm_use_mmu() check whether the DRM 'component master' device is translated by the IOMMU. At this moment it is the 'mdss' device. However on platforms using the MDP5 driver (e.g. MSM8916/APQ8016, MSM8996/APQ8096) it's the mdp5 device, which has the iommus property (and thus is "translated by the IOMMU"). This results in these devices being broken with the following lines in the dmesg. [drm] Initialized msm 1.9.0 20130625 for 1a0.mdss on minor 0 msm 1a0.mdss: [drm:adreno_request_fw] loaded qcom/a300_pm4.fw from new location msm 1a0.mdss: [drm:adreno_request_fw] loaded qcom/a300_pfp.fw from new location msm 1a0.mdss: [drm:get_pages] *ERROR* could not get pages: -28 msm 1a0.mdss: could not allocate stolen bo msm 1a0.mdss: [drm:get_pages] *ERROR* could not get pages: -28 msm 1a0.mdss: [drm:msm_alloc_stolen_fb] *ERROR* failed to allocate buffer object msm 1a0.mdss: [drm:msm_fbdev_create] *ERROR* failed to allocate fb Getting the mdp5 device pointer from this function is not that easy at this moment. Thus this patch is reverted till the MDSS rework [1] lands. It will make the mdp5/dpu1 device component master and the check will be legit. [1] https://patchwork.freedesktop.org/series/98525/ Oh, DRM... If that series is going to land got 5.19, could you please implement the correct equivalent of this patch within it? Yes, that's the plan. I'm sending a reworked version of your patch shortly (but it still depends on [1]). I'm fine with the revert for now if this patch doesn't work properly in all cases, but I have very little sympathy left for DRM drivers riding roughshod over all the standard driver model abstractions because they're "special". iommu_present() *needs* to go away, so if it's left to me to have a second go at fixing this driver next cycle, you're liable to get some abomination based on of_find_compatible_node() or similar, and I'll probably be demanding an ack to take it through the IOMMU tree ;) No need for such measures :-) Awesome, thanks! Robin.
Re: [PATCHv4] drm/amdgpu: disable ASPM on Intel Alder Lake based systems
Hi Nathan, On 4/13/2022 10:40 AM, Nathan Chancellor wrote: Hi Richard, On Tue, Apr 12, 2022 at 04:50:00PM -0500, Richard Gong wrote: Active State Power Management (ASPM) feature is enabled since kernel 5.14. There are some AMD GFX cards (such as WX3200 and RX640) that won't work with ASPM-enabled Intel Alder Lake based systems. Using these GFX cards as video/display output, Intel Alder Lake based systems will hang during suspend/resume. The issue was initially reported on one system (Dell Precision 3660 with BIOS version 0.14.81), but was later confirmed to affect at least 4 Alder Lake based systems. Add extra check to disable ASPM on Intel Alder Lake based systems. Fixes: 0064b0ce85bb ("drm/amd/pm: enable ASPM by default") Link: https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitlab.freedesktop.org%2Fdrm%2Famd%2F-%2Fissues%2F1885data=04%7C01%7Crichard.gong%40amd.com%7C35699b2c088747daedf508da1d63f1f3%7C3dd8961fe4884e608e11a82d994e183d%7C0%7C0%7C637854612351767549%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000sdata=lzgZ3bV0PLFFl9uo3wt6N1dOoZpU2DqpddAk%2BTX8rEI%3Dreserved=0 Reported-by: kernel test robot Signed-off-by: Richard Gong --- v4: s/CONFIG_X86_64/CONFIG_X86 enhanced check logic v3: s/intel_core_asom_chk/aspm_support_quirk_check correct build error with W=1 option v2: correct commit description move the check from chip family to problematic platform --- drivers/gpu/drm/amd/amdgpu/vi.c | 17 - 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c index 039b90cdc3bc..b33e0a9bee65 100644 --- a/drivers/gpu/drm/amd/amdgpu/vi.c +++ b/drivers/gpu/drm/amd/amdgpu/vi.c @@ -81,6 +81,10 @@ #include "mxgpu_vi.h" #include "amdgpu_dm.h" +#if IS_ENABLED(CONFIG_X86) +#include +#endif + #define ixPCIE_LC_L1_PM_SUBSTATE 0x100100C6 #define PCIE_LC_L1_PM_SUBSTATE__LC_L1_SUBSTATES_OVERRIDE_EN_MASK 0x0001L #define PCIE_LC_L1_PM_SUBSTATE__LC_PCI_PM_L1_2_OVERRIDE_MASK 0x0002L @@ -1134,13 +1138,24 @@ static void vi_enable_aspm(struct amdgpu_device *adev) WREG32_PCIE(ixPCIE_LC_CNTL, data); } +static bool aspm_support_quirk_check(void) +{ + if (IS_ENABLED(CONFIG_X86)) { + struct cpuinfo_x86 *c = _data(0); + + return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE); + } I have not seen this reported by a bot, sorry if it is a duplicate. This breaks non-x86 builds (arm64 allmodconfig for example): drivers/gpu/drm/amd/amdgpu/vi.c:1144:28: error: implicit declaration of function 'cpu_data' is invalid in C99 [-Werror,-Wimplicit-function-declaration] struct cpuinfo_x86 *c = _data(0); ^ drivers/gpu/drm/amd/amdgpu/vi.c:1144:27: error: cannot take the address of an rvalue of type 'int' struct cpuinfo_x86 *c = _data(0); ^~~~ drivers/gpu/drm/amd/amdgpu/vi.c:1146:13: error: incomplete definition of type 'struct cpuinfo_x86' return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE); ~^ drivers/gpu/drm/amd/amdgpu/vi.c:1144:10: note: forward declaration of 'struct cpuinfo_x86' struct cpuinfo_x86 *c = _data(0); ^ drivers/gpu/drm/amd/amdgpu/vi.c:1146:28: error: incomplete definition of type 'struct cpuinfo_x86' return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE); ~^ drivers/gpu/drm/amd/amdgpu/vi.c:1144:10: note: forward declaration of 'struct cpuinfo_x86' struct cpuinfo_x86 *c = _data(0); ^ drivers/gpu/drm/amd/amdgpu/vi.c:1146:43: error: use of undeclared identifier 'INTEL_FAM6_ALDERLAKE' return !(c->x86 == 6 && c->x86_model == INTEL_FAM6_ALDERLAKE); ^ 5 errors generated. 'struct cpuinfo_x86' is only defined for CONFIG_X86 so this section needs to guarded with the preprocessor, which is how it was done in v2. Please go back to that. Thanks, I will do that. Regards, Richard Cheers, Nathan
Re: [PATCH] drm/msm: Revert "drm/msm: Stop using iommu_present()"
On 20/04/2022 00:04, Robin Murphy wrote: On 2022-04-19 14:04, Dmitry Baryshkov wrote: This reverts commit e2a88eabb02410267519b838fb9b79f5206769be. The commit in question makes msm_use_mmu() check whether the DRM 'component master' device is translated by the IOMMU. At this moment it is the 'mdss' device. However on platforms using the MDP5 driver (e.g. MSM8916/APQ8016, MSM8996/APQ8096) it's the mdp5 device, which has the iommus property (and thus is "translated by the IOMMU"). This results in these devices being broken with the following lines in the dmesg. [drm] Initialized msm 1.9.0 20130625 for 1a0.mdss on minor 0 msm 1a0.mdss: [drm:adreno_request_fw] loaded qcom/a300_pm4.fw from new location msm 1a0.mdss: [drm:adreno_request_fw] loaded qcom/a300_pfp.fw from new location msm 1a0.mdss: [drm:get_pages] *ERROR* could not get pages: -28 msm 1a0.mdss: could not allocate stolen bo msm 1a0.mdss: [drm:get_pages] *ERROR* could not get pages: -28 msm 1a0.mdss: [drm:msm_alloc_stolen_fb] *ERROR* failed to allocate buffer object msm 1a0.mdss: [drm:msm_fbdev_create] *ERROR* failed to allocate fb Getting the mdp5 device pointer from this function is not that easy at this moment. Thus this patch is reverted till the MDSS rework [1] lands. It will make the mdp5/dpu1 device component master and the check will be legit. [1] https://patchwork.freedesktop.org/series/98525/ Oh, DRM... If that series is going to land got 5.19, could you please implement the correct equivalent of this patch within it? Yes, that's the plan. I'm sending a reworked version of your patch shortly (but it still depends on [1]). I'm fine with the revert for now if this patch doesn't work properly in all cases, but I have very little sympathy left for DRM drivers riding roughshod over all the standard driver model abstractions because they're "special". iommu_present() *needs* to go away, so if it's left to me to have a second go at fixing this driver next cycle, you're liable to get some abomination based on of_find_compatible_node() or similar, and I'll probably be demanding an ack to take it through the IOMMU tree ;) No need for such measures :-) Thanks, Robin. Fixes: e2a88eabb024 ("drm/msm: Stop using iommu_present()") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b6702b0fafcb..e2b5307b2360 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -263,7 +263,7 @@ bool msm_use_mmu(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; /* a2xx comes with its own MMU */ - return priv->is_a2xx || device_iommu_mapped(dev->dev); + return priv->is_a2xx || iommu_present(_bus_type); } static int msm_init_vram(struct drm_device *dev) -- With best wishes Dmitry
Re: [PATCH] drm/msm: Revert "drm/msm: Stop using iommu_present()"
On 2022-04-19 14:04, Dmitry Baryshkov wrote: This reverts commit e2a88eabb02410267519b838fb9b79f5206769be. The commit in question makes msm_use_mmu() check whether the DRM 'component master' device is translated by the IOMMU. At this moment it is the 'mdss' device. However on platforms using the MDP5 driver (e.g. MSM8916/APQ8016, MSM8996/APQ8096) it's the mdp5 device, which has the iommus property (and thus is "translated by the IOMMU"). This results in these devices being broken with the following lines in the dmesg. [drm] Initialized msm 1.9.0 20130625 for 1a0.mdss on minor 0 msm 1a0.mdss: [drm:adreno_request_fw] loaded qcom/a300_pm4.fw from new location msm 1a0.mdss: [drm:adreno_request_fw] loaded qcom/a300_pfp.fw from new location msm 1a0.mdss: [drm:get_pages] *ERROR* could not get pages: -28 msm 1a0.mdss: could not allocate stolen bo msm 1a0.mdss: [drm:get_pages] *ERROR* could not get pages: -28 msm 1a0.mdss: [drm:msm_alloc_stolen_fb] *ERROR* failed to allocate buffer object msm 1a0.mdss: [drm:msm_fbdev_create] *ERROR* failed to allocate fb Getting the mdp5 device pointer from this function is not that easy at this moment. Thus this patch is reverted till the MDSS rework [1] lands. It will make the mdp5/dpu1 device component master and the check will be legit. [1] https://patchwork.freedesktop.org/series/98525/ Oh, DRM... If that series is going to land got 5.19, could you please implement the correct equivalent of this patch within it? I'm fine with the revert for now if this patch doesn't work properly in all cases, but I have very little sympathy left for DRM drivers riding roughshod over all the standard driver model abstractions because they're "special". iommu_present() *needs* to go away, so if it's left to me to have a second go at fixing this driver next cycle, you're liable to get some abomination based on of_find_compatible_node() or similar, and I'll probably be demanding an ack to take it through the IOMMU tree ;) Thanks, Robin. Fixes: e2a88eabb024 ("drm/msm: Stop using iommu_present()") Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index b6702b0fafcb..e2b5307b2360 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -263,7 +263,7 @@ bool msm_use_mmu(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; /* a2xx comes with its own MMU */ - return priv->is_a2xx || device_iommu_mapped(dev->dev); + return priv->is_a2xx || iommu_present(_bus_type); } static int msm_init_vram(struct drm_device *dev)
Re: [PATCH v7 08/14] drm/msm/dpu: don't use merge_3d if DSC merge topology is used
On 4/6/2022 2:40 AM, Vinod Koul wrote: From: Dmitry Baryshkov DPU supports different topologies for the case when multiple INTFs are being driven by the single phys_enc. The driver defaults to using 3DMux in such cases. Don't use it if DSC merge is used instead. Suggested-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Signed-off-by: Vinod Koul Thank you for making the change generic as suggested. Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 16 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h | 6 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 4 +++- 3 files changed, 25 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 4052486f19d8..95d1588f3bb6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -511,6 +511,22 @@ void dpu_encoder_helper_split_config( } } +bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc) +{ + struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc); + int i, intf_count = 0, num_dsc = 0; + + for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++) + if (dpu_enc->phys_encs[i]) + intf_count++; + + /* See dpu_encoder_get_topology, we only support 2:2:1 topology */ + if (dpu_enc->dsc) + num_dsc = 2; + + return (num_dsc > 0) && (num_dsc > intf_count); +} + static struct msm_display_topology dpu_encoder_get_topology( struct dpu_encoder_virt *dpu_enc, struct dpu_kms *dpu_kms, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index ef873e5285a0..084c5265d7e5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -172,4 +172,10 @@ int dpu_encoder_get_linecount(struct drm_encoder *drm_enc); */ int dpu_encoder_get_vsync_count(struct drm_encoder *drm_enc); +/** + * dpu_encoder_use_dsc_merge - returns true if the encoder uses DSC merge topology. + * @drm_enc:Pointer to previously created drm encoder structure + */ +bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc); + #endif /* __DPU_ENCODER_H__ */ 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 4842070fdfa8..b5ad43b8a19b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -314,8 +314,10 @@ static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state); + /* Use merge_3d unless DSC MERGE topology is used */ if (phys_enc->split_role == ENC_ROLE_SOLO && - dpu_cstate->num_mixers == CRTC_DUAL_MIXERS) + dpu_cstate->num_mixers == CRTC_DUAL_MIXERS && + !dpu_encoder_use_dsc_merge(phys_enc->parent)) return BLEND_3D_H_ROW_INT; return BLEND_3D_NONE;
Re: [PATCH v4 11/15] drm/shmem-helper: Add generic memory shrinker
On 4/19/22 10:22, Thomas Zimmermann wrote: > Hi > > Am 18.04.22 um 00:37 schrieb Dmitry Osipenko: >> Introduce a common DRM SHMEM shrinker. It allows to reduce code >> duplication among DRM drivers that implement theirs own shrinkers. >> This is initial version of the shrinker that covers basic needs of >> GPU drivers, both purging and eviction of shmem objects are supported. >> >> This patch is based on a couple ideas borrowed from Rob's Clark MSM >> shrinker and Thomas' Zimmermann variant of SHMEM shrinker. >> >> In order to start using DRM SHMEM shrinker drivers should: >> >> 1. Implement new purge(), evict() + swap_in() GEM callbacks. >> 2. Register shrinker using drm_gem_shmem_shrinker_register(drm_device). >> 3. Use drm_gem_shmem_set_purgeable_and_evictable(shmem) and alike API >> functions to activate shrinking of GEMs. >> >> Signed-off-by: Daniel Almeida >> Signed-off-by: Dmitry Osipenko >> --- >> drivers/gpu/drm/drm_gem_shmem_helper.c | 765 - >> include/drm/drm_device.h | 4 + >> include/drm/drm_gem.h | 35 ++ >> include/drm/drm_gem_shmem_helper.h | 105 +++- >> 4 files changed, 877 insertions(+), 32 deletions(-) ... >> @@ -172,6 +172,41 @@ struct drm_gem_object_funcs { >> * This is optional but necessary for mmap support. >> */ >> const struct vm_operations_struct *vm_ops; >> + >> + /** >> + * @purge: >> + * >> + * Releases the GEM object's allocated backing storage to the >> system. >> + * >> + * Returns the number of pages that have been freed by purging >> the GEM object. >> + * >> + * This callback is used by the GEM shrinker. >> + */ >> + unsigned long (*purge)(struct drm_gem_object *obj); >> + >> + /** >> + * @evict: >> + * >> + * Unpins the GEM object's allocated backing storage, allowing >> shmem pages >> + * to be swapped out. > > What's the difference to the existing unpin() callback? Drivers need to do more than just unpinning pages when GEMs are evicted. Unpinning is only a part of the eviction process. I'll improve the doc-comment in v5. For example, for VirtIO-GPU driver we need to to detach host from the guest's memory before pages are evicted [1]. [1] https://gitlab.collabora.com/dmitry.osipenko/linux-kernel-rd/-/blob/932eb03198bce3a21353b09ab71e95f1c19b84c2/drivers/gpu/drm/virtio/virtgpu_object.c#L145 In case of Panfrost driver, we will need to remove mappings before pages are evicted. >> + * >> + * Returns the number of pages that have been unpinned. >> + * >> + * This callback is used by the GEM shrinker. >> + */ >> + unsigned long (*evict)(struct drm_gem_object *obj); >> + >> + /** >> + * @swap_in: >> + * >> + * Pins GEM object's allocated backing storage if it was >> previously evicted, >> + * moving swapped out pages back to memory. >> + * >> + * Returns 0 on success, or -errno on error. >> + * >> + * This callback is used by the GEM shrinker. >> + */ >> + int (*swap_in)(struct drm_gem_object *obj); > > Why do you need swap_in()? This can be done on-demand as part of a pin > or vmap operation. Similarly to the unpinning, the pining of pages is only a part of what needs to be done for GPU drivers. Besides of returning pages back to memory, we also need to make them accessible to GPU and this is a driver-specific process. This why we need the additional callbacks. >> }; >> /** >> diff --git a/include/drm/drm_gem_shmem_helper.h >> b/include/drm/drm_gem_shmem_helper.h >> index 70889533962a..a65557b446e6 100644 >> --- a/include/drm/drm_gem_shmem_helper.h >> +++ b/include/drm/drm_gem_shmem_helper.h >> @@ -6,6 +6,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> @@ -15,8 +16,18 @@ >> struct dma_buf_attachment; >> struct drm_mode_create_dumb; >> struct drm_printer; >> +struct drm_device; >> struct sg_table; >> +enum drm_gem_shmem_pages_state { >> + DRM_GEM_SHMEM_PAGES_STATE_PURGED = -2, >> + DRM_GEM_SHMEM_PAGES_STATE_EVICTED = -1, >> + DRM_GEM_SHMEM_PAGES_STATE_UNPINNED = 0, >> + DRM_GEM_SHMEM_PAGES_STATE_PINNED = 1, >> + DRM_GEM_SHMEM_PAGES_STATE_EVICTABLE = 2, >> + DRM_GEM_SHMEM_PAGES_STATE_PURGEABLE = 3, >> +}; > > These states can be detected by looking at the vmap and pin refcounts. > No need to store them explicitly. I'll try to revisit this, but I was finding that it's much more difficult to follow and debug code without the explicit states. > In your patch, they also come with a > big zoo of trivial helpers. None of that seems necessary AFAICT. There are couple functions which could be squashed, although this may hurt readability of the code a tad. I'll try to take another look at this for v5. > What's the difference between purge and evict BTW? The evicted pages are moved out from memory to a SWAP partition or file. The purged pages are destroyed permanently.
2022 X.Org Foundation Election vote results
The Board of Directors election and the vote on the By-laws concluded at 23:59 UTC on 18 April 2022. There are 80 current Members of the X.Org Foundation, and 52 Members cast votes. This is a 65.0% turn out. In the election of the Directors to the Board of the X.Org Foundation, the results were that Emma Anholt, Alyssa Rosenzweig, Mark Filion and Ricardo Garcia were elected for two year terms. The old full board is: Emma Anholt, Samuel Iglesias Gonsálvez, Mark Filion, Manasi D Navare, Keith Packard, Lyude Paul, Daniel Vetter, Harry Wentland The new full board is: Emma Anholt, Samuel Iglesias Gonsálvez, Mark Filion, Manasi D Navare, Alyssa Rosenzweig, Lyude Paul, Daniel Vetter, and Ricardo Garcia The full election results were as follows: Option | Rank 1 | Rank 2 | Rank 3 | Rank 4 | Rank 5 | Rank 6 | Final Score Emma Anholt | 21 | 16 | 4 | 1 | 5 | 5 | 240 Alyssa Rosenzweig | 4 | 10 | 17 | 7 | 11 | 3 | 188 Mark Filion | 8 | 12 | 7 | 10 | 5 | 10 | 186 Ricardo Garcia | 9 | 4 | 5 | 17 | 10 | 7 | 172 Lucas Stach | 4 | 5 | 14 | 9 | 11 | 9 | 163 Shashank Sharma | 6 | 5 | 5 | 8 | 10 | 18 | 143 Lyude Paul, on behalf of the X.Org elections committee
Re: [Freedreno] [PATCH 08/12] drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback
On 4/14/2022 5:24 PM, Dmitry Baryshkov wrote: On 15/04/2022 01:16, Abhinav Kumar wrote: On 2/4/2022 3:19 PM, Dmitry Baryshkov wrote: On 05/02/2022 00:17, Abhinav Kumar wrote: Introduce the dpu_encoder_phys_* for the writeback interface to handle writeback specific hardware programming. Signed-off-by: Abhinav Kumar Mostly looks ok, see minor comments bellow. --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h | 36 +- .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 813 + 3 files changed, 849 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index c43ef35..3abaf84 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -53,6 +53,7 @@ msm-y := \ disp/dpu1/dpu_encoder.o \ disp/dpu1/dpu_encoder_phys_cmd.o \ disp/dpu1/dpu_encoder_phys_vid.o \ + disp/dpu1/dpu_encoder_phys_wb.o \ disp/dpu1/dpu_formats.o \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ 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 7b3354d..80da0a9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -159,6 +159,7 @@ struct dpu_encoder_phys_ops { * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel * @INTR_IDX_RDPTR: Readpointer done unterrupt for cmd mode panel + * @INTR_IDX_WB_DONE: Writeback fone interrupt for virtual connector */ enum dpu_intr_idx { INTR_IDX_VSYNC, @@ -166,6 +167,7 @@ enum dpu_intr_idx { INTR_IDX_UNDERRUN, INTR_IDX_CTL_START, INTR_IDX_RDPTR, + INTR_IDX_WB_DONE, INTR_IDX_MAX, }; @@ -196,7 +198,7 @@ struct dpu_encoder_irq { * @hw_ctl: Hardware interface to the ctl registers * @hw_pp: Hardware interface to the ping pong registers * @hw_intf: Hardware interface to the intf registers - * @hw_wb: Hardware interface to the wb registers + * @hw_wb: Hardware interface to the wb registers * @dpu_kms: Pointer to the dpu_kms top level * @cached_mode: DRM mode cached at mode_set time, acted on in enable * @enabled: Whether the encoder has enabled and running a mode @@ -250,6 +252,31 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys) } /** + * struct dpu_encoder_phys_wb - sub-class of dpu_encoder_phys to handle command + * mode specific operations + * @base: Baseclass physical encoder structure + * @wbirq_refcount: Reference count of writeback interrupt + * @wb_done_timeout_cnt: number of wb done irq timeout errors + * @wb_cfg: writeback block config to store fb related details + * @cdp_cfg: chroma down prefetch block config for wb + * @aspace: address space to be used for wb framebuffer + * @wb_conn: backpointer to writeback connector + * @wb_job: backpointer to current writeback job + * @dest: dpu buffer layout for current writeback output buffer + */ +struct dpu_encoder_phys_wb { + struct dpu_encoder_phys base; + atomic_t wbirq_refcount; + int wb_done_timeout_cnt; + struct dpu_hw_wb_cfg wb_cfg; + struct dpu_hw_wb_cdp_cfg cdp_cfg; What about moving them to the stack rather storing them in the structure? Yes cdp_cfg can be moved to the stack. Will do it in the next version. wb_cfg cannot because for drm_wb, prepare_wb_job has the job's fb attributes which are used to setup the wb. But we commit it only in the encoder_kickoff in dpu_encoder_phys_wb_setup_fb(). So its shared across two methods. + struct msm_gem_address_space *aspace; + struct drm_writeback_connector *wb_conn; + struct drm_writeback_job *wb_job; + struct dpu_hw_fmt_layout dest; +}; + +/** * struct dpu_encoder_phys_cmd - sub-class of dpu_encoder_phys to handle command * mode specific operations * @base: Baseclass physical encoder structure @@ -317,6 +344,13 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( struct dpu_enc_phys_init_params *p); /** + * dpu_encoder_phys_wb_init - initialize writeback encoder + * @init: Pointer to init info structure with initialization params + */ +struct dpu_encoder_phys *dpu_encoder_phys_wb_init( + struct dpu_enc_phys_init_params *p); + +/** * dpu_encoder_helper_trigger_start - control start helper function * This helper function may be optionally specified by physical * encoders if they require ctl_start triggering. diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c new file mode 100644 index 000..783f83e --- /dev/null +++
[PATCH] Staging: fbtft: Fix style problem in header
Removed an unnecessary semicolon at the end of a macro call Signed-off-by: Ian Cowan --- drivers/staging/fbtft/fbtft.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/fbtft/fbtft.h b/drivers/staging/fbtft/fbtft.h index 2c2b5f1c1df3..aa66760e1a9c 100644 --- a/drivers/staging/fbtft/fbtft.h +++ b/drivers/staging/fbtft/fbtft.h @@ -277,7 +277,7 @@ static const struct of_device_id dt_ids[] = { \ { .compatible = _compatible }, \ {}, \ }; \ -MODULE_DEVICE_TABLE(of, dt_ids); +MODULE_DEVICE_TABLE(of, dt_ids) #define FBTFT_SPI_DRIVER(_name, _compatible, _display, _spi_ids) \ \ -- 2.32.0
Re: [PATCH] drm: bridge: adv7511: Enable DRM_BRIDGE_OP_HPD based on HPD interrupt
Quoting Biju Das (2022-04-19 15:24:53) > Connector detection using poll method won't work in case of bridge > attached to the encoder with the flag DRM_BRIDGE_ATTACH_NO_CONNECTOR, as > the code defaults to HPD. > > Enable DRM_BRIDGE_OP_HPD based on HPD interrupt availability, so that > it will fall back to polling, if HPD is not available. Reviewed-by: Kieran Bingham > > Signed-off-by: Biju Das > --- > drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 6 -- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > index 668dcefbae17..b3f10c54e064 100644 > --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c > @@ -1292,8 +1292,10 @@ static int adv7511_probe(struct i2c_client *i2c, const > struct i2c_device_id *id) > goto err_unregister_cec; > > adv7511->bridge.funcs = _bridge_funcs; > - adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID > - | DRM_BRIDGE_OP_HPD; > + adv7511->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID; > + if (adv7511->i2c_main->irq) > + adv7511->bridge.ops |= DRM_BRIDGE_OP_HPD; > + > adv7511->bridge.of_node = dev->of_node; > adv7511->bridge.type = DRM_MODE_CONNECTOR_HDMIA; > > -- > 2.25.1 >
[linux-next:master] BUILD REGRESSION 634de1db0e9bbeb90d7b01020e59ec3dab4d38a1
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master branch HEAD: 634de1db0e9bbeb90d7b01020e59ec3dab4d38a1 Add linux-next specific files for 20220419 Error/Warning reports: https://lore.kernel.org/linux-mm/202204081656.6x4pfen4-...@intel.com https://lore.kernel.org/linux-mm/202204140108.derahwen-...@intel.com https://lore.kernel.org/linux-mm/202204192051.bh3il8de-...@intel.com https://lore.kernel.org/lkml/202204140043.tx7bibvi-...@intel.com https://lore.kernel.org/llvm/202203241958.uw9bwfmd-...@intel.com Error/Warning: (recently discovered and may have been fixed) drivers/bus/mhi/host/main.c:787:13: warning: parameter 'event_quota' set but not used [-Wunused-but-set-parameter] drivers/gpu/drm/amd/amdgpu/../display/dc/virtual/virtual_link_hwss.c:32:6: warning: no previous prototype for 'virtual_setup_stream_attribute' [-Wmissing-prototypes] kernel/sched/sched.h: linux/static_key.h is included more than once. ntb_perf.c:(.text+0x6052): undefined reference to `__umoddi3' Unverified Error/Warning (likely false positive, please contact us if interested): Makefile:684: arch/h8300/Makefile: No such file or directory arch/Kconfig:10: can't open file "arch/h8300/Kconfig" arch/s390/include/asm/spinlock.h:81:3: error: unexpected token in '.rept' directive arch/s390/include/asm/spinlock.h:81:3: error: unknown directive arch/s390/include/asm/spinlock.h:81:3: error: unmatched '.endr' directive arch/s390/lib/spinlock.c:78:3: error: unexpected token in '.rept' directive arch/s390/lib/spinlock.c:78:3: error: unknown directive arch/s390/lib/spinlock.c:78:3: error: unmatched '.endr' directive drivers/bus/mhi/host/main.c:1580:4: warning: Attempt to free released memory [clang-analyzer-unix.Malloc] drivers/dma-buf/st-dma-fence-unwrap.c:125:13: warning: variable 'err' set but not used [-Wunused-but-set-variable] drivers/edac/edac_device.c:73 edac_device_alloc_ctl_info() warn: Please consider using kcalloc instead drivers/edac/edac_mc.c:369 edac_mc_alloc() warn: Please consider using kcalloc instead drivers/gpu/drm/amd/amdgpu/../display/dc/dcn31/dcn31_hubp.c:57:6: warning: no previous prototype for 'hubp31_program_extended_blank' [-Wmissing-prototypes] drivers/gpu/drm/solomon/ssd130x.c:486:2: warning: Undefined or garbage value returned to caller [clang-analyzer-core.uninitialized.UndefReturn] drivers/hwmon/da9055-hwmon.c:201:9: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] drivers/hwmon/scpi-hwmon.c:121:9: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] drivers/hwmon/vt8231.c:634:9: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] drivers/tty/synclink_gt.c:3432:2: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] drivers/usb/chipidea/core.c:956:10: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] drivers/usb/gadget/udc/core.c:1664:9: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides boundary checks such as 'sprintf_s' in case of C11 [clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling] drivers/video/fbdev/matrox/matroxfb_base.c:1094:5: warning: Call to function 'sprintf' is insecure as it does not provide bounding of the memory buffer or security checks introduced in the C11 standard. Replace with analogous functions that support length arguments or provides bound
Re: [PATCH 09/48] watchdog: sa1100: use platform device registration
On 4/19/22 09:37, Arnd Bergmann wrote: From: Arnd Bergmann Rather than relying on machine specific headers to pass down the reboot status and the register locations, use resources and platform_data. Aside from this, keep the changes to a minimum. Cc: Wim Van Sebroeck Cc: Guenter Roeck Cc: linux-watch...@vger.kernel.org Signed-off-by: Arnd Bergmann Acked-by: Guenter Roeck --- arch/arm/mach-pxa/devices.c | 11 +++ arch/arm/mach-pxa/include/mach/regs-ost.h | 2 + arch/arm/mach-pxa/include/mach/reset.h| 2 +- arch/arm/mach-pxa/pxa25x.c| 2 +- arch/arm/mach-pxa/pxa27x.c| 2 +- arch/arm/mach-pxa/pxa3xx.c| 2 +- arch/arm/mach-pxa/reset.c | 3 - arch/arm/mach-sa1100/generic.c| 6 +- arch/arm/mach-sa1100/include/mach/reset.h | 1 - drivers/watchdog/sa1100_wdt.c | 87 --- 10 files changed, 83 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 454523237c97..12f78636045f 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -24,6 +24,8 @@ #include #include +#include +#include #include "devices.h" #include "generic.h" @@ -1118,3 +1120,12 @@ void __init pxa2xx_set_dmac_info(struct mmp_dma_platdata *dma_pdata) { pxa_register_device(_pxa_dma, dma_pdata); } + +void __init pxa_register_wdt(unsigned int reset_status) +{ + struct resource res = DEFINE_RES_MEM(OST_PHYS, OST_LEN); + + reset_status &= RESET_STATUS_WATCHDOG; + platform_device_register_resndata(NULL, "sa1100_wdt", -1, , 1, + _status, sizeof(reset_status)); +} diff --git a/arch/arm/mach-pxa/include/mach/regs-ost.h b/arch/arm/mach-pxa/include/mach/regs-ost.h index 109d0ed264df..c8001cfc8d6b 100644 --- a/arch/arm/mach-pxa/include/mach/regs-ost.h +++ b/arch/arm/mach-pxa/include/mach/regs-ost.h @@ -7,6 +7,8 @@ /* * OS Timer & Match Registers */ +#define OST_PHYS 0x40A0 +#define OST_LEN0x0020 #define OSMR0 io_p2v(0x40A0) /* */ #define OSMR1 io_p2v(0x40A4) /* */ diff --git a/arch/arm/mach-pxa/include/mach/reset.h b/arch/arm/mach-pxa/include/mach/reset.h index e1c4d100fd45..963dd190bc13 100644 --- a/arch/arm/mach-pxa/include/mach/reset.h +++ b/arch/arm/mach-pxa/include/mach/reset.h @@ -8,8 +8,8 @@ #define RESET_STATUS_GPIO (1 << 3) /* GPIO Reset */ #define RESET_STATUS_ALL (0xf) -extern unsigned int reset_status; extern void clear_reset_status(unsigned int mask); +extern void pxa_register_wdt(unsigned int reset_status); /** * init_gpio_reset() - register GPIO as reset generator diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 305047ebd2f1..dfc90b41fba3 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -240,7 +240,7 @@ static int __init pxa25x_init(void) if (cpu_is_pxa25x()) { - reset_status = RCSR; + pxa_register_wdt(RCSR); pxa25x_init_pm(); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index a81ac88ecbfd..38fdd22c4dc5 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -337,7 +337,7 @@ static int __init pxa27x_init(void) if (cpu_is_pxa27x()) { - reset_status = RCSR; + pxa_register_wdt(RCSR); pxa27x_init_pm(); diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index fc84aed99481..7c569fa2a6da 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -463,7 +463,7 @@ static int __init pxa3xx_init(void) if (cpu_is_pxa3xx()) { - reset_status = ARSR; + pxa_register_wdt(ARSR); /* * clear RDH bit every time after reset diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c index af78405aa4e9..fcb791c5ae3e 100644 --- a/arch/arm/mach-pxa/reset.c +++ b/arch/arm/mach-pxa/reset.c @@ -11,9 +11,6 @@ #include #include -unsigned int reset_status; -EXPORT_SYMBOL(reset_status); - static void do_hw_reset(void); static int reset_gpio = -1; diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 4dfb7554649d..6c21f214cd60 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -39,9 +39,6 @@ #include "generic.h" #include -unsigned int reset_status; -EXPORT_SYMBOL(reset_status); - #define NR_FREQS 16 /* @@ -319,10 +316,13 @@ static struct platform_device *sa11x0_devices[] __initdata = { static int __init sa1100_init(void) { + struct resource wdt_res = DEFINE_RES_MEM(0x9000, 0x20); pm_power_off = sa1100_power_off; regulator_has_full_constraints(); + platform_device_register_simple("sa1100_wdt", -1, _res, 1); + return platform_add_devices(sa11x0_devices,
Re: [PATCH AUTOSEL 5.4 11/14] drm/msm: Stop using iommu_present()
You might want to drop this one, it seems to be causing some issues on older generations.. I'll be sending another PR shortly with a revert. https://patchwork.freedesktop.org/patch/482453 BR, -R On Tue, Apr 19, 2022 at 11:15 AM Sasha Levin wrote: > > From: Robin Murphy > > [ Upstream commit e2a88eabb02410267519b838fb9b79f5206769be ] > > Even if some IOMMU has registered itself on the platform "bus", that > doesn't necessarily mean it provides translation for the device we > care about. Replace iommu_present() with a more appropriate check. > > Signed-off-by: Robin Murphy > Reviewed-by: Rob Clark > Patchwork: https://patchwork.freedesktop.org/patch/480707/ > Link: > https://lore.kernel.org/r/5ab4f4574d7f3e042261da702d493ee40d003356.1649168268.git.robin.mur...@arm.com > Signed-off-by: Dmitry Baryshkov > Signed-off-by: Rob Clark > Signed-off-by: Sasha Levin > --- > drivers/gpu/drm/msm/msm_drv.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c > index 407b51cf6790..7322df9cf673 100644 > --- a/drivers/gpu/drm/msm/msm_drv.c > +++ b/drivers/gpu/drm/msm/msm_drv.c > @@ -303,7 +303,7 @@ bool msm_use_mmu(struct drm_device *dev) > struct msm_drm_private *priv = dev->dev_private; > > /* a2xx comes with its own MMU */ > - return priv->is_a2xx || iommu_present(_bus_type); > + return priv->is_a2xx || device_iommu_mapped(dev->dev); > } > > static int msm_init_vram(struct drm_device *dev) > -- > 2.35.1 >
[PATCH AUTOSEL 4.9 7/7] drm/msm/mdp5: check the return of kzalloc()
From: Xiaoke Wang [ Upstream commit 047ae66556b7feb11bd4f81f46627cff95e7 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Besides, since mdp5_plane_reset() is void type, so we should better set `plane-state` to NULL after releasing it. Signed-off-by: Xiaoke Wang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/481055/ Link: https://lore.kernel.org/r/tencent_8e2a1c78140ee1784ab2ff4b2088cc0ab...@qq.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 83bf997dda03..e14bfbdbaf2b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -192,7 +192,10 @@ static void mdp5_plane_reset(struct drm_plane *plane) drm_framebuffer_unreference(plane->state->fb); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; /* assign default blend parameters */ mdp5_state->alpha = 255; -- 2.35.1
[PATCH AUTOSEL 4.14 7/9] drm/msm/mdp5: check the return of kzalloc()
From: Xiaoke Wang [ Upstream commit 047ae66556b7feb11bd4f81f46627cff95e7 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Besides, since mdp5_plane_reset() is void type, so we should better set `plane-state` to NULL after releasing it. Signed-off-by: Xiaoke Wang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/481055/ Link: https://lore.kernel.org/r/tencent_8e2a1c78140ee1784ab2ff4b2088cc0ab...@qq.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index 4b22ac3413a1..1f9e3c5ea47d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c @@ -197,7 +197,10 @@ static void mdp5_plane_reset(struct drm_plane *plane) drm_framebuffer_unreference(plane->state->fb); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; /* assign default blend parameters */ mdp5_state->alpha = 255; -- 2.35.1
[PATCH AUTOSEL 4.19 10/12] drm/msm/mdp5: check the return of kzalloc()
From: Xiaoke Wang [ Upstream commit 047ae66556b7feb11bd4f81f46627cff95e7 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Besides, since mdp5_plane_reset() is void type, so we should better set `plane-state` to NULL after releasing it. Signed-off-by: Xiaoke Wang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/481055/ Link: https://lore.kernel.org/r/tencent_8e2a1c78140ee1784ab2ff4b2088cc0ab...@qq.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 1ddf07514de6..3d8eaa25bea0 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -188,7 +188,10 @@ static void mdp5_plane_reset(struct drm_plane *plane) drm_framebuffer_unreference(plane->state->fb); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; /* assign default blend parameters */ mdp5_state->alpha = 255; -- 2.35.1
[PATCH AUTOSEL 5.4 11/14] drm/msm: Stop using iommu_present()
From: Robin Murphy [ Upstream commit e2a88eabb02410267519b838fb9b79f5206769be ] Even if some IOMMU has registered itself on the platform "bus", that doesn't necessarily mean it provides translation for the device we care about. Replace iommu_present() with a more appropriate check. Signed-off-by: Robin Murphy Reviewed-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/480707/ Link: https://lore.kernel.org/r/5ab4f4574d7f3e042261da702d493ee40d003356.1649168268.git.robin.mur...@arm.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 407b51cf6790..7322df9cf673 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -303,7 +303,7 @@ bool msm_use_mmu(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; /* a2xx comes with its own MMU */ - return priv->is_a2xx || iommu_present(_bus_type); + return priv->is_a2xx || device_iommu_mapped(dev->dev); } static int msm_init_vram(struct drm_device *dev) -- 2.35.1
[PATCH AUTOSEL 5.4 10/14] drm/msm/mdp5: check the return of kzalloc()
From: Xiaoke Wang [ Upstream commit 047ae66556b7feb11bd4f81f46627cff95e7 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Besides, since mdp5_plane_reset() is void type, so we should better set `plane-state` to NULL after releasing it. Signed-off-by: Xiaoke Wang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/481055/ Link: https://lore.kernel.org/r/tencent_8e2a1c78140ee1784ab2ff4b2088cc0ab...@qq.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 83423092de2f..da0799333970 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -179,7 +179,10 @@ static void mdp5_plane_reset(struct drm_plane *plane) drm_framebuffer_put(plane->state->fb); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; /* assign default blend parameters */ mdp5_state->alpha = 255; -- 2.35.1
[PATCH AUTOSEL 5.10 13/18] drm/msm: Stop using iommu_present()
From: Robin Murphy [ Upstream commit e2a88eabb02410267519b838fb9b79f5206769be ] Even if some IOMMU has registered itself on the platform "bus", that doesn't necessarily mean it provides translation for the device we care about. Replace iommu_present() with a more appropriate check. Signed-off-by: Robin Murphy Reviewed-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/480707/ Link: https://lore.kernel.org/r/5ab4f4574d7f3e042261da702d493ee40d003356.1649168268.git.robin.mur...@arm.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index e37e5afc680a..ad88cb9c86ec 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -316,7 +316,7 @@ bool msm_use_mmu(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; /* a2xx comes with its own MMU */ - return priv->is_a2xx || iommu_present(_bus_type); + return priv->is_a2xx || device_iommu_mapped(dev->dev); } static int msm_init_vram(struct drm_device *dev) -- 2.35.1
[PATCH AUTOSEL 5.10 12/18] drm/msm/mdp5: check the return of kzalloc()
From: Xiaoke Wang [ Upstream commit 047ae66556b7feb11bd4f81f46627cff95e7 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Besides, since mdp5_plane_reset() is void type, so we should better set `plane-state` to NULL after releasing it. Signed-off-by: Xiaoke Wang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/481055/ Link: https://lore.kernel.org/r/tencent_8e2a1c78140ee1784ab2ff4b2088cc0ab...@qq.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 83423092de2f..da0799333970 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -179,7 +179,10 @@ static void mdp5_plane_reset(struct drm_plane *plane) drm_framebuffer_put(plane->state->fb); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; /* assign default blend parameters */ mdp5_state->alpha = 255; -- 2.35.1
[PATCH AUTOSEL 5.15 15/27] drm/msm: Stop using iommu_present()
From: Robin Murphy [ Upstream commit e2a88eabb02410267519b838fb9b79f5206769be ] Even if some IOMMU has registered itself on the platform "bus", that doesn't necessarily mean it provides translation for the device we care about. Replace iommu_present() with a more appropriate check. Signed-off-by: Robin Murphy Reviewed-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/480707/ Link: https://lore.kernel.org/r/5ab4f4574d7f3e042261da702d493ee40d003356.1649168268.git.robin.mur...@arm.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index bbf999c66517..d6d40429016d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -403,7 +403,7 @@ bool msm_use_mmu(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; /* a2xx comes with its own MMU */ - return priv->is_a2xx || iommu_present(_bus_type); + return priv->is_a2xx || device_iommu_mapped(dev->dev); } static int msm_init_vram(struct drm_device *dev) -- 2.35.1
[PATCH AUTOSEL 5.15 14/27] drm/msm/mdp5: check the return of kzalloc()
From: Xiaoke Wang [ Upstream commit 047ae66556b7feb11bd4f81f46627cff95e7 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Besides, since mdp5_plane_reset() is void type, so we should better set `plane-state` to NULL after releasing it. Signed-off-by: Xiaoke Wang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/481055/ Link: https://lore.kernel.org/r/tencent_8e2a1c78140ee1784ab2ff4b2088cc0ab...@qq.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index c6b69afcbac8..50e854207c70 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -90,7 +90,10 @@ static void mdp5_plane_reset(struct drm_plane *plane) __drm_atomic_helper_plane_destroy_state(plane->state); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; if (plane->type == DRM_PLANE_TYPE_PRIMARY) mdp5_state->base.zpos = STAGE_BASE; -- 2.35.1
[PATCH AUTOSEL 5.15 06/27] drm/msm/disp: check the return value of kzalloc()
From: Xiaoke Wang [ Upstream commit f75e582b0c3ee8f0bddc2248cc8b9175f29c5937 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Signed-off-by: Xiaoke Wang Reviewed-by: Abhinav Kumar Link: https://lore.kernel.org/r/tencent_b3e19486ff39415098b572b7397c2936c...@qq.com Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c index cabe15190ec1..369e57f73a47 100644 --- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c +++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c @@ -169,6 +169,8 @@ void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len, va_list va; new_blk = kzalloc(sizeof(struct msm_disp_state_block), GFP_KERNEL); + if (!new_blk) + return; va_start(va, fmt); -- 2.35.1
[PATCH AUTOSEL 5.17 19/34] drm/msm: Stop using iommu_present()
From: Robin Murphy [ Upstream commit e2a88eabb02410267519b838fb9b79f5206769be ] Even if some IOMMU has registered itself on the platform "bus", that doesn't necessarily mean it provides translation for the device we care about. Replace iommu_present() with a more appropriate check. Signed-off-by: Robin Murphy Reviewed-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/480707/ Link: https://lore.kernel.org/r/5ab4f4574d7f3e042261da702d493ee40d003356.1649168268.git.robin.mur...@arm.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/msm_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 555666e3f960..5959527efc6e 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -427,7 +427,7 @@ bool msm_use_mmu(struct drm_device *dev) struct msm_drm_private *priv = dev->dev_private; /* a2xx comes with its own MMU */ - return priv->is_a2xx || iommu_present(_bus_type); + return priv->is_a2xx || device_iommu_mapped(dev->dev); } static int msm_init_vram(struct drm_device *dev) -- 2.35.1
[PATCH AUTOSEL 5.17 18/34] drm/msm/mdp5: check the return of kzalloc()
From: Xiaoke Wang [ Upstream commit 047ae66556b7feb11bd4f81f46627cff95e7 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Besides, since mdp5_plane_reset() is void type, so we should better set `plane-state` to NULL after releasing it. Signed-off-by: Xiaoke Wang Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/481055/ Link: https://lore.kernel.org/r/tencent_8e2a1c78140ee1784ab2ff4b2088cc0ab...@qq.com Signed-off-by: Dmitry Baryshkov Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index c6b69afcbac8..50e854207c70 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -90,7 +90,10 @@ static void mdp5_plane_reset(struct drm_plane *plane) __drm_atomic_helper_plane_destroy_state(plane->state); kfree(to_mdp5_plane_state(plane->state)); + plane->state = NULL; mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + if (!mdp5_state) + return; if (plane->type == DRM_PLANE_TYPE_PRIMARY) mdp5_state->base.zpos = STAGE_BASE; -- 2.35.1
[PATCH AUTOSEL 5.17 08/34] drm/msm/disp: check the return value of kzalloc()
From: Xiaoke Wang [ Upstream commit f75e582b0c3ee8f0bddc2248cc8b9175f29c5937 ] kzalloc() is a memory allocation function which can return NULL when some internal memory errors happen. So it is better to check it to prevent potential wrong memory access. Signed-off-by: Xiaoke Wang Reviewed-by: Abhinav Kumar Link: https://lore.kernel.org/r/tencent_b3e19486ff39415098b572b7397c2936c...@qq.com Signed-off-by: Rob Clark Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c index 5d2ff6791058..acfe1b31e079 100644 --- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c +++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c @@ -176,6 +176,8 @@ void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len, va_list va; new_blk = kzalloc(sizeof(struct msm_disp_state_block), GFP_KERNEL); + if (!new_blk) + return; va_start(va, fmt); -- 2.35.1
[PATCH AUTOSEL 5.17 02/34] drm/msm/gpu: Remove mutex from wait_event condition
From: Rob Clark [ Upstream commit 7242795d520d3fb48e005e3c96ba54bb59639d6e ] The mutex wasn't really protecting anything before. Before the previous patch we could still be racing with the scheduler's kthread, as that is not necessarily frozen yet. Now that we've parked the sched threads, the only race is with jobs retiring, and that is harmless, ie. Signed-off-by: Rob Clark Link: https://lore.kernel.org/r/20220310234611.424743-4-robdcl...@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/adreno_device.c | 11 +-- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index b93de79000e1..e8a8240a6868 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -608,22 +608,13 @@ static int adreno_runtime_resume(struct device *dev) return gpu->funcs->pm_resume(gpu); } -static int active_submits(struct msm_gpu *gpu) -{ - int active_submits; - mutex_lock(>active_lock); - active_submits = gpu->active_submits; - mutex_unlock(>active_lock); - return active_submits; -} - static int adreno_runtime_suspend(struct device *dev) { struct msm_gpu *gpu = dev_to_gpu(dev); int remaining; remaining = wait_event_timeout(gpu->retire_event, - active_submits(gpu) == 0, + gpu->active_submits == 0, msecs_to_jiffies(1000)); if (remaining == 0) { dev_err(dev, "Timeout waiting for GPU to suspend\n"); -- 2.35.1
[PATCH AUTOSEL 5.17 01/34] drm/msm/gpu: Rename runtime suspend/resume functions
From: Rob Clark [ Upstream commit f7eab1ddb9f8bc99206e3efa8d34ca1d2faca209 ] Signed-off-by: Rob Clark Link: https://lore.kernel.org/r/20220310234611.424743-2-robdcl...@gmail.com Signed-off-by: Sasha Levin --- drivers/gpu/drm/msm/adreno/adreno_device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index fb261930ad1c..b93de79000e1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -601,7 +601,7 @@ static const struct of_device_id dt_match[] = { }; #ifdef CONFIG_PM -static int adreno_resume(struct device *dev) +static int adreno_runtime_resume(struct device *dev) { struct msm_gpu *gpu = dev_to_gpu(dev); @@ -617,7 +617,7 @@ static int active_submits(struct msm_gpu *gpu) return active_submits; } -static int adreno_suspend(struct device *dev) +static int adreno_runtime_suspend(struct device *dev) { struct msm_gpu *gpu = dev_to_gpu(dev); int remaining; @@ -636,7 +636,7 @@ static int adreno_suspend(struct device *dev) static const struct dev_pm_ops adreno_pm_ops = { SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) - SET_RUNTIME_PM_OPS(adreno_suspend, adreno_resume, NULL) + SET_RUNTIME_PM_OPS(adreno_runtime_suspend, adreno_runtime_resume, NULL) }; static struct platform_driver adreno_driver = { -- 2.35.1
Re: [PATCH] drm: bridge: panel: Register connector if DRM device is already registered
On Tue, Apr 19, 2022 at 06:16:07PM +0200, Robert Foss wrote: > On Tue, 19 Apr 2022 at 11:41, Jagan Teki wrote: > > > > On Tue, Apr 19, 2022 at 2:44 PM Marek Szyprowski > > wrote: > > > > > > If panel_bridge_attach() happens after DRM device registration, the > > > created connector will not be registered by the DRM core anymore. Fix > > > this by registering it explicitely in such case. > > > > > > This fixes the following issue observed on Samsung Exynos4210-based Trats > > > board with a DSI panel (the panel driver is registed after the Exynos DRM > > > component device is bound): > > > > > > $ ./modetest -c -Mexynos > > > could not get connector 56: No such file or directory > > > Segmentation fault > > > > > > While touching this, move the connector reset() call also under the DRM > > > device registered check, because otherwise it is not really needed. > > > > > > Fixes: 934aef885f9d ("drm: bridge: panel: Reset the connector state > > > pointer") > > > Signed-off-by: Marek Szyprowski > > > --- > > > Here is a bit more backgroud on this issue is available in this thread: > > > https://lore.kernel.org/all/f0474a95-4ba3-a74f-d7de-ef7aab12b...@samsung.com/ > > > --- > > > drivers/gpu/drm/bridge/panel.c | 7 +-- > > > 1 file changed, 5 insertions(+), 2 deletions(-) > > > > > > diff --git a/drivers/gpu/drm/bridge/panel.c > > > b/drivers/gpu/drm/bridge/panel.c > > > index ff1c37b2e6e5..0ee563eb2b6f 100644 > > > --- a/drivers/gpu/drm/bridge/panel.c > > > +++ b/drivers/gpu/drm/bridge/panel.c > > > @@ -83,8 +83,11 @@ static int panel_bridge_attach(struct drm_bridge > > > *bridge, > > > drm_connector_attach_encoder(_bridge->connector, > > > bridge->encoder); > > > > > > - if (connector->funcs->reset) > > > - connector->funcs->reset(connector); > > > + if (bridge->dev->registered) { > > > + if (connector->funcs->reset) > > > + connector->funcs->reset(connector); > > > + drm_connector_register(connector); > > > + } > > > > Reviewed-by: Jagan Teki > > Fixed typos in commit message. > > Reviewed-by: Robert Foss > > Applied to drm-misc-next Doesn't this open the door to various race conditions ? Also, what happens if the panel bridge is detached and reattached ? If I recall correctly, registering new connectors at runtime is at least partly supported for DP MST, but I'm not sure about unregistration. -- Regards, Laurent Pinchart
Re: [PATCH 2/2] drm: bridge: icn6211: Add DSI lane count DT property parsing
On Thu, 7 Apr 2022 at 20:56, Marek Vasut wrote: > > The driver currently hard-codes DSI lane count to two, however the chip > is capable of operating in 1..4 DSI lanes mode. Parse 'data-lanes' DT > property and program the result into DSI_CTRL register. > > Signed-off-by: Marek Vasut > Cc: Jagan Teki > Cc: Laurent Pinchart > Cc: Maxime Ripard > Cc: Robert Foss > Cc: Sam Ravnborg > Cc: Thomas Zimmermann > To: dri-devel@lists.freedesktop.org > --- > drivers/gpu/drm/bridge/chipone-icn6211.c | 23 +-- > 1 file changed, 21 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/chipone-icn6211.c > b/drivers/gpu/drm/bridge/chipone-icn6211.c > index 6ce0633d4c089..e2b599a44275c 100644 > --- a/drivers/gpu/drm/bridge/chipone-icn6211.c > +++ b/drivers/gpu/drm/bridge/chipone-icn6211.c > @@ -395,6 +395,11 @@ static void chipone_atomic_enable(struct drm_bridge > *bridge, > /* dsi specific sequence */ > chipone_writeb(icn, SYNC_EVENT_DLY, 0x80); > chipone_writeb(icn, HFP_MIN, hfp & 0xff); > + > + /* DSI data lane count */ > + chipone_writeb(icn, DSI_CTRL, > + DSI_CTRL_UNKNOWN | DSI_CTRL_DSI_LANES(icn->dsi->lanes - > 1)); > + > chipone_writeb(icn, MIPI_PD_CK_LANE, 0xa0); > chipone_writeb(icn, PLL_CTRL(12), 0xff); > chipone_writeb(icn, MIPI_PN_SWAP, 0x00); > @@ -480,9 +485,23 @@ static void chipone_mode_set(struct drm_bridge *bridge, > static int chipone_dsi_attach(struct chipone *icn) > { > struct mipi_dsi_device *dsi = icn->dsi; > - int ret; > + struct device *dev = icn->dev; > + struct device_node *endpoint; > + int dsi_lanes, ret; > + > + endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0); > + dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes"); > + of_node_put(endpoint); > + > + /* > +* If the 'data-lanes' property does not exist in DT or is invalid, > +* default to previously hard-coded behavior, which was 4 data lanes. > +*/ > + if (dsi_lanes >= 1 && dsi_lanes <= 4) > + icn->dsi->lanes = dsi_lanes; > + else > + icn->dsi->lanes = 4; > > - dsi->lanes = 4; > dsi->format = MIPI_DSI_FMT_RGB888; > dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | > MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_NO_EOT_PACKET; Reviewed-by: Robert Foss Fixed checkpatch --strict format warning & applied to drm-misc-next. Rob.
Re: [PATCH] drm/bridge: anx7625: Use uint8 for lane-swing arrays
On Fri, 8 Apr 2022 at 10:21, AngeloGioacchino Del Regno wrote: > > Il 08/04/22 03:30, Nícolas F. R. A. Prado ha scritto: > > As defined in the anx7625 dt-binding, the analogix,lane0-swing and > > analogix,lane1-swing properties are uint8 arrays. Yet, the driver was > > reading the array as if it were of uint32 and masking to 8-bit before > > writing to the registers. This means that a devicetree written in > > accordance to the dt-binding would have its values incorrectly parsed. > > > > Fix the issue by reading the array as uint8 and storing them as uint8 > > internally, so that we can also drop the masking when writing the > > registers. > > > > Fixes: fd0310b6fe7d ("drm/bridge: anx7625: add MIPI DPI input feature") > > Signed-off-by: Nícolas F. R. A. Prado > > > > Reviewed-by: AngeloGioacchino Del Regno > Applied to drm-misc-next
Re: [PATCH 3/9] vfio/mdev: Pass in a struct vfio_device * to vfio_pin/unpin_pages()
On Mon, Apr 18, 2022 at 11:25:15AM -0400, Jason J. Herne wrote: > On 4/12/22 11:53, Jason Gunthorpe wrote: > > Every caller has a readily available vfio_device pointer, use that instead > > of passing in a generic struct device. The struct vfio_device already > > contains the group we need so this avoids complexity, extra refcountings, > > and a confusing lifecycle model. > > ... > > diff --git a/drivers/s390/crypto/vfio_ap_ops.c > > b/drivers/s390/crypto/vfio_ap_ops.c > > index 69768061cd7bd9..a10b3369d76c41 100644 > > +++ b/drivers/s390/crypto/vfio_ap_ops.c > > @@ -124,7 +124,7 @@ static void vfio_ap_free_aqic_resources(struct > > vfio_ap_queue *q) > > q->saved_isc = VFIO_AP_ISC_INVALID; > > } > > if (q->saved_pfn && !WARN_ON(!q->matrix_mdev)) { > > - vfio_unpin_pages(mdev_dev(q->matrix_mdev->mdev), > > + vfio_unpin_pages(>matrix_mdev->vdev, > > >saved_pfn, 1); > > Could be contracted to a single line. If you feel like it :) Done, thanks Jason
[PATCH 3/4] soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator
Adds support to AFFINE image processing accelerator on Toshiba Visconti ARM SoCs. This accelerator supoorts affine transform, lens undistortion and LUT transform. Signed-off-by: Yuji Ishikawa Reviewed-by: Nobuhiro Iwamatsu --- drivers/soc/visconti/Kconfig | 6 + drivers/soc/visconti/Makefile| 2 + drivers/soc/visconti/affine/Makefile | 6 + drivers/soc/visconti/affine/affine.c | 451 +++ drivers/soc/visconti/affine/hwd_affine.c | 207 + drivers/soc/visconti/affine/hwd_affine.h | 83 drivers/soc/visconti/affine/hwd_affine_reg.h | 45 ++ drivers/soc/visconti/uapi/affine.h | 87 8 files changed, 887 insertions(+) create mode 100644 drivers/soc/visconti/affine/Makefile create mode 100644 drivers/soc/visconti/affine/affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.h create mode 100644 drivers/soc/visconti/affine/hwd_affine_reg.h create mode 100644 drivers/soc/visconti/uapi/affine.h diff --git a/drivers/soc/visconti/Kconfig b/drivers/soc/visconti/Kconfig index 8b1378917..01583d407 100644 --- a/drivers/soc/visconti/Kconfig +++ b/drivers/soc/visconti/Kconfig @@ -1 +1,7 @@ +if ARCH_VISCONTI + +config VISCONTI_AFFINE +bool "Visconti Affine driver" + +endif diff --git a/drivers/soc/visconti/Makefile b/drivers/soc/visconti/Makefile index 8d710da08..b25a726c3 100644 --- a/drivers/soc/visconti/Makefile +++ b/drivers/soc/visconti/Makefile @@ -4,3 +4,5 @@ # obj-y += ipa_common.o + +obj-$(CONFIG_VISCONTI_AFFINE) += affine/ diff --git a/drivers/soc/visconti/affine/Makefile b/drivers/soc/visconti/affine/Makefile new file mode 100644 index 0..82f83b2d6 --- /dev/null +++ b/drivers/soc/visconti/affine/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the Visconti AFFINE driver +# + +obj-y += affine.o hwd_affine.o diff --git a/drivers/soc/visconti/affine/affine.c b/drivers/soc/visconti/affine/affine.c new file mode 100644 index 0..3b31e41c8 --- /dev/null +++ b/drivers/soc/visconti/affine/affine.c @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Toshiba Visconti Affine Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "hwd_affine.h" +#include "../ipa_common.h" +#include "../uapi/affine.h" + +struct affine_priv { + struct device *dev; + struct miscdevice miscdev; + struct mutex lock; + void __iomem *regs; + int irq; + wait_queue_head_t waitq; + enum drv_ipa_state status; + unsigned int hwd_event; + unsigned int poll_event; + int id; + char name[16]; + bool dma_coherent; + struct hwd_affine_status hwd_status; + + struct dma_buf_attachment *dba[DRV_AFFINE_BUFFER_INDEX_MAX]; + struct sg_table *sgt[DRV_AFFINE_BUFFER_INDEX_MAX]; + enum dma_data_direction dma_dir[DRV_AFFINE_BUFFER_INDEX_MAX]; + unsigned int dma_count; + + dma_addr_t buffer_iova[DRV_AFFINE_BUFFER_INDEX_MAX]; +}; + +static uint32_t affine_ipa_addr_to_iova(struct affine_priv *priv, struct drv_ipa_addr addr) +{ + uint32_t iova = 0; + + if ((addr.buffer_index < priv->dma_count) && + (addr.offset < priv->dba[addr.buffer_index]->dmabuf->size)) + iova = priv->buffer_iova[addr.buffer_index] + addr.offset; + return iova; +} + +static int affine_attach_dma_buf(struct affine_priv *priv, unsigned int buffer_index, +struct drv_ipa_buffer_info *buffer_info) +{ + int ret = 0; + dma_addr_t addr; + + if (buffer_index >= DRV_AFFINE_BUFFER_INDEX_MAX) { + dev_err(priv->dev, "Buffer index invalid: index=%d\n", buffer_index); + return -EINVAL; + } + + switch (buffer_info[buffer_index].direction) { + case DRV_IPA_DIR_NONE: + priv->dma_dir[priv->dma_count] = DMA_NONE; + break; + case DRV_IPA_DIR_TO_DEVICE: + priv->dma_dir[priv->dma_count] = DMA_TO_DEVICE; + break; + case DRV_IPA_DIR_FROM_DEVICE: + priv->dma_dir[priv->dma_count] = DMA_FROM_DEVICE; + break; + case DRV_IPA_DIR_BIDIRECTION: + priv->dma_dir[priv->dma_count] = DMA_BIDIRECTIONAL; + break; + default: + dev_err(priv->dev, "DMA direction invalid: index=%d dir=%d\n", buffer_index, + buffer_info[buffer_index].direction); + return -EINVAL; + } + + if (buffer_info[buffer_index].coherent == false) { + priv->dev->dma_coherent = false; + if (priv->dma_coherent ==
[PATCH 1/4] dt-bindings: soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator bindings
Adds the Device Tree binding documentation that allows to describe the AFFINE image processing accelerator found in Toshiba Visconti SoCs. Signed-off-by: Yuji Ishikawa Reviewed-by: Nobuhiro Iwamatsu --- .../soc/visconti/toshiba,visconti-affine.yaml | 53 +++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml diff --git a/Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml b/Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml new file mode 100644 index 0..a446e1c4f --- /dev/null +++ b/Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml @@ -0,0 +1,53 @@ +# SPDX-LIcense-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/visconti/toshiba,visconti-affine.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Toshiba Visconti AFFINE image processing accelerator + +maintainers: + - Nobuhiro Iwamatsu + +description: | + Toshiba Visconti AFFINE image processing accelerator provides affine transform, lens undistortion and LUT transform. + Visconti5 have up to 2 AFFINE units. + +properties: + compatible: +items: + - const: toshiba,visconti-affine + + reg: +maxItems: 1 + + interrupts: +maxItems: 1 + + index: +enum: [0, 1] + +required: + - compatible + - reg + - interrupts + - index + +additionalProperties: false + +examples: + - | +#include +#include + +soc { +#address-cells = <2>; +#size-cells = <2>; +affine0: affine@1400 { +compatible = "toshiba,visconti-affine"; +reg = <0 0x1400 0 0x8000>; +interrupts = ; +index = <0>; +status = "disabled"; +}; +}; -- 2.17.1
[PATCH 0/4] Add Toshiba Visconti AFFINE image processing accelerator driver
This series is the AFFINE image processing accelerator driver for Toshiba's ARM SoC, Visconti[0]. This provides DT binding documentation, device driver, MAINTAINER files. Best regards, Yuji [0]: https://toshiba.semicon-storage.com/ap-en/semiconductor/product/image-recognition-processors-visconti.html Yuji Ishikawa (4): dt-bindings: soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator bindings soc: visconti: Add Toshiba Visconti image processing accelerator common source soc: visconti: Add Toshiba Visconti AFFINE image processing accelerator MAINTAINERS: Add entries for Toshiba Visconti AFFINE image processing accelerator .../soc/visconti/toshiba,visconti-affine.yaml | 53 ++ MAINTAINERS | 2 + drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/visconti/Kconfig | 7 + drivers/soc/visconti/Makefile | 8 + drivers/soc/visconti/affine/Makefile | 6 + drivers/soc/visconti/affine/affine.c | 451 ++ drivers/soc/visconti/affine/hwd_affine.c | 207 drivers/soc/visconti/affine/hwd_affine.h | 83 drivers/soc/visconti/affine/hwd_affine_reg.h | 45 ++ drivers/soc/visconti/ipa_common.c | 55 +++ drivers/soc/visconti/ipa_common.h | 19 + drivers/soc/visconti/uapi/affine.h| 87 drivers/soc/visconti/uapi/ipa.h | 87 15 files changed, 1112 insertions(+) create mode 100644 Documentation/devicetree/bindings/soc/visconti/toshiba,visconti-affine.yaml create mode 100644 drivers/soc/visconti/Kconfig create mode 100644 drivers/soc/visconti/Makefile create mode 100644 drivers/soc/visconti/affine/Makefile create mode 100644 drivers/soc/visconti/affine/affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.c create mode 100644 drivers/soc/visconti/affine/hwd_affine.h create mode 100644 drivers/soc/visconti/affine/hwd_affine_reg.h create mode 100644 drivers/soc/visconti/ipa_common.c create mode 100644 drivers/soc/visconti/ipa_common.h create mode 100644 drivers/soc/visconti/uapi/affine.h create mode 100644 drivers/soc/visconti/uapi/ipa.h -- 2.17.1
[PATCH] drm/amd/pm: fix double free in si_parse_power_table()
In function si_parse_power_table(), array adev->pm.dpm.ps and its member is allocated. If the allocation of each member fails, the array itself is freed and returned with an error code. However, the array is later freed again in si_dpm_fini() function which is called when the function returns an error. This leads to potential double free of the array adev->pm.dpm.ps, as well as leak of its array members, since the members are not freed in the allocation function and the array is not nulled when freed. In addition adev->pm.dpm.num_ps, which keeps track of the allocated array member, is not updated until the member allocation is successfully finished, this could also lead to either use after free, or uninitialized variable access in si_dpm_fini(). Fix this by postponing the free of the array until si_dpm_fini() and increment adev->pm.dpm.num_ps everytime the array member is allocated. Signed-off-by: Keita Suzuki --- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c index caae54487f9c..079888229485 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -7331,17 +7331,15 @@ static int si_parse_power_table(struct amdgpu_device *adev) if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; - for (i = 0; i < state_array->ucNumEntries; i++) { + for (adev->pm.dpm.num_ps = 0, i = 0; i < state_array->ucNumEntries; i++) { u8 *idx; power_state = (union pplib_power_state *)power_state_offset; non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) _clock_info_array->nonClockInfo[non_clock_array_index]; ps = kzalloc(sizeof(struct si_ps), GFP_KERNEL); - if (ps == NULL) { - kfree(adev->pm.dpm.ps); + if (ps == NULL) return -ENOMEM; - } adev->pm.dpm.ps[i].ps_priv = ps; si_parse_pplib_non_clock_info(adev, >pm.dpm.ps[i], non_clock_info, @@ -7363,8 +7361,8 @@ static int si_parse_power_table(struct amdgpu_device *adev) k++; } power_state_offset += 2 + power_state->v2.ucNumDPMLevels; + adev->pm.dpm.num_ps++; } - adev->pm.dpm.num_ps = state_array->ucNumEntries; /* fill in the vce power states */ for (i = 0; i < adev->pm.dpm.num_of_vce_states; i++) { -- 2.25.1
[PATCH 4/4] MAINTAINERS: Add entries for Toshiba Visconti AFFINE image processing accelerator
Signed-off-by: Yuji Ishikawa Reviewed-by: Nobuhiro Iwamatsu --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index dd36acc87..231b2c6f9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2796,12 +2796,14 @@ F: Documentation/devicetree/bindings/net/toshiba,visconti-dwmac.yaml F: Documentation/devicetree/bindings/gpio/toshiba,gpio-visconti.yaml F: Documentation/devicetree/bindings/pci/toshiba,visconti-pcie.yaml F: Documentation/devicetree/bindings/pinctrl/toshiba,visconti-pinctrl.yaml +F: Documentation/devicetree/bindings/soc/visconti/ F: Documentation/devicetree/bindings/watchdog/toshiba,visconti-wdt.yaml F: arch/arm64/boot/dts/toshiba/ F: drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c F: drivers/gpio/gpio-visconti.c F: drivers/pci/controller/dwc/pcie-visconti.c F: drivers/pinctrl/visconti/ +F: drivers/soc/visconti/ F: drivers/watchdog/visconti_wdt.c N: visconti -- 2.17.1
[PATCH 2/4] soc: visconti: Add Toshiba Visconti image processing accelerator common source
Adds common operations for image processing accelerator drivers including dma-buf control and ioctl definitiion Signed-off-by: Yuji Ishikawa Reviewed-by: Nobuhiro Iwamatsu --- drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 1 + drivers/soc/visconti/Kconfig | 1 + drivers/soc/visconti/Makefile | 6 +++ drivers/soc/visconti/ipa_common.c | 55 +++ drivers/soc/visconti/ipa_common.h | 19 +++ drivers/soc/visconti/uapi/ipa.h | 87 +++ 7 files changed, 170 insertions(+) create mode 100644 drivers/soc/visconti/Kconfig create mode 100644 drivers/soc/visconti/Makefile create mode 100644 drivers/soc/visconti/ipa_common.c create mode 100644 drivers/soc/visconti/ipa_common.h create mode 100644 drivers/soc/visconti/uapi/ipa.h diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index e8a30c4c5..c99139aa8 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -22,6 +22,7 @@ source "drivers/soc/tegra/Kconfig" source "drivers/soc/ti/Kconfig" source "drivers/soc/ux500/Kconfig" source "drivers/soc/versatile/Kconfig" +source "drivers/soc/visconti/Kconfig" source "drivers/soc/xilinx/Kconfig" endmenu diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index a05e9fbcd..455b993c2 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -28,4 +28,5 @@ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_PLAT_VERSATILE) += versatile/ +obj-$(CONFIG_ARCH_VISCONTI)+= visconti/ obj-y += xilinx/ diff --git a/drivers/soc/visconti/Kconfig b/drivers/soc/visconti/Kconfig new file mode 100644 index 0..8b1378917 --- /dev/null +++ b/drivers/soc/visconti/Kconfig @@ -0,0 +1 @@ + diff --git a/drivers/soc/visconti/Makefile b/drivers/soc/visconti/Makefile new file mode 100644 index 0..8d710da08 --- /dev/null +++ b/drivers/soc/visconti/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for the Visconti specific device drivers. +# + +obj-y += ipa_common.o diff --git a/drivers/soc/visconti/ipa_common.c b/drivers/soc/visconti/ipa_common.c new file mode 100644 index 0..6345f33c5 --- /dev/null +++ b/drivers/soc/visconti/ipa_common.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* Toshiba Visconti Image Processing Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#include "ipa_common.h" + +int ipa_attach_dmabuf(struct device *dev, int fd, struct dma_buf_attachment **a, + struct sg_table **s, dma_addr_t *addr, enum dma_data_direction dma_dir) +{ + struct dma_buf_attachment *attachment; + struct dma_buf *dmabuf; + struct sg_table *sgt; + int ret; + + dmabuf = dma_buf_get(fd); + if (IS_ERR(dmabuf)) { + dev_err(dev, "Invalid dmabuf FD\n"); + return PTR_ERR(dmabuf); + } + attachment = dma_buf_attach(dmabuf, dev); + + if (IS_ERR(attachment)) { + dev_err(dev, "Failed to attach dmabuf\n"); + ret = PTR_ERR(attachment); + goto err_put; + } + sgt = dma_buf_map_attachment(attachment, dma_dir); + if (IS_ERR(sgt)) { + dev_err(dev, "Failed to get dmabufs sg_table\n"); + ret = PTR_ERR(sgt); + goto err_detach; + } + if (sgt->nents != 1) { + dev_err(dev, "Sparse DMA region is unsupported\n"); + ret = -EINVAL; + goto err_unmap; + } + + *addr = sg_dma_address(sgt->sgl); + *a = attachment; + *s = sgt; + + return 0; + +err_unmap: + dma_buf_unmap_attachment(attachment, sgt, dma_dir); +err_detach: + dma_buf_detach(dmabuf, attachment); +err_put: + dma_buf_put(dmabuf); + return ret; +} diff --git a/drivers/soc/visconti/ipa_common.h b/drivers/soc/visconti/ipa_common.h new file mode 100644 index 0..2c3b64837 --- /dev/null +++ b/drivers/soc/visconti/ipa_common.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause */ +/* Toshiba Visconti Image Processing Accelerator Support + * + * (C) Copyright 2022 TOSHIBA CORPORATION + * (C) Copyright 2022 Toshiba Electronic Devices & Storage Corporation + */ + +#include +#include + +#define COHERENT_ADDRESS_BIT (0x4ULL) +#define IPA_POLL_EVENT_NONE(0) +#define IPA_POLL_EVENT_DONE(1) +#define IPA_POLL_EVENT_ERROR (2) +#define IPA_WAKEUP_RETRY_DELAY (300 * 1000) /*usec*/ + +extern int ipa_attach_dmabuf(struct device *dev, int fd, struct dma_buf_attachment **a, +struct sg_table **s, dma_addr_t *addr, +enum dma_data_direction dma_dir); diff --git a/drivers/soc/visconti/uapi/ipa.h b/drivers/soc/visconti/uapi/ipa.h new file mode
Re: drm: of: Improve error handling in bridge/panel detection
Hi Paul, Le jeu., avril 7 2022 at 11:34:08 +0200, Paul Kocialkowski a écrit : With the previous rework of drm_of_find_panel_or_bridge only -EPROBE_DEFER is returned while previous behavior allowed -ENODEV to be returned when the port/endpoint is either missing or unavailable. Make the default return code of the function -ENODEV to handle this and only return -EPROBE_DEFER in find_panel_or_bridge when the of device is available but not yet registered. Also return the error code whenever the remote node exists to avoid checking for child nodes. Checking child nodes could result in -EPROBE_DEFER returned by find_panel_or_bridge with an unrelated child node that would overwrite a legitimate -ENODEV from find_panel_or_bridge if the remote node from the of graph is unavailable. This happens because find_panel_or_bridge has no way to distinguish between a legitimate panel/bridge node that isn't yet registered and an unrelated node. Add comments around to clarify this behavior. Signed-off-by: Paul Kocialkowski Fixes: 67bae5f28c89 ("drm: of: Properly try all possible cases for bridge/panel detection") Cc: Bjorn Andersson Cc: Thierry Reding Cc: Linus Walleij This fixes the ingenic-drm driver, which was broken by the commit this patch addresses. So: Tested-by: Paul Cercueil Cheers, -Paul --- drivers/gpu/drm/drm_of.c | 23 ++- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_of.c b/drivers/gpu/drm/drm_of.c index 8716da6369a6..97ea9d2016ff 100644 --- a/drivers/gpu/drm/drm_of.c +++ b/drivers/gpu/drm/drm_of.c @@ -223,6 +223,9 @@ static int find_panel_or_bridge(struct device_node *node, struct drm_panel **panel, struct drm_bridge **bridge) { + if (!of_device_is_available(node)) + return -ENODEV; + if (panel) { *panel = of_drm_find_panel(node); if (!IS_ERR(*panel)) @@ -265,7 +268,7 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, struct drm_bridge **bridge) { struct device_node *node; - int ret; + int ret = -ENODEV; if (!panel && !bridge) return -EINVAL; @@ -282,8 +285,12 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, ret = find_panel_or_bridge(node, panel, bridge); of_node_put(node); - if (!ret) - return 0; + /* +* If the graph/remote node is present we consider it +* to be the legitimate candidate here and return +* whatever code we got from find_panel_or_bridge. +*/ + return ret; } } @@ -296,12 +303,18 @@ int drm_of_find_panel_or_bridge(const struct device_node *np, ret = find_panel_or_bridge(node, panel, bridge); of_node_put(node); - /* Stop at the first found occurrence. */ + /* +* Note that an unrelated (available) child node will cause +* find_panel_or_bridge to return -EPROBE_DEFER because there +* is no way to distinguish the node from a legitimate +* panel/bridge that didn't register yet. Keep iterating nodes +* and only return on the first found occurrence. +*/ if (!ret) return 0; } - return -EPROBE_DEFER; + return ret; } EXPORT_SYMBOL_GPL(drm_of_find_panel_or_bridge);
[PATCH 48/48] ARM: pxa: convert to multiplatform
From: Arnd Bergmann PXA is now ready to be built into a single kernel with all the other ARMv5 platforms, so change the Kconfig bit to finish it off. The mach/uncompress.h support is the last bit that goes away, getting replaced with the normal DEBUG_LL based approach. Signed-off-by: Arnd Bergmann --- arch/arm/Kconfig| 17 - arch/arm/configs/am200epdkit_defconfig | 1 + arch/arm/configs/cm_x300_defconfig | 1 + arch/arm/configs/colibri_pxa270_defconfig | 1 + arch/arm/configs/colibri_pxa300_defconfig | 1 + arch/arm/configs/corgi_defconfig| 1 + arch/arm/configs/eseries_pxa_defconfig | 1 + arch/arm/configs/ezx_defconfig | 1 + arch/arm/configs/h5000_defconfig| 1 + arch/arm/configs/imote2_defconfig | 1 + arch/arm/configs/lpd270_defconfig | 1 + arch/arm/configs/lubbock_defconfig | 1 + arch/arm/configs/magician_defconfig | 1 + arch/arm/configs/mainstone_defconfig| 1 + arch/arm/configs/palmz72_defconfig | 1 + arch/arm/configs/pcm027_defconfig | 1 + arch/arm/configs/pxa255-idp_defconfig | 1 + arch/arm/configs/pxa3xx_defconfig | 1 + arch/arm/configs/pxa_defconfig | 1 + arch/arm/configs/spitz_defconfig| 1 + arch/arm/configs/trizeps4_defconfig | 1 + arch/arm/configs/viper_defconfig| 1 + arch/arm/configs/xcep_defconfig | 1 + arch/arm/configs/zeus_defconfig | 1 + arch/arm/mach-pxa/Kconfig | 14 + arch/arm/mach-pxa/Makefile.boot | 3 - arch/arm/mach-pxa/include/mach/uncompress.h | 70 - 27 files changed, 37 insertions(+), 90 deletions(-) delete mode 100644 arch/arm/mach-pxa/Makefile.boot delete mode 100644 arch/arm/mach-pxa/include/mach/uncompress.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ace6c08c8ae2..001f77e0058c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -411,23 +411,6 @@ config ARCH_DOVE help Support for the Marvell Dove SoC 88AP510 -config ARCH_PXA - bool "PXA2xx/PXA3xx-based" - select ARM_CPU_SUSPEND if PM - select AUTO_ZRELADDR - select COMMON_CLK - select CLKSRC_PXA - select CLKSRC_MMIO - select TIMER_OF - select CPU_XSCALE if !CPU_XSC3 - select GPIO_PXA - select GPIOLIB - select IRQ_DOMAIN - select PLAT_PXA - select SPARSE_IRQ - help - Support for Intel/Marvell's PXA2xx/PXA3xx processor line. - config ARCH_RPC bool "RiscPC" depends on !CC_IS_CLANG && GCC_VERSION < 90100 && GCC_VERSION >= 6 diff --git a/arch/arm/configs/am200epdkit_defconfig b/arch/arm/configs/am200epdkit_defconfig index 4e49d6cb2f62..9252ce0e722b 100644 --- a/arch/arm/configs/am200epdkit_defconfig +++ b/arch/arm/configs/am200epdkit_defconfig @@ -10,6 +10,7 @@ CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_PXA=y CONFIG_ARCH_GUMSTIX=y CONFIG_PCCARD=y diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index 45769d0ddd4e..bb0fcd82d2a7 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig @@ -10,6 +10,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_PXA=y CONFIG_GPIO_PCA953X=y CONFIG_MACH_CM_X300=y diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig index 52bad9a544a0..b29898fd6a12 100644 --- a/arch/arm/configs/colibri_pxa270_defconfig +++ b/arch/arm/configs/colibri_pxa270_defconfig @@ -16,6 +16,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_PXA=y CONFIG_MACH_COLIBRI=y CONFIG_PREEMPT=y diff --git a/arch/arm/configs/colibri_pxa300_defconfig b/arch/arm/configs/colibri_pxa300_defconfig index 26e5a67f8e2d..f9d110294644 100644 --- a/arch/arm/configs/colibri_pxa300_defconfig +++ b/arch/arm/configs/colibri_pxa300_defconfig @@ -1,6 +1,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_PXA=y CONFIG_MACH_COLIBRI300=y CONFIG_AEABI=y diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 15b749f6996d..96c677c98bc7 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -9,6 +9,7 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set +# CONFIG_ARCH_MULTI_V7 is not set CONFIG_ARCH_PXA=y CONFIG_PXA_SHARPSL=y CONFIG_MACH_POODLE=y diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig index
[PATCH 47/48] ARM: pxa: remove support for MTD_XIP
From: Arnd Bergmann Using MTD-XIP does not work on multiplatform kernels because it requires SoC specific register accesses to be done from low-level flash handling functions in RAM while the rest of the kernel sits in flash. I found no evidence of anyone still actually using this feature, so remove it from PXA to avoid spending a lot of time on actually making it work. Signed-off-by: Arnd Bergmann --- arch/arm/Kconfig | 1 - arch/arm/mach-pxa/include/mach/mtd-xip.h | 36 2 files changed, 37 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/mtd-xip.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index eef8cbf20045..ace6c08c8ae2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -413,7 +413,6 @@ config ARCH_DOVE config ARCH_PXA bool "PXA2xx/PXA3xx-based" - select ARCH_MTD_XIP select ARM_CPU_SUSPEND if PM select AUTO_ZRELADDR select COMMON_CLK diff --git a/arch/arm/mach-pxa/include/mach/mtd-xip.h b/arch/arm/mach-pxa/include/mach/mtd-xip.h deleted file mode 100644 index 4b31bef9e50a.. --- a/arch/arm/mach-pxa/include/mach/mtd-xip.h +++ /dev/null @@ -1,36 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * MTD primitives for XIP support. Architecture specific functions - * - * Do not include this file directly. It's included from linux/mtd/xip.h - * - * Author: Nicolas Pitre - * Created:Nov 2, 2004 - * Copyright: (C) 2004 MontaVista Software, Inc. - */ - -#ifndef __ARCH_PXA_MTD_XIP_H__ -#define __ARCH_PXA_MTD_XIP_H__ - -#include - -/* restored July 2017, this did not build since 2011! */ - -#define ICIP io_p2v(0x40d0) -#define ICMR io_p2v(0x40d4) -#define xip_irqpending() (readl(ICIP) & readl(ICMR)) - -/* we sample OSCR and convert desired delta to usec (1/4 ~= 100/3686400) */ -#define xip_currtime() readl(OSCR) -#define xip_elapsed_since(x) (signed)((readl(OSCR) - (x)) / 4) - -/* - * xip_cpu_idle() is used when waiting for a delay equal or larger than - * the system timer tick period. This should put the CPU into idle mode - * to save power and to be woken up only when some interrupts are pending. - * As above, this should not rely upon standard kernel code. - */ - -#define xip_cpu_idle() asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1)) - -#endif /* __ARCH_PXA_MTD_XIP_H__ */ -- 2.29.2
[PATCH 46/48] ARM: pxa: move mach/*.h to mach-pxa/
From: Arnd Bergmann None of the headers are included from outside of the mach-pxa directory, so move them all in there. Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/am300epd.c | 2 +- arch/arm/mach-pxa/balloon3.h | 2 +- arch/arm/mach-pxa/colibri-pxa3xx.c| 2 +- arch/arm/mach-pxa/colibri.h | 2 +- arch/arm/mach-pxa/corgi.h | 2 +- arch/arm/mach-pxa/corgi_pm.c | 2 +- arch/arm/mach-pxa/csb726.c| 2 +- arch/arm/mach-pxa/csb726.h| 2 +- arch/arm/mach-pxa/devices.c | 6 +-- arch/arm/mach-pxa/e740-pcmcia.c | 2 +- .../{include/mach => }/eseries-gpio.h | 0 arch/arm/mach-pxa/eseries.c | 2 +- arch/arm/mach-pxa/generic.c | 8 +-- arch/arm/mach-pxa/gumstix.h | 2 +- arch/arm/mach-pxa/h5000.c | 2 +- arch/arm/mach-pxa/hx4700.h| 2 +- arch/arm/mach-pxa/idp.h | 2 +- arch/arm/mach-pxa/include/mach/pxa-regs.h | 52 -- arch/arm/mach-pxa/irq.c | 2 +- arch/arm/mach-pxa/{include/mach => }/irqs.h | 0 arch/arm/mach-pxa/lpd270.c| 2 +- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/lubbock.h | 2 +- arch/arm/mach-pxa/magician.c | 2 +- .../mach-pxa/{include/mach => }/magician.h| 2 +- arch/arm/mach-pxa/mainstone.c | 2 +- arch/arm/mach-pxa/mainstone.h | 2 +- arch/arm/mach-pxa/mfp-pxa2xx.c| 2 +- arch/arm/mach-pxa/mfp-pxa3xx.c| 2 +- arch/arm/mach-pxa/{include/mach => }/mfp.h| 0 arch/arm/mach-pxa/mioa701.c | 2 +- arch/arm/mach-pxa/palmld.h| 2 +- arch/arm/mach-pxa/palmt5.h| 2 +- arch/arm/mach-pxa/palmtc.h| 2 +- arch/arm/mach-pxa/palmtreo.c | 2 +- arch/arm/mach-pxa/palmtx.h| 2 +- arch/arm/mach-pxa/pcm027.h| 2 +- arch/arm/mach-pxa/pcm990_baseboard.h | 2 +- arch/arm/mach-pxa/poodle.h| 2 +- arch/arm/mach-pxa/pxa-dt.c| 2 +- arch/arm/mach-pxa/pxa-regs.h | 53 ++- arch/arm/mach-pxa/pxa25x.c| 6 +-- arch/arm/mach-pxa/pxa25x.h| 4 +- arch/arm/mach-pxa/pxa27x.c| 6 +-- arch/arm/mach-pxa/pxa27x.h| 4 +- .../mach-pxa/{include/mach => }/pxa2xx-regs.h | 0 arch/arm/mach-pxa/pxa2xx.c| 6 +-- .../mach-pxa/{include/mach => }/pxa3xx-regs.h | 0 arch/arm/mach-pxa/pxa3xx.c| 8 +-- arch/arm/mach-pxa/pxa3xx.h| 4 +- .../mach-pxa/{include/mach => }/regs-ost.h| 0 arch/arm/mach-pxa/reset.c | 6 +-- arch/arm/mach-pxa/{include/mach => }/reset.h | 0 arch/arm/mach-pxa/sharpsl_pm.c| 2 +- arch/arm/mach-pxa/sleep.S | 4 +- arch/arm/mach-pxa/smemc.c | 2 +- arch/arm/mach-pxa/{include/mach => }/smemc.h | 0 arch/arm/mach-pxa/spitz.c | 4 +- arch/arm/mach-pxa/spitz.h | 2 +- arch/arm/mach-pxa/standby.S | 2 +- arch/arm/mach-pxa/tosa.c | 6 +-- arch/arm/mach-pxa/{include/mach => }/tosa.h | 0 arch/arm/mach-pxa/trizeps4-pcmcia.c | 2 +- arch/arm/mach-pxa/trizeps4.c | 2 +- arch/arm/mach-pxa/trizeps4.h | 2 +- arch/arm/mach-pxa/xcep.c | 2 +- arch/arm/mach-pxa/z2.c| 2 +- arch/arm/mach-pxa/{include/mach => }/z2.h | 0 arch/arm/mach-pxa/zeus.c | 2 +- arch/arm/mach-pxa/zylonite.c | 2 +- 70 files changed, 133 insertions(+), 134 deletions(-) rename arch/arm/mach-pxa/{include/mach => }/eseries-gpio.h (100%) delete mode 100644 arch/arm/mach-pxa/include/mach/pxa-regs.h rename arch/arm/mach-pxa/{include/mach => }/irqs.h (100%) rename arch/arm/mach-pxa/{include/mach => }/magician.h (99%) rename arch/arm/mach-pxa/{include/mach => }/mfp.h (100%) rename arch/arm/mach-pxa/{include/mach => }/pxa2xx-regs.h (100%) rename arch/arm/mach-pxa/{include/mach => }/pxa3xx-regs.h (100%) rename arch/arm/mach-pxa/{include/mach => }/regs-ost.h (100%) rename arch/arm/mach-pxa/{include/mach => }/reset.h (100%) rename arch/arm/mach-pxa/{include/mach => }/smemc.h (100%) rename arch/arm/mach-pxa/{include/mach => }/tosa.h (100%) rename arch/arm/mach-pxa/{include/mach => }/z2.h (100%) diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c index 17d08abeeb17..4b55bc89db8f 100644 --- a/arch/arm/mach-pxa/am300epd.c +++ b/arch/arm/mach-pxa/am300epd.c @@
[PATCH 45/48] ARM: PXA: fix multi-cpu build of xsc3
From: Arnd Bergmann On a kernel that includes both ARMv4 and XScale support, the copypage function fails to build with invalid instructions. Since these are only called on an actual XScale processor, annotate the assembly with the correct .arch directive. Signed-off-by: Arnd Bergmann --- arch/arm/mm/copypage-xsc3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mm/copypage-xsc3.c b/arch/arm/mm/copypage-xsc3.c index 6f0909dda2f9..c86e79677ff9 100644 --- a/arch/arm/mm/copypage-xsc3.c +++ b/arch/arm/mm/copypage-xsc3.c @@ -29,6 +29,7 @@ static void xsc3_mc_copy_user_page(void *kto, const void *kfrom) int tmp; asm volatile ("\ +.arch xscale \n\ pld [%1, #0]\n\ pld [%1, #32] \n\ 1: pld [%1, #64] \n\ @@ -80,6 +81,7 @@ void xsc3_mc_clear_user_highpage(struct page *page, unsigned long vaddr) { void *ptr, *kaddr = kmap_atomic(page); asm volatile ("\ +.arch xscale \n\ mov r1, %2 \n\ mov r2, #0 \n\ mov r3, #0 \n\ -- 2.29.2
[PATCH 44/48] ARM: pxa: move plat-pxa to drivers/soc/
From: Arnd Bergmann There are two drivers in arch/arm/plat-pxa: mfp and ssp. Both of them should ideally not be needed at all, as there are proper subsystems to replace them. OTOH, they are self-contained and can simply be normal SoC drivers, so move them over there to eliminate one more of the plat-* directories. Acked-by: Robert Jarzmik (mach-pxa) Acked-by: Lubomir Rintel (mach-mmp) Signed-off-by: Arnd Bergmann --- arch/arm/Kconfig| 4 arch/arm/Makefile | 1 - arch/arm/mach-mmp/mfp.h | 2 +- arch/arm/mach-pxa/include/mach/mfp.h| 2 +- arch/arm/mach-pxa/mfp-pxa2xx.h | 2 +- arch/arm/mach-pxa/mfp-pxa3xx.h | 2 +- drivers/soc/Kconfig | 1 + drivers/soc/Makefile| 1 + {arch/arm/plat-pxa => drivers/soc/pxa}/Kconfig | 5 ++--- {arch/arm/plat-pxa => drivers/soc/pxa}/Makefile | 4 {arch/arm/plat-pxa => drivers/soc/pxa}/mfp.c| 2 +- {arch/arm/plat-pxa => drivers/soc/pxa}/ssp.c| 0 .../plat-pxa/include/plat => include/linux/soc/pxa}/mfp.h | 6 ++ 13 files changed, 11 insertions(+), 21 deletions(-) rename {arch/arm/plat-pxa => drivers/soc/pxa}/Kconfig (83%) rename {arch/arm/plat-pxa => drivers/soc/pxa}/Makefile (51%) rename {arch/arm/plat-pxa => drivers/soc/pxa}/mfp.c (99%) rename {arch/arm/plat-pxa => drivers/soc/pxa}/ssp.c (100%) rename {arch/arm/plat-pxa/include/plat => include/linux/soc/pxa}/mfp.h (98%) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2e8091e2d8a8..eef8cbf20045 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -667,7 +667,6 @@ source "arch/arm/mach-orion5x/Kconfig" source "arch/arm/mach-oxnas/Kconfig" source "arch/arm/mach-pxa/Kconfig" -source "arch/arm/plat-pxa/Kconfig" source "arch/arm/mach-qcom/Kconfig" @@ -753,9 +752,6 @@ config PLAT_ORION_LEGACY bool select PLAT_ORION -config PLAT_PXA - bool - config PLAT_VERSATILE bool diff --git a/arch/arm/Makefile b/arch/arm/Makefile index a2391b8de5a5..206a900fc87c 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -230,7 +230,6 @@ machine-$(CONFIG_PLAT_SPEAR)+= spear # by CONFIG_* macro name. plat-$(CONFIG_ARCH_OMAP) += omap plat-$(CONFIG_PLAT_ORION) += orion -plat-$(CONFIG_PLAT_PXA)+= pxa plat-$(CONFIG_PLAT_VERSATILE) += versatile # The byte offset of the kernel image in RAM from the start of RAM. diff --git a/arch/arm/mach-mmp/mfp.h b/arch/arm/mach-mmp/mfp.h index 75a4acb33b1b..6f3057987756 100644 --- a/arch/arm/mach-mmp/mfp.h +++ b/arch/arm/mach-mmp/mfp.h @@ -2,7 +2,7 @@ #ifndef __ASM_MACH_MFP_H #define __ASM_MACH_MFP_H -#include +#include /* * NOTE: the MFPR register bit definitions on PXA168 processor lines are a diff --git a/arch/arm/mach-pxa/include/mach/mfp.h b/arch/arm/mach-pxa/include/mach/mfp.h index dbb961fb570e..7e0879bd4102 100644 --- a/arch/arm/mach-pxa/include/mach/mfp.h +++ b/arch/arm/mach-pxa/include/mach/mfp.h @@ -13,6 +13,6 @@ #ifndef __ASM_ARCH_MFP_H #define __ASM_ARCH_MFP_H -#include +#include #endif /* __ASM_ARCH_MFP_H */ diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.h b/arch/arm/mach-pxa/mfp-pxa2xx.h index 980145e7ee99..683a3ea5f154 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.h +++ b/arch/arm/mach-pxa/mfp-pxa2xx.h @@ -2,7 +2,7 @@ #ifndef __ASM_ARCH_MFP_PXA2XX_H #define __ASM_ARCH_MFP_PXA2XX_H -#include +#include /* * the following MFP_xxx bit definitions in mfp.h are re-used for pxa2xx: diff --git a/arch/arm/mach-pxa/mfp-pxa3xx.h b/arch/arm/mach-pxa/mfp-pxa3xx.h index cdd830926d1c..81fec4fa5a0f 100644 --- a/arch/arm/mach-pxa/mfp-pxa3xx.h +++ b/arch/arm/mach-pxa/mfp-pxa3xx.h @@ -2,7 +2,7 @@ #ifndef __ASM_ARCH_MFP_PXA3XX_H #define __ASM_ARCH_MFP_PXA3XX_H -#include +#include #define MFPR_BASE (0x40e1) diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index c5aae42673d3..86ccf5970bc1 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -14,6 +14,7 @@ source "drivers/soc/ixp4xx/Kconfig" source "drivers/soc/litex/Kconfig" source "drivers/soc/mediatek/Kconfig" source "drivers/soc/microchip/Kconfig" +source "drivers/soc/pxa/Kconfig" source "drivers/soc/qcom/Kconfig" source "drivers/soc/renesas/Kconfig" source "drivers/soc/rockchip/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 904eec2a7871..fd7717d597fc 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_SOC_XWAY)+= lantiq/ obj-$(CONFIG_LITEX_SOC_CONTROLLER) += litex/ obj-y += mediatek/ obj-y += microchip/ +obj-y += pxa/ obj-y += amlogic/ obj-y
[PATCH 43/48] ARM: mmp: rename pxa_register_device
From: Arnd Bergmann In a multiplatform kernel that includes both pxa and mmp, we get a link failure from the clash of two pxa_register_device functions. Rename the one in mach-mmp to mmp_register_device, along with with the rename of pxa_device_desc. Acked-by: Lubomir Rintel Signed-off-by: Arnd Bergmann --- arch/arm/mach-mmp/devices.c | 2 +- arch/arm/mach-mmp/devices.h | 10 +++ arch/arm/mach-mmp/mmp2.h| 48 ++--- arch/arm/mach-mmp/pxa168.h | 60 ++--- arch/arm/mach-mmp/pxa910.h | 38 +++ arch/arm/mach-mmp/ttc_dkb.c | 6 ++-- 6 files changed, 82 insertions(+), 82 deletions(-) diff --git a/arch/arm/mach-mmp/devices.c b/arch/arm/mach-mmp/devices.c index 18bee66a671f..79f4a2aa5475 100644 --- a/arch/arm/mach-mmp/devices.c +++ b/arch/arm/mach-mmp/devices.c @@ -14,7 +14,7 @@ #include #include "regs-usb.h" -int __init pxa_register_device(struct pxa_device_desc *desc, +int __init mmp_register_device(struct mmp_device_desc *desc, void *data, size_t size) { struct platform_device *pdev; diff --git a/arch/arm/mach-mmp/devices.h b/arch/arm/mach-mmp/devices.h index 4df596c5c201..d4920ebfebc5 100644 --- a/arch/arm/mach-mmp/devices.h +++ b/arch/arm/mach-mmp/devices.h @@ -7,7 +7,7 @@ #define MAX_RESOURCE_DMA 2 /* structure for describing the on-chip devices */ -struct pxa_device_desc { +struct mmp_device_desc { const char *dev_name; const char *drv_name; int id; @@ -18,7 +18,7 @@ struct pxa_device_desc { }; #define PXA168_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \ -struct pxa_device_desc pxa168_device_##_name __initdata = {\ +struct mmp_device_desc pxa168_device_##_name __initdata = {\ .dev_name = "pxa168-" #_name, \ .drv_name = _drv, \ .id = _id, \ @@ -29,7 +29,7 @@ struct pxa_device_desc pxa168_device_##_name __initdata = { \ }; #define PXA910_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...) \ -struct pxa_device_desc pxa910_device_##_name __initdata = {\ +struct mmp_device_desc pxa910_device_##_name __initdata = {\ .dev_name = "pxa910-" #_name, \ .drv_name = _drv, \ .id = _id, \ @@ -40,7 +40,7 @@ struct pxa_device_desc pxa910_device_##_name __initdata = { \ }; #define MMP2_DEVICE(_name, _drv, _id, _irq, _start, _size, _dma...)\ -struct pxa_device_desc mmp2_device_##_name __initdata = { \ +struct mmp_device_desc mmp2_device_##_name __initdata = { \ .dev_name = "mmp2-" #_name, \ .drv_name = _drv, \ .id = _id, \ @@ -50,7 +50,7 @@ struct pxa_device_desc mmp2_device_##_name __initdata = { \ .dma= { _dma }, \ } -extern int pxa_register_device(struct pxa_device_desc *, void *, size_t); +extern int mmp_register_device(struct mmp_device_desc *, void *, size_t); extern int pxa_usb_phy_init(void __iomem *phy_reg); extern void pxa_usb_phy_deinit(void __iomem *phy_reg); diff --git a/arch/arm/mach-mmp/mmp2.h b/arch/arm/mach-mmp/mmp2.h index adafc4fba8f4..3ebc1bb13f71 100644 --- a/arch/arm/mach-mmp/mmp2.h +++ b/arch/arm/mach-mmp/mmp2.h @@ -15,28 +15,28 @@ extern void mmp2_clear_pmic_int(void); #include "devices.h" -extern struct pxa_device_desc mmp2_device_uart1; -extern struct pxa_device_desc mmp2_device_uart2; -extern struct pxa_device_desc mmp2_device_uart3; -extern struct pxa_device_desc mmp2_device_uart4; -extern struct pxa_device_desc mmp2_device_twsi1; -extern struct pxa_device_desc mmp2_device_twsi2; -extern struct pxa_device_desc mmp2_device_twsi3; -extern struct pxa_device_desc mmp2_device_twsi4; -extern struct pxa_device_desc mmp2_device_twsi5; -extern struct pxa_device_desc mmp2_device_twsi6; -extern struct pxa_device_desc mmp2_device_sdh0; -extern struct pxa_device_desc mmp2_device_sdh1; -extern struct pxa_device_desc mmp2_device_sdh2; -extern struct pxa_device_desc mmp2_device_sdh3; -extern struct pxa_device_desc mmp2_device_asram; -extern struct pxa_device_desc mmp2_device_isram; +extern struct mmp_device_desc mmp2_device_uart1; +extern struct mmp_device_desc mmp2_device_uart2; +extern struct mmp_device_desc mmp2_device_uart3; +extern struct mmp_device_desc mmp2_device_uart4; +extern struct mmp_device_desc mmp2_device_twsi1; +extern struct mmp_device_desc mmp2_device_twsi2; +extern struct mmp_device_desc mmp2_device_twsi3; +extern struct
[PATCH 42/48] ARM: mmp: remove tavorevb board support
From: Arnd Bergmann There are two tavorevb boards in the kernel, one using a PXA930 chip in mach-pxa, and one using the later PXA910 chip in mach-mmp. They use the same board number, which is generally a bad idea, and in a multiplatform kernel, we can end up with funny link errors like this one resulting from two boards gettting controlled by the same Kconfig symbol: arch/arm/mach-mmp/tavorevb.o: In function `tavorevb_init': tavorevb.c:(.init.text+0x4c): undefined reference to `pxa910_device_uart1' tavorevb.c:(.init.text+0x50): undefined reference to `pxa910_device_gpio' tavorevb.o:(.arch.info.init+0x54): undefined reference to `pxa910_init_irq' tavorevb.o:(.arch.info.init+0x58): undefined reference to `pxa910_timer_init' The mach-pxa TavorEVB seems much more complete than the mach-mmp one that supports only uart, gpio and ethernet. Further, I could find no information about the board on the internet aside from references to the Linux kernel, so I assume this was never available outside of Marvell and can be removed entirely. There is a third board named TavorEVB in the Kconfig description, but this refers to the "TTC_DKB" machine. The two are clearly related, so I change the Kconfig description to just list both names. Cc: Lubomir Rintel Reviewed-by: Lubomir Rintel Signed-off-by: Arnd Bergmann --- arch/arm/mach-mmp/Kconfig| 10 +--- arch/arm/mach-mmp/Makefile | 1 - arch/arm/mach-mmp/tavorevb.c | 113 --- 3 files changed, 1 insertion(+), 123 deletions(-) delete mode 100644 arch/arm/mach-mmp/tavorevb.c diff --git a/arch/arm/mach-mmp/Kconfig b/arch/arm/mach-mmp/Kconfig index 0dd999212944..92a730a573b9 100644 --- a/arch/arm/mach-mmp/Kconfig +++ b/arch/arm/mach-mmp/Kconfig @@ -39,16 +39,8 @@ config MACH_AVENGERS_LITE Say 'Y' here if you want to support the Marvell PXA168-based Avengers Lite Development Board. -config MACH_TAVOREVB - bool "Marvell's PXA910 TavorEVB Development Board" - depends on ARCH_MULTI_V5 - select CPU_PXA910 - help - Say 'Y' here if you want to support the Marvell PXA910-based - TavorEVB Development Board. - config MACH_TTC_DKB - bool "Marvell's PXA910 TavorEVB Development Board" + bool "Marvell's PXA910 TavorEVB/TTC_DKB Development Board" depends on ARCH_MULTI_V5 select CPU_PXA910 help diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index e3758f7e1fe7..81338db77ec7 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -24,7 +24,6 @@ endif obj-$(CONFIG_MACH_ASPENITE)+= aspenite.o obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o obj-$(CONFIG_MACH_AVENGERS_LITE)+= avengers_lite.o -obj-$(CONFIG_MACH_TAVOREVB)+= tavorevb.o obj-$(CONFIG_MACH_TTC_DKB) += ttc_dkb.o obj-$(CONFIG_MACH_BROWNSTONE) += brownstone.o obj-$(CONFIG_MACH_FLINT) += flint.o diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c deleted file mode 100644 index 3261d2322198.. --- a/arch/arm/mach-mmp/tavorevb.c +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/arch/arm/mach-mmp/tavorevb.c - * - * Support for the Marvell PXA910-based TavorEVB Development Platform. - */ -#include -#include -#include -#include -#include -#include - -#include -#include -#include "addr-map.h" -#include "mfp-pxa910.h" -#include "pxa910.h" -#include "irqs.h" - -#include "common.h" - -static unsigned long tavorevb_pin_config[] __initdata = { - /* UART2 */ - GPIO47_UART2_RXD, - GPIO48_UART2_TXD, - - /* SMC */ - SM_nCS0_nCS0, - SM_ADV_SM_ADV, - SM_SCLK_SM_SCLK, - SM_SCLK_SM_SCLK, - SM_BE0_SM_BE0, - SM_BE1_SM_BE1, - - /* DFI */ - DF_IO0_ND_IO0, - DF_IO1_ND_IO1, - DF_IO2_ND_IO2, - DF_IO3_ND_IO3, - DF_IO4_ND_IO4, - DF_IO5_ND_IO5, - DF_IO6_ND_IO6, - DF_IO7_ND_IO7, - DF_IO8_ND_IO8, - DF_IO9_ND_IO9, - DF_IO10_ND_IO10, - DF_IO11_ND_IO11, - DF_IO12_ND_IO12, - DF_IO13_ND_IO13, - DF_IO14_ND_IO14, - DF_IO15_ND_IO15, - DF_nCS0_SM_nCS2_nCS0, - DF_ALE_SM_WEn_ND_ALE, - DF_CLE_SM_OEn_ND_CLE, - DF_WEn_DF_WEn, - DF_REn_DF_REn, - DF_RDY0_DF_RDY0, -}; - -static struct pxa_gpio_platform_data pxa910_gpio_pdata = { - .irq_base = MMP_GPIO_TO_IRQ(0), -}; - -static struct smc91x_platdata tavorevb_smc91x_info = { - .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, -}; - -static struct resource smc91x_resources[] = { - [0] = { - .start = SMC_CS1_PHYS_BASE + 0x300, - .end= SMC_CS1_PHYS_BASE + 0xf, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = MMP_GPIO_TO_IRQ(80), - .end= MMP_GPIO_TO_IRQ(80), - .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, - } -}; -
[PATCH 41/48] ARM: pxa: remove unused mach/bitfield.h
From: Arnd Bergmann The sa.h header defines some constants using the bitfield macros, but those are only used on sa1100, not on pxa, and the users include the bitfield header through mach/hardware.h. Acked-by: Robert Jarzmik Signed-off-by: Arnd Bergmann --- arch/arm/include/asm/hardware/sa.h| 2 - arch/arm/mach-pxa/include/mach/bitfield.h | 114 -- 2 files changed, 116 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/bitfield.h diff --git a/arch/arm/include/asm/hardware/sa.h b/arch/arm/include/asm/hardware/sa.h index 2e70db6f22ea..d8c6f8a99dfa 100644 --- a/arch/arm/include/asm/hardware/sa.h +++ b/arch/arm/include/asm/hardware/sa.h @@ -13,8 +13,6 @@ #ifndef _ASM_ARCH_SA #define _ASM_ARCH_SA -#include - /* * Don't ask the (SAC) DMA engines to move less than this amount. */ diff --git a/arch/arm/mach-pxa/include/mach/bitfield.h b/arch/arm/mach-pxa/include/mach/bitfield.h deleted file mode 100644 index fe2ca441bc0a.. --- a/arch/arm/mach-pxa/include/mach/bitfield.h +++ /dev/null @@ -1,114 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * FILEbitfield.h - * - * Version 1.1 - * Author Copyright (c) Marc A. Viredaz, 1998 - * DEC Western Research Laboratory, Palo Alto, CA - * DateApril 1998 (April 1997) - * System Advanced RISC Machine (ARM) - * LanguageC or ARM Assembly - * Purpose Definition of macros to operate on bit fields. - */ - - - -#ifndef __BITFIELD_H -#define __BITFIELD_H - -#ifndef __ASSEMBLY__ -#define UData(Data)((unsigned long) (Data)) -#else -#define UData(Data)(Data) -#endif - - -/* - * MACRO: Fld - * - * Purpose - *The macro "Fld" encodes a bit field, given its size and its shift value - *with respect to bit 0. - * - * Note - *A more intuitive way to encode bit fields would have been to use their - *mask. However, extracting size and shift value information from a bit - *field's mask is cumbersome and might break the assembler (255-character - *line-size limit). - * - * Input - *Size Size of the bit field, in number of bits. - *Shft Shift value of the bit field with respect to bit 0. - * - * Output - *Fld Encoded bit field. - */ - -#define Fld(Size, Shft)(((Size) << 16) + (Shft)) - - -/* - * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit - * - * Purpose - *The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return - *the size, shift value, mask, aligned mask, and first bit of a - *bit field. - * - * Input - *FieldEncoded bit field (using the macro "Fld"). - * - * Output - *FSizeSize of the bit field, in number of bits. - *FShftShift value of the bit field with respect to bit 0. - *FMsk Mask for the bit field. - *FAlnMsk Mask for the bit field, aligned on bit 0. - *F1stBit First bit of the bit field. - */ - -#define FSize(Field) ((Field) >> 16) -#define FShft(Field) ((Field) & 0x) -#define FMsk(Field)(((UData (1) << FSize (Field)) - 1) << FShft (Field)) -#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1) -#define F1stBit(Field) (UData (1) << FShft (Field)) - - -/* - * MACRO: FInsrt - * - * Purpose - *The macro "FInsrt" inserts a value into a bit field by shifting the - *former appropriately. - * - * Input - *ValueBit-field value. - *FieldEncoded bit field (using the macro "Fld"). - * - * Output - *FInsrt Bit-field value positioned appropriately. - */ - -#define FInsrt(Value, Field) \ - (UData (Value) << FShft (Field)) - - -/* - * MACRO: FExtr - * - * Purpose - *The macro "FExtr" extracts the value of a bit field by masking and - *shifting it appropriately. - * - * Input - *Data Data containing the bit-field to be extracted. - *FieldEncoded bit field (using the macro "Fld"). - * - * Output - *FExtrBit-field value. - */ - -#define FExtr(Data, Field) \ - ((UData (Data) >> FShft (Field)) & FAlnMsk (Field)) - - -#endif /* __BITFIELD_H */ -- 2.29.2
[PATCH 40/48] ARM: pxa: tosa: use gpio lookup for battery
From: Arnd Bergmann The battery driver uses a lot of GPIO lines, hardcoded from a machine header file. Change it to use a gpiod lookup table instead. Reviewed-by: Sebastian Reichel Acked-by: Sebastian Reichel Cc: linux...@vger.kernel.org Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/tosa.c| 23 + drivers/power/supply/tosa_battery.c | 147 2 files changed, 109 insertions(+), 61 deletions(-) diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 5a16a025192c..19fe79518aaf 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -366,6 +366,28 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = { .shutdown = tosa_irda_shutdown, }; +static struct gpiod_lookup_table tosa_battery_gpio_table = { + .dev_id = "wm97xx-battery", + .table = { + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF - TOSA_TC6393XB_GPIO_BASE,"main charge off", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_CHARGE_OFF_JC - TOSA_TC6393XB_GPIO_BASE, "jacket charge off", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT_SW_ON - TOSA_TC6393XB_GPIO_BASE, "battery switch", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_V_ON - TOSA_TC6393XB_GPIO_BASE, "main battery", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_V_ON - TOSA_TC6393XB_GPIO_BASE, "jacket battery", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT1_TH_ON - TOSA_TC6393XB_GPIO_BASE,"main battery temp", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BAT0_TH_ON - TOSA_TC6393XB_GPIO_BASE,"jacket battery temp", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("tc6393xb", TOSA_GPIO_BU_CHRG_ON - TOSA_TC6393XB_GPIO_BASE,"backup battery", GPIO_ACTIVE_HIGH ), + + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_CRG, "main battery full", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_CRG, "jacket battery full", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT0_LOW, "main battery low", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_BAT1_LOW, "jacket battery low", GPIO_ACTIVE_HIGH ), + GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_JACKET_DETECT, "jacket detect", GPIO_ACTIVE_HIGH ), + { }, + }, +}; + + /* * Tosa AC IN */ @@ -954,6 +976,7 @@ static void __init tosa_init(void) /* enable batt_fault */ PMCR = 0x01; + gpiod_add_lookup_table(_battery_gpio_table); gpiod_add_lookup_table(_mci_gpio_table); gpiod_add_lookup_table(_audio_gpio_table); pxa_set_mci_info(_mci_platform_data); diff --git a/drivers/power/supply/tosa_battery.c b/drivers/power/supply/tosa_battery.c index b26b0eca33e1..d10320f348d0 100644 --- a/drivers/power/supply/tosa_battery.c +++ b/drivers/power/supply/tosa_battery.c @@ -15,11 +15,16 @@ #include #include -#include static DEFINE_MUTEX(bat_lock); /* protects gpio pins */ static struct work_struct bat_work; +struct tosa_gpio { + const char *con; + enum gpiod_flags flags; + struct gpio_desc *desc; +}; + struct tosa_bat { int status; struct power_supply *psy; @@ -28,38 +33,42 @@ struct tosa_bat { struct mutex work_lock; /* protects data */ bool (*is_present)(struct tosa_bat *bat); - int gpio_full; - int gpio_charge_off; + struct tosa_gpio gpio_full; + struct tosa_gpio gpio_charge_off; int technology; - int gpio_bat; + struct tosa_gpio gpio_bat; int adc_bat; int adc_bat_divider; int bat_max; int bat_min; - int gpio_temp; + struct tosa_gpio gpio_temp; int adc_temp; int adc_temp_divider; }; static struct tosa_bat tosa_bat_main; static struct tosa_bat tosa_bat_jacket; +static struct tosa_gpio gpiod_jacket_det = { "jacket detect", GPIOD_IN }; +static struct tosa_gpio gpiod_battery_switch = { "battery switch", GPIOD_OUT_LOW }; +static struct tosa_gpio gpiod_main_battery_low = { "main battery low", GPIOD_IN }; +static struct tosa_gpio gpiod_jacket_battery_low = { "jacket battery low", GPIOD_IN }; static unsigned long tosa_read_bat(struct tosa_bat *bat) { unsigned long value = 0; - if (bat->gpio_bat < 0 || bat->adc_bat < 0) + if (!bat->gpio_bat.desc || bat->adc_bat < 0) return 0; mutex_lock(_lock); - gpio_set_value(bat->gpio_bat, 1); + gpiod_set_value(bat->gpio_bat.desc, 1); msleep(5); value = wm97xx_read_aux_adc(dev_get_drvdata(bat->psy->dev.parent), bat->adc_bat); - gpio_set_value(bat->gpio_bat, 0); + gpiod_set_value(bat->gpio_bat.desc, 0); mutex_unlock(_lock); value =
[PATCH 39/48] power: tosa: simplify probe function
From: Arnd Bergmann We have three power supplies that need similar initialization. As a preparation for the gpio lookup table conversion, split out the initialization into a separate function. Reviewed-by: Sebastian Reichel Acked-by: Sebastian Reichel Cc: linux...@vger.kernel.org Signed-off-by: Arnd Bergmann --- drivers/power/supply/tosa_battery.c | 50 ++--- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/drivers/power/supply/tosa_battery.c b/drivers/power/supply/tosa_battery.c index 32cc31cd4761..b26b0eca33e1 100644 --- a/drivers/power/supply/tosa_battery.c +++ b/drivers/power/supply/tosa_battery.c @@ -343,12 +343,24 @@ static int tosa_bat_resume(struct platform_device *dev) #define tosa_bat_resume NULL #endif +static int tosa_power_supply_register(struct device *dev, + struct tosa_bat *bat, + const struct power_supply_desc *desc) +{ + struct power_supply_config cfg = { + .drv_data = bat, + }; + + mutex_init(>work_lock); + bat->psy = power_supply_register(dev, desc, ); + + return PTR_ERR_OR_ZERO(bat->psy); +} + + static int tosa_bat_probe(struct platform_device *dev) { int ret; - struct power_supply_config main_psy_cfg = {}, - jacket_psy_cfg = {}, - bu_psy_cfg = {}; if (!machine_is_tosa()) return -ENODEV; @@ -357,36 +369,22 @@ static int tosa_bat_probe(struct platform_device *dev) if (ret) return ret; - mutex_init(_bat_main.work_lock); - mutex_init(_bat_jacket.work_lock); - INIT_WORK(_work, tosa_bat_work); - main_psy_cfg.drv_data = _bat_main; - tosa_bat_main.psy = power_supply_register(>dev, - _bat_main_desc, - _psy_cfg); - if (IS_ERR(tosa_bat_main.psy)) { - ret = PTR_ERR(tosa_bat_main.psy); + ret = tosa_power_supply_register(>dev, _bat_main, +_bat_main_desc); + if (ret) goto err_psy_reg_main; - } - jacket_psy_cfg.drv_data = _bat_jacket; - tosa_bat_jacket.psy = power_supply_register(>dev, - _bat_jacket_desc, - _psy_cfg); - if (IS_ERR(tosa_bat_jacket.psy)) { - ret = PTR_ERR(tosa_bat_jacket.psy); + ret = tosa_power_supply_register(>dev, _bat_jacket, +_bat_jacket_desc); + if (ret) goto err_psy_reg_jacket; - } - bu_psy_cfg.drv_data = _bat_bu; - tosa_bat_bu.psy = power_supply_register(>dev, _bat_bu_desc, - _psy_cfg); - if (IS_ERR(tosa_bat_bu.psy)) { - ret = PTR_ERR(tosa_bat_bu.psy); + ret = tosa_power_supply_register(>dev, _bat_bu, +_bat_bu_desc); + if (ret) goto err_psy_reg_bu; - } ret = request_irq(gpio_to_irq(TOSA_GPIO_BAT0_CRG), tosa_bat_gpio_isr, -- 2.29.2
[PATCH 38/48] ARM: pxa: move clk register definitions to driver
From: Arnd Bergmann The clock register definitions are now used (almost) exclusively in the clk driver, and that relies on no other mach/*.h header files any more. Remove the dependency on mach/pxa*-regs.h by addressing the registers as offsets from a void __iomem * pointer, which is either passed from a board file, or (for the moment) ioremapped at boot time from a hardcoded address in case of DT (this should be moved into the DT of course). Cc: linux-...@vger.kernel.org Acked-by: Stephen Boyd Acked-by: Robert Jarzmik Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/generic.c | 7 +- arch/arm/mach-pxa/generic.h | 3 - arch/arm/mach-pxa/include/mach/pxa2xx-regs.h | 45 --- arch/arm/mach-pxa/include/mach/pxa3xx-regs.h | 69 --- arch/arm/mach-pxa/sleep.S| 4 +- drivers/clk/pxa/clk-pxa.c| 4 +- drivers/clk/pxa/clk-pxa.h| 6 +- drivers/clk/pxa/clk-pxa25x.c | 18 +-- drivers/clk/pxa/clk-pxa27x.c | 39 +++--- drivers/clk/pxa/clk-pxa2xx.h | 58 + drivers/clk/pxa/clk-pxa3xx.c | 120 +++ include/linux/clk/pxa.h | 7 ++ 12 files changed, 210 insertions(+), 170 deletions(-) create mode 100644 drivers/clk/pxa/clk-pxa2xx.h diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 971d25e95a1a..91ea063dc54d 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -48,11 +49,11 @@ void clear_reset_status(unsigned int mask) void __init pxa_timer_init(void) { if (cpu_is_pxa25x()) - pxa25x_clocks_init(); + pxa25x_clocks_init(io_p2v(0x4130)); if (cpu_is_pxa27x()) - pxa27x_clocks_init(); + pxa27x_clocks_init(io_p2v(0x4130)); if (cpu_is_pxa3xx()) - pxa3xx_clocks_init(); + pxa3xx_clocks_init(io_p2v(0x4134), io_p2v(0x4135)); pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a0)); } diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 487eadb0fc2a..7bb1499de4c5 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -22,19 +22,16 @@ extern void pxa_timer_init(void); #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) #define pxa25x_handle_irq icip_handle_irq -extern int __init pxa25x_clocks_init(void); extern void __init pxa25x_init_irq(void); extern void __init pxa25x_map_io(void); extern void __init pxa26x_init_irq(void); #define pxa27x_handle_irq ichp_handle_irq -extern int __init pxa27x_clocks_init(void); extern unsignedpxa27x_get_clk_frequency_khz(int); extern void __init pxa27x_init_irq(void); extern void __init pxa27x_map_io(void); #define pxa3xx_handle_irq ichp_handle_irq -extern int __init pxa3xx_clocks_init(void); extern void __init pxa3xx_init_irq(void); extern void __init pxa3xx_map_io(void); diff --git a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h index f68b573ab4a0..0b7eaf6b5813 100644 --- a/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h +++ b/arch/arm/mach-pxa/include/mach/pxa2xx-regs.h @@ -136,51 +136,6 @@ #define CKEN io_p2v(0x4134) /* Clock Enable Register */ #define OSCC io_p2v(0x4138) /* Oscillator Configuration Register */ -#define CCCR_N_MASK0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */ -#define CCCR_M_MASK0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */ -#define CCCR_L_MASK0x001f /* Crystal Frequency to Memory Frequency Multiplier */ - -#define CCCR_CPDIS_BIT (31) -#define CCCR_PPDIS_BIT (30) -#define CCCR_LCD_26_BIT(27) -#define CCCR_A_BIT (25) - -#define CCSR_N2_MASK CCCR_N_MASK -#define CCSR_M_MASKCCCR_M_MASK -#define CCSR_L_MASKCCCR_L_MASK -#define CCSR_N2_SHIFT 7 - -#define CKEN_AC97CONF (31)/* AC97 Controller Configuration */ -#define CKEN_CAMERA(24)/* Camera Interface Clock Enable */ -#define CKEN_SSP1 (23)/* SSP1 Unit Clock Enable */ -#define CKEN_MEMC (22)/* Memory Controller Clock Enable */ -#define CKEN_MEMSTK(21)/* Memory Stick Host Controller */ -#define CKEN_IM(20)/* Internal Memory Clock Enable */ -#define CKEN_KEYPAD(19)/* Keypad Interface Clock Enable */ -#define CKEN_USIM (18)/* USIM Unit Clock Enable */ -#define CKEN_MSL (17)/* MSL Unit Clock Enable */ -#define CKEN_LCD (16)/* LCD Unit Clock Enable */ -#define CKEN_PWRI2C(15)/* PWR I2C Unit Clock Enable */ -#define CKEN_I2C (14)/* I2C Unit Clock Enable */ -#define CKEN_FICP (13)/* FICP Unit Clock Enable */ -#define CKEN_MMC (12)/* MMC Unit Clock Enable */ -#define CKEN_USB (11)
[PATCH 37/48] ARM: pxa: move smemc register access from clk to platform
From: Arnd Bergmann The get_sdram_rows() and get_memclkdiv() helpers need smemc register that are separate from the clk registers, move them out of the clk driver, and use an extern declaration instead. Cc: Michael Turquette Cc: Stephen Boyd Cc: linux-...@vger.kernel.org Link: https://lore.kernel.org/lkml/87pnielzo4@belgarion.home/ Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/generic.c | 6 ++ arch/arm/mach-pxa/pxa2xx.c| 25 + arch/arm/mach-pxa/pxa3xx.c| 4 arch/arm/mach-pxa/smemc.c | 9 + drivers/clk/pxa/clk-pxa.c | 4 +++- drivers/clk/pxa/clk-pxa.h | 5 +++-- drivers/clk/pxa/clk-pxa25x.c | 30 +++--- drivers/clk/pxa/clk-pxa27x.c | 31 +++ drivers/clk/pxa/clk-pxa3xx.c | 8 +++- include/linux/soc/pxa/smemc.h | 3 +++ 10 files changed, 62 insertions(+), 63 deletions(-) diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 2c2c82fcf9cb..971d25e95a1a 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,11 @@ void pxa_smemc_set_pcmcia_socket(int nr) } EXPORT_SYMBOL_GPL(pxa_smemc_set_pcmcia_socket); +void __iomem *pxa_smemc_get_mdrefr(void) +{ + return MDREFR; +} + /* * Intel PXA2xx internal register mapping. * diff --git a/arch/arm/mach-pxa/pxa2xx.c b/arch/arm/mach-pxa/pxa2xx.c index ac72acb43e26..f583759ac00d 100644 --- a/arch/arm/mach-pxa/pxa2xx.c +++ b/arch/arm/mach-pxa/pxa2xx.c @@ -15,6 +15,7 @@ #include #include "mfp-pxa25x.h" #include +#include #include void pxa2xx_clear_reset_status(unsigned int mask) @@ -50,3 +51,27 @@ void pxa2xx_transceiver_mode(struct device *dev, int mode) BUG(); } EXPORT_SYMBOL_GPL(pxa2xx_transceiver_mode); + +#define MDCNFG_DRAC2(mdcnfg) (((mdcnfg) >> 21) & 0x3) +#define MDCNFG_DRAC0(mdcnfg) (((mdcnfg) >> 5) & 0x3) + +int pxa2xx_smemc_get_sdram_rows(void) +{ + static int sdram_rows; + unsigned int drac2 = 0, drac0 = 0; + u32 mdcnfg; + + if (sdram_rows) + return sdram_rows; + + mdcnfg = readl_relaxed(MDCNFG); + + if (mdcnfg & (MDCNFG_DE2 | MDCNFG_DE3)) + drac2 = MDCNFG_DRAC2(mdcnfg); + + if (mdcnfg & (MDCNFG_DE0 | MDCNFG_DE1)) + drac0 = MDCNFG_DRAC0(mdcnfg); + + sdram_rows = 1 << (11 + max(drac0, drac2)); + return sdram_rows; +} diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index f4657f4edb3b..d486efb79dcd 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -52,6 +52,10 @@ extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int)); #define NDCR_ND_ARB_EN (1 << 12) #define NDCR_ND_ARB_CNTL (1 << 19) +#define CKEN_BOOT 11 /* < Boot rom clock enable */ +#define CKEN_TPM 19 /* < TPM clock enable */ +#define CKEN_HSIO2 41 /* < HSIO2 clock enable */ + #ifdef CONFIG_PM #define ISRAM_START0x5c00 diff --git a/arch/arm/mach-pxa/smemc.c b/arch/arm/mach-pxa/smemc.c index 47b99549d616..da0eeafdb5a0 100644 --- a/arch/arm/mach-pxa/smemc.c +++ b/arch/arm/mach-pxa/smemc.c @@ -69,4 +69,13 @@ static int __init smemc_init(void) return 0; } subsys_initcall(smemc_init); + #endif + +static const unsigned int df_clkdiv[4] = { 1, 2, 4, 1 }; +unsigned int pxa3xx_smemc_get_memclkdiv(void) +{ + unsigned long memclkcfg = __raw_readl(MEMCLKCFG); + + return df_clkdiv[(memclkcfg >> 16) & 0x3]; +} diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c index cfc79f942b07..831180360069 100644 --- a/drivers/clk/pxa/clk-pxa.c +++ b/drivers/clk/pxa/clk-pxa.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "clk-pxa.h" @@ -150,12 +151,13 @@ void pxa2xx_core_turbo_switch(bool on) } void pxa2xx_cpll_change(struct pxa2xx_freq *freq, - u32 (*mdrefr_dri)(unsigned int), void __iomem *mdrefr, + u32 (*mdrefr_dri)(unsigned int), void __iomem *cccr) { unsigned int clkcfg = freq->clkcfg; unsigned int unused, preset_mdrefr, postset_mdrefr; unsigned long flags; + void __iomem *mdrefr = pxa_smemc_get_mdrefr(); local_irq_save(flags); diff --git a/drivers/clk/pxa/clk-pxa.h b/drivers/clk/pxa/clk-pxa.h index 5768e0f728ce..bd688fdb7ecc 100644 --- a/drivers/clk/pxa/clk-pxa.h +++ b/drivers/clk/pxa/clk-pxa.h @@ -146,12 +146,13 @@ static inline int dummy_clk_set_parent(struct clk_hw *hw, u8 index) extern void clkdev_pxa_register(int ckid, const char *con_id, const char *dev_id, struct clk *clk); -extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, int nb_clks); +extern int clk_pxa_cken_init(const struct desc_clk_cken *clks, +
[PATCH 36/48] cpufreq: pxa3: move clk register access to clk driver
From: Arnd Bergmann The driver needs some low-level register access for setting the core and bus frequencies. These registers are owned by the clk driver, so move the low-level access into that driver with a slightly higher-level interface and avoid any machine header file dependencies. Cc: Michael Turquette Cc: Stephen Boyd Acked-by: Viresh Kumar Cc: linux-...@vger.kernel.org Cc: linux...@vger.kernel.org Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/generic.h | 1 - arch/arm/mach-pxa/include/mach/generic.h | 5 -- arch/arm/mach-pxa/pxa3xx.c | 1 + drivers/clk/pxa/clk-pxa3xx.c | 16 ++ drivers/cpufreq/pxa2xx-cpufreq.c | 3 -- drivers/cpufreq/pxa3xx-cpufreq.c | 64 +--- include/linux/clk/pxa.h | 9 7 files changed, 62 insertions(+), 37 deletions(-) delete mode 100644 arch/arm/mach-pxa/include/mach/generic.h create mode 100644 include/linux/clk/pxa.h diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 2f706ef97357..487eadb0fc2a 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -7,7 +7,6 @@ */ #include -#include struct irq_data; diff --git a/arch/arm/mach-pxa/include/mach/generic.h b/arch/arm/mach-pxa/include/mach/generic.h deleted file mode 100644 index 613f6a299d0d.. --- a/arch/arm/mach-pxa/include/mach/generic.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef CONFIG_PXA3xx -extern unsignedpxa3xx_get_clk_frequency_khz(int); -#else -#define pxa3xx_get_clk_frequency_khz(x)(0) -#endif diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 7881888107c7..f4657f4edb3b 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include diff --git a/drivers/clk/pxa/clk-pxa3xx.c b/drivers/clk/pxa/clk-pxa3xx.c index 027b78183565..60a0db4f3790 100644 --- a/drivers/clk/pxa/clk-pxa3xx.c +++ b/drivers/clk/pxa/clk-pxa3xx.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -79,6 +80,21 @@ unsigned int pxa3xx_get_clk_frequency_khz(int info) return (unsigned int)clks[0] / KHz; } +void pxa3xx_clk_update_accr(u32 disable, u32 enable, u32 xclkcfg, u32 mask) +{ + u32 accr = ACCR; + + accr &= ~disable; + accr |= enable; + + ACCR = accr; + if (xclkcfg) + __asm__("mcr p14, 0, %0, c6, c0, 0\n" : : "r"(xclkcfg)); + + while ((ACSR & mask) != (accr & mask)) + cpu_relax(); +} + static unsigned long clk_pxa3xx_ac97_get_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index e74d36d6f78d..ed1ae061a687 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -27,9 +27,6 @@ #include #include -#include -#include - #ifdef DEBUG static unsigned int freq_debug; module_param(freq_debug, uint, 0); diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index d3b398b4aa6a..4afa48d172db 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -9,12 +9,10 @@ #include #include #include +#include #include #include -#include -#include - #define HSS_104M (0) #define HSS_156M (1) #define HSS_208M (2) @@ -35,6 +33,28 @@ #define DMCFS_26M (0) #define DMCFS_260M (3) +#define ACCR_XPDIS (1 << 31) /* Core PLL Output Disable */ +#define ACCR_SPDIS (1 << 30) /* System PLL Output Disable */ +#define ACCR_D0CS (1 << 26) /* D0 Mode Clock Select */ +#define ACCR_PCCE (1 << 11) /* Power Mode Change Clock Enable */ +#define ACCR_DDR_D0CS (1 << 7)/* DDR SDRAM clock frequency in D0CS (PXA31x only) */ + +#define ACCR_SMCFS_MASK(0x7 << 23) /* Static Memory Controller Frequency Select */ +#define ACCR_SFLFS_MASK(0x3 << 18) /* Frequency Select for Internal Memory Controller */ +#define ACCR_XSPCLK_MASK (0x3 << 16) /* Core Frequency during Frequency Change */ +#define ACCR_HSS_MASK (0x3 << 14) /* System Bus-Clock Frequency Select */ +#define ACCR_DMCFS_MASK(0x3 << 12) /* Dynamic Memory Controller Clock Frequency Select */ +#define ACCR_XN_MASK (0x7 << 8) /* Core PLL Turbo-Mode-to-Run-Mode Ratio */ +#define ACCR_XL_MASK (0x1f) /* Core PLL Run-Mode-to-Oscillator Ratio */ + +#define ACCR_SMCFS(x) (((x) & 0x7) << 23) +#define ACCR_SFLFS(x) (((x) & 0x3) << 18) +#define ACCR_XSPCLK(x) (((x) & 0x3) << 16) +#define ACCR_HSS(x)(((x) & 0x3) << 14) +#define ACCR_DMCFS(x) (((x) & 0x3) << 12) +#define ACCR_XN(x)
[PATCH 35/48] ARM: pxa: remove get_clk_frequency_khz()
From: Arnd Bergmann get_clk_frequency_khz() is not a proper name for a global function, and there is only one caller. Convert viper to use the properly namespaced pxa25x_get_clk_frequency_khz() and remove the other references. Acked-by: Viresh Kumar Acked-by: Robert Jarzmik Cc: linux...@vger.kernel.org Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/generic.c | 15 --- arch/arm/mach-pxa/generic.h | 1 - arch/arm/mach-pxa/viper.c| 2 +- drivers/cpufreq/pxa2xx-cpufreq.c | 2 -- 4 files changed, 1 insertion(+), 19 deletions(-) diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index fe1d55d328e5..2c2c82fcf9cb 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -55,21 +55,6 @@ void __init pxa_timer_init(void) pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x40a0)); } -/* - * Get the clock frequency as reflected by CCCR and the turbo flag. - * We assume these values have been applied via a fcs. - * If info is not 0 we also display the current settings. - */ -unsigned int get_clk_frequency_khz(int info) -{ - if (cpu_is_pxa25x()) - return pxa25x_get_clk_frequency_khz(info); - else if (cpu_is_pxa27x()) - return pxa27x_get_clk_frequency_khz(info); - return 0; -} -EXPORT_SYMBOL(get_clk_frequency_khz); - void pxa_smemc_set_pcmcia_timing(int sock, u32 mcmem, u32 mcatt, u32 mcio) { __raw_writel(mcmem, MCMEM(sock)); diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h index 67925d3ea026..2f706ef97357 100644 --- a/arch/arm/mach-pxa/generic.h +++ b/arch/arm/mach-pxa/generic.h @@ -11,7 +11,6 @@ struct irq_data; -extern unsigned int get_clk_frequency_khz(int info); extern void __init pxa_dt_irq_init(int (*fn)(struct irq_data *, unsigned int)); extern void __init pxa_map_io(void); diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c index 600d9e80b00c..0782f0ed5a6e 100644 --- a/arch/arm/mach-pxa/viper.c +++ b/arch/arm/mach-pxa/viper.c @@ -851,7 +851,7 @@ static void __init viper_init_vcore_gpios(void) goto err_dir; /* c/should assume redboot set the correct level ??? */ - viper_set_core_cpu_voltage(get_clk_frequency_khz(0), 1); + viper_set_core_cpu_voltage(pxa25x_get_clk_frequency_khz(0), 1); return; diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 0f0e676ff781..e74d36d6f78d 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -107,8 +107,6 @@ static struct pxa_freqs pxa27x_freqs[] = { static struct cpufreq_frequency_table pxa27x_freq_table[NUM_PXA27x_FREQS+1]; -extern unsigned get_clk_frequency_khz(int info); - #ifdef CONFIG_REGULATOR static int pxa_cpufreq_change_voltage(const struct pxa_freqs *pxa_freq) -- 2.29.2
[PATCH 34/48] ARM: pxa: pcmcia: move smemc configuration back to arch
From: Arnd Bergmann Rather than poking at the smemc registers directly from the pcmcia/pxa2xx_base driver, move those bits into machine file to have a cleaner interface. Cc: Dominik Brodowski Link: https://lore.kernel.org/lkml/87d0egjzxk@belgarion.home/ Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/generic.c | 29 ++ drivers/pcmcia/pxa2xx_base.c | 46 --- include/linux/soc/pxa/smemc.h | 10 3 files changed, 55 insertions(+), 30 deletions(-) create mode 100644 include/linux/soc/pxa/smemc.h diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index f9083c4f0aea..fe1d55d328e5 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -70,6 +70,35 @@ unsigned int get_clk_frequency_khz(int info) } EXPORT_SYMBOL(get_clk_frequency_khz); +void pxa_smemc_set_pcmcia_timing(int sock, u32 mcmem, u32 mcatt, u32 mcio) +{ + __raw_writel(mcmem, MCMEM(sock)); + __raw_writel(mcatt, MCATT(sock)); + __raw_writel(mcio, MCIO(sock)); +} +EXPORT_SYMBOL_GPL(pxa_smemc_set_pcmcia_timing); + +void pxa_smemc_set_pcmcia_socket(int nr) +{ + switch (nr) { + case 0: + __raw_writel(0, MECR); + break; + case 1: + /* +* We have at least one socket, so set MECR:CIT +* (Card Is There) +*/ + __raw_writel(MECR_CIT, MECR); + break; + case 2: + /* Set CIT and MECR:NOS (Number Of Sockets) */ + __raw_writel(MECR_CIT | MECR_NOS, MECR); + break; + } +} +EXPORT_SYMBOL_GPL(pxa_smemc_set_pcmcia_socket); + /* * Intel PXA2xx internal register mapping. * diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 7cd1375d6087..0ea41f1411e5 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -24,11 +24,10 @@ #include #include #include +#include -#include #include #include -#include #include #include @@ -113,7 +112,7 @@ static inline u_int pxa2xx_pcmcia_cmd_time(u_int mem_clk_10khz, return (30 * (pcmcia_mcxx_asst + 1) / mem_clk_10khz); } -static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock ) +static uint32_t pxa2xx_pcmcia_mcmem(int sock, int speed, int clock) { uint32_t val; @@ -124,12 +123,10 @@ static int pxa2xx_pcmcia_set_mcmem( int sock, int speed, int clock ) | ((pxa2xx_mcxx_hold(speed, clock) & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); - __raw_writel(val, MCMEM(sock)); - - return 0; + return val; } -static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock ) +static int pxa2xx_pcmcia_mcio(int sock, int speed, int clock) { uint32_t val; @@ -140,12 +137,11 @@ static int pxa2xx_pcmcia_set_mcio( int sock, int speed, int clock ) | ((pxa2xx_mcxx_hold(speed, clock) & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); - __raw_writel(val, MCIO(sock)); - return 0; + return val; } -static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) +static int pxa2xx_pcmcia_mcatt(int sock, int speed, int clock) { uint32_t val; @@ -156,31 +152,26 @@ static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock ) | ((pxa2xx_mcxx_hold(speed, clock) & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT); - __raw_writel(val, MCATT(sock)); - return 0; + return val; } -static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int clk) +static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) { + unsigned long clk = clk_get_rate(skt->clk) / 1; struct soc_pcmcia_timing timing; int sock = skt->nr; soc_common_pcmcia_get_timing(skt, ); - pxa2xx_pcmcia_set_mcmem(sock, timing.mem, clk); - pxa2xx_pcmcia_set_mcatt(sock, timing.attr, clk); - pxa2xx_pcmcia_set_mcio(sock, timing.io, clk); + pxa_smemc_set_pcmcia_timing(sock, + pxa2xx_pcmcia_mcmem(sock, timing.mem, clk), + pxa2xx_pcmcia_mcatt(sock, timing.attr, clk), + pxa2xx_pcmcia_mcio(sock, timing.io, clk)); return 0; } -static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) -{ - unsigned long clk = clk_get_rate(skt->clk); - return pxa2xx_pcmcia_set_mcxx(skt, clk / 1); -} - #ifdef CONFIG_CPU_FREQ static int @@ -215,18 +206,13 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops) { - /* -* We have at least one socket, so set MECR:CIT -* (Card Is There) -*/ - uint32_t mecr = MECR_CIT; + int nr = 1; - /* Set MECR:NOS (Number Of Sockets) */ if ((ops->first + ops->nr) > 1 || machine_is_viper()
[PATCH 33/48] ASoC: pxa: i2s: use normal MMIO accessors
From: Arnd Bergmann To avoid dereferencing hardwired constant pointers from a global header file, change the driver to use devm_platform_ioremap_resource for getting an __iomem pointer, and then using readl/writel on that. Each pointer dereference gets changed by a search, which leads to a few overlong lines, but seems less risky than trying to clean up the code at the same time. Acked-by: Mark Brown Acked-by: Robert Jarzmik Cc: alsa-de...@alsa-project.org Signed-off-by: Arnd Bergmann --- sound/soc/pxa/pxa2xx-i2s.c | 110 + 1 file changed, 62 insertions(+), 48 deletions(-) diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 5164c60ba89f..746e6ec9198b 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c @@ -21,7 +21,6 @@ #include #include -#include #include #include "pxa2xx-i2s.h" @@ -29,13 +28,13 @@ /* * I2S Controller Register and Bit Definitions */ -#define SACR0 __REG(0x4040) /* Global Control Register */ -#define SACR1 __REG(0x4044) /* Serial Audio I 2 S/MSB-Justified Control Register */ -#define SASR0 __REG(0x404C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ -#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */ -#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */ -#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ -#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ +#define SACR0 (0x)/* Global Control Register */ +#define SACR1 (0x0004)/* Serial Audio I 2 S/MSB-Justified Control Register */ +#define SASR0 (0x000C)/* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ +#define SAIMR (0x0014)/* Serial Audio Interrupt Mask Register */ +#define SAICR (0x0018)/* Serial Audio Interrupt Clear Register */ +#define SADIV (0x0060)/* Audio Clock Divider Register. */ +#define SADR (0x0080)/* Serial Audio Data Register (TX and RX FIFO access Register). */ #define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */ #define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */ @@ -77,16 +76,15 @@ struct pxa_i2s_port { static struct pxa_i2s_port pxa_i2s; static struct clk *clk_i2s; static int clk_ena = 0; +static void __iomem *i2s_reg_base; static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_out = { - .addr = __PREG(SADR), .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, .chan_name = "tx", .maxburst = 32, }; static struct snd_dmaengine_dai_dma_data pxa2xx_i2s_pcm_stereo_in = { - .addr = __PREG(SADR), .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, .chan_name = "rx", .maxburst = 32, @@ -102,7 +100,7 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream, return PTR_ERR(clk_i2s); if (!snd_soc_dai_active(cpu_dai)) - SACR0 = 0; + writel(0, i2s_reg_base + SACR0); return 0; } @@ -114,7 +112,7 @@ static int pxa_i2s_wait(void) /* flush the Rx FIFO */ for (i = 0; i < 16; i++) - SADR; + readl(i2s_reg_base + SADR); return 0; } @@ -174,39 +172,39 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, /* is port used by another stream */ if (!(SACR0 & SACR0_ENB)) { - SACR0 = 0; + writel(0, i2s_reg_base + SACR0); if (pxa_i2s.master) - SACR0 |= SACR0_BCKD; + writel(readl(i2s_reg_base + SACR0) | (SACR0_BCKD), i2s_reg_base + SACR0); - SACR0 |= SACR0_RFTH(14) | SACR0_TFTH(1); - SACR1 |= pxa_i2s.fmt; + writel(readl(i2s_reg_base + SACR0) | (SACR0_RFTH(14) | SACR0_TFTH(1)), i2s_reg_base + SACR0); + writel(readl(i2s_reg_base + SACR1) | (pxa_i2s.fmt), i2s_reg_base + SACR1); } if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - SAIMR |= SAIMR_TFS; + writel(readl(i2s_reg_base + SAIMR) | (SAIMR_TFS), i2s_reg_base + SAIMR); else - SAIMR |= SAIMR_RFS; + writel(readl(i2s_reg_base + SAIMR) | (SAIMR_RFS), i2s_reg_base + SAIMR); switch (params_rate(params)) { case 8000: - SADIV = 0x48; + writel(0x48, i2s_reg_base + SADIV); break; case 11025: - SADIV = 0x34; + writel(0x34, i2s_reg_base + SADIV); break; case 16000: - SADIV = 0x24; + writel(0x24, i2s_reg_base
[PATCH 32/48] ASoC: pxa: ac97: use normal MMIO accessors
From: Arnd Bergmann To avoid dereferencing hardwired constant pointers from a global header file, change the driver to use devm_platform_ioremap_resource for getting an __iomem pointer, and then using readl/writel on that. Each pointer dereference gets changed by a search, which leads to a few overlong lines, but seems less risky than trying to clean up the code at the same time. Cc: alsa-de...@alsa-project.org Acked-by: Robert Jarzmik Signed-off-by: Arnd Bergmann --- sound/arm/pxa2xx-ac97-lib.c | 124 ++ .../arm/pxa2xx-ac97-regs.h| 42 +++--- sound/arm/pxa2xx-ac97.c | 1 - 3 files changed, 92 insertions(+), 75 deletions(-) rename arch/arm/mach-pxa/include/mach/regs-ac97.h => sound/arm/pxa2xx-ac97-regs.h (71%) diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c index 572b73d73762..e55c0421718b 100644 --- a/sound/arm/pxa2xx-ac97-lib.c +++ b/sound/arm/pxa2xx-ac97-lib.c @@ -21,15 +21,17 @@ #include -#include #include +#include "pxa2xx-ac97-regs.h" + static DEFINE_MUTEX(car_mutex); static DECLARE_WAIT_QUEUE_HEAD(gsr_wq); static volatile long gsr_bits; static struct clk *ac97_clk; static struct clk *ac97conf_clk; static int reset_gpio; +static void __iomem *ac97_reg_base; extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio); @@ -46,7 +48,7 @@ extern void pxa27x_configure_ac97reset(int reset_gpio, bool to_gpio); int pxa2xx_ac97_read(int slot, unsigned short reg) { int val = -ENODEV; - volatile u32 *reg_addr; + u32 __iomem *reg_addr; if (slot > 0) return -ENODEV; @@ -55,31 +57,33 @@ int pxa2xx_ac97_read(int slot, unsigned short reg) /* set up primary or secondary codec space */ if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS) - reg_addr = slot ? _REG_BASE : _REG_BASE; + reg_addr = ac97_reg_base + + (slot ? SMC_REG_BASE : PMC_REG_BASE); else - reg_addr = slot ? _REG_BASE : _REG_BASE; + reg_addr = ac97_reg_base + + (slot ? SAC_REG_BASE : PAC_REG_BASE); reg_addr += (reg >> 1); /* start read access across the ac97 link */ - GSR = GSR_CDONE | GSR_SDONE; + writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR); gsr_bits = 0; - val = (*reg_addr & 0x); + val = (readl(reg_addr) & 0x); if (reg == AC97_GPIO_STATUS) goto out; - if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 && - !((GSR | gsr_bits) & GSR_SDONE)) { + if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1) <= 0 && + !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE)) { printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n", - __func__, reg, GSR | gsr_bits); + __func__, reg, readl(ac97_reg_base + GSR) | gsr_bits); val = -ETIMEDOUT; goto out; } /* valid data now */ - GSR = GSR_CDONE | GSR_SDONE; + writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR); gsr_bits = 0; - val = (*reg_addr & 0x); + val = (readl(reg_addr) & 0x); /* but we've just started another cycle... */ - wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1); + wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_SDONE, 1); out: mutex_unlock(_mutex); return val; @@ -88,25 +92,27 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_read); int pxa2xx_ac97_write(int slot, unsigned short reg, unsigned short val) { - volatile u32 *reg_addr; + u32 __iomem *reg_addr; int ret = 0; mutex_lock(_mutex); /* set up primary or secondary codec space */ if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS) - reg_addr = slot ? _REG_BASE : _REG_BASE; + reg_addr = ac97_reg_base + + (slot ? SMC_REG_BASE : PMC_REG_BASE); else - reg_addr = slot ? _REG_BASE : _REG_BASE; + reg_addr = ac97_reg_base + + (slot ? SAC_REG_BASE : PAC_REG_BASE); reg_addr += (reg >> 1); - GSR = GSR_CDONE | GSR_SDONE; + writel(GSR_CDONE | GSR_SDONE, ac97_reg_base + GSR); gsr_bits = 0; - *reg_addr = val; - if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 && - !((GSR | gsr_bits) & GSR_CDONE)) { + writel(val, reg_addr); + if (wait_event_timeout(gsr_wq, (readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE, 1) <= 0 && + !((readl(ac97_reg_base + GSR) | gsr_bits) & GSR_CDONE)) { printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n", - __func__, reg, GSR | gsr_bits); +
[PATCH 31/48] ASoC: pxa: use pdev resource for FIFO regs
From: Arnd Bergmann The driver currently takes the hardwired FIFO address from a header file that we want to eliminate. Change it to use the mmio resource instead and stop including the here. Acked-by: Mark Brown Cc: alsa-de...@alsa-project.org Acked-by: Robert Jarzmik Signed-off-by: Arnd Bergmann --- sound/soc/pxa/pxa2xx-ac97.c | 22 +++--- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index 9443c1390d2f..809ea34736ed 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c @@ -21,10 +21,12 @@ #include #include -#include -#include #include +#define PCDR 0x0040 /* PCM FIFO Data Register */ +#define MODR 0x0140 /* Modem FIFO Data Register */ +#define MCDR 0x0060 /* Mic-in FIFO Data Register */ + static void pxa2xx_ac97_warm_reset(struct ac97_controller *adrv) { pxa2xx_ac97_try_warm_reset(); @@ -59,35 +61,30 @@ static struct ac97_controller_ops pxa2xx_ac97_ops = { }; static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_in = { - .addr = __PREG(PCDR), .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, .chan_name = "pcm_pcm_stereo_in", .maxburst = 32, }; static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_stereo_out = { - .addr = __PREG(PCDR), .addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, .chan_name = "pcm_pcm_stereo_out", .maxburst = 32, }; static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_out = { - .addr = __PREG(MODR), .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, .chan_name = "pcm_aux_mono_out", .maxburst = 16, }; static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_aux_mono_in = { - .addr = __PREG(MODR), .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, .chan_name = "pcm_aux_mono_in", .maxburst = 16, }; static struct snd_dmaengine_dai_dma_data pxa2xx_ac97_pcm_mic_mono_in = { - .addr = __PREG(MCDR), .addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES, .chan_name = "pcm_aux_mic_mono", .maxburst = 16, @@ -226,6 +223,7 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) int ret; struct ac97_controller *ctrl; pxa2xx_audio_ops_t *pdata = pdev->dev.platform_data; + struct resource *regs; void **codecs_pdata; if (pdev->id != -1) { @@ -233,6 +231,16 @@ static int pxa2xx_ac97_dev_probe(struct platform_device *pdev) return -ENXIO; } + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!regs) + return -ENXIO; + + pxa2xx_ac97_pcm_stereo_in.addr = regs->start + PCDR; + pxa2xx_ac97_pcm_stereo_out.addr = regs->start + PCDR; + pxa2xx_ac97_pcm_aux_mono_out.addr = regs->start + MODR; + pxa2xx_ac97_pcm_aux_mono_in.addr = regs->start + MODR; + pxa2xx_ac97_pcm_mic_mono_in.addr = regs->start + MCDR; + ret = pxa2xx_ac97_hw_probe(pdev); if (ret) { dev_err(>dev, "PXA2xx AC97 hw probe error (%d)\n", ret); -- 2.29.2
[PATCH 30/48] Input: wm97xx - get rid of irq_enable method in wm97xx_mach_ops
From: Dmitry Torokhov Now that we are using oneshot threaded IRQ this method is not used anymore. Signed-off-by: Dmitry Torokhov [arnd: add the db1300 change as well] Cc: Manuel Lauss Signed-off-by: Arnd Bergmann --- arch/mips/alchemy/devboards/db1300.c | 9 - drivers/input/touchscreen/mainstone-wm97xx.c | 9 - drivers/input/touchscreen/zylonite-wm97xx.c | 9 - include/linux/wm97xx.h | 3 --- 4 files changed, 30 deletions(-) diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index cd72eaa1168f..e70e529ddd91 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c @@ -732,16 +732,7 @@ static struct platform_device db1300_lcd_dev = { /**/ #if IS_ENABLED(CONFIG_TOUCHSCREEN_WM97XX) -static void db1300_wm97xx_irqen(struct wm97xx *wm, int enable) -{ - if (enable) - enable_irq(DB1300_AC97_PEN_INT); - else - disable_irq_nosync(DB1300_AC97_PEN_INT); -} - static struct wm97xx_mach_ops db1300_wm97xx_ops = { - .irq_enable = db1300_wm97xx_irqen, .irq_gpio = WM97XX_GPIO_3, }; diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 8f6fe68f1f99..c39f49720fe4 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -246,21 +246,12 @@ static void wm97xx_acc_shutdown(struct wm97xx *wm) } } -static void wm97xx_irq_enable(struct wm97xx *wm, int enable) -{ - if (enable) - enable_irq(wm->pen_irq); - else - disable_irq_nosync(wm->pen_irq); -} - static struct wm97xx_mach_ops mainstone_mach_ops = { .acc_enabled= 1, .acc_pen_up = wm97xx_acc_pen_up, .acc_pen_down = wm97xx_acc_pen_down, .acc_startup= wm97xx_acc_startup, .acc_shutdown = wm97xx_acc_shutdown, - .irq_enable = wm97xx_irq_enable, .irq_gpio = WM97XX_GPIO_2, }; diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index ed7eae638713..a70fe4abe520 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c @@ -160,20 +160,11 @@ static int wm97xx_acc_startup(struct wm97xx *wm) return 0; } -static void wm97xx_irq_enable(struct wm97xx *wm, int enable) -{ - if (enable) - enable_irq(wm->pen_irq); - else - disable_irq_nosync(wm->pen_irq); -} - static struct wm97xx_mach_ops zylonite_mach_ops = { .acc_enabled= 1, .acc_pen_up = wm97xx_acc_pen_up, .acc_pen_down = wm97xx_acc_pen_down, .acc_startup= wm97xx_acc_startup, - .irq_enable = wm97xx_irq_enable, .irq_gpio = WM97XX_GPIO_2, }; diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h index 85bd8dd3caea..332d2b0f29b9 100644 --- a/include/linux/wm97xx.h +++ b/include/linux/wm97xx.h @@ -254,9 +254,6 @@ struct wm97xx_mach_ops { int (*acc_startup) (struct wm97xx *); void (*acc_shutdown) (struct wm97xx *); - /* interrupt mask control - required for accelerated operation */ - void (*irq_enable) (struct wm97xx *, int enable); - /* GPIO pin used for accelerated operation */ int irq_gpio; -- 2.29.2
[PATCH 29/48] Input: wm97xx - switch to using threaded IRQ
From: Dmitry Torokhov Instead of manually disabling and enabling interrupts and scheduling work to access the device, let's use threaded oneshot interrupt handler. It simplifies things. Signed-off-by: Dmitry Torokhov Signed-off-by: Arnd Bergmann --- drivers/input/touchscreen/wm97xx-core.c | 42 + include/linux/wm97xx.h | 1 - 2 files changed, 7 insertions(+), 36 deletions(-) diff --git a/drivers/input/touchscreen/wm97xx-core.c b/drivers/input/touchscreen/wm97xx-core.c index 1b58611c8084..2757c7768ffe 100644 --- a/drivers/input/touchscreen/wm97xx-core.c +++ b/drivers/input/touchscreen/wm97xx-core.c @@ -285,11 +285,12 @@ void wm97xx_set_suspend_mode(struct wm97xx *wm, u16 mode) EXPORT_SYMBOL_GPL(wm97xx_set_suspend_mode); /* - * Handle a pen down interrupt. + * Codec PENDOWN irq handler + * */ -static void wm97xx_pen_irq_worker(struct work_struct *work) +static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id) { - struct wm97xx *wm = container_of(work, struct wm97xx, pen_event_work); + struct wm97xx *wm = dev_id; int pen_was_down = wm->pen_is_down; /* do we need to enable the touch panel reader */ @@ -343,27 +344,6 @@ static void wm97xx_pen_irq_worker(struct work_struct *work) if (!wm->pen_is_down && wm->mach_ops->acc_enabled) wm->mach_ops->acc_pen_up(wm); - wm->mach_ops->irq_enable(wm, 1); -} - -/* - * Codec PENDOWN irq handler - * - * We have to disable the codec interrupt in the handler because it - * can take up to 1ms to clear the interrupt source. We schedule a task - * in a work queue to do the actual interaction with the chip. The - * interrupt is then enabled again in the slow handler when the source - * has been cleared. - */ -static irqreturn_t wm97xx_pen_interrupt(int irq, void *dev_id) -{ - struct wm97xx *wm = dev_id; - - if (!work_pending(>pen_event_work)) { - wm->mach_ops->irq_enable(wm, 0); - queue_work(wm->ts_workq, >pen_event_work); - } - return IRQ_HANDLED; } @@ -374,12 +354,9 @@ static int wm97xx_init_pen_irq(struct wm97xx *wm) { u16 reg; - /* If an interrupt is supplied an IRQ enable operation must also be -* provided. */ - BUG_ON(!wm->mach_ops->irq_enable); - - if (request_irq(wm->pen_irq, wm97xx_pen_interrupt, IRQF_SHARED, - "wm97xx-pen", wm)) { + if (request_threaded_irq(wm->pen_irq, NULL, wm97xx_pen_interrupt, +IRQF_SHARED | IRQF_ONESHOT, +"wm97xx-pen", wm)) { dev_err(wm->dev, "Failed to register pen down interrupt, polling"); wm->pen_irq = 0; @@ -509,7 +486,6 @@ static int wm97xx_ts_input_open(struct input_dev *idev) wm->codec->dig_enable(wm, 1); INIT_DELAYED_WORK(>ts_reader, wm97xx_ts_reader); - INIT_WORK(>pen_event_work, wm97xx_pen_irq_worker); wm->ts_reader_min_interval = HZ >= 100 ? HZ / 100 : 1; if (wm->ts_reader_min_interval < 1) @@ -560,10 +536,6 @@ static void wm97xx_ts_input_close(struct input_dev *idev) wm->pen_is_down = 0; - /* Balance out interrupt disables/enables */ - if (cancel_work_sync(>pen_event_work)) - wm->mach_ops->irq_enable(wm, 1); - /* ts_reader rearms itself so we need to explicitly stop it * before we destroy the workqueue. */ diff --git a/include/linux/wm97xx.h b/include/linux/wm97xx.h index 462854f4f286..85bd8dd3caea 100644 --- a/include/linux/wm97xx.h +++ b/include/linux/wm97xx.h @@ -281,7 +281,6 @@ struct wm97xx { unsigned long ts_reader_min_interval; /* Minimum interval */ unsigned int pen_irq; /* Pen IRQ number in use */ struct workqueue_struct *ts_workq; - struct work_struct pen_event_work; u16 acc_slot; /* AC97 slot used for acc touch data */ u16 acc_rate; /* acc touch data rate */ unsigned pen_is_down:1; /* Pen is down */ -- 2.29.2
[PATCH 28/48] Input: touchscreen: use wrapper for pxa2xx ac97 registers
From: Arnd Bergmann To avoid a dependency on the pxa platform header files with hardcoded registers, change the driver to call a wrapper in the pxa2xx-ac97-lib that encapsulates all the other ac97 stuff. Acked-by: Dmitry Torokhov Acked-by: Robert Jarzmik Cc: linux-in...@vger.kernel.org Cc: alsa-de...@alsa-project.org Signed-off-by: Arnd Bergmann --- drivers/input/touchscreen/Kconfig| 2 ++ drivers/input/touchscreen/mainstone-wm97xx.c | 16 drivers/input/touchscreen/zylonite-wm97xx.c | 12 ++-- include/sound/pxa2xx-lib.h | 4 sound/arm/pxa2xx-ac97-lib.c | 12 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 43c7d6e5bdc0..2d70c945b20a 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -902,6 +902,7 @@ config TOUCHSCREEN_WM9713 config TOUCHSCREEN_WM97XX_MAINSTONE tristate "WM97xx Mainstone/Palm accelerated touch" depends on TOUCHSCREEN_WM97XX && ARCH_PXA + depends on SND_PXA2XX_LIB_AC97 help Say Y here for support for streaming mode with WM97xx touchscreens on Mainstone, Palm Tungsten T5, TX and LifeDrive systems. @@ -914,6 +915,7 @@ config TOUCHSCREEN_WM97XX_MAINSTONE config TOUCHSCREEN_WM97XX_ZYLONITE tristate "Zylonite accelerated touch" depends on TOUCHSCREEN_WM97XX && MACH_ZYLONITE + depends on SND_PXA2XX_LIB_AC97 select TOUCHSCREEN_WM9713 help Say Y here for support for streaming mode with the touchscreen diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 940d3c92b1f8..8f6fe68f1f99 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include @@ -104,11 +104,11 @@ static void wm97xx_acc_pen_up(struct wm97xx *wm) msleep(1); if (cpu_is_pxa27x()) { - while (MISR & (1 << 2)) - MODR; + while (pxa2xx_ac97_read_misr() & (1 << 2)) + pxa2xx_ac97_read_modr(); } else if (cpu_is_pxa3xx()) { for (count = 0; count < 16; count++) - MODR; + pxa2xx_ac97_read_modr(); } } @@ -130,7 +130,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) return RC_PENUP; } - x = MODR; + x = pxa2xx_ac97_read_modr(); if (x == last) { tries++; return RC_AGAIN; @@ -138,10 +138,10 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) last = x; do { if (reads) - x = MODR; - y = MODR; + x = pxa2xx_ac97_read_modr(); + y = pxa2xx_ac97_read_modr(); if (pressure) - p = MODR; + p = pxa2xx_ac97_read_modr(); dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", x, y, p); diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c index cabdd6e3c6f8..ed7eae638713 100644 --- a/drivers/input/touchscreen/zylonite-wm97xx.c +++ b/drivers/input/touchscreen/zylonite-wm97xx.c @@ -24,7 +24,7 @@ #include #include -#include +#include struct continuous { u16 id;/* codec id */ @@ -79,7 +79,7 @@ static void wm97xx_acc_pen_up(struct wm97xx *wm) msleep(1); for (i = 0; i < 16; i++) - MODR; + pxa2xx_ac97_read_modr(); } static int wm97xx_acc_pen_down(struct wm97xx *wm) @@ -100,7 +100,7 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) return RC_PENUP; } - x = MODR; + x = pxa2xx_ac97_read_modr(); if (x == last) { tries++; return RC_AGAIN; @@ -108,10 +108,10 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) last = x; do { if (reads) - x = MODR; - y = MODR; + x = pxa2xx_ac97_read_modr(); + y = pxa2xx_ac97_read_modr(); if (pressure) - p = MODR; + p = pxa2xx_ac97_read_modr(); dev_dbg(wm->dev, "Raw coordinates: x=%x, y=%x, p=%x\n", x, y, p); diff --git a/include/sound/pxa2xx-lib.h b/include/sound/pxa2xx-lib.h index 95100cff25d1..0a6f8dabf8c4 100644 --- a/include/sound/pxa2xx-lib.h +++ b/include/sound/pxa2xx-lib.h @@ -52,4 +52,8 @@ extern int pxa2xx_ac97_hw_resume(void); extern int pxa2xx_ac97_hw_probe(struct platform_device *dev); extern void pxa2xx_ac97_hw_remove(struct platform_device *dev); +/* modem registers,
[PATCH 27/48] input: touchscreen: mainstone: sync with zylonite driver
From: Arnd Bergmann The two drivers are almost identical and can work on a variety of hardware in principle. The mainstone driver supports additional hardware, and the zylonite driver has a few cleanup patches. Sync the two by adding the zylonite changes into the mainstone one, and checking for the zylonite board to order to keep the default behavior (interrupt enabled) there. Acked-by: Dmitry Torokhov Cc: linux-in...@vger.kernel.org Signed-off-by: Arnd Bergmann --- drivers/input/touchscreen/mainstone-wm97xx.c | 59 ++-- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c index 618c80847d9f..940d3c92b1f8 100644 --- a/drivers/input/touchscreen/mainstone-wm97xx.c +++ b/drivers/input/touchscreen/mainstone-wm97xx.c @@ -24,9 +24,9 @@ #include #include #include -#include #include -#include +#include +#include #include @@ -42,23 +42,22 @@ struct continuous { #define WM_READS(sp) ((sp / HZ) + 1) static const struct continuous cinfo[] = { - {WM9705_ID2, 0, WM_READS(94), 94}, - {WM9705_ID2, 1, WM_READS(188), 188}, - {WM9705_ID2, 2, WM_READS(375), 375}, - {WM9705_ID2, 3, WM_READS(750), 750}, - {WM9712_ID2, 0, WM_READS(94), 94}, - {WM9712_ID2, 1, WM_READS(188), 188}, - {WM9712_ID2, 2, WM_READS(375), 375}, - {WM9712_ID2, 3, WM_READS(750), 750}, - {WM9713_ID2, 0, WM_READS(94), 94}, - {WM9713_ID2, 1, WM_READS(120), 120}, - {WM9713_ID2, 2, WM_READS(154), 154}, - {WM9713_ID2, 3, WM_READS(188), 188}, + { WM9705_ID2, 0, WM_READS(94), 94 }, + { WM9705_ID2, 1, WM_READS(188), 188 }, + { WM9705_ID2, 2, WM_READS(375), 375 }, + { WM9705_ID2, 3, WM_READS(750), 750 }, + { WM9712_ID2, 0, WM_READS(94), 94 }, + { WM9712_ID2, 1, WM_READS(188), 188 }, + { WM9712_ID2, 2, WM_READS(375), 375 }, + { WM9712_ID2, 3, WM_READS(750), 750 }, + { WM9713_ID2, 0, WM_READS(94), 94 }, + { WM9713_ID2, 1, WM_READS(120), 120 }, + { WM9713_ID2, 2, WM_READS(154), 154 }, + { WM9713_ID2, 3, WM_READS(188), 188 }, }; /* continuous speed index */ static int sp_idx; -static u16 last, tries; static struct gpio_desc *gpiod_irq; /* @@ -102,7 +101,7 @@ static void wm97xx_acc_pen_up(struct wm97xx *wm) { unsigned int count; - schedule_timeout_uninterruptible(1); + msleep(1); if (cpu_is_pxa27x()) { while (MISR & (1 << 2)) @@ -117,13 +116,14 @@ static int wm97xx_acc_pen_down(struct wm97xx *wm) { u16 x, y, p = 0x100 | WM97XX_ADCSEL_PRES; int reads = 0; + static u16 last, tries; /* When the AC97 queue has been drained we need to allow time * to buffer up samples otherwise we end up spinning polling * for samples. The controller can't have a suitably low * threshold set to use the notifications it gives. */ - schedule_timeout_uninterruptible(1); + msleep(1); if (tries > 5) { tries = 0; @@ -193,6 +193,8 @@ static int wm97xx_acc_startup(struct wm97xx *wm) /* There is some obscure mutant of WM9712 interbred with WM9713 * used on Palm HW */ wm->variant = WM97xx_WM1613; + } else if (machine_is_zylonite()) { + pen_int = 1; } if (pen_int) { @@ -253,13 +255,13 @@ static void wm97xx_irq_enable(struct wm97xx *wm, int enable) } static struct wm97xx_mach_ops mainstone_mach_ops = { - .acc_enabled = 1, - .acc_pen_up = wm97xx_acc_pen_up, - .acc_pen_down = wm97xx_acc_pen_down, - .acc_startup = wm97xx_acc_startup, - .acc_shutdown = wm97xx_acc_shutdown, - .irq_enable = wm97xx_irq_enable, - .irq_gpio = WM97XX_GPIO_2, + .acc_enabled= 1, + .acc_pen_up = wm97xx_acc_pen_up, + .acc_pen_down = wm97xx_acc_pen_down, + .acc_startup= wm97xx_acc_startup, + .acc_shutdown = wm97xx_acc_shutdown, + .irq_enable = wm97xx_irq_enable, + .irq_gpio = WM97XX_GPIO_2, }; static int mainstone_wm97xx_probe(struct platform_device *pdev) @@ -274,14 +276,15 @@ static int mainstone_wm97xx_remove(struct platform_device *pdev) struct wm97xx *wm = platform_get_drvdata(pdev); wm97xx_unregister_mach_ops(wm); + return 0; } static struct platform_driver mainstone_wm97xx_driver = { - .probe = mainstone_wm97xx_probe, - .remove = mainstone_wm97xx_remove, - .driver = { - .name = "wm97xx-touch", + .probe = mainstone_wm97xx_probe, + .remove = mainstone_wm97xx_remove, + .driver = { + .name = "wm97xx-touch", }, }; module_platform_driver(mainstone_wm97xx_driver); -- 2.29.2