Re: [PATCH 1/1] drm/panel: truly: Add additional delay after pulling down reset gpio
On Wed, Jun 5, 2019 at 1:54 PM Sam Ravnborg wrote: > > Hi Vivek, > > On Mon, May 27, 2019 at 03:56:16PM +0530, Vivek Gautam wrote: > > MTP SDM845 panel seems to need additional delay to bring panel > > to a workable state. Running modetest without this change displays > > blurry artifacts. > > > > Signed-off-by: Vivek Gautam > > added to drm-misc-next Thanks a lot. Best regards Vivek > > Sam > > > --- > > drivers/gpu/drm/panel/panel-truly-nt35597.c | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/drivers/gpu/drm/panel/panel-truly-nt35597.c > > b/drivers/gpu/drm/panel/panel-truly-nt35597.c > > index fc2a66c53db4..aa7153fd3be4 100644 > > --- a/drivers/gpu/drm/panel/panel-truly-nt35597.c > > +++ b/drivers/gpu/drm/panel/panel-truly-nt35597.c > > @@ -280,6 +280,7 @@ static int truly_35597_power_on(struct truly_nt35597 > > *ctx) > > gpiod_set_value(ctx->reset_gpio, 1); > > usleep_range(1, 2); > > gpiod_set_value(ctx->reset_gpio, 0); > > + usleep_range(1, 2); > > > > return 0; > > } > > -- > > QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member > > of Code Aurora Forum, hosted by The Linux Foundation > > > > ___ > > dri-devel mailing list > > dri-devel@lists.freedesktop.org > > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH] of/device: add blacklist for iommu dma_ops
On Mon, Jun 3, 2019 at 4:14 PM Rob Clark wrote: > > On Mon, Jun 3, 2019 at 12:57 AM Vivek Gautam > wrote: > > > > > > > > On 6/3/2019 11:50 AM, Tomasz Figa wrote: > > > On Mon, Jun 3, 2019 at 4:40 AM Rob Clark wrote: > > >> On Fri, May 10, 2019 at 7:35 AM Rob Clark wrote: > > >>> On Tue, Dec 4, 2018 at 2:29 PM Rob Herring wrote: > > >>>> On Sat, Dec 1, 2018 at 10:54 AM Rob Clark wrote: > > >>>>> This solves a problem we see with drm/msm, caused by getting > > >>>>> iommu_dma_ops while we attach our own domain and manage it directly at > > >>>>> the iommu API level: > > >>>>> > > >>>>>[0038] user address but active_mm is swapper > > >>>>>Internal error: Oops: 9605 [#1] PREEMPT SMP > > >>>>>Modules linked in: > > >>>>>CPU: 7 PID: 70 Comm: kworker/7:1 Tainted: GW > > >>>>> 4.19.3 #90 > > >>>>>Hardware name: xxx (DT) > > >>>>>Workqueue: events deferred_probe_work_func > > >>>>>pstate: 80c9 (Nzcv daif +PAN +UAO) > > >>>>>pc : iommu_dma_map_sg+0x7c/0x2c8 > > >>>>>lr : iommu_dma_map_sg+0x40/0x2c8 > > >>>>>sp : ff80095eb4f0 > > >>>>>x29: ff80095eb4f0 x28: > > >>>>>x27: ffc0f9431578 x26: > > >>>>>x25: x24: 0003 > > >>>>>x23: 0001 x22: ffc0fa9ac010 > > >>>>>x21: x20: ffc0fab40980 > > >>>>>x19: ffc0fab40980 x18: 0003 > > >>>>>x17: 01c4 x16: 0007 > > >>>>>x15: 000e x14: > > >>>>>x13: x12: 0028 > > >>>>>x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f > > >>>>>x9 : x8 : ffc0fab409a0 > > >>>>>x7 : x6 : 0002 > > >>>>>x5 : 0001 x4 : > > >>>>>x3 : 0001 x2 : 0002 > > >>>>>x1 : ffc0f9431578 x0 : > > >>>>>Process kworker/7:1 (pid: 70, stack limit = 0x17d08ffb) > > >>>>>Call trace: > > >>>>> iommu_dma_map_sg+0x7c/0x2c8 > > >>>>> __iommu_map_sg_attrs+0x70/0x84 > > >>>>> get_pages+0x170/0x1e8 > > >>>>> msm_gem_get_iova+0x8c/0x128 > > >>>>> _msm_gem_kernel_new+0x6c/0xc8 > > >>>>> msm_gem_kernel_new+0x4c/0x58 > > >>>>> dsi_tx_buf_alloc_6g+0x4c/0x8c > > >>>>> msm_dsi_host_modeset_init+0xc8/0x108 > > >>>>> msm_dsi_modeset_init+0x54/0x18c > > >>>>> _dpu_kms_drm_obj_init+0x430/0x474 > > >>>>> dpu_kms_hw_init+0x5f8/0x6b4 > > >>>>> msm_drm_bind+0x360/0x6c8 > > >>>>> try_to_bring_up_master.part.7+0x28/0x70 > > >>>>> component_master_add_with_match+0xe8/0x124 > > >>>>> msm_pdev_probe+0x294/0x2b4 > > >>>>> platform_drv_probe+0x58/0xa4 > > >>>>> really_probe+0x150/0x294 > > >>>>> driver_probe_device+0xac/0xe8 > > >>>>> __device_attach_driver+0xa4/0xb4 > > >>>>> bus_for_each_drv+0x98/0xc8 > > >>>>> __device_attach+0xac/0x12c > > >>>>> device_initial_probe+0x24/0x30 > > >>>>> bus_probe_device+0x38/0x98 > > >>>>> deferred_probe_work_func+0x78/0xa4 > > >>>>> process_one_work+0x24c/0x3dc > > >>>>> worker_thread+0x280/0x360 > > >>>>> kthread+0x134/0x13c > > >>>>> ret_from_fork+0x10/0x18 > > >>>>>Code: d284 91000725 6b17039f 5400048a (f9401f40) > > >>>>>---[ end trace f22dda57f3648e2c ]--- > > >>>>>Kernel panic - not syncing: Fatal exception > > >>>>>SMP: stopping secondary CPUs > > >>>>>Kernel Offset: disable
Re: [PATCH] of/device: add blacklist for iommu dma_ops
On Mon, Jun 3, 2019 at 4:47 PM Christoph Hellwig wrote: > > If you (and a few others actors in the thread) want people to actually > read what you wrote please follow proper mailing list ettiquette. I've > given up on reading all the recent mails after scrolling through two > pages of full quotes. Apologies for not cutting down the quoted text. I will be more careful next time onwards. Regards Vivek -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Re: [PATCH] of/device: add blacklist for iommu dma_ops
On 6/3/2019 11:50 AM, Tomasz Figa wrote: On Mon, Jun 3, 2019 at 4:40 AM Rob Clark wrote: On Fri, May 10, 2019 at 7:35 AM Rob Clark wrote: On Tue, Dec 4, 2018 at 2:29 PM Rob Herring wrote: On Sat, Dec 1, 2018 at 10:54 AM Rob Clark wrote: This solves a problem we see with drm/msm, caused by getting iommu_dma_ops while we attach our own domain and manage it directly at the iommu API level: [0038] user address but active_mm is swapper Internal error: Oops: 9605 [#1] PREEMPT SMP Modules linked in: CPU: 7 PID: 70 Comm: kworker/7:1 Tainted: GW 4.19.3 #90 Hardware name: xxx (DT) Workqueue: events deferred_probe_work_func pstate: 80c9 (Nzcv daif +PAN +UAO) pc : iommu_dma_map_sg+0x7c/0x2c8 lr : iommu_dma_map_sg+0x40/0x2c8 sp : ff80095eb4f0 x29: ff80095eb4f0 x28: x27: ffc0f9431578 x26: x25: x24: 0003 x23: 0001 x22: ffc0fa9ac010 x21: x20: ffc0fab40980 x19: ffc0fab40980 x18: 0003 x17: 01c4 x16: 0007 x15: 000e x14: x13: x12: 0028 x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f x9 : x8 : ffc0fab409a0 x7 : x6 : 0002 x5 : 0001 x4 : x3 : 0001 x2 : 0002 x1 : ffc0f9431578 x0 : Process kworker/7:1 (pid: 70, stack limit = 0x17d08ffb) Call trace: iommu_dma_map_sg+0x7c/0x2c8 __iommu_map_sg_attrs+0x70/0x84 get_pages+0x170/0x1e8 msm_gem_get_iova+0x8c/0x128 _msm_gem_kernel_new+0x6c/0xc8 msm_gem_kernel_new+0x4c/0x58 dsi_tx_buf_alloc_6g+0x4c/0x8c msm_dsi_host_modeset_init+0xc8/0x108 msm_dsi_modeset_init+0x54/0x18c _dpu_kms_drm_obj_init+0x430/0x474 dpu_kms_hw_init+0x5f8/0x6b4 msm_drm_bind+0x360/0x6c8 try_to_bring_up_master.part.7+0x28/0x70 component_master_add_with_match+0xe8/0x124 msm_pdev_probe+0x294/0x2b4 platform_drv_probe+0x58/0xa4 really_probe+0x150/0x294 driver_probe_device+0xac/0xe8 __device_attach_driver+0xa4/0xb4 bus_for_each_drv+0x98/0xc8 __device_attach+0xac/0x12c device_initial_probe+0x24/0x30 bus_probe_device+0x38/0x98 deferred_probe_work_func+0x78/0xa4 process_one_work+0x24c/0x3dc worker_thread+0x280/0x360 kthread+0x134/0x13c ret_from_fork+0x10/0x18 Code: d284 91000725 6b17039f 5400048a (f9401f40) ---[ end trace f22dda57f3648e2c ]--- Kernel panic - not syncing: Fatal exception SMP: stopping secondary CPUs Kernel Offset: disabled CPU features: 0x0,22802a18 Memory Limit: none The problem is that when drm/msm does it's own iommu_attach_device(), now the domain returned by iommu_get_domain_for_dev() is drm/msm's domain, and it doesn't have domain->iova_cookie. We kind of avoided this problem prior to sdm845/dpu because the iommu was attached to the mdp node in dt, which is a child of the toplevel mdss node (which corresponds to the dev passed in dma_map_sg()). But with sdm845, now the iommu is attached at the mdss level so we hit the iommu_dma_ops in dma_map_sg(). But auto allocating/attaching a domain before the driver is probed was already a blocking problem for enabling per-context pagetables for the GPU. This problem is also now solved with this patch. Fixes: 97890ba9289c dma-mapping: detect and configure IOMMU in of_dma_configure Tested-by: Douglas Anderson Signed-off-by: Rob Clark --- This is an alternative/replacement for [1]. What it lacks in elegance it makes up for in practicality ;-) [1] https://patchwork.freedesktop.org/patch/264930/ drivers/of/device.c | 22 ++ 1 file changed, 22 insertions(+) diff --git a/drivers/of/device.c b/drivers/of/device.c index 5957cd4fa262..15ffee00fb22 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -72,6 +72,14 @@ int of_device_add(struct platform_device *ofdev) return device_add(>dev); } +static const struct of_device_id iommu_blacklist[] = { + { .compatible = "qcom,mdp4" }, + { .compatible = "qcom,mdss" }, + { .compatible = "qcom,sdm845-mdss" }, + { .compatible = "qcom,adreno" }, + {} +}; Not completely clear to whether this is still needed or not, but this really won't scale. Why can't the driver for these devices override whatever has been setup by default? fwiw, at the moment it is not needed, but it will become needed again to implement per-context pagetables (although I suppose for this we only need to blacklist qcom,adreno and not also the display nodes). So, another case I've come across, on the display side.. I'm working on handling the case where bootloader enables display (and takes iommu out of reset).. as soon as DMA domain gets attached we get iommu faults, because bootloader has
[PATCH 1/1] drm/panel: truly: Add additional delay after pulling down reset gpio
MTP SDM845 panel seems to need additional delay to bring panel to a workable state. Running modetest without this change displays blurry artifacts. Signed-off-by: Vivek Gautam --- drivers/gpu/drm/panel/panel-truly-nt35597.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-truly-nt35597.c b/drivers/gpu/drm/panel/panel-truly-nt35597.c index fc2a66c53db4..aa7153fd3be4 100644 --- a/drivers/gpu/drm/panel/panel-truly-nt35597.c +++ b/drivers/gpu/drm/panel/panel-truly-nt35597.c @@ -280,6 +280,7 @@ static int truly_35597_power_on(struct truly_nt35597 *ctx) gpiod_set_value(ctx->reset_gpio, 1); usleep_range(1, 2); gpiod_set_value(ctx->reset_gpio, 0); + usleep_range(1, 2); return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
[PATCH 1/1] drm/prime: Use sg_dma_len() macro to get sg's length
After mapping a sg list we should use sg_dma_address(), and sg_dma_len() macros to access sg->address and sg->length. Fix the same for sg->length in drm_prime_sg_to_page_addr_arrays(). Signed-off-by: Vivek Gautam --- This came while debugging one dmabuf import issue that we are seeing on sdm845 target. The dmabuf which is prepared by video (venus in this case), is imported by drm device. The import call flow looks like follows: drm_gem_prime_import() - drm_gem_prime_import_dev() - dma_buf_attach() & dma_buf_map_attachment() - From dma_buf_map_attachment() - vb2_dma_sg_dmabuf_ops_map() - dma_map_sg(): this updates the sg->nents. From debugging, the sg table mapping results in sg's 'nents' to be less that the original nents. Now drm device prepares the page information based on this sg table, and messes up with the mappings, and we start seeing random crashes as below from drm's memory space. Although this change isn't helping to fix the issue currently, but this fix seems the right thing to do. One thing to notice is that, if we restore the sg->nents to sg->orig_nents in vb2_dma_sg_dmabuf_ops_map(), we don't see the below corruptions. Any pointers on this will be highly appreciated. Thanks. -- [ 338.070558] Unable to handle kernel paging request at virtual address 4038 [ 338.078751] Mem abort info: [ 338.081671] ESR = 0x9604 [ 338.084860] Exception class = DABT (current EL), IL = 32 bits [ 338.090972] SET = 0, FnV = 0 [ 338.094139] EA = 0, S1PTW = 0 [ 338.097393] Data abort info: [ 338.100375] ISV = 0, ISS = 0x0004 [ 338.104362] CM = 0, WnR = 0 [ 338.107446] [4038] address between user and kernel address ranges [ 338.114801] Internal error: Oops: 9604 [#1] PREEMPT SMP [ 338.120527] Modules linked in: rfcomm uinput cdc_ether venus_dec venus_enc usbnet videobuf2_dma_sg videobuf2_memops hci_uart btqca bluetooth r8152 mii ath10k_snoc venus_core ath10k_core v4l2_mem2mem videobuf2_v4l2 videobuf2_common ath mac80211 ecdh_generic qcom_q6v5_mss lzo lzo_compress qcom_q6v5_adsp qcom_common qcom_q6v5 zram bridge stp llc ipt_MASQUERADE fuse snd_seq_dummy snd_seq snd_seq_device cfg80211 joydev [ 338.158192] CPU: 4 PID: 3235 Comm: chrome Tainted: GW 4.19.0 #2 [ 338.165700] Hardware name: Google Cheza (rev1) (DT) [ 338.170720] pstate: 8049 (Nzcv daif +PAN -UAO) [ 338.175660] pc : drm_mm_insert_node_in_range+0xfc/0x348 [ 338.181035] lr : drm_mm_insert_node_in_range+0x24/0x348 [ 338.186407] sp : ff8013033b30 [ 338.189816] x29: ff8013033bd0 x28: ff8008591894 [ 338.195275] x27: 0010 x26: [ 338.200734] x25: x24: [ 338.206194] x23: x22: ffc0f48b7e08 [ 338.211656] x21: x20: 005d [ 338.217118] x19: x18: [ 338.222581] x17: x16: [ 338.228046] x15: x14: [ 338.233511] x13: 0001 x12: ffc0b1da7200 [ 338.238978] x11: 0010 x10: 0010 [ 338.244437] x9 : 0008 x8 : 4000 [ 338.249898] x7 : x6 : [ 338.255361] x5 : x4 : [ 338.260823] x3 : x2 : 005d [ 338.266285] x1 : ffc0b1da7100 x0 : ffc0b0215800 [ 338.271748] Process chrome (pid: 3235, stack limit = 0x0900f416) [ 338.278628] Call trace: [ 338.281151] drm_mm_insert_node_in_range+0xfc/0x348 [ 338.286168] msm_gem_map_vma+0x60/0xdc [ 338.290022] msm_gem_get_iova+0xb4/0xf4 [ 338.293967] msm_ioctl_gem_info+0x90/0xdc [ 338.298089] drm_ioctl_kernel+0xa8/0xe8 [ 338.302043] drm_ioctl+0x218/0x384 [ 338.305547] drm_compat_ioctl+0xd8/0xe8 [ 338.309503] __arm64_compat_sys_ioctl+0x134/0x20c [ 338.314339] el0_svc_common+0xa0/0xf0 [ 338.318108] el0_svc_compat_handler+0x2c/0x38 [ 338.322588] el0_svc_compat+0x8/0x18 [ 338.326274] Code: f94066c8 aa1f03e0 321d03e9 321c03ea (f9401d0b) [ 338.332538] ---[ end trace 5c09e60869887d87 ]--- [ 338.354633] Kernel panic - not syncing: Fatal exception [ 338.360018] SMP: stopping secondary CPUs [ 338.364179] Kernel Offset: disabled [ 338.367779] CPU features: 0x0,22802a18 [ 338.371643] Memory Limit: none -- drivers/gpu/drm/drm_prime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 231e3f6d5f41..0d9b1c43523a 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -945,7 +945,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, index = 0; for_each_sg(sgt->sgl, sg, sgt->nents, count) { - len = sg->length; + len = sg_dma_length(sg); page = sg_page(sg);
[PATCH v2 1/1] drm/prime: Use sg_dma_len() macro to get sg's length
After mapping a sg list the we should use sg_dma_address() and sg_dma_len() macros to access sg->address and sg->length. Fix the same for sg->length in drm_prime_sg_to_page_addr_arrays(). Signed-off-by: Vivek Gautam --- Changes since v1: - Fixed compilation error: replaced sg_dma_length() with sg_dma_len(). This came while debugging one dmabuf import issue that we are seeing on sdm845 target. The dmabuf which is prepared by video (venus in this case), is imported by drm device. The import call flow looks like follows: drm_gem_prime_import() - drm_gem_prime_import_dev() - dma_buf_attach() & dma_buf_map_attachment() - From dma_buf_map_attachment() - vb2_dma_sg_dmabuf_ops_map() - dma_map_sg(): this updates the sg->nents. From debugging, the sg table mapping results in sg's 'nents' to be less that the original nents. Now drm device prepares the page information based on this sg table, and messes up with the mappings, and we start seeing random crashes as below from drm's memory space. Although this change isn't helping to fix the issue currently, but this fix seems the right thing to do. One thing to notice is that, if we restore the sg->nents to sg->orig_nents in vb2_dma_sg_dmabuf_ops_map(), we don't see the below corruptions. Any pointers on this will be highly appreciated. Thanks. -- [ 338.070558] Unable to handle kernel paging request at virtual address 4038 [ 338.078751] Mem abort info: [ 338.081671] ESR = 0x9604 [ 338.084860] Exception class = DABT (current EL), IL = 32 bits [ 338.090972] SET = 0, FnV = 0 [ 338.094139] EA = 0, S1PTW = 0 [ 338.097393] Data abort info: [ 338.100375] ISV = 0, ISS = 0x0004 [ 338.104362] CM = 0, WnR = 0 [ 338.107446] [4038] address between user and kernel address ranges [ 338.114801] Internal error: Oops: 9604 [#1] PREEMPT SMP [ 338.120527] Modules linked in: rfcomm uinput cdc_ether venus_dec venus_enc usbnet videobuf2_dma_sg videobuf2_memops hci_uart btqca bluetooth r8152 mii ath10k_snoc venus_core ath10k_core v4l2_mem2mem videobuf2_v4l2 videobuf2_common ath mac80211 ecdh_generic qcom_q6v5_mss lzo lzo_compress qcom_q6v5_adsp qcom_common qcom_q6v5 zram bridge stp llc ipt_MASQUERADE fuse snd_seq_dummy snd_seq snd_seq_device cfg80211 joydev [ 338.158192] CPU: 4 PID: 3235 Comm: chrome Tainted: GW 4.19.0 #2 [ 338.165700] Hardware name: Google Cheza (rev1) (DT) [ 338.170720] pstate: 8049 (Nzcv daif +PAN -UAO) [ 338.175660] pc : drm_mm_insert_node_in_range+0xfc/0x348 [ 338.181035] lr : drm_mm_insert_node_in_range+0x24/0x348 [ 338.186407] sp : ff8013033b30 [ 338.189816] x29: ff8013033bd0 x28: ff8008591894 [ 338.195275] x27: 0010 x26: [ 338.200734] x25: x24: [ 338.206194] x23: x22: ffc0f48b7e08 [ 338.211656] x21: x20: 005d [ 338.217118] x19: x18: [ 338.222581] x17: x16: [ 338.228046] x15: x14: [ 338.233511] x13: 0001 x12: ffc0b1da7200 [ 338.238978] x11: 0010 x10: 0010 [ 338.244437] x9 : 0008 x8 : 4000 [ 338.249898] x7 : x6 : [ 338.255361] x5 : x4 : [ 338.260823] x3 : x2 : 005d [ 338.266285] x1 : ffc0b1da7100 x0 : ffc0b0215800 [ 338.271748] Process chrome (pid: 3235, stack limit = 0x0900f416) [ 338.278628] Call trace: [ 338.281151] drm_mm_insert_node_in_range+0xfc/0x348 [ 338.286168] msm_gem_map_vma+0x60/0xdc [ 338.290022] msm_gem_get_iova+0xb4/0xf4 [ 338.293967] msm_ioctl_gem_info+0x90/0xdc [ 338.298089] drm_ioctl_kernel+0xa8/0xe8 [ 338.302043] drm_ioctl+0x218/0x384 [ 338.305547] drm_compat_ioctl+0xd8/0xe8 [ 338.309503] __arm64_compat_sys_ioctl+0x134/0x20c [ 338.314339] el0_svc_common+0xa0/0xf0 [ 338.318108] el0_svc_compat_handler+0x2c/0x38 [ 338.322588] el0_svc_compat+0x8/0x18 [ 338.326274] Code: f94066c8 aa1f03e0 321d03e9 321c03ea (f9401d0b) [ 338.332538] ---[ end trace 5c09e60869887d87 ]--- [ 338.354633] Kernel panic - not syncing: Fatal exception [ 338.360018] SMP: stopping secondary CPUs [ 338.364179] Kernel Offset: disabled [ 338.367779] CPU features: 0x0,22802a18 [ 338.371643] Memory Limit: none -- drivers/gpu/drm/drm_prime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 231e3f6d5f41..aa87ba9c0d7b 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -945,7 +945,7 @@ int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages, index = 0; for_each_sg(sgt->sgl, sg, sgt->nents, count) { - len = sg->length; +
Re: [PATCH 1/1] drm/prime: Use sg_dma_len() macro to get sg's length
On Mon, Jan 7, 2019 at 4:14 PM kbuild test robot wrote: > > Hi Vivek, > > Thank you for the patch! Yet something to improve: > > [auto build test ERROR on linus/master] > [also build test ERROR on v5.0-rc1 next-20190107] > [if your patch is applied to the wrong git tree, please drop us a note to > help improve the system] > > url: > https://github.com/0day-ci/linux/commits/Vivek-Gautam/drm-prime-Use-sg_dma_len-macro-to-get-sg-s-length/20190107-181350 > config: x86_64-randconfig-x013-201901 (attached as .config) > compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 > reproduce: > # save the attached .config to linux build tree > make ARCH=x86_64 > > All errors (new ones prefixed by >>): > >drivers/gpu/drm/drm_prime.c: In function > 'drm_prime_sg_to_page_addr_arrays': > >> drivers/gpu/drm/drm_prime.c:948:9: error: implicit declaration of function > >> 'sg_dma_length'; did you mean 'sg_dma_len'? > >> [-Werror=implicit-function-declaration] > len = sg_dma_length(sg); > ^ > sg_dma_len Sorry, my fat finger :( This should be as suggested - sg_dma_len(). Thanks Vivek >cc1: some warnings being treated as errors > > vim +948 drivers/gpu/drm/drm_prime.c > >926 >927 /** >928 * drm_prime_sg_to_page_addr_arrays - convert an sg table into a page > array >929 * @sgt: scatter-gather table to convert >930 * @pages: optional array of page pointers to store the page array in >931 * @addrs: optional array to store the dma bus address of each page >932 * @max_entries: size of both the passed-in arrays >933 * >934 * Exports an sg table into an array of pages and addresses. This is > currently >935 * required by the TTM driver in order to do correct fault handling. >936 */ >937 int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct > page **pages, >938 dma_addr_t *addrs, int > max_entries) >939 { >940 unsigned count; >941 struct scatterlist *sg; >942 struct page *page; >943 u32 len, index; >944 dma_addr_t addr; >945 >946 index = 0; >947 for_each_sg(sgt->sgl, sg, sgt->nents, count) { > > 948 len = sg_dma_length(sg); >949 page = sg_page(sg); >950 addr = sg_dma_address(sg); >951 >952 while (len > 0) { >953 if (WARN_ON(index >= max_entries)) >954 return -1; >955 if (pages) >956 pages[index] = page; >957 if (addrs) >958 addrs[index] = addr; >959 >960 page++; >961 addr += PAGE_SIZE; >962 len -= PAGE_SIZE; >963 index++; >964 } >965 } >966 return 0; >967 } >968 EXPORT_SYMBOL(drm_prime_sg_to_page_addr_arrays); >969 > > --- > 0-DAY kernel test infrastructureOpen Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH] of/device: add blacklist for iommu dma_ops
On Mon, Dec 3, 2018 at 7:56 PM Rob Clark wrote: > > On Mon, Dec 3, 2018 at 7:45 AM Robin Murphy wrote: > > > > Hi Rob, > > > > On 01/12/2018 16:53, Rob Clark wrote: > > > This solves a problem we see with drm/msm, caused by getting > > > iommu_dma_ops while we attach our own domain and manage it directly at > > > the iommu API level: > > > > > >[0038] user address but active_mm is swapper > > >Internal error: Oops: 9605 [#1] PREEMPT SMP > > >Modules linked in: > > >CPU: 7 PID: 70 Comm: kworker/7:1 Tainted: GW 4.19.3 #90 > > >Hardware name: xxx (DT) > > >Workqueue: events deferred_probe_work_func > > >pstate: 80c9 (Nzcv daif +PAN +UAO) > > >pc : iommu_dma_map_sg+0x7c/0x2c8 > > >lr : iommu_dma_map_sg+0x40/0x2c8 > > >sp : ff80095eb4f0 > > >x29: ff80095eb4f0 x28: > > >x27: ffc0f9431578 x26: > > >x25: x24: 0003 > > >x23: 0001 x22: ffc0fa9ac010 > > >x21: x20: ffc0fab40980 > > >x19: ffc0fab40980 x18: 0003 > > >x17: 01c4 x16: 0007 > > >x15: 000e x14: > > >x13: x12: 0028 > > >x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f > > >x9 : x8 : ffc0fab409a0 > > >x7 : x6 : 0002 > > >x5 : 0001 x4 : > > >x3 : 0001 x2 : 0002 > > >x1 : ffc0f9431578 x0 : > > >Process kworker/7:1 (pid: 70, stack limit = 0x17d08ffb) > > >Call trace: > > > iommu_dma_map_sg+0x7c/0x2c8 > > > __iommu_map_sg_attrs+0x70/0x84 > > > get_pages+0x170/0x1e8 > > > msm_gem_get_iova+0x8c/0x128 > > > _msm_gem_kernel_new+0x6c/0xc8 > > > msm_gem_kernel_new+0x4c/0x58 > > > dsi_tx_buf_alloc_6g+0x4c/0x8c > > > msm_dsi_host_modeset_init+0xc8/0x108 > > > msm_dsi_modeset_init+0x54/0x18c > > > _dpu_kms_drm_obj_init+0x430/0x474 > > > dpu_kms_hw_init+0x5f8/0x6b4 > > > msm_drm_bind+0x360/0x6c8 > > > try_to_bring_up_master.part.7+0x28/0x70 > > > component_master_add_with_match+0xe8/0x124 > > > msm_pdev_probe+0x294/0x2b4 > > > platform_drv_probe+0x58/0xa4 > > > really_probe+0x150/0x294 > > > driver_probe_device+0xac/0xe8 > > > __device_attach_driver+0xa4/0xb4 > > > bus_for_each_drv+0x98/0xc8 > > > __device_attach+0xac/0x12c > > > device_initial_probe+0x24/0x30 > > > bus_probe_device+0x38/0x98 > > > deferred_probe_work_func+0x78/0xa4 > > > process_one_work+0x24c/0x3dc > > > worker_thread+0x280/0x360 > > > kthread+0x134/0x13c > > > ret_from_fork+0x10/0x18 > > >Code: d284 91000725 6b17039f 5400048a (f9401f40) > > >---[ end trace f22dda57f3648e2c ]--- > > >Kernel panic - not syncing: Fatal exception > > >SMP: stopping secondary CPUs > > >Kernel Offset: disabled > > >CPU features: 0x0,22802a18 > > >Memory Limit: none > > > > > > The problem is that when drm/msm does it's own iommu_attach_device(), > > > now the domain returned by iommu_get_domain_for_dev() is drm/msm's > > > domain, and it doesn't have domain->iova_cookie. > > > > Does this crash still happen with 4.20-rc? Because as of 6af588fed391 it > > really shouldn't. > > > > > We kind of avoided this problem prior to sdm845/dpu because the iommu > > > was attached to the mdp node in dt, which is a child of the toplevel > > > mdss node (which corresponds to the dev passed in dma_map_sg()). But > > > with sdm845, now the iommu is attached at the mdss level so we hit the > > > iommu_dma_ops in dma_map_sg(). > > > > > > But auto allocating/attaching a domain before the driver is probed was > > > already a blocking problem for enabling per-context pagetables for the > > > GPU. This problem is also now solved with this patch. > > > > s/solved/worked around/ > > > > If you want a guarantee of actually getting a specific hardware context > > allocated for a given domain, there needs to be code in the IOMMU driver > > to understand and honour that. Implicitly depending on whatever happens > > to fall out of current driver behaviour on current systems is not a real > > solution. > > > > > Fixes: 97890ba9289c dma-mapping: detect and configure IOMMU in > > > of_dma_configure > > > > That's rather misleading, since the crash described above depends on at > > least two other major changes which came long after that commit. > > > > It's not that I don't understand exactly what you want here - just that > > this commit message isn't a coherent justification for that ;) > > > > > Tested-by: Douglas Anderson > > > Signed-off-by: Rob Clark > > > --- > > > This is an alternative/replacement for [1]. What it lacks in elegance > > > it makes up for in practicality ;-) > > > > > > [1]
Re: [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*
Hi Tomasz, On Wed, Nov 28, 2018 at 8:39 AM Tomasz Figa wrote: > > Hi Vivek, > > On Tue, Nov 27, 2018 at 6:37 AM Vivek Gautam > wrote: > > > > dma_map_sg() expects a DMA domain. However, the drm devices > > have been traditionally using unmanaged iommu domain which > > is non-dma type. Using dma mapping APIs with that domain is bad. > > > > Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}() > > to do the cache maintenance. > > > > Signed-off-by: Vivek Gautam > > Suggested-by: Tomasz Figa > > Cc: Rob Clark > > Cc: Jordan Crouse > > Cc: Sean Paul > > --- > > > > Changes since v1: > > - Addressed Jordan's and Tomasz's comments for > >- moving sg dma addresses preparation out of the coditional > > check to the main path so we do it irrespective of whether > > the buffer is cached or uncached. > >- Enhance the comment to explain this dma addresses prepartion. > > > > Thanks for the patch. Some comments inline. > > > drivers/gpu/drm/msm/msm_gem.c | 31 ++- > > 1 file changed, 22 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c > > index 00c795ced02c..1811ac23a31c 100644 > > --- a/drivers/gpu/drm/msm/msm_gem.c > > +++ b/drivers/gpu/drm/msm/msm_gem.c > > @@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj) > > struct drm_device *dev = obj->dev; > > struct page **p; > > int npages = obj->size >> PAGE_SHIFT; > > + struct scatterlist *s; > > + int i; > > > > if (use_pages(obj)) > > p = drm_gem_get_pages(obj); > > @@ -104,12 +106,21 @@ static struct page **get_pages(struct drm_gem_object > > *obj) > > return ptr; > > } > > > > - /* For non-cached buffers, ensure the new pages are clean > > + /* > > +* dma_sync_sg_*() flush the physical pages, so point > > +* sg->dma_address to the physical ones for the right > > behavior. > > The two halves of the sequence don't really relate to each other. An > sglist has the `page` field for the purpose of pointing to physical > pages. The `dma_address` field is for DMA addresses, which are not > equivalent to physical addresses. I'd rewrite it like this; I guess I was lenient in using the physical pages and dma address words. > > /* > * Some implementations of the DMA mapping ops expect > * physical addresses of the pages to be stored as DMA > * addresses of the sglist entries. To work around it, > * set them here explicitly. > */ Will update as suggested. > > +*/ > > + for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i) > > + sg_dma_address(s) = sg_phys(s); > > + > > + /* > > +* For non-cached buffers, ensure the new pages are clean > > * because display controller, GPU, etc. are not coherent: > > */ > > - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) > > - dma_map_sg(dev->dev, msm_obj->sgt->sgl, > > - msm_obj->sgt->nents, > > DMA_BIDIRECTIONAL); > > + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) > > + dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl, > > + msm_obj->sgt->nents, > > + DMA_TO_DEVICE); > > Why changing from DMA_BIDIRECTIONAL? Yea, I went back and checked that we wanted to do this for both. Will keep DMA_BIDIRECTIONAL intact. > > > } > > > > return msm_obj->pages; > > @@ -133,14 +144,16 @@ static void put_pages(struct drm_gem_object *obj) > > > > if (msm_obj->pages) { > > if (msm_obj->sgt) { > > - /* For non-cached buffers, ensure the new > > + /* > > +* For non-cached buffers, ensure the new > > * pages are clean because display controller, > > * GPU, etc. are not coherent: > > */ > > - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) > >
[PATCH v3 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*
dma_map_sg() expects a DMA domain. However, the drm devices have been traditionally using unmanaged iommu domain which is non-dma type. Using dma mapping APIs with that domain is bad. Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}() to do the cache maintenance. Signed-off-by: Vivek Gautam Suggested-by: Tomasz Figa Cc: Rob Clark Cc: Christoph Hellwig Cc: Robin Murphy Cc: Jordan Crouse Cc: Sean Paul --- Changes since v2: - Addressed Tomasz's comment to keep DMA_BIDIRECTIONAL dma direction flag intact. - Updated comment for sg's dma-address assignment as per Tomasz' suggestion. drivers/gpu/drm/msm/msm_gem.c | 33 - 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 00c795ced02c..7048e9fe00c6 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj) struct drm_device *dev = obj->dev; struct page **p; int npages = obj->size >> PAGE_SHIFT; + struct scatterlist *s; + int i; if (use_pages(obj)) p = drm_gem_get_pages(obj); @@ -104,12 +106,23 @@ static struct page **get_pages(struct drm_gem_object *obj) return ptr; } - /* For non-cached buffers, ensure the new pages are clean + /* +* Some implementations of the DMA mapping ops expect +* physical addresses of the pages to be stored as DMA +* addresses of the sglist entries. To work around it, +* set them here explicitly. +*/ + for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i) + sg_dma_address(s) = sg_phys(s); + + /* +* For non-cached buffers, ensure the new pages are clean * because display controller, GPU, etc. are not coherent: */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) - dma_map_sg(dev->dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) + dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl, + msm_obj->sgt->nents, + DMA_BIDIRECTIONAL); } return msm_obj->pages; @@ -133,14 +146,16 @@ static void put_pages(struct drm_gem_object *obj) if (msm_obj->pages) { if (msm_obj->sgt) { - /* For non-cached buffers, ensure the new + /* +* For non-cached buffers, ensure the new * pages are clean because display controller, * GPU, etc. are not coherent: */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) - dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl, -msm_obj->sgt->nents, -DMA_BIDIRECTIONAL); + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) + dma_sync_sg_for_cpu(obj->dev->dev, + msm_obj->sgt->sgl, + msm_obj->sgt->nents, + DMA_BIDIRECTIONAL); sg_free_table(msm_obj->sgt); kfree(msm_obj->sgt); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*
On Wed, Nov 28, 2018 at 6:09 PM Rob Clark wrote: > > On Wed, Nov 28, 2018 at 2:39 AM Christoph Hellwig wrote: > > > > > + /* > > > + * dma_sync_sg_*() flush the physical pages, so point > > > + * sg->dma_address to the physical ones for the right > > > behavior. > > > + */ > > > + for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i) > > > + sg_dma_address(s) = sg_phys(s); > > > + > > > > I'm sorry, but this is completely bogus and not acceptable. > > > > The only place that is allowed to initialize sg_dma_address is > > dma_map_sg. If the default dma ops don't work for your setup we have > > major a problem and need to fix the dma api / iommu integration instead > > of hacking around it. > > I agree that the dma/iommu integration is very problematic for drm (in > particular, gpu drivers that use the iommu as an gpu mmu).. Really we > need a way that a driver can opt-out of this, and access the cpu cache > APIs directly, skipping the dma API entirely. But as it is, we've had > to hack around the dma API. I'm not really sure this hack is any > worse than abusing dma_(un)map_sg() for doing cache operations. > > I probably should have paid more attention and nak'd the dma/iommu > integration before it landed. But given that now we are stuck in this > situation, while I'm certainly interested if anyone has some ideas > about how to let drivers opt out of the dma/iommu integration and > bypass the dma API layer, I'm ok with replacing a hack with a less-bad > hack. May I take it as a positive nod to respin the next version? Regards Vivek > > BR, > -R -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*
Hi Christoph , On Wed, Nov 28, 2018 at 1:10 PM Christoph Hellwig wrote: > > > + /* > > + * dma_sync_sg_*() flush the physical pages, so point > > + * sg->dma_address to the physical ones for the right > > behavior. > > + */ > > + for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i) > > + sg_dma_address(s) = sg_phys(s); > > + > > I'm sorry, but this is completely bogus and not acceptable. > > The only place that is allowed to initialize sg_dma_address is > dma_map_sg. If the default dma ops don't work for your setup we have > major a problem and need to fix the dma api / iommu integration instead > of hacking around it. Thanks for reviewing this change. From what I understand the things in drm, we don't use the default iommu-dma domain for drm devices. Rather we allocate a new iommu domain, and therefore we can't use the default dma ops. Hence we need separate dma_sync_sg*() to flush/invalidate the cache. For this we need to initialize the sg's addresses. Please correct me if my understanding is incomplete. Best regards Vivek -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*
dma_map_sg() expects a DMA domain. However, the drm devices have been traditionally using unmanaged iommu domain which is non-dma type. Using dma mapping APIs with that domain is bad. Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}() to do the cache maintenance. Signed-off-by: Vivek Gautam Suggested-by: Tomasz Figa Cc: Rob Clark Cc: Jordan Crouse Cc: Sean Paul --- Changes since v1: - Addressed Jordan's and Tomasz's comments for - moving sg dma addresses preparation out of the coditional check to the main path so we do it irrespective of whether the buffer is cached or uncached. - Enhance the comment to explain this dma addresses prepartion. drivers/gpu/drm/msm/msm_gem.c | 31 ++- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 00c795ced02c..1811ac23a31c 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj) struct drm_device *dev = obj->dev; struct page **p; int npages = obj->size >> PAGE_SHIFT; + struct scatterlist *s; + int i; if (use_pages(obj)) p = drm_gem_get_pages(obj); @@ -104,12 +106,21 @@ static struct page **get_pages(struct drm_gem_object *obj) return ptr; } - /* For non-cached buffers, ensure the new pages are clean + /* +* dma_sync_sg_*() flush the physical pages, so point +* sg->dma_address to the physical ones for the right behavior. +*/ + for_each_sg(msm_obj->sgt->sgl, s, msm_obj->sgt->nents, i) + sg_dma_address(s) = sg_phys(s); + + /* +* For non-cached buffers, ensure the new pages are clean * because display controller, GPU, etc. are not coherent: */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) - dma_map_sg(dev->dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) + dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl, + msm_obj->sgt->nents, + DMA_TO_DEVICE); } return msm_obj->pages; @@ -133,14 +144,16 @@ static void put_pages(struct drm_gem_object *obj) if (msm_obj->pages) { if (msm_obj->sgt) { - /* For non-cached buffers, ensure the new + /* +* For non-cached buffers, ensure the new * pages are clean because display controller, * GPU, etc. are not coherent: */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) - dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl, -msm_obj->sgt->nents, -DMA_BIDIRECTIONAL); + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) + dma_sync_sg_for_cpu(obj->dev->dev, + msm_obj->sgt->sgl, + msm_obj->sgt->nents, + DMA_FROM_DEVICE); sg_free_table(msm_obj->sgt); kfree(msm_obj->sgt); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*
Hi Tomasz, Jordan, On 11/21/2018 9:18 AM, Tomasz Figa wrote: Hi Jordan, Vivek, On Wed, Nov 21, 2018 at 12:41 AM Jordan Crouse wrote: On Tue, Nov 20, 2018 at 03:24:37PM +0530, Vivek Gautam wrote: dma_map_sg() expects a DMA domain. However, the drm devices have been traditionally using unmanaged iommu domain which is non-dma type. Using dma mapping APIs with that domain is bad. Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}() to do the cache maintenance. Signed-off-by: Vivek Gautam Suggested-by: Tomasz Figa --- Tested on an MTP sdm845: https://github.com/vivekgautam1/linux/tree/v4.19/sdm845-mtp-display-working drivers/gpu/drm/msm/msm_gem.c | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 00c795ced02c..d7a7af610803 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj) struct drm_device *dev = obj->dev; struct page **p; int npages = obj->size >> PAGE_SHIFT; + struct scatterlist *s; + int i; if (use_pages(obj)) p = drm_gem_get_pages(obj); @@ -107,9 +109,19 @@ static struct page **get_pages(struct drm_gem_object *obj) /* For non-cached buffers, ensure the new pages are clean * because display controller, GPU, etc. are not coherent: */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) - dma_map_sg(dev->dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) { + /* + * Fake up the SG table so that dma_sync_sg_*() + * can be used to flush the pages associated with it. + */ We aren't really faking. The table is real, we are just slightly abusing the sg_dma_address() which makes this comment a bit misleading. Instead I would probably say something like: /* dma_sync_sg_* flushes pages using sg_dma_address() so point it at the * physical page for the right behavior */ Or something like that. It's actually quite complicated, but I agree that the comment isn't very precise. The cases are as follows: - arm64 iommu_dma_ops use sg_phys() https://elixir.bootlin.com/linux/v4.20-rc3/source/arch/arm64/mm/dma-mapping.c#L599 - swiotlb_dma_ops used on arm64 if no IOMMU is available use sg->dma_address directly: https://elixir.bootlin.com/linux/v4.20-rc3/source/kernel/dma/swiotlb.c#L832 - arm_dma_ops use sg_dma_address(): https://elixir.bootlin.com/linux/v4.20-rc3/source/arch/arm/mm/dma-mapping.c#L1130 - arm iommu_ops use sg_page(): https://elixir.bootlin.com/linux/v4.20-rc3/source/arch/arm/mm/dma-mapping.c#L1869 Sounds like a mess... Thanks for the review. Technically with the below assignment we address all of the above. How about an even simpler version of the suggested comment: /* dma_sync_sg_* flushes physical pages, so point sg->dma_address to * the physical one for the right behavior. */ + for_each_sg(msm_obj->sgt->sgl, s, + msm_obj->sgt->nents, i) + sg_dma_address(s) = sg_phys(s); + I'm wondering - wouldn't we want to do this association for cached buffers to so we could sync them correctly in cpu_prep and cpu_fini? Maybe it wouldn't hurt to put this association in the main path (obviously the sync should stay inside the conditional for uncached buffers). Sure, I will move this out of the conditional check. I guess it wouldn't hurt indeed. Note that cpu_prep/fini seem to be missing the sync call currently. I can't say I understand the usage of cpu_prep and cpu_fini(). But I can add the necessary support if you can point me in the right direction. Thanks Best regards Vivek P.S. Jordan, not sure if it's my Gmail or your email client, but your message had all the recipients in a Reply-to header, except you, so pressing Reply to all in my case led to a message that didn't have you in recipients anymore... Best regards, Tomasz ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*
dma_map_sg() expects a DMA domain. However, the drm devices have been traditionally using unmanaged iommu domain which is non-dma type. Using dma mapping APIs with that domain is bad. Replace dma_map_sg() calls with dma_sync_sg_for_device{|cpu}() to do the cache maintenance. Signed-off-by: Vivek Gautam Suggested-by: Tomasz Figa --- Tested on an MTP sdm845: https://github.com/vivekgautam1/linux/tree/v4.19/sdm845-mtp-display-working drivers/gpu/drm/msm/msm_gem.c | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 00c795ced02c..d7a7af610803 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -81,6 +81,8 @@ static struct page **get_pages(struct drm_gem_object *obj) struct drm_device *dev = obj->dev; struct page **p; int npages = obj->size >> PAGE_SHIFT; + struct scatterlist *s; + int i; if (use_pages(obj)) p = drm_gem_get_pages(obj); @@ -107,9 +109,19 @@ static struct page **get_pages(struct drm_gem_object *obj) /* For non-cached buffers, ensure the new pages are clean * because display controller, GPU, etc. are not coherent: */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) - dma_map_sg(dev->dev, msm_obj->sgt->sgl, - msm_obj->sgt->nents, DMA_BIDIRECTIONAL); + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) { + /* +* Fake up the SG table so that dma_sync_sg_*() +* can be used to flush the pages associated with it. +*/ + for_each_sg(msm_obj->sgt->sgl, s, + msm_obj->sgt->nents, i) + sg_dma_address(s) = sg_phys(s); + + dma_sync_sg_for_device(dev->dev, msm_obj->sgt->sgl, + msm_obj->sgt->nents, + DMA_TO_DEVICE); + } } return msm_obj->pages; @@ -137,10 +149,11 @@ static void put_pages(struct drm_gem_object *obj) * pages are clean because display controller, * GPU, etc. are not coherent: */ - if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED)) - dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl, -msm_obj->sgt->nents, -DMA_BIDIRECTIONAL); + if (msm_obj->flags & (MSM_BO_WC | MSM_BO_UNCACHED)) + dma_sync_sg_for_cpu(obj->dev->dev, + msm_obj->sgt->sgl, + msm_obj->sgt->nents, + DMA_FROM_DEVICE); sg_free_table(msm_obj->sgt); kfree(msm_obj->sgt); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 5/9] arm64: dts: sdm845: Add gpu and gmu device nodes
Hi Jordan, On Mon, Aug 27, 2018 at 8:42 PM Jordan Crouse wrote: > > Add the nodes to describe the Adreno GPU and GMU devices. > > Signed-off-by: Jordan Crouse > --- > arch/arm64/boot/dts/qcom/sdm845.dtsi | 121 +++ > 1 file changed, 121 insertions(+) > > diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi > b/arch/arm64/boot/dts/qcom/sdm845.dtsi > index cdaabeb3c995..10db0ceb3699 100644 > --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi > +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi > @@ -192,6 +192,59 @@ > method = "smc"; > }; > > +gpu_opp_table: adreno-opp-table { > + compatible = "operating-points-v2-qcom-level"; > + > + opp-71000 { > + opp-hz = /bits/ 64 <71000>; > + qcom,level = <416>; > + }; > + > + opp-67500 { > + opp-hz = /bits/ 64 <67500>; > + qcom,level = <384>; > + }; > + > + opp-59600 { > + opp-hz = /bits/ 64 <59600>; > + qcom,level = <320>; > + }; > + > + opp-52000 { > + opp-hz = /bits/ 64 <52000>; > + qcom,level = <256>; > + }; > + > + opp-41400 { > + opp-hz = /bits/ 64 <41400>; > + qcom,level = <192>; > + }; > + > + opp-34200 { > + opp-hz = /bits/ 64 <34200>; > + qcom,level = <128>; > + }; > + > + opp-25700 { > + opp-hz = /bits/ 64 <25700>; > + qcom,level = <64>; > + }; > + }; > + > + gmu_opp_table: adreno-gmu-opp-table { > + compatible = "operating-points-v2-qcom-level"; > + > + opp-4 { > + opp-hz = /bits/ 64 <4>; > + qcom,level = <128>; > + }; > + > + opp-2 { > + opp-hz = /bits/ 64 <2>; > + qcom,level = <48>; > + }; > + }; > + > soc: soc { > #address-cells = <1>; > #size-cells = <1>; > @@ -323,5 +376,73 @@ > status = "disabled"; > }; > }; > + > + adreno_smmu: adreno-smmu@504 { iommu@504 as pointed out by Rob in [1] > + compatible = "qcom,sdm845-smmu-v2", "qcom,smmu-v2"; > + reg = <0x504 0x1>; > + #iommu-cells = <1>; > + #global-interrupts = <2>; > + interrupts = , > + , > + , > + , > + , > + , > + , > + , > + , > + ; > + clocks = < GCC_GPU_MEMNOC_GFX_CLK>, > + < GCC_GPU_CFG_AHB_CLK>; > + clock-names = "bus", "iface"; > + > + power-domains = < GPU_CX_GDSC>; and for this you need to include the gpucc dt-bindings header which is coming from Amit's gpucc driver patch. [1] https://patchwork.kernel.org/patch/10534999/ Best regards Vivek [snip] -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/2] device core: Rename flag AUTOREMOVE to AUTOREMOVE_CONSUMER
On Wed, Jul 4, 2018 at 6:25 PM, Ulf Hansson wrote: > On 27 June 2018 at 14:50, Vivek Gautam wrote: >> Now that we want to add another flag to autoremove the device link >> on supplier unbind, it's fair to rename the existing flag from >> DL_FLAG_AUTOREMOVE to DL_FLAG_AUTOREMOVE_CONSUMER so that we can >> add similar flag for supplier later. >> And, while we are touching device.h, fix a doc build warning. >> >> Signed-off-by: Vivek Gautam >> Cc: Lukas Wunner >> Cc: Jonathan Corbet >> Cc: Greg Kroah-Hartman >> Cc: Thierry Reding >> Cc: David Airlie >> Cc: Jonathan Hunter >> Cc: Philipp Zabel >> Cc: Shawn Guo >> Cc: Sascha Hauer >> Cc: Robin Murphy >> Cc: linux-...@vger.kernel.org >> Cc: dri-devel@lists.freedesktop.org >> Cc: linux-te...@vger.kernel.org >> Cc: linux-arm-ker...@lists.infradead.org >> Cc: linux...@vger.kernel.org >> Cc: linux-arm-...@vger.kernel.org > > Reviewed-by: Ulf Hansson Thank you Ulf for reviewing the series. Best regards Vivek > > Kind regards > Uffe > >> --- >> Documentation/driver-api/device_link.rst | 8 >> drivers/base/core.c | 15 --- >> drivers/gpu/drm/tegra/dc.c | 2 +- >> drivers/gpu/ipu-v3/ipu-pre.c | 3 ++- >> drivers/gpu/ipu-v3/ipu-prg.c | 3 ++- >> drivers/soc/imx/gpc.c| 2 +- >> include/linux/device.h | 12 ++-- >> 7 files changed, 24 insertions(+), 21 deletions(-) >> >> diff --git a/Documentation/driver-api/device_link.rst >> b/Documentation/driver-api/device_link.rst >> index 70e328e16aad..a005b904a264 100644 >> --- a/Documentation/driver-api/device_link.rst >> +++ b/Documentation/driver-api/device_link.rst >> @@ -81,10 +81,10 @@ integration is desired. >> Two other flags are specifically targeted at use cases where the device >> link is added from the consumer's ``->probe`` callback: >> ``DL_FLAG_RPM_ACTIVE`` >> can be specified to runtime resume the supplier upon addition of the >> -device link. ``DL_FLAG_AUTOREMOVE`` causes the device link to be >> automatically >> -purged when the consumer fails to probe or later unbinds. This obviates >> -the need to explicitly delete the link in the ``->remove`` callback or in >> -the error path of the ``->probe`` callback. >> +device link. ``DL_FLAG_AUTOREMOVE_CONSUMER`` causes the device link to be >> +automatically purged when the consumer fails to probe or later unbinds. >> +This obviates the need to explicitly delete the link in the ``->remove`` >> +callback or in the error path of the ``->probe`` callback. >> >> Limitations >> === >> diff --git a/drivers/base/core.c b/drivers/base/core.c >> index df3e1a44707a..14c1e3151e08 100644 >> --- a/drivers/base/core.c >> +++ b/drivers/base/core.c >> @@ -178,10 +178,10 @@ void device_pm_move_to_tail(struct device *dev) >> * of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will >> be >> * ignored. >> * >> - * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically >> - * when the consumer device driver unbinds from it. The combination of both >> - * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause >> NULL >> - * to be returned. >> + * If the DL_FLAG_AUTOREMOVE_CONSUMER is set, the link will be removed >> + * automatically when the consumer device driver unbinds from it. >> + * The combination of both DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_STATELESS >> + * set is invalid and will cause NULL to be returned. >> * >> * A side effect of the link creation is re-ordering of dpm_list and the >> * devices_kset list by moving the consumer device and all devices depending >> @@ -198,7 +198,8 @@ struct device_link *device_link_add(struct device >> *consumer, >> struct device_link *link; >> >> if (!consumer || !supplier || >> - ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE))) >> + ((flags & DL_FLAG_STATELESS) && >> +(flags & DL_FLAG_AUTOREMOVE_CONSUMER))) >> return NULL; >> >> device_links_write_lock(); >> @@ -479,7 +480,7 @@ static void __device_links_no_driver(struct device *dev) >> if (link->flags & DL_FLAG_STATELESS) >> continue; >> >> - if (link->flags & DL_FLAG_AUTOREMOVE) >> +
[PATCH 1/2] device core: Rename flag AUTOREMOVE to AUTOREMOVE_CONSUMER
Now that we want to add another flag to autoremove the device link on supplier unbind, it's fair to rename the existing flag from DL_FLAG_AUTOREMOVE to DL_FLAG_AUTOREMOVE_CONSUMER so that we can add similar flag for supplier later. And, while we are touching device.h, fix a doc build warning. Signed-off-by: Vivek Gautam Cc: Lukas Wunner Cc: Jonathan Corbet Cc: Greg Kroah-Hartman Cc: Thierry Reding Cc: David Airlie Cc: Jonathan Hunter Cc: Philipp Zabel Cc: Shawn Guo Cc: Sascha Hauer Cc: Robin Murphy Cc: linux-...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org Cc: linux-te...@vger.kernel.org Cc: linux-arm-ker...@lists.infradead.org Cc: linux...@vger.kernel.org Cc: linux-arm-...@vger.kernel.org --- Documentation/driver-api/device_link.rst | 8 drivers/base/core.c | 15 --- drivers/gpu/drm/tegra/dc.c | 2 +- drivers/gpu/ipu-v3/ipu-pre.c | 3 ++- drivers/gpu/ipu-v3/ipu-prg.c | 3 ++- drivers/soc/imx/gpc.c| 2 +- include/linux/device.h | 12 ++-- 7 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Documentation/driver-api/device_link.rst b/Documentation/driver-api/device_link.rst index 70e328e16aad..a005b904a264 100644 --- a/Documentation/driver-api/device_link.rst +++ b/Documentation/driver-api/device_link.rst @@ -81,10 +81,10 @@ integration is desired. Two other flags are specifically targeted at use cases where the device link is added from the consumer's ``->probe`` callback: ``DL_FLAG_RPM_ACTIVE`` can be specified to runtime resume the supplier upon addition of the -device link. ``DL_FLAG_AUTOREMOVE`` causes the device link to be automatically -purged when the consumer fails to probe or later unbinds. This obviates -the need to explicitly delete the link in the ``->remove`` callback or in -the error path of the ``->probe`` callback. +device link. ``DL_FLAG_AUTOREMOVE_CONSUMER`` causes the device link to be +automatically purged when the consumer fails to probe or later unbinds. +This obviates the need to explicitly delete the link in the ``->remove`` +callback or in the error path of the ``->probe`` callback. Limitations === diff --git a/drivers/base/core.c b/drivers/base/core.c index df3e1a44707a..14c1e3151e08 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -178,10 +178,10 @@ void device_pm_move_to_tail(struct device *dev) * of the link. If DL_FLAG_PM_RUNTIME is not set, DL_FLAG_RPM_ACTIVE will be * ignored. * - * If the DL_FLAG_AUTOREMOVE is set, the link will be removed automatically - * when the consumer device driver unbinds from it. The combination of both - * DL_FLAG_AUTOREMOVE and DL_FLAG_STATELESS set is invalid and will cause NULL - * to be returned. + * If the DL_FLAG_AUTOREMOVE_CONSUMER is set, the link will be removed + * automatically when the consumer device driver unbinds from it. + * The combination of both DL_FLAG_AUTOREMOVE_CONSUMER and DL_FLAG_STATELESS + * set is invalid and will cause NULL to be returned. * * A side effect of the link creation is re-ordering of dpm_list and the * devices_kset list by moving the consumer device and all devices depending @@ -198,7 +198,8 @@ struct device_link *device_link_add(struct device *consumer, struct device_link *link; if (!consumer || !supplier || - ((flags & DL_FLAG_STATELESS) && (flags & DL_FLAG_AUTOREMOVE))) + ((flags & DL_FLAG_STATELESS) && +(flags & DL_FLAG_AUTOREMOVE_CONSUMER))) return NULL; device_links_write_lock(); @@ -479,7 +480,7 @@ static void __device_links_no_driver(struct device *dev) if (link->flags & DL_FLAG_STATELESS) continue; - if (link->flags & DL_FLAG_AUTOREMOVE) + if (link->flags & DL_FLAG_AUTOREMOVE_CONSUMER) kref_put(>kref, __device_link_del); else if (link->status != DL_STATE_SUPPLIER_UNBIND) WRITE_ONCE(link->status, DL_STATE_AVAILABLE); @@ -515,7 +516,7 @@ void device_links_driver_cleanup(struct device *dev) if (link->flags & DL_FLAG_STATELESS) continue; - WARN_ON(link->flags & DL_FLAG_AUTOREMOVE); + WARN_ON(link->flags & DL_FLAG_AUTOREMOVE_CONSUMER); WARN_ON(link->status != DL_STATE_SUPPLIER_UNBIND); WRITE_ONCE(link->status, DL_STATE_DORMANT); } diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index c3afe7b2237e..965088afcfad 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -2312,7 +2312,7 @@ static int tegra_dc_couple(struct tegra_dc *dc) * POWER_CONTROL registers during CRTC enabling. */ if (dc->soc->coupled_pm &
Re: [PATCH 1/5] drm/msm: Remove pm_runtime operations from msm_iommu
On Wed, Jun 20, 2018 at 4:00 AM, Jordan Crouse wrote: > Now that the IOMMU is the master of it's own power we don't need to bring > up the GPU to do IOMMU operations. This is good because bringing up a6xx > requires the GMU so calling pm_runtime_get_sync() too early in the process > gets us into some nasty circular dependency situations. > > Signed-off-by: Jordan Crouse > --- > drivers/gpu/drm/msm/msm_iommu.c | 13 + > 1 file changed, 1 insertion(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c > index b23d33622f37..e80c79b3bb5c 100644 > --- a/drivers/gpu/drm/msm/msm_iommu.c > +++ b/drivers/gpu/drm/msm/msm_iommu.c > @@ -38,13 +38,8 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const > char * const *names, > int cnt) > { > struct msm_iommu *iommu = to_msm_iommu(mmu); > - int ret; > > - pm_runtime_get_sync(mmu->dev); > - ret = iommu_attach_device(iommu->domain, mmu->dev); > - pm_runtime_put_sync(mmu->dev); > - > - return ret; > + return iommu_attach_device(iommu->domain, mmu->dev); > } > > static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, > @@ -52,9 +47,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const > char * const *names, > { > struct msm_iommu *iommu = to_msm_iommu(mmu); > > - pm_runtime_get_sync(mmu->dev); > iommu_detach_device(iommu->domain, mmu->dev); > - pm_runtime_put_sync(mmu->dev); > } > > static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, > @@ -63,9 +56,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, > struct msm_iommu *iommu = to_msm_iommu(mmu); > size_t ret; > > -// pm_runtime_get_sync(mmu->dev); > ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); > -// pm_runtime_put_sync(mmu->dev); > WARN_ON(ret < 0); > > return (ret == len) ? 0 : -EINVAL; > @@ -76,9 +67,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t > iova, > { > struct msm_iommu *iommu = to_msm_iommu(mmu); > > - pm_runtime_get_sync(mmu->dev); > iommu_unmap(iommu->domain, iova, len); > - pm_runtime_put_sync(mmu->dev); > > return 0; > } Looks good to me. Reviewed-by: Vivek Gautam Best regards Vivek > -- > 2.17.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 1/5] drm/msm: Remove pm_runtime operations from msm_iommu
Hi Jordan, On Mon, Jun 11, 2018 at 11:56 PM, Jordan Crouse wrote: > Now that the IOMMU is the master of it's own power we don't need to bring > up the GPU to do IOMMU operations. This is good because bringing up a6xx > requires the GMU so calling pm_runtime_get_sync() too early in the process > gets us into some nasty circular dependency situations. Thanks for the patch. While you are removing these calls, we should add pm_runtime calls to qcom_iommu_map(). That should make qcom_iommu too master of its power control. Then we should be good to go with this patch. > > Signed-off-by: Jordan Crouse > --- > drivers/gpu/drm/msm/msm_iommu.c | 8 > 1 file changed, 8 deletions(-) > > diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c > index b23d33622f37..ccd93ac6a4d8 100644 > --- a/drivers/gpu/drm/msm/msm_iommu.c > +++ b/drivers/gpu/drm/msm/msm_iommu.c > @@ -40,9 +40,7 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char > * const *names, > struct msm_iommu *iommu = to_msm_iommu(mmu); > int ret; > > - pm_runtime_get_sync(mmu->dev); > ret = iommu_attach_device(iommu->domain, mmu->dev); > - pm_runtime_put_sync(mmu->dev); may be just do the following here. return iommu_attach_device(iommu->domain, mmu->dev); Rest looks good. So after the change. Reviewed-by: Vivek Gautam Best regards Vivek > > return ret; > } > @@ -52,9 +50,7 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const > char * const *names, > { > struct msm_iommu *iommu = to_msm_iommu(mmu); > > - pm_runtime_get_sync(mmu->dev); > iommu_detach_device(iommu->domain, mmu->dev); > - pm_runtime_put_sync(mmu->dev); > } > > static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, > @@ -63,9 +59,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, > struct msm_iommu *iommu = to_msm_iommu(mmu); > size_t ret; > > -// pm_runtime_get_sync(mmu->dev); > ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); > -// pm_runtime_put_sync(mmu->dev); > WARN_ON(ret < 0); > > return (ret == len) ? 0 : -EINVAL; > @@ -76,9 +70,7 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t > iova, > { > struct msm_iommu *iommu = to_msm_iommu(mmu); > > - pm_runtime_get_sync(mmu->dev); > iommu_unmap(iommu->domain, iova, len); > - pm_runtime_put_sync(mmu->dev); > > return 0; > } > -- > 2.17.1 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 5/5] drm/msm/A6xx: Add support for using system cache(llc)
Hi Sharat, On 3/23/2018 12:49 PM, Sharat Masetty wrote: The last level system cache can be partitioned to 32 different slices of which GPU has two slices preallocated. The "gpu" slice is used for caching GPU buffers and the "gpuhtw" slice is used for caching the GPU SMMU pagetables. This patch talks to the core system cache driver to acquire the slice handles, configure the SCID's to those slices and activates and deactivates the slices upon GPU power collapse and restore. Some support from the IOMMU driver is also needed to make use of the system cache. IOMMU_UPSTREAM_HINT is a buffer protection flag which enables caching GPU data buffers in the system cache with memory attributes such as outer cacheable, read-allocate, write-allocate for buffers. The GPU then has the ability to override a few cacheability parameters which it does to override write-allocate to write-no-allocate as the GPU hardware does not benefit much from it. Similarly DOMAIN_ATTR_USE_UPSTREAM_HINT is another domain level attribute used by the IOMMU driver to set the right attributes to cache the hardware pagetables into the system cache. Signed-off-by: Sharat Masetty--- Couple of minor nits. Please see comments inline below. drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 162 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.h | 9 ++ drivers/gpu/drm/msm/msm_iommu.c | 13 +++ drivers/gpu/drm/msm/msm_mmu.h | 3 + 4 files changed, 186 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index bd50674..e4554eb 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -13,6 +13,7 @@ #include #include +#include #include "msm_gem.h" #include "msm_mmu.h" @@ -913,6 +914,154 @@ static irqreturn_t a6xx_irq(struct msm_gpu *gpu) ~0 }; +#define A6XX_LLC_NUM_GPU_SCIDS 5 +#define A6XX_GPU_LLC_SCID_NUM_BITS 5 + +#define A6XX_GPU_LLC_SCID_MASK \ + ((1 << (A6XX_LLC_NUM_GPU_SCIDS * A6XX_GPU_LLC_SCID_NUM_BITS)) - 1) + +#define A6XX_GPUHTW_LLC_SCID_SHIFT 25 +#define A6XX_GPUHTW_LLC_SCID_MASK \ + (((1 << A6XX_GPU_LLC_SCID_NUM_BITS) - 1) << A6XX_GPUHTW_LLC_SCID_SHIFT) + +static inline void a6xx_gpu_cx_rmw(struct a6xx_llc *llc, + u32 reg, u32 mask, u32 or) +{ + msm_rmw(llc->mmio + (reg << 2), mask, or); +} + +static void a6xx_llc_deactivate(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_llc *llc = _gpu->llc; + + llcc_slice_deactivate(llc->gpu_llc_slice); + llcc_slice_deactivate(llc->gpuhtw_llc_slice); +} + +static void a6xx_llc_activate(struct msm_gpu *gpu) +{ + struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); + struct a6xx_llc *llc = _gpu->llc; + + if (!llc->mmio) + return; + + if (llc->gpu_llc_slice) + if (!llcc_slice_activate(llc->gpu_llc_slice)) + /* Program the sub-cache ID for all GPU blocks */ + a6xx_gpu_cx_rmw(llc, + REG_A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, + A6XX_GPU_LLC_SCID_MASK, + (llc->cntl1_regval & + A6XX_GPU_LLC_SCID_MASK)); + + if (llc->gpuhtw_llc_slice) + if (!llcc_slice_activate(llc->gpuhtw_llc_slice)) + /* Program the sub-cache ID for GPU pagetables */ + a6xx_gpu_cx_rmw(llc, + REG_A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_1, + A6XX_GPUHTW_LLC_SCID_MASK, + (llc->cntl1_regval & + A6XX_GPUHTW_LLC_SCID_MASK)); + + /* Program cacheability overrides */ + a6xx_gpu_cx_rmw(llc, REG_A6XX_GPU_CX_MISC_SYSTEM_CACHE_CNTL_0, 0xF, + llc->cntl0_regval); +} + +void a6xx_llc_slices_destroy(struct a6xx_llc *llc) static? +{ + if (llc->mmio) { + iounmap(llc->mmio); + llc->mmio = NULL; + } + + llcc_slice_putd(llc->gpu_llc_slice); + llc->gpu_llc_slice = NULL; + + llcc_slice_putd(llc->gpuhtw_llc_slice); + llc->gpuhtw_llc_slice = NULL; +} + +static int a6xx_llc_slices_init(struct platform_device *pdev, + struct a6xx_llc *llc) +{ + int i; + + /* Get the system cache slice descriptor for GPU and GPUHTWs */ + llc->gpu_llc_slice = llcc_slice_getd(>dev, "gpu"); + if (IS_ERR(llc->gpu_llc_slice)) + llc->gpu_llc_slice = NULL; + + llc->gpuhtw_llc_slice = llcc_slice_getd(>dev, "gpuhtw"); + if (IS_ERR(llc->gpuhtw_llc_slice)) + llc->gpuhtw_llc_slice = NULL; + +
Re: [PATCH 2/5] arm64:dts:sdm845: Add support for GPU LLCC
Hi Sharat, On 3/23/2018 12:49 PM, Sharat Masetty wrote: Add client side bindings required for the GPU to use the last level system cache. Also add a register range in the GPU CX domain. Signed-off-by: Sharat Masetty--- arch/arm64/boot/dts/qcom/sdm845.dtsi | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index eb0a1b2..7e2d938 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -887,8 +887,8 @@ compatible = "qcom,adreno-630.2", "qcom,adreno"; #stream-id-cells = <16>; - reg = <0x500 0x4>; - reg-names = "kgsl_3d0_reg_memory"; + reg = <0x500 0x4>, <0x509e000 0x10>; + reg-names = "kgsl_3d0_reg_memory", "cx_mem"; /* * Look ma, no clocks! The GPU clocks and power are controlled @@ -898,6 +898,10 @@ interrupts = <0 300 0>; interrupt-names = "kgsl_3d0_irq"; + /* GPU related llc slices */ + cache-slice-names = "gpu", "gpuhtw"; + cache-slices = < 12>, < 11>; Please add corresponding binding doc changes. Best regards Vivek + iommus = <_smmu 0>; operating-points-v2 = <_opp_table>; ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH 4/5] drm/msm: Pass mmu features to generic layers
Hi Sharat, On 3/23/2018 12:49 PM, Sharat Masetty wrote: Allow different Adreno targets the ability to pass specific mmu features to the generic layers. This will help conditionally configure certain iommu features for certain Adreno targets. Also Add a few simple support functions to support a bitmask of features that a specific MMU implementation supports. Signed-off-by: Sharat MasettyJust a nit; please see my comment below. --- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 2 +- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 +++- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 2 +- drivers/gpu/drm/msm/msm_gpu.c | 6 -- drivers/gpu/drm/msm/msm_gpu.h | 1 + drivers/gpu/drm/msm/msm_mmu.h | 13 + 9 files changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index 1dd84d3..a7a8573 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -492,7 +492,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = a3xx_registers; adreno_gpu->reg_offsets = a3xx_register_offsets; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1, 0); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index 2884b1b..5e7e15d6 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -574,7 +574,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = a4xx_registers; adreno_gpu->reg_offsets = a4xx_register_offsets; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 1, 0); if (ret) goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index a4f68af..c9e06ff 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1295,7 +1295,7 @@ struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) check_speed_bin(>dev); - ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4, 0); if (ret) { a5xx_destroy(&(a5xx_gpu->base.base)); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index e83b066..bd50674 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -1040,7 +1040,7 @@ struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) adreno_gpu->registers = a6xx_registers; adreno_gpu->reg_offsets = a6xx_register_offsets; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, , 4, 0); if (ret) { a6xx_destroy(&(a6xx_gpu->base.base)); return ERR_PTR(ret); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 6657461..a87ec6b 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -557,7 +557,8 @@ static int adreno_get_pwrlevels(struct device *dev, int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *adreno_gpu, - const struct adreno_gpu_funcs *funcs, int nr_rings) + const struct adreno_gpu_funcs *funcs, int nr_rings, + unsigned long mmu_features) { struct adreno_platform_config *config = pdev->dev.platform_data; struct msm_gpu_config adreno_gpu_config = { 0 }; @@ -576,6 +577,7 @@ int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, adreno_gpu_config.va_end = 0x; adreno_gpu_config.nr_rings = nr_rings; + adreno_gpu_config.mmu_features = mmu_features; adreno_get_pwrlevels(>dev, gpu); diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index bb9affd..19eda65 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -225,7 +225,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev, struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs, - int nr_rings); + int nr_rings, unsigned long mmu_features); void adreno_gpu_cleanup(struct adreno_gpu *gpu); int adreno_load_fw(struct adreno_gpu *adreno_gpu); diff --git a/drivers/gpu/drm/msm/msm_gpu.c
Re: [Freedreno] [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
On Fri, Feb 23, 2018 at 9:10 PM, Jordan Crouse <jcro...@codeaurora.org> wrote: > On Fri, Feb 23, 2018 at 04:06:39PM +0530, Vivek Gautam wrote: >> On Fri, Feb 23, 2018 at 5:22 AM, Jordan Crouse <jcro...@codeaurora.org> >> wrote: >> > On Wed, Feb 07, 2018 at 04:01:19PM +0530, Vivek Gautam wrote: >> >> From: Sricharan R <sricha...@codeaurora.org> >> >> >> >> The smmu device probe/remove and add/remove master device callbacks >> >> gets called when the smmu is not linked to its master, that is without >> >> the context of the master device. So calling runtime apis in those places >> >> separately. >> >> >> >> Signed-off-by: Sricharan R <sricha...@codeaurora.org> >> >> [vivek: Cleanup pm runtime calls] >> >> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >> >> --- >> >> drivers/iommu/arm-smmu.c | 42 ++ >> >> 1 file changed, 38 insertions(+), 4 deletions(-) >> >> >> >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c >> >> index 9e2f917e16c2..c024f69c1682 100644 >> >> --- a/drivers/iommu/arm-smmu.c >> >> +++ b/drivers/iommu/arm-smmu.c >> >> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct >> >> iommu_domain *domain) >> >> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); >> >> struct arm_smmu_device *smmu = smmu_domain->smmu; >> >> struct arm_smmu_cfg *cfg = _domain->cfg; >> >> - int irq; >> >> + int ret, irq; >> >> >> >> if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) >> >> return; >> >> >> >> + ret = pm_runtime_get_sync(smmu->dev); >> >> + if (ret) >> >> + return; >> >> + >> >> /* >> >>* Disable the context bank and free the page tables before freeing >> >>* it. >> >> @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct >> >> iommu_domain *domain) >> >> >> >> free_io_pgtable_ops(smmu_domain->pgtbl_ops); >> >> __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); >> >> + >> >> + pm_runtime_put_sync(smmu->dev); >> >> } >> >> >> >> static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) >> >> @@ -1407,14 +1413,22 @@ static int arm_smmu_add_device(struct device *dev) >> >> while (i--) >> >> cfg->smendx[i] = INVALID_SMENDX; >> >> >> >> - ret = arm_smmu_master_alloc_smes(dev); >> >> + ret = pm_runtime_get_sync(smmu->dev); >> >> if (ret) >> >> goto out_cfg_free; >> > >> > Hey Vivek, I just hit a problem with this on sdm845. It turns out that >> > pm_runtime_get_sync() returns a positive 1 if the device is already active. >> > >> > I hit this in the GPU code. The a6xx has two platform devices that each >> > use a >> > different sid on the iommu. The GPU is probed normally from a platform >> > driver >> > and it in turn initializes the GMU device by way of a phandle. >> > >> > Because the GMU isn't probed with a platform driver we need to call >> > of_dma_configure() on the device to set up the IOMMU for the device which >> > ends >> > up calling through this path and we discover that the smmu->dev is already >> > powered (pm_runtime_get_sync returns 1). >> > >> > I'm not immediately sure if this is a bug on sdm845 or not because a >> > cursory >> > inspection says that the SMMU device shouldn't be powered at this time but >> > there >> > might be a connection that I'm not seeing. Obviously if the SMMU was left >> > powered thats a bad thing. But putting that aside it is obvious that this >> > code should be accommodating of the possibility that the device is already >> > powered, and so this should be >> > >> > if (ret < 0) >> > goto out_cfg_free; >> >> Right, as Tomasz also pointed, we should surely check the negative value of >> pm_runtime_get_sync(). > > Sorry, I didn't notice that Tomasz had pointed it out as well. I wanted to > quickly get it on the mailing list so you could catch it in your time zone. > >> From
Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
On Fri, Feb 23, 2018 at 5:22 AM, Jordan Crouse <jcro...@codeaurora.org> wrote: > On Wed, Feb 07, 2018 at 04:01:19PM +0530, Vivek Gautam wrote: >> From: Sricharan R <sricha...@codeaurora.org> >> >> The smmu device probe/remove and add/remove master device callbacks >> gets called when the smmu is not linked to its master, that is without >> the context of the master device. So calling runtime apis in those places >> separately. >> >> Signed-off-by: Sricharan R <sricha...@codeaurora.org> >> [vivek: Cleanup pm runtime calls] >> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >> --- >> drivers/iommu/arm-smmu.c | 42 ++ >> 1 file changed, 38 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c >> index 9e2f917e16c2..c024f69c1682 100644 >> --- a/drivers/iommu/arm-smmu.c >> +++ b/drivers/iommu/arm-smmu.c >> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct >> iommu_domain *domain) >> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); >> struct arm_smmu_device *smmu = smmu_domain->smmu; >> struct arm_smmu_cfg *cfg = _domain->cfg; >> - int irq; >> + int ret, irq; >> >> if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) >> return; >> >> + ret = pm_runtime_get_sync(smmu->dev); >> + if (ret) >> + return; >> + >> /* >>* Disable the context bank and free the page tables before freeing >>* it. >> @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct >> iommu_domain *domain) >> >> free_io_pgtable_ops(smmu_domain->pgtbl_ops); >> __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); >> + >> + pm_runtime_put_sync(smmu->dev); >> } >> >> static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) >> @@ -1407,14 +1413,22 @@ static int arm_smmu_add_device(struct device *dev) >> while (i--) >> cfg->smendx[i] = INVALID_SMENDX; >> >> - ret = arm_smmu_master_alloc_smes(dev); >> + ret = pm_runtime_get_sync(smmu->dev); >> if (ret) >> goto out_cfg_free; > > Hey Vivek, I just hit a problem with this on sdm845. It turns out that > pm_runtime_get_sync() returns a positive 1 if the device is already active. > > I hit this in the GPU code. The a6xx has two platform devices that each use a > different sid on the iommu. The GPU is probed normally from a platform driver > and it in turn initializes the GMU device by way of a phandle. > > Because the GMU isn't probed with a platform driver we need to call > of_dma_configure() on the device to set up the IOMMU for the device which ends > up calling through this path and we discover that the smmu->dev is already > powered (pm_runtime_get_sync returns 1). > > I'm not immediately sure if this is a bug on sdm845 or not because a cursory > inspection says that the SMMU device shouldn't be powered at this time but > there > might be a connection that I'm not seeing. Obviously if the SMMU was left > powered thats a bad thing. But putting that aside it is obvious that this > code should be accommodating of the possibility that the device is already > powered, and so this should be > > if (ret < 0) > goto out_cfg_free; Right, as Tomasz also pointed, we should surely check the negative value of pm_runtime_get_sync(). From your description, it may be that the GPU has turned on the smmu, and then once if goes and probes the GMU, the GMU device also wants to turn-on the same smmu device. But that's already active. So pm_runtime_get_sync() returns 1. Am i making sense? regards Vivek > > With that the GPU/GMU successfully comes up on Sean Paul's display testing > branch. > > Jordan > > -- > The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, > a Linux Foundation Collaborative Project > -- > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
Hi, On Thu, Feb 22, 2018 at 7:42 PM, Tomasz Figawrote: > On Thu, Feb 22, 2018 at 10:45 PM, Robin Murphy wrote: >> [sorry, I had intended to reply sooner but clearly forgot] >> >> >> On 16/02/18 00:13, Tomasz Figa wrote: >>> >>> On Fri, Feb 16, 2018 at 2:14 AM, Robin Murphy >>> wrote: On 15/02/18 04:17, Tomasz Figa wrote: [...] >> >> >> Could you elaborate on what kind of locking you are concerned about? >> As I explained before, the normally happening fast path would lock >> dev->power_lock only for the brief moment of incrementing the runtime >> PM usage counter. > > > > My bad, that's not even it. > > The atomic usage counter is incremented beforehands, without any > locking [1] and the spinlock is acquired only for the sake of > validating that device's runtime PM state remained valid indeed [2], > which would be the case in the fast path of the same driver doing two > mappings in parallel, with the master powered on (and so the SMMU, > through device links; if master was not powered on already, powering > on the SMMU is unavoidable anyway and it would add much more latency > than the spinlock itself). We now have no locking at all in the map path, and only a per-domain lock around TLB sync in unmap which is unfortunately necessary for correctness; the latter isn't too terrible, since in "serious" hardware it should only be serialising a few cpus serving the same device against each other (e.g. for multiple queues on a single NIC). Putting in a global lock which serialises *all* concurrent map and unmap calls for *all* unrelated devices makes things worse. Period. Even if the lock itself were held for the minimum possible time, i.e. trivially "spin_lock(); spin_unlock()", the cost of repeatedly bouncing that one cache line around between 96 CPUs across two sockets is not negligible. >>> >>> >>> Fair enough. Note that we're in a quite interesting situation now: >>> a) We need to have runtime PM enabled on Qualcomm SoC to have power >>> properly managed, >>> b) We need to have lock-free map/unmap on such distributed systems, >>> c) If runtime PM is enabled, we need to call into runtime PM from any >>> code that does hardware accesses, otherwise the IOMMU API (and so DMA >>> API and then any V4L2 driver) becomes unusable. >>> >>> I can see one more way that could potentially let us have all the >>> three. How about enabling runtime PM only on selected implementations >>> (e.g. qcom,smmu) and then having all the runtime PM calls surrounded >>> with if (pm_runtime_enabled()), which is lockless? >> >> >> Yes, that's the kind of thing I was gravitating towards - my vague thought >> was adding some flag to the smmu_domain, but pm_runtime_enabled() does look >> conceptually a lot cleaner. > > Great, thanks. Looks like we're in agreement now. \o/ > > Vivek, does this sound reasonable to you? Yea, sound good to me. I will respin the patches. Thanks & Regards Vivek > > Best regards, > Tomasz -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
On Wed, Feb 14, 2018 at 2:46 PM, Tomasz Figa <tf...@chromium.org> wrote: Adding Jordan to this thread as well. > On Wed, Feb 14, 2018 at 6:13 PM, Vivek Gautam > <vivek.gau...@codeaurora.org> wrote: >> Hi Tomasz, >> >> On Wed, Feb 14, 2018 at 11:08 AM, Tomasz Figa <tf...@chromium.org> wrote: >>> On Wed, Feb 14, 2018 at 1:17 PM, Vivek Gautam >>> <vivek.gau...@codeaurora.org> wrote: >>>> Hi Tomasz, >>>> >>>> On Wed, Feb 14, 2018 at 8:31 AM, Tomasz Figa <tf...@chromium.org> wrote: >>>>> On Wed, Feb 14, 2018 at 11:13 AM, Rob Clark <robdcl...@gmail.com> wrote: >>>>>> On Tue, Feb 13, 2018 at 8:59 PM, Tomasz Figa <tf...@chromium.org> wrote: >>>>>>> On Wed, Feb 14, 2018 at 3:03 AM, Rob Clark <robdcl...@gmail.com> wrote: >>>>>>>> On Tue, Feb 13, 2018 at 4:10 AM, Tomasz Figa <tf...@chromium.org> >>>>>>>> wrote: >>>>>>>>> Hi Vivek, >>>>>>>>> >>>>>>>>> Thanks for the patch. Please see my comments inline. >>>>>>>>> >>>>>>>>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam >>>>>>>>> <vivek.gau...@codeaurora.org> wrote: >>>>>>>>>> While handling the concerned iommu, there should not be a >>>>>>>>>> need to power control the drm devices from iommu interface. >>>>>>>>>> If these drm devices need to be powered around this time, >>>>>>>>>> the respective drivers should take care of this. >>>>>>>>>> >>>>>>>>>> Replace the pm_runtime_get/put_sync() with >>>>>>>>>> pm_runtime_get/put_suppliers() calls, to power-up >>>>>>>>>> the connected iommu through the device link interface. >>>>>>>>>> In case the device link is not setup these get/put_suppliers() >>>>>>>>>> calls will be a no-op, and the iommu driver should take care of >>>>>>>>>> powering on its devices accordingly. >>>>>>>>>> >>>>>>>>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >>>>>>>>>> --- >>>>>>>>>> drivers/gpu/drm/msm/msm_iommu.c | 16 >>>>>>>>>> 1 file changed, 8 insertions(+), 8 deletions(-) >>>>>>>>>> >>>>>>>>>> diff --git a/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>>>> b/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>>>> index b23d33622f37..1ab629bbee69 100644 >>>>>>>>>> --- a/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>>>> +++ b/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>>>> @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, >>>>>>>>>> const char * const *names, >>>>>>>>>> struct msm_iommu *iommu = to_msm_iommu(mmu); >>>>>>>>>> int ret; >>>>>>>>>> >>>>>>>>>> - pm_runtime_get_sync(mmu->dev); >>>>>>>>>> + pm_runtime_get_suppliers(mmu->dev); >>>>>>>>>> ret = iommu_attach_device(iommu->domain, mmu->dev); >>>>>>>>>> - pm_runtime_put_sync(mmu->dev); >>>>>>>>>> + pm_runtime_put_suppliers(mmu->dev); >>>>>>>>> >>>>>>>>> For me, it looks like a wrong place to handle runtime PM of IOMMU >>>>>>>>> here. iommu_attach_device() calls into IOMMU driver's attach_device() >>>>>>>>> callback and that's where necessary runtime PM gets should happen, if >>>>>>>>> any. In other words, driver A (MSM DRM driver) shouldn't be dealing >>>>>>>>> with power state of device controlled by driver B (ARM SMMU). >>>>>>>> >>>>>>>> Note that we end up having to do the same, because of iommu_unmap() >>>>>>>> while DRM driver is powered off.. it might be cleaner if it was all >>>>>>>> self contained in the iommu driver, but that would make it so other >>>>>>>> drivers couldn't call
Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
Hi Tomasz, On Wed, Feb 14, 2018 at 11:08 AM, Tomasz Figa <tf...@chromium.org> wrote: > On Wed, Feb 14, 2018 at 1:17 PM, Vivek Gautam > <vivek.gau...@codeaurora.org> wrote: >> Hi Tomasz, >> >> On Wed, Feb 14, 2018 at 8:31 AM, Tomasz Figa <tf...@chromium.org> wrote: >>> On Wed, Feb 14, 2018 at 11:13 AM, Rob Clark <robdcl...@gmail.com> wrote: >>>> On Tue, Feb 13, 2018 at 8:59 PM, Tomasz Figa <tf...@chromium.org> wrote: >>>>> On Wed, Feb 14, 2018 at 3:03 AM, Rob Clark <robdcl...@gmail.com> wrote: >>>>>> On Tue, Feb 13, 2018 at 4:10 AM, Tomasz Figa <tf...@chromium.org> wrote: >>>>>>> Hi Vivek, >>>>>>> >>>>>>> Thanks for the patch. Please see my comments inline. >>>>>>> >>>>>>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam >>>>>>> <vivek.gau...@codeaurora.org> wrote: >>>>>>>> While handling the concerned iommu, there should not be a >>>>>>>> need to power control the drm devices from iommu interface. >>>>>>>> If these drm devices need to be powered around this time, >>>>>>>> the respective drivers should take care of this. >>>>>>>> >>>>>>>> Replace the pm_runtime_get/put_sync() with >>>>>>>> pm_runtime_get/put_suppliers() calls, to power-up >>>>>>>> the connected iommu through the device link interface. >>>>>>>> In case the device link is not setup these get/put_suppliers() >>>>>>>> calls will be a no-op, and the iommu driver should take care of >>>>>>>> powering on its devices accordingly. >>>>>>>> >>>>>>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >>>>>>>> --- >>>>>>>> drivers/gpu/drm/msm/msm_iommu.c | 16 >>>>>>>> 1 file changed, 8 insertions(+), 8 deletions(-) >>>>>>>> >>>>>>>> diff --git a/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>> b/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>> index b23d33622f37..1ab629bbee69 100644 >>>>>>>> --- a/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>> +++ b/drivers/gpu/drm/msm/msm_iommu.c >>>>>>>> @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, >>>>>>>> const char * const *names, >>>>>>>> struct msm_iommu *iommu = to_msm_iommu(mmu); >>>>>>>> int ret; >>>>>>>> >>>>>>>> - pm_runtime_get_sync(mmu->dev); >>>>>>>> + pm_runtime_get_suppliers(mmu->dev); >>>>>>>> ret = iommu_attach_device(iommu->domain, mmu->dev); >>>>>>>> - pm_runtime_put_sync(mmu->dev); >>>>>>>> + pm_runtime_put_suppliers(mmu->dev); >>>>>>> >>>>>>> For me, it looks like a wrong place to handle runtime PM of IOMMU >>>>>>> here. iommu_attach_device() calls into IOMMU driver's attach_device() >>>>>>> callback and that's where necessary runtime PM gets should happen, if >>>>>>> any. In other words, driver A (MSM DRM driver) shouldn't be dealing >>>>>>> with power state of device controlled by driver B (ARM SMMU). >>>>>> >>>>>> Note that we end up having to do the same, because of iommu_unmap() >>>>>> while DRM driver is powered off.. it might be cleaner if it was all >>>>>> self contained in the iommu driver, but that would make it so other >>>>>> drivers couldn't call iommu_unmap() from an irq handler, which is >>>>>> apparently something that some of them want to do.. >>>>> >>>>> I'd assume that runtime PM status is already guaranteed to be active >>>>> when the IRQ handler is running, by some other means (e.g. >>>>> pm_runtime_get_sync() called earlier, when queuing some work to the >>>>> hardware). Otherwise, I'm not sure how a powered down device could >>>>> trigger an IRQ. >>>>> >>>>> So, if the master device power is already on, suppliers should be >>>>> powered on as well, thanks to device links. >>>>> >>>>
Re: [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
Hi Tomasz, On Wed, Feb 14, 2018 at 8:31 AM, Tomasz Figa <tf...@chromium.org> wrote: > On Wed, Feb 14, 2018 at 11:13 AM, Rob Clark <robdcl...@gmail.com> wrote: >> On Tue, Feb 13, 2018 at 8:59 PM, Tomasz Figa <tf...@chromium.org> wrote: >>> On Wed, Feb 14, 2018 at 3:03 AM, Rob Clark <robdcl...@gmail.com> wrote: >>>> On Tue, Feb 13, 2018 at 4:10 AM, Tomasz Figa <tf...@chromium.org> wrote: >>>>> Hi Vivek, >>>>> >>>>> Thanks for the patch. Please see my comments inline. >>>>> >>>>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam >>>>> <vivek.gau...@codeaurora.org> wrote: >>>>>> While handling the concerned iommu, there should not be a >>>>>> need to power control the drm devices from iommu interface. >>>>>> If these drm devices need to be powered around this time, >>>>>> the respective drivers should take care of this. >>>>>> >>>>>> Replace the pm_runtime_get/put_sync() with >>>>>> pm_runtime_get/put_suppliers() calls, to power-up >>>>>> the connected iommu through the device link interface. >>>>>> In case the device link is not setup these get/put_suppliers() >>>>>> calls will be a no-op, and the iommu driver should take care of >>>>>> powering on its devices accordingly. >>>>>> >>>>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >>>>>> --- >>>>>> drivers/gpu/drm/msm/msm_iommu.c | 16 >>>>>> 1 file changed, 8 insertions(+), 8 deletions(-) >>>>>> >>>>>> diff --git a/drivers/gpu/drm/msm/msm_iommu.c >>>>>> b/drivers/gpu/drm/msm/msm_iommu.c >>>>>> index b23d33622f37..1ab629bbee69 100644 >>>>>> --- a/drivers/gpu/drm/msm/msm_iommu.c >>>>>> +++ b/drivers/gpu/drm/msm/msm_iommu.c >>>>>> @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const >>>>>> char * const *names, >>>>>> struct msm_iommu *iommu = to_msm_iommu(mmu); >>>>>> int ret; >>>>>> >>>>>> - pm_runtime_get_sync(mmu->dev); >>>>>> + pm_runtime_get_suppliers(mmu->dev); >>>>>> ret = iommu_attach_device(iommu->domain, mmu->dev); >>>>>> - pm_runtime_put_sync(mmu->dev); >>>>>> + pm_runtime_put_suppliers(mmu->dev); >>>>> >>>>> For me, it looks like a wrong place to handle runtime PM of IOMMU >>>>> here. iommu_attach_device() calls into IOMMU driver's attach_device() >>>>> callback and that's where necessary runtime PM gets should happen, if >>>>> any. In other words, driver A (MSM DRM driver) shouldn't be dealing >>>>> with power state of device controlled by driver B (ARM SMMU). >>>> >>>> Note that we end up having to do the same, because of iommu_unmap() >>>> while DRM driver is powered off.. it might be cleaner if it was all >>>> self contained in the iommu driver, but that would make it so other >>>> drivers couldn't call iommu_unmap() from an irq handler, which is >>>> apparently something that some of them want to do.. >>> >>> I'd assume that runtime PM status is already guaranteed to be active >>> when the IRQ handler is running, by some other means (e.g. >>> pm_runtime_get_sync() called earlier, when queuing some work to the >>> hardware). Otherwise, I'm not sure how a powered down device could >>> trigger an IRQ. >>> >>> So, if the master device power is already on, suppliers should be >>> powered on as well, thanks to device links. >>> >> >> umm, that is kindof the inverse of the problem.. the problem is >> things like gpu driver (and v4l2 drivers that import dma-buf's, >> afaict).. they will potentially call iommu->unmap() when device is not >> active (due to userspace or things beyond the control of the driver).. >> so *they* would want iommu to do pm get/put calls. > > Which is fine and which is actually already done by one of the patches > in this series, not for map/unmap, but probe, add_device, > remove_device. Having parts of the API doing it inside the callback > and other parts outside sounds at least inconsistent. > >> But other drivers >> trying to unmap from irq ctx would not. Which is t
Re: [PATCH v7 4/6] iommu/arm-smmu: Add the device_link between masters and smmu
Hi Tomasz, On Tue, Feb 13, 2018 at 2:01 PM, Tomasz Figa <tf...@chromium.org> wrote: > Hi Vivek, > > Thanks for the patch. Please see my comments inline. Thanks for reviewing the patch series. > > On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam > <vivek.gau...@codeaurora.org> wrote: >> From: Sricharan R <sricha...@codeaurora.org> >> >> Finally add the device link between the master device and >> smmu, so that the smmu gets runtime enabled/disabled only when the >> master needs it. This is done from add_device callback which gets >> called once when the master is added to the smmu. >> >> Signed-off-by: Sricharan R <sricha...@codeaurora.org> >> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >> --- >> drivers/iommu/arm-smmu.c | 16 >> 1 file changed, 16 insertions(+) >> >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c >> index c024f69c1682..c7e924d553bd 100644 >> --- a/drivers/iommu/arm-smmu.c >> +++ b/drivers/iommu/arm-smmu.c >> @@ -215,6 +215,9 @@ struct arm_smmu_device { >> >> /* IOMMU core code handle */ >> struct iommu_device iommu; >> + >> + /* runtime PM link to master */ >> + struct device_link *link; >> }; >> >> enum arm_smmu_context_fmt { >> @@ -1425,6 +1428,17 @@ static int arm_smmu_add_device(struct device *dev) >> >> pm_runtime_put_sync(smmu->dev); >> >> + /* >> +* Establish the link between smmu and master, so that the >> +* smmu gets runtime enabled/disabled as per the master's >> +* needs. >> +*/ >> + smmu->link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME); >> + if (!smmu->link) >> + dev_warn(smmu->dev, >> +"Unable to create device link between %s and %s\n", >> +dev_name(smmu->dev), dev_name(dev)); > > How likely it is that the master can work normally even if the link > add fails? Perhaps we should just return an error here? Right. We are assuming that the power is handled for most of the smmu operations, after we add the master with smmu, based on the fact that the device link is successful. We should return error code here. Will make the necessary change. > >> + >> return 0; >> >> out_rpm_put: >> @@ -1449,6 +1463,8 @@ static void arm_smmu_remove_device(struct device *dev) >> cfg = fwspec->iommu_priv; >> smmu = cfg->smmu; >> >> + device_link_del(smmu->link); > > We allowed smmu->link in arm_smmu_add_device(), but here we don't > check it. Looking at the code, device_link_del() doesn't seem to check > either. > > Note that this problem would go away if we fail add_device on > device_link_add() failure, as I suggested above, so no change would be > necessary. Sure. After making the above change, this should also be handled. Best regards Vivek > > Best regards, > Tomasz -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
On Tue, Feb 13, 2018 at 7:22 PM, Tomasz Figa <tf...@chromium.org> wrote: > On Tue, Feb 13, 2018 at 9:57 PM, Robin Murphy <robin.mur...@arm.com> wrote: >> On 13/02/18 08:24, Tomasz Figa wrote: >>> >>> Hi Vivek, >>> >>> Thanks for the patch. Please see my comments inline. >>> >>> On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam >>> <vivek.gau...@codeaurora.org> wrote: >>>> >>>> From: Sricharan R <sricha...@codeaurora.org> >>>> >>>> The smmu device probe/remove and add/remove master device callbacks >>>> gets called when the smmu is not linked to its master, that is without >>>> the context of the master device. So calling runtime apis in those places >>>> separately. >>>> >>>> Signed-off-by: Sricharan R <sricha...@codeaurora.org> >>>> [vivek: Cleanup pm runtime calls] >>>> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >>>> --- >>>> drivers/iommu/arm-smmu.c | 42 >>>> ++ >>>> 1 file changed, 38 insertions(+), 4 deletions(-) >>>> >>>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c >>>> index 9e2f917e16c2..c024f69c1682 100644 >>>> --- a/drivers/iommu/arm-smmu.c >>>> +++ b/drivers/iommu/arm-smmu.c >>>> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct >>>> iommu_domain *domain) >>>> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); >>>> struct arm_smmu_device *smmu = smmu_domain->smmu; >>>> struct arm_smmu_cfg *cfg = _domain->cfg; >>>> - int irq; >>>> + int ret, irq; >>>> >>>> if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) >>>> return; >>>> >>>> + ret = pm_runtime_get_sync(smmu->dev); >>>> + if (ret) >>>> + return; >>> >>> >>> pm_runtime_get_sync() will return 0 if the device was powered off, 1 >>> if it was already/still powered on or runtime PM is not compiled in, >>> or a negative value on error, so shouldn't the test be (ret < 0)? >>> >>> Moreover, I'm actually wondering if it makes any sense to power up the >>> hardware just to program it and power it down again. In a system where >>> the IOMMU is located within a power domain, it would cause the IOMMU >>> block to lose its state anyway. >> >> >> This is generally for the case where the SMMU internal state remains active, >> but the programming interface needs to be powered up in order to access it. > > That's true for Qualcomm SMMU, but I think that would be different for > existing users of the driver? > >> >>> Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add >>> pm_runtime/sleep ops", perhaps it would make more sense to just >>> control the clocks independently of runtime PM? Then, runtime PM could >>> be used for real power management, e.g. really powering the block up >>> and down, for further power saving. >> >> >> Unfortunately that ends up pretty much unmanageable, because there are >> numerous different SMMU microarchitectures with fundamentally different >> clock/power domain schemes (multiplied by individual SoC integration >> possibilities). Since this is fundamentally a generic architectural driver, >> adding explicit clock support would probably make the whole thing about 50% >> clock code, with complicated decision trees around every hardware access >> calculating which clocks are necessary for a given operation on a given >> system. That maintainability aspect is why we've already nacked such a >> fine-grained approach in the past. > > Hmm, I think we are talking about different things here. My suggestion > would not add much more code to the driver than this patch does, calls > to arm_smmu_enable_clocks() instead of pm_runtime_get_sync() and > arm_smmu_disable_clocks() instead of pm_runtime_put(). The > implementation of both functions would be a simple call to clk_bulk_ > API (possibly even no need to put this into functions, just call > directly). Well, things are not so straight on msm. The IP clocks on msm are usually powered by (or i should rather say, controlled by) the same power domain that provides the VDD supply to iommu block. This is the behavior on msm8996 atleast that we are testing on right now. On later SoCs too things
Re: [PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
Hi Tomasz, On Tue, Feb 13, 2018 at 1:54 PM, Tomasz Figa <tf...@chromium.org> wrote: > Hi Vivek, > > Thanks for the patch. Please see my comments inline. > > On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam > <vivek.gau...@codeaurora.org> wrote: >> From: Sricharan R <sricha...@codeaurora.org> >> >> The smmu device probe/remove and add/remove master device callbacks >> gets called when the smmu is not linked to its master, that is without >> the context of the master device. So calling runtime apis in those places >> separately. >> >> Signed-off-by: Sricharan R <sricha...@codeaurora.org> >> [vivek: Cleanup pm runtime calls] >> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >> --- >> drivers/iommu/arm-smmu.c | 42 ++ >> 1 file changed, 38 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c >> index 9e2f917e16c2..c024f69c1682 100644 >> --- a/drivers/iommu/arm-smmu.c >> +++ b/drivers/iommu/arm-smmu.c >> @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct >> iommu_domain *domain) >> struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); >> struct arm_smmu_device *smmu = smmu_domain->smmu; >> struct arm_smmu_cfg *cfg = _domain->cfg; >> - int irq; >> + int ret, irq; >> >> if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) >> return; >> >> + ret = pm_runtime_get_sync(smmu->dev); >> + if (ret) >> + return; > > pm_runtime_get_sync() will return 0 if the device was powered off, 1 > if it was already/still powered on or runtime PM is not compiled in, > or a negative value on error, so shouldn't the test be (ret < 0)? Yes, I too noticed it while i was testing on a different platform, and was hitting a failure case. Will update at all places. > > Moreover, I'm actually wondering if it makes any sense to power up the > hardware just to program it and power it down again. In a system where > the IOMMU is located within a power domain, it would cause the IOMMU > block to lose its state anyway. > > Actually, reflecting back on "[PATCH v7 2/6] iommu/arm-smmu: Add > pm_runtime/sleep ops", perhaps it would make more sense to just > control the clocks independently of runtime PM? Then, runtime PM could > be used for real power management, e.g. really powering the block up > and down, for further power saving. > > +Generally similar comments for other places in this patch. > >> + >> /* >> * Disable the context bank and free the page tables before freeing >> * it. >> @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct >> iommu_domain *domain) >> >> free_io_pgtable_ops(smmu_domain->pgtbl_ops); >> __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); >> + >> + pm_runtime_put_sync(smmu->dev); > > Is there any point in the put being sync here? No, I don't think. Can manage with just a 'put' here. Will modify. best regards Vivek > > [snip] > >> @@ -2131,6 +2152,14 @@ static int arm_smmu_device_probe(struct >> platform_device *pdev) >> if (err) >> return err; >> >> + platform_set_drvdata(pdev, smmu); >> + >> + pm_runtime_enable(dev); > > I suspect this may be a disaster for systems where IOMMUs are located > inside power domains, because the driver doesn't take care of the > IOMMU block losing its state on physical power down, as I mentioned in > my comments above. > > Best regards, > Tomasz -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops
Hi Tomasz, Please find my response inline below. On Tue, Feb 13, 2018 at 1:33 PM, Tomasz Figa <tf...@chromium.org> wrote: > Hi Vivek, > > Thanks for the patch. Please see some comments inline. > > On Wed, Feb 7, 2018 at 7:31 PM, Vivek Gautam > <vivek.gau...@codeaurora.org> wrote: >> From: Sricharan R <sricha...@codeaurora.org> >> >> The smmu needs to be functional only when the respective >> master's using it are active. The device_link feature >> helps to track such functional dependencies, so that the >> iommu gets powered when the master device enables itself >> using pm_runtime. So by adapting the smmu driver for >> runtime pm, above said dependency can be addressed. >> >> This patch adds the pm runtime/sleep callbacks to the >> driver and also the functions to parse the smmu clocks >> from DT and enable them in resume/suspend. >> >> Signed-off-by: Sricharan R <sricha...@codeaurora.org> >> Signed-off-by: Archit Taneja <arch...@codeaurora.org> >> [vivek: Clock rework to request bulk of clocks] >> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> >> --- >> drivers/iommu/arm-smmu.c | 56 >> ++-- >> 1 file changed, 54 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c >> index 69e7c60792a8..9e2f917e16c2 100644 >> --- a/drivers/iommu/arm-smmu.c >> +++ b/drivers/iommu/arm-smmu.c >> @@ -48,6 +48,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> >> @@ -205,6 +206,8 @@ struct arm_smmu_device { >> u32 num_global_irqs; >> u32 num_context_irqs; >> unsigned int*irqs; >> + struct clk_bulk_data*clocks; >> + int num_clks; > > nit: Perhaps "num_clocks" to be consistent with "clocks"? > >> >> u32 cavium_id_base; /* Specific to >> Cavium */ >> >> @@ -1897,10 +1900,12 @@ static int arm_smmu_device_cfg_probe(struct >> arm_smmu_device *smmu) >> struct arm_smmu_match_data { >> enum arm_smmu_arch_version version; >> enum arm_smmu_implementation model; >> + const char * const *clks; >> + int num_clks; > > nit: Perhaps s/clks/clocks/ here or s/clocks/clks/ in struct arm_smmu_device? Sure. Will change to s/clocks/clks/ in struct arm_smmu_device. > >> }; >> >> #define ARM_SMMU_MATCH_DATA(name, ver, imp)\ >> -static struct arm_smmu_match_data name = { .version = ver, .model = imp } >> +static const struct arm_smmu_match_data name = { .version = ver, .model = >> imp } >> >> ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU); >> ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU); >> @@ -2001,6 +2006,7 @@ static int arm_smmu_device_dt_probe(struct >> platform_device *pdev, >> data = of_device_get_match_data(dev); >> smmu->version = data->version; >> smmu->model = data->model; >> + smmu->num_clks = data->num_clks; >> >> parse_driver_options(smmu); >> >> @@ -2039,6 +2045,28 @@ static void arm_smmu_bus_init(void) >> #endif >> } >> >> +static int arm_smmu_init_clks(struct arm_smmu_device *smmu) >> +{ >> + int i; >> + int num = smmu->num_clks; >> + const struct arm_smmu_match_data *data; >> + >> + if (num < 1) >> + return 0; >> + >> + smmu->clocks = devm_kcalloc(smmu->dev, num, >> + sizeof(*smmu->clocks), GFP_KERNEL); >> + if (!smmu->clocks) >> + return -ENOMEM; >> + >> + data = of_device_get_match_data(smmu->dev); >> + >> + for (i = 0; i < num; i++) >> + smmu->clocks[i].id = data->clks[i]; > > I'd argue that arm_smmu_device_dt_probe() is a better place for all > the code above, since this function is called regardless of whether > the device is probed from DT or not. Going further, > arm_smmu_device_acpi_probe() could fill smmu->num_clks and ->clocks > using ACPI-like way (as opposed to OF match data) if necessary. Right, it's valid to fill the data in arm_smmu_device_dt_probe(). Perhaps we can just keep the devm_clk_bulk_get() in arm_smmu_device_probe() at the point where we are currently doing arm_smmu_init_clks(). Thanks & regards Vivek > > Best regards, > Tomasz > -- > To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v8 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific clock and power requirements. This smmu core is used with multiple masters on msm8996, viz. mdss, video, etc. Add bindings for the same. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> Reviewed-by: Rob Herring <r...@kernel.org> --- Changes in v8: - Added the missing IOMMU_OF_DECLARE declaration for "qcom,smmu-v2" .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++ drivers/iommu/arm-smmu.c | 14 +++ 2 files changed, 57 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 8a6ffce12af5..169222ae2706 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -17,10 +17,19 @@ conditions. "arm,mmu-401" "arm,mmu-500" "cavium,smmu-v2" +"qcom,-smmu-v2", "qcom,smmu-v2" depending on the particular implementation and/or the version of the architecture implemented. + A number of Qcom SoCs use qcom,smmu-v2 version of the IP. + "qcom,-smmu-v2" represents a soc specific compatible + string that should be present along with the "qcom,smmu-v2" + to facilitate SoC specific clocks/power connections and to + address specific bug fixes. + An example string would be - + "qcom,msm8996-smmu-v2", "qcom,smmu-v2". + - reg : Base address and size of the SMMU. - #global-interrupts : The number of global interrupts exposed by the @@ -71,6 +80,23 @@ conditions. or using stream matching with #iommu-cells = <2>, and may be ignored if present in such cases. +- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2" + implementation. + + "bus" clock for "qcom,smmu-v2" is required for downstream + bus access and for the smmu ptw. + + "iface" clock is required to access smmu's registers through + the TCU's programming interface. + +- clocks: Phandles for respective clocks described by clock-names. + +- power-domains: Phandles to SMMU's power domain specifier. This is + required even if SMMU belongs to the master's power + domain, as the SMMU will have to be enabled and + accessed before master gets enabled and linked to its + SMMU. + ** Deprecated properties: - mmu-masters (deprecated in favour of the generic "iommus" binding) : @@ -137,3 +163,20 @@ conditions. iommu-map = <0 0 0x400>; ... }; + + /* Qcom's arm,smmu-v2 implementation */ + smmu4: iommu { + compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; + reg = <0xd0 0x1>; + + #global-interrupts = <1>; + interrupts = , +, +; + #iommu-cells = <1>; + power-domains = < MDSS_GDSC>; + + clocks = < SMMU_MDP_AXI_CLK>, +< SMMU_MDP_AHB_CLK>; + clock-names = "bus", "iface"; + }; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c7e924d553bd..40da3f251acf 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -119,6 +119,7 @@ enum arm_smmu_implementation { GENERIC_SMMU, ARM_MMU500, CAVIUM_SMMUV2, + QCOM_SMMUV2, }; struct arm_smmu_s2cr { @@ -1950,6 +1951,17 @@ struct arm_smmu_match_data { ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500); ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2); +static const char * const qcom_smmuv2_clks[] = { + "bus", "iface", +}; + +static const struct arm_smmu_match_data qcom_smmuv2 = { + .version = ARM_SMMU_V2, + .model = QCOM_SMMUV2, + .clks = qcom_smmuv2_clks, + .num_clks = ARRAY_SIZE(qcom_smmuv2_clks), +}; + static const struct of_device_id arm_smmu_of_match[] = { { .compatible = "arm,smmu-v1", .data = _generic_v1 }, { .compatible = "arm,smmu-v2", .data = _generic_v2 }, @@ -1957,6 +1969,7 @@ struct arm_smmu_match_data { { .compatible = "arm,mmu-401", .data = _mmu401 }, { .compatible = "arm,mmu-500", .data = _mmu500 }, { .compatible = "cavi
[PATCH v7 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
From: Sricharan R <sricha...@codeaurora.org> The smmu device probe/remove and add/remove master device callbacks gets called when the smmu is not linked to its master, that is without the context of the master device. So calling runtime apis in those places separately. Signed-off-by: Sricharan R <sricha...@codeaurora.org> [vivek: Cleanup pm runtime calls] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 42 ++ 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 9e2f917e16c2..c024f69c1682 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -913,11 +913,15 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = _domain->cfg; - int irq; + int ret, irq; if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) return; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + /* * Disable the context bank and free the page tables before freeing * it. @@ -932,6 +936,8 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) free_io_pgtable_ops(smmu_domain->pgtbl_ops); __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); + + pm_runtime_put_sync(smmu->dev); } static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) @@ -1407,14 +1413,22 @@ static int arm_smmu_add_device(struct device *dev) while (i--) cfg->smendx[i] = INVALID_SMENDX; - ret = arm_smmu_master_alloc_smes(dev); + ret = pm_runtime_get_sync(smmu->dev); if (ret) goto out_cfg_free; + ret = arm_smmu_master_alloc_smes(dev); + if (ret) + goto out_rpm_put; + iommu_device_link(>iommu, dev); + pm_runtime_put_sync(smmu->dev); + return 0; +out_rpm_put: + pm_runtime_put_sync(smmu->dev); out_cfg_free: kfree(cfg); out_free: @@ -1427,7 +1441,7 @@ static void arm_smmu_remove_device(struct device *dev) struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_master_cfg *cfg; struct arm_smmu_device *smmu; - + int ret; if (!fwspec || fwspec->ops != _smmu_ops) return; @@ -1435,8 +1449,15 @@ static void arm_smmu_remove_device(struct device *dev) cfg = fwspec->iommu_priv; smmu = cfg->smmu; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + iommu_device_unlink(>iommu, dev); arm_smmu_master_free_smes(fwspec); + + pm_runtime_put_sync(smmu->dev); + iommu_group_remove_device(dev); kfree(fwspec->iommu_priv); iommu_fwspec_free(dev); @@ -2131,6 +2152,14 @@ static int arm_smmu_device_probe(struct platform_device *pdev) if (err) return err; + platform_set_drvdata(pdev, smmu); + + pm_runtime_enable(dev); + + err = pm_runtime_get_sync(dev); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2172,9 +2201,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev) return err; } - platform_set_drvdata(pdev, smmu); arm_smmu_device_reset(smmu); arm_smmu_test_smr_masks(smmu); + pm_runtime_put_sync(dev); /* * For ACPI and generic DT bindings, an SMMU will be probed before @@ -2211,8 +2240,13 @@ static int arm_smmu_device_remove(struct platform_device *pdev) if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS)) dev_err(>dev, "removing device with active domains!\n"); + pm_runtime_get_sync(smmu->dev); /* Turn the thing off */ writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); + pm_runtime_put_sync(smmu->dev); + + pm_runtime_disable(smmu->dev); + return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops
From: Sricharan R <sricha...@codeaurora.org> The smmu needs to be functional only when the respective master's using it are active. The device_link feature helps to track such functional dependencies, so that the iommu gets powered when the master device enables itself using pm_runtime. So by adapting the smmu driver for runtime pm, above said dependency can be addressed. This patch adds the pm runtime/sleep callbacks to the driver and also the functions to parse the smmu clocks from DT and enable them in resume/suspend. Signed-off-by: Sricharan R <sricha...@codeaurora.org> Signed-off-by: Archit Taneja <arch...@codeaurora.org> [vivek: Clock rework to request bulk of clocks] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 56 ++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 69e7c60792a8..9e2f917e16c2 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -205,6 +206,8 @@ struct arm_smmu_device { u32 num_global_irqs; u32 num_context_irqs; unsigned int*irqs; + struct clk_bulk_data*clocks; + int num_clks; u32 cavium_id_base; /* Specific to Cavium */ @@ -1897,10 +1900,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) struct arm_smmu_match_data { enum arm_smmu_arch_version version; enum arm_smmu_implementation model; + const char * const *clks; + int num_clks; }; #define ARM_SMMU_MATCH_DATA(name, ver, imp)\ -static struct arm_smmu_match_data name = { .version = ver, .model = imp } +static const struct arm_smmu_match_data name = { .version = ver, .model = imp } ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU); ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU); @@ -2001,6 +2006,7 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, data = of_device_get_match_data(dev); smmu->version = data->version; smmu->model = data->model; + smmu->num_clks = data->num_clks; parse_driver_options(smmu); @@ -2039,6 +2045,28 @@ static void arm_smmu_bus_init(void) #endif } +static int arm_smmu_init_clks(struct arm_smmu_device *smmu) +{ + int i; + int num = smmu->num_clks; + const struct arm_smmu_match_data *data; + + if (num < 1) + return 0; + + smmu->clocks = devm_kcalloc(smmu->dev, num, + sizeof(*smmu->clocks), GFP_KERNEL); + if (!smmu->clocks) + return -ENOMEM; + + data = of_device_get_match_data(smmu->dev); + + for (i = 0; i < num; i++) + smmu->clocks[i].id = data->clks[i]; + + return devm_clk_bulk_get(smmu->dev, num, smmu->clocks); +} + static int arm_smmu_device_probe(struct platform_device *pdev) { struct resource *res; @@ -2099,6 +2127,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev) smmu->irqs[i] = irq; } + err = arm_smmu_init_clks(smmu); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2197,7 +2229,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume); +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks); +} + +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks); + + return 0; +} + +static const struct dev_pm_ops arm_smmu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume) + SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend, + arm_smmu_runtime_resume, NULL) +}; static struct platform_driver arm_smmu_driver = { .driver = { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
The device link allows the pm framework to tie the supplier and consumer. So, whenever the consumer is powered-on the supplier is powered-on first. There are however cases in which the consumer wants to power-on the supplier, but not itself. E.g., A Graphics or multimedia driver wants to power-on the SMMU to unmap a buffer and finish the TLB operations without powering on itself. Some of these unmap requests are coming from the user space when the controller itself is not powered-up, and it can be huge penalty in terms of power and latency to power-up the graphics/mm controllers. There can be an argument that the supplier should handle this case on its own and there should not be a need for the consumer to power-on the supplier. But as discussed on the thread [1] about ARM-SMMU runtime pm, we don't want to introduce runtime pm calls in atomic path in arm_smmu_unmap. [1] https://patchwork.kernel.org/patch/9827825/ Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> Acked-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com> --- drivers/base/power/runtime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 8bef3cb2424d..5b8226c8af19 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers); /** * pm_runtime_put_suppliers - Drop references to supplier devices. @@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers); void pm_runtime_new_link(struct device *dev) { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 0/6] iommu/arm-smmu: Add runtime pm/sleep support
This series provides the support for turning on the arm-smmu's clocks/power domains using runtime pm. This is done using the recently introduced device links patches, which lets the smmu's runtime to follow the master's runtime pm, so the smmu remains powered only when the masters use it. It also adds support for Qcom's arm-smmu-v2 variant that has different clocks and power requirements. Took some reference from the exynos runtime patches [1]. After much discussion [3] over the use of pm_runtime_get/put() in .unmap op path for the arm-smmu, and after disussing over more than a couple of approaches to address this, we are putting forward the changes *without* using pm_runtime APIs in 'unmap'. Rather, letting the client device take the control of powering on/off the connected iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios when the iommu power can't be directly controlled by clients through device links. Rafael acked the change to export the suppliers APIs. Previous version of this patch series is @ [5]. [v7] * Addressed review comments given by Robin Murphy - -- Added device_link_del() in .remove_device path. -- Error path cleanup in arm_smmu_add_device(). -- Added pm_runtime_get/put_sync() in .remove path, and replaced pm_runtime_force_suspend() with pm_runtime_disable(). -- clk_names cleanup in arm_smmu_init_clks() * Added 'Reviewed-by' given by Rob H. [V6] * Added Ack given by Rafael to first patch in the series. * Addressed Rob Herring's comment for adding soc specific compatible string as well besides 'qcom,smmu-v2'. [V5] * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over the list [3] for the last patch series. * Added a patch to export pm_runtime_get/put_suppliers() APIs to the series as agreed with Rafael [4]. * Added the related patch for msm drm iommu layer to use pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs. * Dropped arm-mmu500 clock patch since that would break existing platforms. * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect the IP version rather than the platform on which it is used. The same IP is used across multiple platforms including msm8996, and sdm845 etc. * Using clock bulk APIs to handle the clocks available to the IP as suggested by Stephen Boyd. * The first patch in v4 version of the patch-series: ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has already made it to mainline. [V4] * Reworked the clock handling part. We now take clock names as data in the driver for supported compatible versions, and loop over them to get, enable, and disable the clocks. * Using qcom,msm8996 based compatibles for bindings instead of a generic qcom compatible. * Refactor MMU500 patch to just add the necessary clock names data and corresponding bindings. * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by Stanimir on top of previous patch version. * Added a patch to fix error path in arm_smmu_add_device() * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings. [V3] * Reworked the patches to keep the clocks init/enabling function separately for each compatible. * Added clocks bindings for MMU40x/500. * Added a new compatible for qcom,smmu-v2 implementation and the clock bindings for the same. * Rebased on top of 4.11-rc1 [V2] * Split the patches little differently. * Addressed comments. * Removed the patch #4 [2] from previous post for arm-smmu context save restore. Planning to post this separately after reworking/addressing Robin's feedback. * Reversed the sequence to disable clocks than enabling. This was required for those cases where the clocks are populated in a dependent order from DT. [1] https://lkml.org/lkml/2016/10/20/70 [2] https://patchwork.kernel.org/patch/9389717/ [3] https://patchwork.kernel.org/patch/9827825/ [4] https://patchwork.kernel.org/patch/10102445/ [5] https://lkml.org/lkml/2018/1/19/217 Sricharan R (3): iommu/arm-smmu: Add pm_runtime/sleep ops iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device iommu/arm-smmu: Add the device_link between masters and smmu Vivek Gautam (3): base: power: runtime: Export pm_runtime_get/put_suppliers iommu/arm-smmu: Add support for qcom,smmu-v2 variant drm/msm: iommu: Replace runtime calls with runtime suppliers .../devicetree/bindings/iommu/arm,smmu.txt | 43 +++ drivers/base/power/runtime.c | 2 + drivers/gpu/drm/msm/msm_iommu.c| 16 +-- drivers/iommu/arm-smmu.c | 127 - 4 files changed, 174 insertions(+), 14 deletions(-) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by
[PATCH v7 4/6] iommu/arm-smmu: Add the device_link between masters and smmu
From: Sricharan R <sricha...@codeaurora.org> Finally add the device link between the master device and smmu, so that the smmu gets runtime enabled/disabled only when the master needs it. This is done from add_device callback which gets called once when the master is added to the smmu. Signed-off-by: Sricharan R <sricha...@codeaurora.org> Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c024f69c1682..c7e924d553bd 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -215,6 +215,9 @@ struct arm_smmu_device { /* IOMMU core code handle */ struct iommu_device iommu; + + /* runtime PM link to master */ + struct device_link *link; }; enum arm_smmu_context_fmt { @@ -1425,6 +1428,17 @@ static int arm_smmu_add_device(struct device *dev) pm_runtime_put_sync(smmu->dev); + /* +* Establish the link between smmu and master, so that the +* smmu gets runtime enabled/disabled as per the master's +* needs. +*/ + smmu->link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME); + if (!smmu->link) + dev_warn(smmu->dev, +"Unable to create device link between %s and %s\n", +dev_name(smmu->dev), dev_name(dev)); + return 0; out_rpm_put: @@ -1449,6 +1463,8 @@ static void arm_smmu_remove_device(struct device *dev) cfg = fwspec->iommu_priv; smmu = cfg->smmu; + device_link_del(smmu->link); + ret = pm_runtime_get_sync(smmu->dev); if (ret) return; -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v7 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific clock and power requirements. This smmu core is used with multiple masters on msm8996, viz. mdss, video, etc. Add bindings for the same. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> Reviewed-by: Rob Herring <r...@kernel.org> --- .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++ drivers/iommu/arm-smmu.c | 13 +++ 2 files changed, 56 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 8a6ffce12af5..169222ae2706 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -17,10 +17,19 @@ conditions. "arm,mmu-401" "arm,mmu-500" "cavium,smmu-v2" +"qcom,-smmu-v2", "qcom,smmu-v2" depending on the particular implementation and/or the version of the architecture implemented. + A number of Qcom SoCs use qcom,smmu-v2 version of the IP. + "qcom,-smmu-v2" represents a soc specific compatible + string that should be present along with the "qcom,smmu-v2" + to facilitate SoC specific clocks/power connections and to + address specific bug fixes. + An example string would be - + "qcom,msm8996-smmu-v2", "qcom,smmu-v2". + - reg : Base address and size of the SMMU. - #global-interrupts : The number of global interrupts exposed by the @@ -71,6 +80,23 @@ conditions. or using stream matching with #iommu-cells = <2>, and may be ignored if present in such cases. +- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2" + implementation. + + "bus" clock for "qcom,smmu-v2" is required for downstream + bus access and for the smmu ptw. + + "iface" clock is required to access smmu's registers through + the TCU's programming interface. + +- clocks: Phandles for respective clocks described by clock-names. + +- power-domains: Phandles to SMMU's power domain specifier. This is + required even if SMMU belongs to the master's power + domain, as the SMMU will have to be enabled and + accessed before master gets enabled and linked to its + SMMU. + ** Deprecated properties: - mmu-masters (deprecated in favour of the generic "iommus" binding) : @@ -137,3 +163,20 @@ conditions. iommu-map = <0 0 0x400>; ... }; + + /* Qcom's arm,smmu-v2 implementation */ + smmu4: iommu { + compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; + reg = <0xd0 0x1>; + + #global-interrupts = <1>; + interrupts = , +, +; + #iommu-cells = <1>; + power-domains = < MDSS_GDSC>; + + clocks = < SMMU_MDP_AXI_CLK>, +< SMMU_MDP_AHB_CLK>; + clock-names = "bus", "iface"; + }; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index c7e924d553bd..721cf1291f85 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -119,6 +119,7 @@ enum arm_smmu_implementation { GENERIC_SMMU, ARM_MMU500, CAVIUM_SMMUV2, + QCOM_SMMUV2, }; struct arm_smmu_s2cr { @@ -1950,6 +1951,17 @@ struct arm_smmu_match_data { ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500); ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2); +static const char * const qcom_smmuv2_clks[] = { + "bus", "iface", +}; + +static const struct arm_smmu_match_data qcom_smmuv2 = { + .version = ARM_SMMU_V2, + .model = QCOM_SMMUV2, + .clks = qcom_smmuv2_clks, + .num_clks = ARRAY_SIZE(qcom_smmuv2_clks), +}; + static const struct of_device_id arm_smmu_of_match[] = { { .compatible = "arm,smmu-v1", .data = _generic_v1 }, { .compatible = "arm,smmu-v2", .data = _generic_v2 }, @@ -1957,6 +1969,7 @@ struct arm_smmu_match_data { { .compatible = "arm,mmu-401", .data = _mmu401 }, { .compatible = "arm,mmu-500", .data = _mmu500 }, { .compatible = "cavium,smmu-v2", .data = _smmuv2 }, + { .compatible = "qcom,smmu-v2", .data = _smmuv2 },
[PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
While handling the concerned iommu, there should not be a need to power control the drm devices from iommu interface. If these drm devices need to be powered around this time, the respective drivers should take care of this. Replace the pm_runtime_get/put_sync() with pm_runtime_get/put_suppliers() calls, to power-up the connected iommu through the device link interface. In case the device link is not setup these get/put_suppliers() calls will be a no-op, and the iommu driver should take care of powering on its devices accordingly. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/gpu/drm/msm/msm_iommu.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index b23d33622f37..1ab629bbee69 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names, struct msm_iommu *iommu = to_msm_iommu(mmu); int ret; - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_attach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return ret; } @@ -52,9 +52,9 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_detach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); } static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, @@ -63,9 +63,9 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, struct msm_iommu *iommu = to_msm_iommu(mmu); size_t ret; -// pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); -// pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); WARN_ON(ret < 0); return (ret == len) ? 0 : -EINVAL; @@ -76,9 +76,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_unmap(iommu->domain, iova, len); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 4/6] iommu/arm-smmu: Add the device_link between masters and smmu
Hi, On 1/31/2018 6:39 PM, Robin Murphy wrote: On 19/01/18 11:43, Vivek Gautam wrote: From: Sricharan R <sricha...@codeaurora.org> Finally add the device link between the master device and smmu, so that the smmu gets runtime enabled/disabled only when the master needs it. This is done from add_device callback which gets called once when the master is added to the smmu. Don't we need to balance this with a device_link_del() in .remove_device (like exynos-iommu does)? Right. Will add device_link_del() call. Thanks for pointing out. regards Vivek Robin. Signed-off-by: Sricharan R <sricha...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 95478bfb182c..33bbcfedb896 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1367,6 +1367,7 @@ static int arm_smmu_add_device(struct device *dev) struct arm_smmu_device *smmu; struct arm_smmu_master_cfg *cfg; struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct device_link *link; int i, ret; if (using_legacy_binding) { @@ -1428,6 +1429,16 @@ static int arm_smmu_add_device(struct device *dev) pm_runtime_put_sync(smmu->dev); + /* + * Establish the link between smmu and master, so that the + * smmu gets runtime enabled/disabled as per the master's + * needs. + */ + link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME); + if (!link) + dev_warn(smmu->dev, "Unable to create device link between %s and %s\n", + dev_name(smmu->dev), dev_name(dev)); + return 0; out_cfg_free: ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
On 2/1/2018 5:03 PM, Sricharan R wrote: Hi Robin, On 1/31/2018 6:36 PM, Robin Murphy wrote: On 19/01/18 11:43, Vivek Gautam wrote: From: Sricharan R <sricha...@codeaurora.org> The smmu device probe/remove and add/remove master device callbacks gets called when the smmu is not linked to its master, that is without the context of the master device. So calling runtime apis in those places separately. Signed-off-by: Sricharan R <sricha...@codeaurora.org> [vivek: Cleanup pm runtime calls] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 45 + 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 21acffe91a1c..95478bfb182c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -914,11 +914,15 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = _domain->cfg; - int irq; + int ret, irq; if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) return; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + /* * Disable the context bank and free the page tables before freeing * it. @@ -933,6 +937,8 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) free_io_pgtable_ops(smmu_domain->pgtbl_ops); __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); + + pm_runtime_put_sync(smmu->dev); } static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) @@ -1408,12 +1414,20 @@ static int arm_smmu_add_device(struct device *dev) while (i--) cfg->smendx[i] = INVALID_SMENDX; - ret = arm_smmu_master_alloc_smes(dev); + ret = pm_runtime_get_sync(smmu->dev); if (ret) goto out_cfg_free; + ret = arm_smmu_master_alloc_smes(dev); + if (ret) { + pm_runtime_put_sync(smmu->dev); + goto out_cfg_free; Please keep to the existing pattern and put this on the cleanup path with a new label, rather than inline. ok. + } + iommu_device_link(>iommu, dev); + pm_runtime_put_sync(smmu->dev); + return 0; out_cfg_free: @@ -1428,7 +1442,7 @@ static void arm_smmu_remove_device(struct device *dev) struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_master_cfg *cfg; struct arm_smmu_device *smmu; - + int ret; if (!fwspec || fwspec->ops != _smmu_ops) return; @@ -1436,8 +1450,21 @@ static void arm_smmu_remove_device(struct device *dev) cfg = fwspec->iommu_priv; smmu = cfg->smmu; + /* + * The device link between the master device and + * smmu is already purged at this point. + * So enable the power to smmu explicitly. + */ I don't understand this comment, especially since we don't even introduce device links until the following patch... :/ This is because the core device_del callback, does a device_links_purge for that device, before calling the remove_device notifier. As a result, have to explicitly turn on the power to iommu. Probably the comment should be removed, rest of the places we don't explain why we are turning on explicitly. Yes, will remove the comment here. + + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + iommu_device_unlink(>iommu, dev); arm_smmu_master_free_smes(fwspec); + + pm_runtime_put_sync(smmu->dev); + iommu_group_remove_device(dev); kfree(fwspec->iommu_priv); iommu_fwspec_free(dev); @@ -2130,6 +2157,14 @@ static int arm_smmu_device_probe(struct platform_device *pdev) if (err) return err; + platform_set_drvdata(pdev, smmu); + + pm_runtime_enable(dev); + + err = pm_runtime_get_sync(dev); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2171,9 +2206,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev) return err; } - platform_set_drvdata(pdev, smmu); arm_smmu_device_reset(smmu); arm_smmu_test_smr_masks(smmu); + pm_runtime_put_sync(dev); /* * For ACPI and generic DT bindings, an SMMU will be probed before @@ -2212,6 +2247,8 @@ static int arm_smmu_device_remove(struct platform_device *pdev) /* Turn the thing off */ writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); + pm_runtime_force_suspend(smmu->dev); Why do we need this? I guess it might be a Qualcomm-ism as I don't see anyone else calling it from .remove other than a couple of other qcom_* drivers. Given that we only get here during
Re: [PATCH v6 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant
On 1/30/2018 1:12 AM, Rob Herring wrote: On Fri, Jan 19, 2018 at 05:13:42PM +0530, Vivek Gautam wrote: qcom,smmu-v2 is an arm,smmu-v2 implementation with specific clock and power requirements. This smmu core is used with multiple masters on msm8996, viz. mdss, video, etc. Add bindings for the same. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++ drivers/iommu/arm-smmu.c | 13 +++ 2 files changed, 56 insertions(+) Reviewed-by: Rob Herring <r...@kernel.org> Thanks Rob. -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v6 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops
On 1/31/2018 5:53 PM, Robin Murphy wrote: On 19/01/18 11:43, Vivek Gautam wrote: From: Sricharan R <sricha...@codeaurora.org> The smmu needs to be functional only when the respective master's using it are active. The device_link feature helps to track such functional dependencies, so that the iommu gets powered when the master device enables itself using pm_runtime. So by adapting the smmu driver for runtime pm, above said dependency can be addressed. This patch adds the pm runtime/sleep callbacks to the driver and also the functions to parse the smmu clocks from DT and enable them in resume/suspend. Signed-off-by: Sricharan R <sricha...@codeaurora.org> Signed-off-by: Archit Taneja <arch...@codeaurora.org> [vivek: Clock rework to request bulk of clocks] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 55 ++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 78d4c6b8f1ba..21acffe91a1c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -205,6 +206,9 @@ struct arm_smmu_device { u32 num_global_irqs; u32 num_context_irqs; unsigned int *irqs; + struct clk_bulk_data *clocks; + int num_clks; + const char * const *clk_names; This seems unnecessary, as we use it a grand total of of once, during initialisation when we have the source data directly to hand. Just pass data->clks into arm_smmu_init_clks() as an additional argument. Sure, will do that. Otherwise, I think this looks reasonable; it's about as unobtrusive as it's going to get. Thanks for reviewing. regards Vivek Robin. u32 cavium_id_base; /* Specific to Cavium */ @@ -1685,6 +1689,25 @@ static int arm_smmu_id_size_to_bits(int size) } } +static int arm_smmu_init_clocks(struct arm_smmu_device *smmu) +{ + int i; + int num = smmu->num_clks; + + if (num < 1) + return 0; + + smmu->clocks = devm_kcalloc(smmu->dev, num, + sizeof(*smmu->clocks), GFP_KERNEL); + if (!smmu->clocks) + return -ENOMEM; + + for (i = 0; i < num; i++) + smmu->clocks[i].id = smmu->clk_names[i]; + + return devm_clk_bulk_get(smmu->dev, num, smmu->clocks); +} + static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) { unsigned long size; @@ -1897,10 +1920,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) struct arm_smmu_match_data { enum arm_smmu_arch_version version; enum arm_smmu_implementation model; + const char * const *clks; + int num_clks; }; #define ARM_SMMU_MATCH_DATA(name, ver, imp) \ -static struct arm_smmu_match_data name = { .version = ver, .model = imp } +static const struct arm_smmu_match_data name = { .version = ver, .model = imp } ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU); ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU); @@ -2001,6 +2026,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, data = of_device_get_match_data(dev); smmu->version = data->version; smmu->model = data->model; + smmu->clk_names = data->clks; + smmu->num_clks = data->num_clks; parse_driver_options(smmu); @@ -2099,6 +2126,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev) smmu->irqs[i] = irq; } + err = arm_smmu_init_clocks(smmu); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2197,7 +2228,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume); +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks); +} + +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks); + + return 0; +} + +static const struct dev_pm_ops arm_smmu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume) + SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend, + arm_smmu_runtime_resume, NULL) +}; static struct platform_driver arm_smmu_driver = { .driver = { ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 4/6] iommu/arm-smmu: Add the device_link between masters and smmu
From: Sricharan RFinally add the device link between the master device and smmu, so that the smmu gets runtime enabled/disabled only when the master needs it. This is done from add_device callback which gets called once when the master is added to the smmu. Signed-off-by: Sricharan R --- drivers/iommu/arm-smmu.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 95478bfb182c..33bbcfedb896 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1367,6 +1367,7 @@ static int arm_smmu_add_device(struct device *dev) struct arm_smmu_device *smmu; struct arm_smmu_master_cfg *cfg; struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct device_link *link; int i, ret; if (using_legacy_binding) { @@ -1428,6 +1429,16 @@ static int arm_smmu_add_device(struct device *dev) pm_runtime_put_sync(smmu->dev); + /* +* Establish the link between smmu and master, so that the +* smmu gets runtime enabled/disabled as per the master's +* needs. +*/ + link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME); + if (!link) + dev_warn(smmu->dev, "Unable to create device link between %s and %s\n", +dev_name(smmu->dev), dev_name(dev)); + return 0; out_cfg_free: -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 0/6] iommu/arm-smmu: Add runtime pm/sleep support
This series provides the support for turning on the arm-smmu's clocks/power domains using runtime pm. This is done using the recently introduced device links patches, which lets the smmu's runtime to follow the master's runtime pm, so the smmu remains powered only when the masters use it. It also adds support for Qcom's arm-smmu-v2 variant that has different clocks and power requirements. Took some reference from the exynos runtime patches [1]. After much discussion [3] over the use of pm_runtime_get/put() in .unmap op path for the arm-smmu, and after disussing over more than a couple of approaches to address this, we are putting forward the changes *without* using pm_runtime APIs in 'unmap'. Rather, letting the client device take the control of powering on/off the connected iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios when the iommu power can't be directly controlled by clients through device links. Rafael has agreed to export the suppliers APIs [4]. Hi Robin, Will, please consider reviewing this series. [V6] * Added Ack given by Rafael to first patch in the series. * Addressed Rob Herring's comment for adding soc specific compatible string as well besides 'qcom,smmu-v2'. [V5] * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over the list [3] for the last patch series. * Added a patch to export pm_runtime_get/put_suppliers() APIs to the series as agreed with Rafael [4]. * Added the related patch for msm drm iommu layer to use pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs. * Dropped arm-mmu500 clock patch since that would break existing platforms. * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect the IP version rather than the platform on which it is used. The same IP is used across multiple platforms including msm8996, and sdm845 etc. * Using clock bulk APIs to handle the clocks available to the IP as suggested by Stephen Boyd. * The first patch in v4 version of the patch-series: ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has already made it to mainline. [V4] * Reworked the clock handling part. We now take clock names as data in the driver for supported compatible versions, and loop over them to get, enable, and disable the clocks. * Using qcom,msm8996 based compatibles for bindings instead of a generic qcom compatible. * Refactor MMU500 patch to just add the necessary clock names data and corresponding bindings. * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by Stanimir on top of previous patch version. * Added a patch to fix error path in arm_smmu_add_device() * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings. [V3] * Reworked the patches to keep the clocks init/enabling function separately for each compatible. * Added clocks bindings for MMU40x/500. * Added a new compatible for qcom,smmu-v2 implementation and the clock bindings for the same. * Rebased on top of 4.11-rc1 [V2] * Split the patches little differently. * Addressed comments. * Removed the patch #4 [2] from previous post for arm-smmu context save restore. Planning to post this separately after reworking/addressing Robin's feedback. * Reversed the sequence to disable clocks than enabling. This was required for those cases where the clocks are populated in a dependent order from DT. [1] https://lkml.org/lkml/2016/10/20/70 [2] https://patchwork.kernel.org/patch/9389717/ [3] https://patchwork.kernel.org/patch/9827825/ [4] https://patchwork.kernel.org/patch/10102445/ Sricharan R (3): iommu/arm-smmu: Add pm_runtime/sleep ops iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device iommu/arm-smmu: Add the device_link between masters and smmu Vivek Gautam (3): base: power: runtime: Export pm_runtime_get/put_suppliers iommu/arm-smmu: Add support for qcom,smmu-v2 variant drm/msm: iommu: Replace runtime calls with runtime suppliers .../devicetree/bindings/iommu/arm,smmu.txt | 43 +++ drivers/base/power/runtime.c | 2 + drivers/gpu/drm/msm/msm_iommu.c| 16 +-- drivers/iommu/arm-smmu.c | 124 - 4 files changed, 171 insertions(+), 14 deletions(-) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
From: Sricharan R <sricha...@codeaurora.org> The smmu device probe/remove and add/remove master device callbacks gets called when the smmu is not linked to its master, that is without the context of the master device. So calling runtime apis in those places separately. Signed-off-by: Sricharan R <sricha...@codeaurora.org> [vivek: Cleanup pm runtime calls] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 45 + 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 21acffe91a1c..95478bfb182c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -914,11 +914,15 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = _domain->cfg; - int irq; + int ret, irq; if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) return; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + /* * Disable the context bank and free the page tables before freeing * it. @@ -933,6 +937,8 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) free_io_pgtable_ops(smmu_domain->pgtbl_ops); __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); + + pm_runtime_put_sync(smmu->dev); } static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) @@ -1408,12 +1414,20 @@ static int arm_smmu_add_device(struct device *dev) while (i--) cfg->smendx[i] = INVALID_SMENDX; - ret = arm_smmu_master_alloc_smes(dev); + ret = pm_runtime_get_sync(smmu->dev); if (ret) goto out_cfg_free; + ret = arm_smmu_master_alloc_smes(dev); + if (ret) { + pm_runtime_put_sync(smmu->dev); + goto out_cfg_free; + } + iommu_device_link(>iommu, dev); + pm_runtime_put_sync(smmu->dev); + return 0; out_cfg_free: @@ -1428,7 +1442,7 @@ static void arm_smmu_remove_device(struct device *dev) struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_master_cfg *cfg; struct arm_smmu_device *smmu; - + int ret; if (!fwspec || fwspec->ops != _smmu_ops) return; @@ -1436,8 +1450,21 @@ static void arm_smmu_remove_device(struct device *dev) cfg = fwspec->iommu_priv; smmu = cfg->smmu; + /* +* The device link between the master device and +* smmu is already purged at this point. +* So enable the power to smmu explicitly. +*/ + + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + iommu_device_unlink(>iommu, dev); arm_smmu_master_free_smes(fwspec); + + pm_runtime_put_sync(smmu->dev); + iommu_group_remove_device(dev); kfree(fwspec->iommu_priv); iommu_fwspec_free(dev); @@ -2130,6 +2157,14 @@ static int arm_smmu_device_probe(struct platform_device *pdev) if (err) return err; + platform_set_drvdata(pdev, smmu); + + pm_runtime_enable(dev); + + err = pm_runtime_get_sync(dev); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2171,9 +2206,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev) return err; } - platform_set_drvdata(pdev, smmu); arm_smmu_device_reset(smmu); arm_smmu_test_smr_masks(smmu); + pm_runtime_put_sync(dev); /* * For ACPI and generic DT bindings, an SMMU will be probed before @@ -2212,6 +2247,8 @@ static int arm_smmu_device_remove(struct platform_device *pdev) /* Turn the thing off */ writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); + pm_runtime_force_suspend(smmu->dev); + return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
While handling the concerned iommu, there should not be a need to power control the drm devices from iommu interface. If these drm devices need to be powered around this time, the respective drivers should take care of this. Replace the pm_runtime_get/put_sync() with pm_runtime_get/put_suppliers() calls, to power-up the connected iommu through the device link interface. In case the device link is not setup these get/put_suppliers() calls will be a no-op, and the iommu driver should take care of powering on its devices accordingly. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/gpu/drm/msm/msm_iommu.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index b23d33622f37..1ab629bbee69 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names, struct msm_iommu *iommu = to_msm_iommu(mmu); int ret; - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_attach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return ret; } @@ -52,9 +52,9 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_detach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); } static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, @@ -63,9 +63,9 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, struct msm_iommu *iommu = to_msm_iommu(mmu); size_t ret; -// pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); -// pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); WARN_ON(ret < 0); return (ret == len) ? 0 : -EINVAL; @@ -76,9 +76,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_unmap(iommu->domain, iova, len); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific clock and power requirements. This smmu core is used with multiple masters on msm8996, viz. mdss, video, etc. Add bindings for the same. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- .../devicetree/bindings/iommu/arm,smmu.txt | 43 ++ drivers/iommu/arm-smmu.c | 13 +++ 2 files changed, 56 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 8a6ffce12af5..169222ae2706 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -17,10 +17,19 @@ conditions. "arm,mmu-401" "arm,mmu-500" "cavium,smmu-v2" +"qcom,-smmu-v2", "qcom,smmu-v2" depending on the particular implementation and/or the version of the architecture implemented. + A number of Qcom SoCs use qcom,smmu-v2 version of the IP. + "qcom,-smmu-v2" represents a soc specific compatible + string that should be present along with the "qcom,smmu-v2" + to facilitate SoC specific clocks/power connections and to + address specific bug fixes. + An example string would be - + "qcom,msm8996-smmu-v2", "qcom,smmu-v2". + - reg : Base address and size of the SMMU. - #global-interrupts : The number of global interrupts exposed by the @@ -71,6 +80,23 @@ conditions. or using stream matching with #iommu-cells = <2>, and may be ignored if present in such cases. +- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2" + implementation. + + "bus" clock for "qcom,smmu-v2" is required for downstream + bus access and for the smmu ptw. + + "iface" clock is required to access smmu's registers through + the TCU's programming interface. + +- clocks: Phandles for respective clocks described by clock-names. + +- power-domains: Phandles to SMMU's power domain specifier. This is + required even if SMMU belongs to the master's power + domain, as the SMMU will have to be enabled and + accessed before master gets enabled and linked to its + SMMU. + ** Deprecated properties: - mmu-masters (deprecated in favour of the generic "iommus" binding) : @@ -137,3 +163,20 @@ conditions. iommu-map = <0 0 0x400>; ... }; + + /* Qcom's arm,smmu-v2 implementation */ + smmu4: iommu { + compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; + reg = <0xd0 0x1>; + + #global-interrupts = <1>; + interrupts = , +, +; + #iommu-cells = <1>; + power-domains = < MDSS_GDSC>; + + clocks = < SMMU_MDP_AXI_CLK>, +< SMMU_MDP_AHB_CLK>; + clock-names = "bus", "iface"; + }; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 33bbcfedb896..2ade214c41bc 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -119,6 +119,7 @@ enum arm_smmu_implementation { GENERIC_SMMU, ARM_MMU500, CAVIUM_SMMUV2, + QCOM_SMMUV2, }; struct arm_smmu_s2cr { @@ -1971,6 +1972,17 @@ struct arm_smmu_match_data { ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500); ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2); +static const char * const qcom_smmuv2_clks[] = { + "bus", "iface", +}; + +static const struct arm_smmu_match_data qcom_smmuv2 = { + .version = ARM_SMMU_V2, + .model = QCOM_SMMUV2, + .clks = qcom_smmuv2_clks, + .num_clks = ARRAY_SIZE(qcom_smmuv2_clks), +}; + static const struct of_device_id arm_smmu_of_match[] = { { .compatible = "arm,smmu-v1", .data = _generic_v1 }, { .compatible = "arm,smmu-v2", .data = _generic_v2 }, @@ -1978,6 +1990,7 @@ struct arm_smmu_match_data { { .compatible = "arm,mmu-401", .data = _mmu401 }, { .compatible = "arm,mmu-500", .data = _mmu500 }, { .compatible = "cavium,smmu-v2", .data = _smmuv2 }, + { .compatible = "qcom,smmu-v2", .data = _smmuv2 }, { }, }; MODULE_DEVICE_TABLE(of, arm_smmu_of_match); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
The device link allows the pm framework to tie the supplier and consumer. So, whenever the consumer is powered-on the supplier is powered-on first. There are however cases in which the consumer wants to power-on the supplier, but not itself. E.g., A Graphics or multimedia driver wants to power-on the SMMU to unmap a buffer and finish the TLB operations without powering on itself. Some of these unmap requests are coming from the user space when the controller itself is not powered-up, and it can be huge penalty in terms of power and latency to power-up the graphics/mm controllers. There can be an argument that the supplier should handle this case on its own and there should not be a need for the consumer to power-on the supplier. But as discussed on the thread [1] about ARM-SMMU runtime pm, we don't want to introduce runtime pm calls in atomic path in arm_smmu_unmap. [1] https://patchwork.kernel.org/patch/9827825/ Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> Acked-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com> --- drivers/base/power/runtime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 6e89b51ea3d9..06a2a88fe866 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers); /** * pm_runtime_put_suppliers - Drop references to supplier devices. @@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers); void pm_runtime_new_link(struct device *dev) { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v6 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops
From: Sricharan R <sricha...@codeaurora.org> The smmu needs to be functional only when the respective master's using it are active. The device_link feature helps to track such functional dependencies, so that the iommu gets powered when the master device enables itself using pm_runtime. So by adapting the smmu driver for runtime pm, above said dependency can be addressed. This patch adds the pm runtime/sleep callbacks to the driver and also the functions to parse the smmu clocks from DT and enable them in resume/suspend. Signed-off-by: Sricharan R <sricha...@codeaurora.org> Signed-off-by: Archit Taneja <arch...@codeaurora.org> [vivek: Clock rework to request bulk of clocks] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 55 ++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 78d4c6b8f1ba..21acffe91a1c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -205,6 +206,9 @@ struct arm_smmu_device { u32 num_global_irqs; u32 num_context_irqs; unsigned int*irqs; + struct clk_bulk_data*clocks; + int num_clks; + const char * const *clk_names; u32 cavium_id_base; /* Specific to Cavium */ @@ -1685,6 +1689,25 @@ static int arm_smmu_id_size_to_bits(int size) } } +static int arm_smmu_init_clocks(struct arm_smmu_device *smmu) +{ + int i; + int num = smmu->num_clks; + + if (num < 1) + return 0; + + smmu->clocks = devm_kcalloc(smmu->dev, num, + sizeof(*smmu->clocks), GFP_KERNEL); + if (!smmu->clocks) + return -ENOMEM; + + for (i = 0; i < num; i++) + smmu->clocks[i].id = smmu->clk_names[i]; + + return devm_clk_bulk_get(smmu->dev, num, smmu->clocks); +} + static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) { unsigned long size; @@ -1897,10 +1920,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) struct arm_smmu_match_data { enum arm_smmu_arch_version version; enum arm_smmu_implementation model; + const char * const *clks; + int num_clks; }; #define ARM_SMMU_MATCH_DATA(name, ver, imp)\ -static struct arm_smmu_match_data name = { .version = ver, .model = imp } +static const struct arm_smmu_match_data name = { .version = ver, .model = imp } ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU); ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU); @@ -2001,6 +2026,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, data = of_device_get_match_data(dev); smmu->version = data->version; smmu->model = data->model; + smmu->clk_names = data->clks; + smmu->num_clks = data->num_clks; parse_driver_options(smmu); @@ -2099,6 +2126,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev) smmu->irqs[i] = irq; } + err = arm_smmu_init_clocks(smmu); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2197,7 +2228,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume); +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks); +} + +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks); + + return 0; +} + +static const struct dev_pm_ops arm_smmu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume) + SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend, + arm_smmu_runtime_resume, NULL) +}; static struct platform_driver arm_smmu_driver = { .driver = { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
On 01/12/2018 04:23 AM, Rafael J. Wysocki wrote: On Tue, Jan 9, 2018 at 11:01 AM, Vivek Gautam <vivek.gau...@codeaurora.org> wrote: The device link allows the pm framework to tie the supplier and consumer. So, whenever the consumer is powered-on the supplier is powered-on first. There are however cases in which the consumer wants to power-on the supplier, but not itself. E.g., A Graphics or multimedia driver wants to power-on the SMMU to unmap a buffer and finish the TLB operations without powering on itself. Some of these unmap requests are coming from the user space when the controller itself is not powered-up, and it can be huge penalty in terms of power and latency to power-up the graphics/mm controllers. There can be an argument that the supplier should handle this case on its own and there should not be a need for the consumer to power-on the supplier. But as discussed on the thread [1] about ARM-SMMU runtime pm, we don't want to introduce runtime pm calls in atomic path in arm_smmu_unmap. [1] https://patchwork.kernel.org/patch/9827825/ Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> Acked-by: Rafael J. Wysocki <rafael.j.wyso...@intel.com> Please feel free to route this along with the rest of the series. Thanks Rafael. regards Vivek Thanks! --- * This is v2 of the patch [1]. Adding it to this patch series. [1] https://patchwork.kernel.org/patch/10102447/ drivers/base/power/runtime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 6e89b51ea3d9..06a2a88fe866 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers); /** * pm_runtime_put_suppliers - Drop references to supplier devices. @@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers); void pm_runtime_new_link(struct device *dev) { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant
Hi Rob, On 01/12/2018 03:53 AM, Rob Herring wrote: On Tue, Jan 09, 2018 at 03:31:48PM +0530, Vivek Gautam wrote: qcom,smmu-v2 is an arm,smmu-v2 implementation with specific clock and power requirements. This smmu core is used with multiple masters on msm8996, viz. mdss, video, etc. Add bindings for the same. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- * Major change in this patch - Changed compatible string from 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect the IP version rather than the platform on which it is used. The bugs and how things are connected are all the same? I'd suggest you keep both strings. Sure, compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2"; The same IP is used across multiple platforms including msm8996, and sdm845 etc. But for only 2 or so platforms a fallback is not really worth it. You'll probably be on SMMUv3 before too long... Right. There's msm8998 as well, but as you said keeping both strings will make more sense. Thanks. Best regards Vivek [snip] -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 1/6] base: power: runtime: Export pm_runtime_get/put_suppliers
The device link allows the pm framework to tie the supplier and consumer. So, whenever the consumer is powered-on the supplier is powered-on first. There are however cases in which the consumer wants to power-on the supplier, but not itself. E.g., A Graphics or multimedia driver wants to power-on the SMMU to unmap a buffer and finish the TLB operations without powering on itself. Some of these unmap requests are coming from the user space when the controller itself is not powered-up, and it can be huge penalty in terms of power and latency to power-up the graphics/mm controllers. There can be an argument that the supplier should handle this case on its own and there should not be a need for the consumer to power-on the supplier. But as discussed on the thread [1] about ARM-SMMU runtime pm, we don't want to introduce runtime pm calls in atomic path in arm_smmu_unmap. [1] https://patchwork.kernel.org/patch/9827825/ Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- * This is v2 of the patch [1]. Adding it to this patch series. [1] https://patchwork.kernel.org/patch/10102447/ drivers/base/power/runtime.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 6e89b51ea3d9..06a2a88fe866 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -1579,6 +1579,7 @@ void pm_runtime_get_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_get_suppliers); /** * pm_runtime_put_suppliers - Drop references to supplier devices. @@ -1597,6 +1598,7 @@ void pm_runtime_put_suppliers(struct device *dev) device_links_read_unlock(idx); } +EXPORT_SYMBOL_GPL(pm_runtime_put_suppliers); void pm_runtime_new_link(struct device *dev) { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 5/6] iommu/arm-smmu: Add support for qcom,smmu-v2 variant
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific clock and power requirements. This smmu core is used with multiple masters on msm8996, viz. mdss, video, etc. Add bindings for the same. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- * Major change in this patch - Changed compatible string from 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect the IP version rather than the platform on which it is used. The same IP is used across multiple platforms including msm8996, and sdm845 etc. .../devicetree/bindings/iommu/arm,smmu.txt | 35 ++ drivers/iommu/arm-smmu.c | 13 2 files changed, 48 insertions(+) diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt b/Documentation/devicetree/bindings/iommu/arm,smmu.txt index 8a6ffce12af5..e4951288c87c 100644 --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt @@ -17,6 +17,7 @@ conditions. "arm,mmu-401" "arm,mmu-500" "cavium,smmu-v2" +"qcom,smmu-v2" depending on the particular implementation and/or the version of the architecture implemented. @@ -71,6 +72,23 @@ conditions. or using stream matching with #iommu-cells = <2>, and may be ignored if present in such cases. +- clock-names:Should be "bus", and "iface" for "qcom,smmu-v2" + implementation. + + "bus" clock for "qcom,smmu-v2" is required for downstream + bus access and for the smmu ptw. + + "iface" clock is required to access smmu's registers through + the TCU's programming interface. + +- clocks: Phandles for respective clocks described by clock-names. + +- power-domains: Phandles to SMMU's power domain specifier. This is + required even if SMMU belongs to the master's power + domain, as the SMMU will have to be enabled and + accessed before master gets enabled and linked to its + SMMU. + ** Deprecated properties: - mmu-masters (deprecated in favour of the generic "iommus" binding) : @@ -137,3 +155,20 @@ conditions. iommu-map = <0 0 0x400>; ... }; + + /* Qcom's arm,smmu-v2 implementation */ + smmu4: iommu { + compatible = "qcom,smmu-v2"; + reg = <0xd0 0x1>; + + #global-interrupts = <1>; + interrupts = , +, +; + #iommu-cells = <1>; + power-domains = < MDSS_GDSC>; + + clocks = < SMMU_MDP_AXI_CLK>, +< SMMU_MDP_AHB_CLK>; + clock-names = "bus", "iface"; + }; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 33bbcfedb896..2ade214c41bc 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -119,6 +119,7 @@ enum arm_smmu_implementation { GENERIC_SMMU, ARM_MMU500, CAVIUM_SMMUV2, + QCOM_SMMUV2, }; struct arm_smmu_s2cr { @@ -1971,6 +1972,17 @@ struct arm_smmu_match_data { ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500); ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2); +static const char * const qcom_smmuv2_clks[] = { + "bus", "iface", +}; + +static const struct arm_smmu_match_data qcom_smmuv2 = { + .version = ARM_SMMU_V2, + .model = QCOM_SMMUV2, + .clks = qcom_smmuv2_clks, + .num_clks = ARRAY_SIZE(qcom_smmuv2_clks), +}; + static const struct of_device_id arm_smmu_of_match[] = { { .compatible = "arm,smmu-v1", .data = _generic_v1 }, { .compatible = "arm,smmu-v2", .data = _generic_v2 }, @@ -1978,6 +1990,7 @@ struct arm_smmu_match_data { { .compatible = "arm,mmu-401", .data = _mmu401 }, { .compatible = "arm,mmu-500", .data = _mmu500 }, { .compatible = "cavium,smmu-v2", .data = _smmuv2 }, + { .compatible = "qcom,smmu-v2", .data = _smmuv2 }, { }, }; MODULE_DEVICE_TABLE(of, arm_smmu_of_match); -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 4/6] iommu/arm-smmu: Add the device_link between masters and smmu
From: Sricharan RFinally add the device link between the master device and smmu, so that the smmu gets runtime enabled/disabled only when the master needs it. This is done from add_device callback which gets called once when the master is added to the smmu. Signed-off-by: Sricharan R --- drivers/iommu/arm-smmu.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 95478bfb182c..33bbcfedb896 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1367,6 +1367,7 @@ static int arm_smmu_add_device(struct device *dev) struct arm_smmu_device *smmu; struct arm_smmu_master_cfg *cfg; struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct device_link *link; int i, ret; if (using_legacy_binding) { @@ -1428,6 +1429,16 @@ static int arm_smmu_add_device(struct device *dev) pm_runtime_put_sync(smmu->dev); + /* +* Establish the link between smmu and master, so that the +* smmu gets runtime enabled/disabled as per the master's +* needs. +*/ + link = device_link_add(dev, smmu->dev, DL_FLAG_PM_RUNTIME); + if (!link) + dev_warn(smmu->dev, "Unable to create device link between %s and %s\n", +dev_name(smmu->dev), dev_name(dev)); + return 0; out_cfg_free: -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 0/6] iommu/arm-smmu: Add runtime pm/sleep support
This series provides the support for turning on the arm-smmu's clocks/power domains using runtime pm. This is done using the recently introduced device links patches, which lets the smmu's runtime to follow the master's runtime pm, so the smmu remains powered only when the masters use it. It also adds support for Qcom's arm-smmu-v2 variant that has different clocks and power requirements. Took some reference from the exynos runtime patches [2]. Previous version of the patchset [1]. After much discussion [4] over the use of pm_runtime_get/put() in .unmap op path for the arm-smmu, and after disussing over more than a couple of approaches to address this, we are putting forward the changes *without* using pm_runtime APIs in 'unmap'. Rather, letting the client device take the control of powering on/off the connected iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios when the iommu power can't be directly controlled by clients through device links. Rafael has agreed to export the suppliers APIs [5]. [V5] * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over the list [4] for the last patch series. * Added a patch to export pm_runtime_get/put_suppliers() APIs to the series as agreed with Rafael [5]. * Added the related patch for msm drm iommu layer to use pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs. * Dropped arm-mmu500 clock patch since that would break existing platforms. * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect the IP version rather than the platform on which it is used. The same IP is used across multiple platforms including msm8996, and sdm845 etc. * Using clock bulk APIs to handle the clocks available to the IP as suggested by Stephen Boyd. * The first patch in v4 version of the patch-series: ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has already made it to mainline. [V4] * Reworked the clock handling part. We now take clock names as data in the driver for supported compatible versions, and loop over them to get, enable, and disable the clocks. * Using qcom,msm8996 based compatibles for bindings instead of a generic qcom compatible. * Refactor MMU500 patch to just add the necessary clock names data and corresponding bindings. * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by Stanimir on top of previous patch version. * Added a patch to fix error path in arm_smmu_add_device() * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings. [V3] * Reworked the patches to keep the clocks init/enabling function separately for each compatible. * Added clocks bindings for MMU40x/500. * Added a new compatible for qcom,smmu-v2 implementation and the clock bindings for the same. * Rebased on top of 4.11-rc1 [V2] * Split the patches little differently. * Addressed comments. * Removed the patch #4 [3] from previous post for arm-smmu context save restore. Planning to post this separately after reworking/addressing Robin's feedback. * Reversed the sequence to disable clocks than enabling. This was required for those cases where the clocks are populated in a dependent order from DT. [1] https://www.spinics.net/lists/arm-kernel/msg567488.html [2] https://lkml.org/lkml/2016/10/20/70 [3] https://patchwork.kernel.org/patch/9389717/ [4] https://patchwork.kernel.org/patch/9827825/ [5] https://patchwork.kernel.org/patch/10102445/ Sricharan R (3): iommu/arm-smmu: Add pm_runtime/sleep ops iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device iommu/arm-smmu: Add the device_link between masters and smmu Vivek Gautam (3): base: power: runtime: Export pm_runtime_get/put_suppliers iommu/arm-smmu: Add support for qcom,smmu-v2 variant drm/msm: iommu: Replace runtime calls with runtime suppliers .../devicetree/bindings/iommu/arm,smmu.txt | 35 ++ drivers/base/power/runtime.c | 2 + drivers/gpu/drm/msm/msm_iommu.c| 16 +-- drivers/iommu/arm-smmu.c | 124 - 4 files changed, 163 insertions(+), 14 deletions(-) -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 3/6] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
From: Sricharan R <sricha...@codeaurora.org> The smmu device probe/remove and add/remove master device callbacks gets called when the smmu is not linked to its master, that is without the context of the master device. So calling runtime apis in those places separately. Signed-off-by: Sricharan R <sricha...@codeaurora.org> [vivek: Cleanup pm runtime calls] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 45 + 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 21acffe91a1c..95478bfb182c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -914,11 +914,15 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_device *smmu = smmu_domain->smmu; struct arm_smmu_cfg *cfg = _domain->cfg; - int irq; + int ret, irq; if (!smmu || domain->type == IOMMU_DOMAIN_IDENTITY) return; + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + /* * Disable the context bank and free the page tables before freeing * it. @@ -933,6 +937,8 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain) free_io_pgtable_ops(smmu_domain->pgtbl_ops); __arm_smmu_free_bitmap(smmu->context_map, cfg->cbndx); + + pm_runtime_put_sync(smmu->dev); } static struct iommu_domain *arm_smmu_domain_alloc(unsigned type) @@ -1408,12 +1414,20 @@ static int arm_smmu_add_device(struct device *dev) while (i--) cfg->smendx[i] = INVALID_SMENDX; - ret = arm_smmu_master_alloc_smes(dev); + ret = pm_runtime_get_sync(smmu->dev); if (ret) goto out_cfg_free; + ret = arm_smmu_master_alloc_smes(dev); + if (ret) { + pm_runtime_put_sync(smmu->dev); + goto out_cfg_free; + } + iommu_device_link(>iommu, dev); + pm_runtime_put_sync(smmu->dev); + return 0; out_cfg_free: @@ -1428,7 +1442,7 @@ static void arm_smmu_remove_device(struct device *dev) struct iommu_fwspec *fwspec = dev->iommu_fwspec; struct arm_smmu_master_cfg *cfg; struct arm_smmu_device *smmu; - + int ret; if (!fwspec || fwspec->ops != _smmu_ops) return; @@ -1436,8 +1450,21 @@ static void arm_smmu_remove_device(struct device *dev) cfg = fwspec->iommu_priv; smmu = cfg->smmu; + /* +* The device link between the master device and +* smmu is already purged at this point. +* So enable the power to smmu explicitly. +*/ + + ret = pm_runtime_get_sync(smmu->dev); + if (ret) + return; + iommu_device_unlink(>iommu, dev); arm_smmu_master_free_smes(fwspec); + + pm_runtime_put_sync(smmu->dev); + iommu_group_remove_device(dev); kfree(fwspec->iommu_priv); iommu_fwspec_free(dev); @@ -2130,6 +2157,14 @@ static int arm_smmu_device_probe(struct platform_device *pdev) if (err) return err; + platform_set_drvdata(pdev, smmu); + + pm_runtime_enable(dev); + + err = pm_runtime_get_sync(dev); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2171,9 +2206,9 @@ static int arm_smmu_device_probe(struct platform_device *pdev) return err; } - platform_set_drvdata(pdev, smmu); arm_smmu_device_reset(smmu); arm_smmu_test_smr_masks(smmu); + pm_runtime_put_sync(dev); /* * For ACPI and generic DT bindings, an SMMU will be probed before @@ -2212,6 +2247,8 @@ static int arm_smmu_device_remove(struct platform_device *pdev) /* Turn the thing off */ writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); + pm_runtime_force_suspend(smmu->dev); + return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
Re: [PATCH v5 0/6] iommu/arm-smmu: Add runtime pm/sleep support
On 01/09/2018 04:53 PM, Rafael J. Wysocki wrote: On Tuesday, January 9, 2018 11:01:43 AM CET Vivek Gautam wrote: This series provides the support for turning on the arm-smmu's clocks/power domains using runtime pm. This is done using the recently introduced device links patches, which lets the smmu's runtime to follow the master's runtime pm, so the smmu remains powered only when the masters use it. It also adds support for Qcom's arm-smmu-v2 variant that has different clocks and power requirements. Took some reference from the exynos runtime patches [2]. Previous version of the patchset [1]. After much discussion [4] over the use of pm_runtime_get/put() in .unmap op path for the arm-smmu, and after disussing over more than a couple of approaches to address this, we are putting forward the changes *without* using pm_runtime APIs in 'unmap'. Rather, letting the client device take the control of powering on/off the connected iommu through pm_runtime_get(put)_suppliers() APIs for the scnerios when the iommu power can't be directly controlled by clients through device links. Rafael has agreed to export the suppliers APIs [5]. [V5] * Dropped runtime pm calls from "arm_smmu_unmap" op as discussed over the list [4] for the last patch series. * Added a patch to export pm_runtime_get/put_suppliers() APIs to the series as agreed with Rafael [5]. * Added the related patch for msm drm iommu layer to use pm_runtime_get/put_suppliers() APIs in msm_mmu_funcs. * Dropped arm-mmu500 clock patch since that would break existing platforms. * Changed compatible 'qcom,msm8996-smmu-v2' to 'qcom,smmu-v2' to reflect the IP version rather than the platform on which it is used. The same IP is used across multiple platforms including msm8996, and sdm845 etc. * Using clock bulk APIs to handle the clocks available to the IP as suggested by Stephen Boyd. * The first patch in v4 version of the patch-series: ("iommu/arm-smmu: Fix the error path in arm_smmu_add_device") has already made it to mainline. [V4] * Reworked the clock handling part. We now take clock names as data in the driver for supported compatible versions, and loop over them to get, enable, and disable the clocks. * Using qcom,msm8996 based compatibles for bindings instead of a generic qcom compatible. * Refactor MMU500 patch to just add the necessary clock names data and corresponding bindings. * Added the pm_runtime_get/put() calls in .unmap iommu op (fix added by Stanimir on top of previous patch version. * Added a patch to fix error path in arm_smmu_add_device() * Removed patch 3/5 of V3 patch series that added qcom,smmu-v2 bindings. [V3] * Reworked the patches to keep the clocks init/enabling function separately for each compatible. * Added clocks bindings for MMU40x/500. * Added a new compatible for qcom,smmu-v2 implementation and the clock bindings for the same. * Rebased on top of 4.11-rc1 [V2] * Split the patches little differently. * Addressed comments. * Removed the patch #4 [3] from previous post for arm-smmu context save restore. Planning to post this separately after reworking/addressing Robin's feedback. * Reversed the sequence to disable clocks than enabling. This was required for those cases where the clocks are populated in a dependent order from DT. [1] https://www.spinics.net/lists/arm-kernel/msg567488.html [2] https://lkml.org/lkml/2016/10/20/70 [3] https://patchwork.kernel.org/patch/9389717/ [4] https://patchwork.kernel.org/patch/9827825/ [5] https://patchwork.kernel.org/patch/10102445/ Sricharan R (3): iommu/arm-smmu: Add pm_runtime/sleep ops iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device iommu/arm-smmu: Add the device_link between masters and smmu Vivek Gautam (3): base: power: runtime: Export pm_runtime_get/put_suppliers iommu/arm-smmu: Add support for qcom,smmu-v2 variant drm/msm: iommu: Replace runtime calls with runtime suppliers .../devicetree/bindings/iommu/arm,smmu.txt | 35 ++ drivers/base/power/runtime.c | 2 + drivers/gpu/drm/msm/msm_iommu.c| 16 +-- drivers/iommu/arm-smmu.c | 124 - 4 files changed, 163 insertions(+), 14 deletions(-) I need some time to review the series. Sure, thanks Rafael. regards Vivek Thanks, Rafael -- To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project ___ dri-devel mailing list dri-dev
[PATCH v5 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers
While handling the concerned iommu, there should not be a need to power control the drm devices from iommu interface. If these drm devices need to be powered around this time, the respective drivers should take care of this. Replace the pm_runtime_get/put_sync() with pm_runtime_get/put_suppliers() calls, to power-up the connected iommu through the device link interface. In case the device link is not setup these get/put_suppliers() calls will be a no-op, and the iommu driver should take care of powering on its devices accordingly. Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- * New patch added in this series for client side change for using pm_runtime_get_suppliers() and pm_runtime_put_suppliers(). drivers/gpu/drm/msm/msm_iommu.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index b23d33622f37..1ab629bbee69 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -40,9 +40,9 @@ static int msm_iommu_attach(struct msm_mmu *mmu, const char * const *names, struct msm_iommu *iommu = to_msm_iommu(mmu); int ret; - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_attach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return ret; } @@ -52,9 +52,9 @@ static void msm_iommu_detach(struct msm_mmu *mmu, const char * const *names, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_detach_device(iommu->domain, mmu->dev); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); } static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, @@ -63,9 +63,9 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, struct msm_iommu *iommu = to_msm_iommu(mmu); size_t ret; -// pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); -// pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); WARN_ON(ret < 0); return (ret == len) ? 0 : -EINVAL; @@ -76,9 +76,9 @@ static int msm_iommu_unmap(struct msm_mmu *mmu, uint64_t iova, { struct msm_iommu *iommu = to_msm_iommu(mmu); - pm_runtime_get_sync(mmu->dev); + pm_runtime_get_suppliers(mmu->dev); iommu_unmap(iommu->domain, iova, len); - pm_runtime_put_sync(mmu->dev); + pm_runtime_put_suppliers(mmu->dev); return 0; } -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH v5 2/6] iommu/arm-smmu: Add pm_runtime/sleep ops
From: Sricharan R <sricha...@codeaurora.org> The smmu needs to be functional only when the respective master's using it are active. The device_link feature helps to track such functional dependencies, so that the iommu gets powered when the master device enables itself using pm_runtime. So by adapting the smmu driver for runtime pm, above said dependency can be addressed. This patch adds the pm runtime/sleep callbacks to the driver and also the functions to parse the smmu clocks from DT and enable them in resume/suspend. Signed-off-by: Sricharan R <sricha...@codeaurora.org> Signed-off-by: Archit Taneja <arch...@codeaurora.org> [vivek: Clock rework to request bulk of clocks] Signed-off-by: Vivek Gautam <vivek.gau...@codeaurora.org> --- drivers/iommu/arm-smmu.c | 55 ++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 78d4c6b8f1ba..21acffe91a1c 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -205,6 +206,9 @@ struct arm_smmu_device { u32 num_global_irqs; u32 num_context_irqs; unsigned int*irqs; + struct clk_bulk_data*clocks; + int num_clks; + const char * const *clk_names; u32 cavium_id_base; /* Specific to Cavium */ @@ -1685,6 +1689,25 @@ static int arm_smmu_id_size_to_bits(int size) } } +static int arm_smmu_init_clocks(struct arm_smmu_device *smmu) +{ + int i; + int num = smmu->num_clks; + + if (num < 1) + return 0; + + smmu->clocks = devm_kcalloc(smmu->dev, num, + sizeof(*smmu->clocks), GFP_KERNEL); + if (!smmu->clocks) + return -ENOMEM; + + for (i = 0; i < num; i++) + smmu->clocks[i].id = smmu->clk_names[i]; + + return devm_clk_bulk_get(smmu->dev, num, smmu->clocks); +} + static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) { unsigned long size; @@ -1897,10 +1920,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu) struct arm_smmu_match_data { enum arm_smmu_arch_version version; enum arm_smmu_implementation model; + const char * const *clks; + int num_clks; }; #define ARM_SMMU_MATCH_DATA(name, ver, imp)\ -static struct arm_smmu_match_data name = { .version = ver, .model = imp } +static const struct arm_smmu_match_data name = { .version = ver, .model = imp } ARM_SMMU_MATCH_DATA(smmu_generic_v1, ARM_SMMU_V1, GENERIC_SMMU); ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, GENERIC_SMMU); @@ -2001,6 +2026,8 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev, data = of_device_get_match_data(dev); smmu->version = data->version; smmu->model = data->model; + smmu->clk_names = data->clks; + smmu->num_clks = data->num_clks; parse_driver_options(smmu); @@ -2099,6 +2126,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev) smmu->irqs[i] = irq; } + err = arm_smmu_init_clocks(smmu); + if (err) + return err; + err = arm_smmu_device_cfg_probe(smmu); if (err) return err; @@ -2197,7 +2228,27 @@ static int __maybe_unused arm_smmu_pm_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume); +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + return clk_bulk_prepare_enable(smmu->num_clks, smmu->clocks); +} + +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev) +{ + struct arm_smmu_device *smmu = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(smmu->num_clks, smmu->clocks); + + return 0; +} + +static const struct dev_pm_ops arm_smmu_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(NULL, arm_smmu_pm_resume) + SET_RUNTIME_PM_OPS(arm_smmu_runtime_suspend, + arm_smmu_runtime_resume, NULL) +}; static struct platform_driver arm_smmu_driver = { .driver = { -- QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation ___ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
[PATCH V2 RESEND] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
On Mon, Nov 24, 2014 at 4:26 PM, Thierry Reding wrote: > On Mon, Nov 24, 2014 at 04:17:18PM +0530, Vivek Gautam wrote: >> Hi, >> >> >> On Mon, Nov 24, 2014 at 4:02 PM, Thierry Reding >> wrote: >> > On Mon, Nov 24, 2014 at 11:11:23AM +0530, Vivek Gautam wrote: >> >> DP PHY now require pmu-system-controller to handle PMU register >> >> to control PHY's power isolation. Adding the same to dp-phy >> >> node. >> >> >> >> Signed-off-by: Vivek Gautam >> >> Reviewed-by: Jingoo Han >> >> Tested-by: Javier Martinez Canillas >> >> Cc: Kukjin Kim >> >> --- >> >> arch/arm/boot/dts/exynos5250.dtsi |2 +- >> >> arch/arm/boot/dts/exynos5420.dtsi |4 ++-- >> >> 2 files changed, 3 insertions(+), 3 deletions(-) >> >> >> >> diff --git a/arch/arm/boot/dts/exynos5250.dtsi >> >> b/arch/arm/boot/dts/exynos5250.dtsi >> >> index 0a588b4..bebd099 100644 >> >> --- a/arch/arm/boot/dts/exynos5250.dtsi >> >> +++ b/arch/arm/boot/dts/exynos5250.dtsi >> >> @@ -732,7 +732,7 @@ >> >> >> >> dp_phy: video-phy at 10040720 { >> >> compatible = "samsung,exynos5250-dp-video-phy"; >> >> - reg = <0x10040720 4>; >> >> + samsung,pmu-syscon = <_system_controller>; >> >> #phy-cells = <0>; >> >> }; >> >> >> >> diff --git a/arch/arm/boot/dts/exynos5420.dtsi >> >> b/arch/arm/boot/dts/exynos5420.dtsi >> >> index 8617a03..1353a09 100644 >> >> --- a/arch/arm/boot/dts/exynos5420.dtsi >> >> +++ b/arch/arm/boot/dts/exynos5420.dtsi >> >> @@ -503,8 +503,8 @@ >> >> }; >> >> >> >> dp_phy: video-phy at 10040728 { >> >> - compatible = "samsung,exynos5250-dp-video-phy"; >> >> - reg = <0x10040728 4>; >> >> + compatible = "samsung,exynos5420-dp-video-phy"; >> >> + samsung,pmu-syscon = <_system_controller>; >> >> #phy-cells = <0>; >> >> }; >> >> >> > >> > It seems like these nodes have been in the Linux tree since 3.12 and >> > 3.17, respectively and these changes break backwards-compatibility. Has >> > anyone thought about the possible consequences? >> >> Sorry for my ignorance, but i have a doubt. >> If the bindings and device node both are being changed in the same kernel >> version (as fixes), >> so that the stable will have both; then the only scenerio of backward >> compatibility comes when kernel is upgraded but not dtbs. > > Correct. > >> Does such upgradation makes sense for distros ? > > Yes. Back at the time a decision was made that device trees need to be > stable ABI because eventually they'd be shipped with the device rather > than the distribution. As such it may not at all be possible to update > them (they could be in some sort of ROM). > > For that reason new kernels need to keep working with old DTBs unless an > argument can be made that would justify breaking things. I don't think I > have ever seen anyone win such an argument. > One of the rare exceptions > that I know of is if you can prove that a given hardware block has never > been used in an upstream kernel, then changing the DTB in backwards- > incompatible ways would be okay because you wouldn't be breaking things > for existing users. I am pretty sure about the Chrome devices (which have not been upgraded to any kernel after 3.8). Probably Javier may have better knowledge. Javier, is there any other device using upstream kernel post 3.12 (any arndale octa based) ? -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH V2 RESEND] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
Hi, On Mon, Nov 24, 2014 at 4:02 PM, Thierry Reding wrote: > On Mon, Nov 24, 2014 at 11:11:23AM +0530, Vivek Gautam wrote: >> DP PHY now require pmu-system-controller to handle PMU register >> to control PHY's power isolation. Adding the same to dp-phy >> node. >> >> Signed-off-by: Vivek Gautam >> Reviewed-by: Jingoo Han >> Tested-by: Javier Martinez Canillas >> Cc: Kukjin Kim >> --- >> arch/arm/boot/dts/exynos5250.dtsi |2 +- >> arch/arm/boot/dts/exynos5420.dtsi |4 ++-- >> 2 files changed, 3 insertions(+), 3 deletions(-) >> >> diff --git a/arch/arm/boot/dts/exynos5250.dtsi >> b/arch/arm/boot/dts/exynos5250.dtsi >> index 0a588b4..bebd099 100644 >> --- a/arch/arm/boot/dts/exynos5250.dtsi >> +++ b/arch/arm/boot/dts/exynos5250.dtsi >> @@ -732,7 +732,7 @@ >> >> dp_phy: video-phy at 10040720 { >> compatible = "samsung,exynos5250-dp-video-phy"; >> - reg = <0x10040720 4>; >> + samsung,pmu-syscon = <_system_controller>; >> #phy-cells = <0>; >> }; >> >> diff --git a/arch/arm/boot/dts/exynos5420.dtsi >> b/arch/arm/boot/dts/exynos5420.dtsi >> index 8617a03..1353a09 100644 >> --- a/arch/arm/boot/dts/exynos5420.dtsi >> +++ b/arch/arm/boot/dts/exynos5420.dtsi >> @@ -503,8 +503,8 @@ >> }; >> >> dp_phy: video-phy at 10040728 { >> - compatible = "samsung,exynos5250-dp-video-phy"; >> - reg = <0x10040728 4>; >> + compatible = "samsung,exynos5420-dp-video-phy"; >> + samsung,pmu-syscon = <_system_controller>; >> #phy-cells = <0>; >> }; >> > > It seems like these nodes have been in the Linux tree since 3.12 and > 3.17, respectively and these changes break backwards-compatibility. Has > anyone thought about the possible consequences? Sorry for my ignorance, but i have a doubt. If the bindings and device node both are being changed in the same kernel version (as fixes), so that the stable will have both; then the only scenerio of backward compatibility comes when kernel is upgraded but not dtbs. Does such upgradation makes sense for distros ? > > Although, looking more closely it seems like this isn't the first time > that backwards-compatibility was broken in these files, so perhaps > nobody cares... > > Thierry -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init
Hi Javier, On Mon, Nov 24, 2014 at 3:35 PM, Javier Martinez Canillas wrote: > Hello Ajay, > > On 11/21/2014 09:57 PM, Javier Martinez Canillas wrote: >> On 11/21/2014 06:32 PM, Ajay kumar wrote: >>> Hi, >>> >>> I have rebased my bridge series on top of linux-next. >>> >>> This is my git log: >>> 4b38a6f Revert "Revert "ARM: exynos_defconfig: Enable options for >>> display panel support"" >>> 6fb39a7 ARM: dts: peach-pit: represent the connection between bridge >>> and panel using videoport and endpoints >>> aee649c ARM: dts: snow: represent the connection between bridge and >>> panel using videoport and endpoints >>> 5b76d8d drm/bridge: Add i2c based driver for ps8622/ps8625 bridge >>> 581257f Documentation: bridge: Add documentation for ps8622 DT properties >>> 178e8b9 Documentation: devicetree: Add vendor prefix for parade >>> 0ceea75 Documentation: drm: bridge: move to video/bridge >>> f143e2e drm/bridge: ptn3460: use gpiod interface >>> 2d5cb9d drm/bridge: ptn3460: probe connector at the end of bridge attach >>> 32ac563 drm/bridge: ptn3460: support drm_panel >>> 91c6c30 drm/exynos: dp: support drm_bridge >>> 7eea7eb drm/bridge: ptn3460: Convert to i2c driver model >>> 602f343 drm/bridge: make bridge registration independent of drm flow >>> 14c7143 drm/bridge: do not pass drm_bridge_funcs to drm_bridge_init >>> 2c01ac4 drm/bridge: ptn3460: Few trivial cleanups >>> 7415f6c arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy >>> 28655d1 drm/exynos: Move platform drivers registration to module init >>> ed6778a Add linux-next specific files for 20141121 >>> >>> I have attached the rebased patches as well. >>> I tested it on snow, peach_pit and peach_pi without *clk_ignore_unused*. >>> Display is totally fine with exynos_defconfig (booting is fine even >>> with CONFIG_SND_SOC_SNOW=y) >>> >> >> Thanks for forward porting your patches to linux-next. Unfortunately I >> won't have time to test them until Monday but I wonder why you didn't >> have the boot issues that we have with next-20141121. >> > > I tested your ToT patches on top of next-20141121, this is my git log: > > 93fe3d7 Revert "Revert "ARM: exynos_defconfig: Enable options for display > panel support"" > 552f74e ARM: dts: peach-pit: represent the connection between bridge and > panel using videoport and endpoints > dbbc293 ARM: dts: snow: represent the connection between bridge and panel > using videoport and endpoints > d8687f8 drm/bridge: Add i2c based driver for ps8622/ps8625 bridge > f29a649 Documentation: bridge: Add documentation for ps8622 DT properties > 6ade887 Documentation: devicetree: Add vendor prefix for parade > d81c42d Documentation: drm: bridge: move to video/bridge > 50b9828 drm/bridge: ptn3460: use gpiod interface > 1274c56 drm/bridge: ptn3460: probe connector at the end of bridge attach > f3cf063 drm/bridge: ptn3460: support drm_panel > cab682b drm/exynos: dp: support drm_bridge > 6e78916 drm/bridge: ptn3460: Convert to i2c driver model > 93f4b5f drm/bridge: make bridge registration independent of drm flow > 81a038f drm/bridge: do not pass drm_bridge_funcs to drm_bridge_init > eb6996e drm/bridge: ptn3460: Few trivial cleanups > c41fa5d arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy > 51b2c75 drm/exynos: Move platform drivers registration to module init > ed6778a Add linux-next specific files for 20141121 > >> I found that the commit ae43b32 ("ARM: 8202/1: dmaengine: pl330: Add >> runtime Power Management support v12") had to be reverted in order to >> boot linux-next. >> > > Display works but I needed to revert the mentioned commit, otherwise > the boot hangs as reported before. I'm using exynos_defconfig and this > kernel command line: > > console=ttySAC3,115200N8 debug earlyprintk root=/dev/mmcblk1p2 rootwait rw My git log --oneline gives following git hash vivek at vivek-linuxpc:~/MAINLINE_KERNEL/linux-next$ git log --oneline 9af3770 arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy 1558298 drm/exynos: Move platform drivers registration to module init 4df404f Revert "Revert "ARM: exynos_defconfig: Enable options for display panel support"" ed6778a Add linux-next specific files for 20141121 eb052c1 Merge branch 'akpm/master' 9c46812 mm: add strictlimit knob Also attached my config (which is just made out of exynos_defconfig) : config_next20141124 The boot arguments used are: [0.00] Kernel command line: root=/dev/mmcblk1p1 rootwait ro console=ttySAC3,115
[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
On Sun, Nov 23, 2014 at 12:26 AM, Javier Martinez Canillas wrote: > Hello Vivek > > On Wed, Nov 19, 2014 at 1:03 PM, Vivek Gautam > wrote: >>> >>> Tested-by: Javier Martinez Canillas >> >> Thanks for testing. >> > > You are welcome > >>> >>> Kukjin, >> >> Sorry for not adding Kukjin to the list and thereby for the delay >> about this patch. >> > > No worries but I'm not sure if Kukjin is aware of this patch. I see he > has been applying other patches but didn't pick $subject. Right, > > Maybe you can resend it to Kukjin just to be sure he will have it in > his mailbox? Posted a RESEND version of this patch. Thanks again for noticing. -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH V2 RESEND] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
DP PHY now require pmu-system-controller to handle PMU register to control PHY's power isolation. Adding the same to dp-phy node. Signed-off-by: Vivek Gautam Reviewed-by: Jingoo Han Tested-by: Javier Martinez Canillas Cc: Kukjin Kim --- arch/arm/boot/dts/exynos5250.dtsi |2 +- arch/arm/boot/dts/exynos5420.dtsi |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 0a588b4..bebd099 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -732,7 +732,7 @@ dp_phy: video-phy at 10040720 { compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040720 4>; + samsung,pmu-syscon = <_system_controller>; #phy-cells = <0>; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 8617a03..1353a09 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -503,8 +503,8 @@ }; dp_phy: video-phy at 10040728 { - compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040728 4>; + compatible = "samsung,exynos5420-dp-video-phy"; + samsung,pmu-syscon = <_system_controller>; #phy-cells = <0>; }; -- 1.7.10.4
[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init
Hi Javier, On Thu, Nov 20, 2014 at 2:15 PM, Javier Martinez Canillas wrote: > Hello Vivek, > > On 11/20/2014 08:51 AM, Vivek Gautam wrote: >>> >>> I tested linux-next on Exynos5800 peach-pi board with linux-next and and >>> the two >>> patches $Subject and [0]. >>> >>> Below is my git hash: >>> 4d9e6ee drm/exynos: Move platform drivers registration to module init >>> 4545ed4 POSTED: arm: dts: Exynos5: Use pmu_system_controller phandle for dp >>> phy >>> 36391a5 Add linux-next specific files for 20141119 >>> 9b1ced1 Merge branch 'akpm/master' >>> 282497e mm: add strictlimit knob >> >> used exynos_defconfig >> > > Same here. > >>> >>> With this display works for me. >>> Without $Subject patch i get lookup in drm. >>> > > I tested with today linux-next (next-20141120) and display is indeed > working for me. So it seems that whatever caused the error in the > phy-exynos-mipi-video driver reported by Paolo, got fixed recently. > > My working git hash is: > > 65a8d01 arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy > a9b43cb drm/exynos: Move platform drivers registration to module init > 5b83d7a Add linux-next specific files for 20141120 > 1172916 mm: add strictlimit knob > > I did have to disable CONFIG_SND_SOC_SNOW though, otherwise the kernel > did not boot due the issue reported previously by Kevin. > >>> Javier can you tell me your git hash. Was it on yesterday's linux-next ? >> > > In fact, my branch where I could reproduce the phy-exynos-mipi-video issue > was not based on yesterday's next but next-20141117. The git hash is: > > 9fb5d7c arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy > f740096 drm/exynos: Move platform drivers registration to module init > efefb5c Add linux-next specific files for 20141117 > 8c944d7 mm: add strictlimit knob > >> With 3.18-rc5 i could see display on Exynos5800 peach-pi with >> following git hash: >> >> b6dca11 drm/exynos: dp: Remove support for unused dptx-phy >> 7cc5c2d ARM: exynos_defconfig: Enable options for display panel support >> d0aca5e arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy >> fc14f9c Linux 3.18-rc5 >> e35c5a2 Merge tag 'armsoc-for-rc5' of >> git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc >> >> I don't need this drm lockup patch with 3.18-rc5 (with exynos_defconfig). >> > > Yes, that works because the commit that caused the Exynos DRM lockup was: > > 43c0767 ("of/platform: Move platform devices under /sys/devices/platform") > > which landed in next-20141105. > > Reverting 43c0767 and only applying [0] should have the same effect. > >> I am checking further with linux-samsung, coz i could see weird >> behavior as mentioned >> in [1] with linux-samsun/for-next merged with above git hash. >> > > Great, it should be good to know what caused: On linux-samsung tree the only patch that's missing apart from dptx-phy patches is the syscon patch from Pankaj Dubey: b784b98 mfd: syscon: Decouple syscon interface from platform devices So with below git hash, linux-samsung/for-next display works fine along with other devices that request PMU system controller : 7bd219e drm/exynos: dp: Remove support for unused dptx-phy e8f21fd arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy 7099bde Revert "Revert "ARM: exynos_defconfig: Enable options for display panel support"" 713a994 mfd: syscon: Decouple syscon interface from platform devices 7552917 Revert "ARM: exynos_defconfig: Enable options for display panel support" /* This is Kukjin's for-next today */ ff0391a Merge branch 'v3.19-samsung-defconfig' into for-next 26c6283 Merge branch 'v3.18-samsung-fixes' into for-next cf864fd Merge branch 'v3.18-samsung-defconfig' into for-next 98b6380 ARM: exynos_defconfig: Enable max77802 rtc and clock drivers 839275c ARM: exynos_defconfig: Use 16 minors per MMC block device 0526f27 ARM: dts: Explicitly set dr_mode on exynos5250-snow fc14f9c Linux 3.18-rc5 > > exynos-mipi-video-phy 10040714.video-phy: can't request region for resource > [mem 0x10040714-0x1004071f] The only reason i see this fails is since PMU is now requesting the entire memory region with base 0x1004. We should convert the mipi-phy pmu register handling too through syscon. > > even when I could not reproduce it anymore with today's linux-next. > >>>> [0]: https://lkml.org/lkml/2014/10/30/394 >>>> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39032.html -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init
Hi, On Thu, Nov 20, 2014 at 12:36 PM, Vivek Gautam wrote: > Hi Javier, Kevin, > > > > On Wed, Nov 19, 2014 at 10:22 PM, Javier Martinez Canillas > wrote: >> [adding Paolo and Vivek as cc] >> >> Hello, >> >> On 11/18/2014 07:41 PM, Kevin Hilman wrote: >>> >>> It fixes the DRM deadlock, issue for me on exynos5800-peach-pi, but then >>> it proceeds to panic in the workqueue code called by the asoc max98090 >>> codec[1]. >>> >>> If I then disable CONFIG_SND_SOC_SNOW, I can get it to boot to a shell, >>> but I still don't have display output. >>> >> >> Paolo Pisati pointed out in another thread that he needed the patch >> "[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp >> phy" >> is also needed to get display working for exynos on linux-next. >> >> I've pinged Kukjin to apply this as a -rc fix since is needed after >> a5ec598 ("phy: exynos-dp-video: Use syscon support to control pmu register") >> landed in 3.18 which broke the Exynos Display Port PHY: >> >> exynos-dp-video-phy 10040728.video-phy: Failed to lookup PMU regmap >> >> I've an Exynos5800 Peach Pi now so I wanted to test display on it. Just >> $subject >> and [0] should be enough to have display working on Peach Pi with linux-next >> but >> it fails to me with: >> >> exynos-mipi-video-phy 10040714.video-phy: can't request region for resource >> [mem 0x10040714-0x1004071f] >> >> The same issue was reported by Paolo a couple of days ago [1]. >> >> Vivek, >> >> Any idea what could cause this regression on linux-next? As reported by >> Paolo this >> works well for me in 3.18-rc5. > > I tested linux-next on Exynos5800 peach-pi board with linux-next and and the > two > patches $Subject and [0]. > > Below is my git hash: > 4d9e6ee drm/exynos: Move platform drivers registration to module init > 4545ed4 POSTED: arm: dts: Exynos5: Use pmu_system_controller phandle for dp > phy > 36391a5 Add linux-next specific files for 20141119 > 9b1ced1 Merge branch 'akpm/master' > 282497e mm: add strictlimit knob used exynos_defconfig > > With this display works for me. > Without $Subject patch i get lookup in drm. > > Javier can you tell me your git hash. Was it on yesterday's linux-next ? With 3.18-rc5 i could see display on Exynos5800 peach-pi with following git hash: b6dca11 drm/exynos: dp: Remove support for unused dptx-phy 7cc5c2d ARM: exynos_defconfig: Enable options for display panel support d0aca5e arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy fc14f9c Linux 3.18-rc5 e35c5a2 Merge tag 'armsoc-for-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc I don't need this drm lockup patch with 3.18-rc5 (with exynos_defconfig). I am checking further with linux-samsung, coz i could see weird behavior as mentioned in [1] with linux-samsun/for-next merged with above git hash. >> [0]: https://lkml.org/lkml/2014/10/30/394 >> [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39032.html -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[RFC PATCH 1/1] drm/exynos: Move platform drivers registration to module init
Hi Javier, Kevin, On Wed, Nov 19, 2014 at 10:22 PM, Javier Martinez Canillas wrote: > [adding Paolo and Vivek as cc] > > Hello, > > On 11/18/2014 07:41 PM, Kevin Hilman wrote: >> >> It fixes the DRM deadlock, issue for me on exynos5800-peach-pi, but then >> it proceeds to panic in the workqueue code called by the asoc max98090 >> codec[1]. >> >> If I then disable CONFIG_SND_SOC_SNOW, I can get it to boot to a shell, >> but I still don't have display output. >> > > Paolo Pisati pointed out in another thread that he needed the patch > "[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp > phy" > is also needed to get display working for exynos on linux-next. > > I've pinged Kukjin to apply this as a -rc fix since is needed after > a5ec598 ("phy: exynos-dp-video: Use syscon support to control pmu register") > landed in 3.18 which broke the Exynos Display Port PHY: > > exynos-dp-video-phy 10040728.video-phy: Failed to lookup PMU regmap > > I've an Exynos5800 Peach Pi now so I wanted to test display on it. Just > $subject > and [0] should be enough to have display working on Peach Pi with linux-next > but > it fails to me with: > > exynos-mipi-video-phy 10040714.video-phy: can't request region for resource > [mem 0x10040714-0x1004071f] > > The same issue was reported by Paolo a couple of days ago [1]. > > Vivek, > > Any idea what could cause this regression on linux-next? As reported by Paolo > this > works well for me in 3.18-rc5. I tested linux-next on Exynos5800 peach-pi board with linux-next and and the two patches $Subject and [0]. Below is my git hash: 4d9e6ee drm/exynos: Move platform drivers registration to module init 4545ed4 POSTED: arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy 36391a5 Add linux-next specific files for 20141119 9b1ced1 Merge branch 'akpm/master' 282497e mm: add strictlimit knob With this display works for me. Without $Subject patch i get lookup in drm. Javier can you tell me your git hash. Was it on yesterday's linux-next ? > > Best regards, > Javier > > [0]: https://lkml.org/lkml/2014/10/30/394 > [1]: http://www.spinics.net/lists/linux-samsung-soc/msg39032.html > -- > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" > in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
Hi Javier, On Wed, Nov 19, 2014 at 5:06 PM, Javier Martinez Canillas wrote: > [adding Kukjin to cc list] > > Hello Vivek, > > On Wed, Nov 12, 2014 at 5:21 AM, Jingoo Han wrote: >> On Thursday, October 30, 2014 10:24 PM, Vivek Gautam wrote: >>> >>> DP PHY now require pmu-system-controller to handle PMU register >>> to control PHY's power isolation. Adding the same to dp-phy >>> node. >>> >>> Signed-off-by: Vivek Gautam >>> Cc: Jingoo Han >> >> Reviewed-by: Jingoo Han >> > > Tested-by: Javier Martinez Canillas Thanks for testing. > > Kukjin, Sorry for not adding Kukjin to the list and thereby for the delay about this patch. > > This patch is -rc material and is needed to have display working in > 3.18 again since commit a5ec598 ("phy: exynos-dp-video: Use syscon > support to control pmu register") landed in 3.18 and broke the Exynos > Display Port PHY: > > exynos-dp-video-phy 10040728.video-phy: Failed to lookup PMU regmap Yes, we should pick this up and merge it since the driver patch is merged now. -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH v3 RESEND 1/2] drm/exynos: dp: Remove support for unused dptx-phy
Now that we have moved to generic phy based bindings, we don't need to have any code related to older dptx-phy. Nobody is using this dptx-phy anymore, so removing the same. Signed-off-by: Vivek Gautam Acked-by: Jingoo Han Cc: Inki Dae --- Problem with my mail client caused change in author's mail id. So resending it with authorship under my Samsung id. drivers/gpu/drm/exynos/exynos_dp_core.c | 74 +++ drivers/gpu/drm/exynos/exynos_dp_core.h |2 - 2 files changed, 17 insertions(+), 59 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index cd50ece..dbe9add 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -1052,28 +1052,14 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, static void exynos_dp_phy_init(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_on(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg |= dp->enable_mask; - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_phy_exit(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_off(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg &= ~(dp->enable_mask); - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_poweron(struct exynos_drm_display *display) @@ -1210,44 +1196,6 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) return dp_video_config; } -static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) -{ - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); - u32 phy_base; - int ret = 0; - - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); - if (!dp_phy_node) { - dp->phy = devm_phy_get(dp->dev, "dp"); - return PTR_ERR_OR_ZERO(dp->phy); - } - - if (of_property_read_u32(dp_phy_node, "reg", _base)) { - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", - >enable_mask)) { - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - dp->phy_addr = ioremap(phy_base, SZ_4); - if (!dp->phy_addr) { - dev_err(dp->dev, "failed to ioremap dp-phy\n"); - ret = -ENOMEM; - goto err; - } - -err: - of_node_put(dp_phy_node); - - return ret; -} - static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) { int ret; @@ -1277,9 +1225,21 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data) if (IS_ERR(dp->video_info)) return PTR_ERR(dp->video_info); - ret = exynos_dp_dt_parse_phydata(dp); - if (ret) - return ret; + dp->phy = devm_phy_get(dp->dev, "dp"); + if (IS_ERR(dp->phy)) { + dev_err(dp->dev, "no DP phy configured\n"); + ret = PTR_ERR(dp->phy); + if (ret) { + /* +* phy itself is not enabled, so we can move forward +* assigning NULL to phy pointer. +*/ + if (ret == -ENOSYS || ret == -ENODEV) + dp->phy = NULL; + else + return ret; + } + } if (!dp->panel) { ret = exynos_dp_dt_parse_panel(dp); diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h index a1aee69..6426201 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.h +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h @@ -153,8 +153,6 @@ struct exynos_dp_device { struct clk *clock; unsigned intirq; void __iomem*reg_base; - void __iomem*phy_addr; - unsigned intenable_mask; struct video_info *video_info; struct link_train link_train; -- 1.7.9.5
[PATCH v2 1/2] drm/exynos: dp: Remove support for unused dptx-phy
On Wed, Nov 12, 2014 at 9:38 AM, Jingoo Han wrote: > On Thursday, October 30, 2014 10:24 PM, Vivek Gautam wrote: >> >> Now that we have moved to generic phy based bindings, >> we don't need to have any code related to older dptx-phy. >> Nobody is using this dptx-phy anymore, so removing the >> same. > > Right, older dptx-phy was replaced long time ago. > However, it was not removed for DT compatibility. > I think that now these old DT properties can be removed. > > I added some comments below. Thanks Jingoo for reviewing. > >> >> Signed-off-by: Vivek Gautam >> Cc: Inki Dae >> Cc: Jingoo Han >> --- >> >> Changes from V1: >> - Reworked error handling in exynos_dp_dt_parse_phydata() as commented >>by Inki. >> >> drivers/gpu/drm/exynos/exynos_dp_core.c | 67 >> --- >> drivers/gpu/drm/exynos/exynos_dp_core.h |2 - >> 2 files changed, 17 insertions(+), 52 deletions(-) >> >> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c >> b/drivers/gpu/drm/exynos/exynos_dp_core.c >> index cd50ece..206163b 100644 >> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c >> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c >> @@ -1052,28 +1052,14 @@ static int exynos_dp_create_connector(struct >> exynos_drm_display *display, >> >> static void exynos_dp_phy_init(struct exynos_dp_device *dp) >> { >> - if (dp->phy) { >> + if (dp->phy) >> phy_power_on(dp->phy); >> - } else if (dp->phy_addr) { >> - u32 reg; >> - >> - reg = __raw_readl(dp->phy_addr); >> - reg |= dp->enable_mask; >> - __raw_writel(reg, dp->phy_addr); >> - } >> } >> >> static void exynos_dp_phy_exit(struct exynos_dp_device *dp) >> { >> - if (dp->phy) { >> + if (dp->phy) >> phy_power_off(dp->phy); >> - } else if (dp->phy_addr) { >> - u32 reg; >> - >> - reg = __raw_readl(dp->phy_addr); >> - reg &= ~(dp->enable_mask); >> - __raw_writel(reg, dp->phy_addr); >> - } >> } >> >> static void exynos_dp_poweron(struct exynos_drm_display *display) >> @@ -1212,40 +1198,13 @@ static struct video_info >> *exynos_dp_dt_parse_pdata(struct device *dev) >> >> static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) >> { >> - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); >> - u32 phy_base; >> - int ret = 0; >> - >> - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); >> - if (!dp_phy_node) { >> - dp->phy = devm_phy_get(dp->dev, "dp"); >> - return PTR_ERR_OR_ZERO(dp->phy); >> - } >> - >> - if (of_property_read_u32(dp_phy_node, "reg", _base)) { >> - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); >> - ret = -EINVAL; >> - goto err; >> - } >> - >> - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", >> - >enable_mask)) { >> - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); >> - ret = -EINVAL; >> - goto err; >> - } >> - >> - dp->phy_addr = ioremap(phy_base, SZ_4); >> - if (!dp->phy_addr) { >> - dev_err(dp->dev, "failed to ioremap dp-phy\n"); >> - ret = -ENOMEM; >> - goto err; >> + dp->phy = devm_phy_get(dp->dev, "dp"); >> + if (IS_ERR(dp->phy)) { >> + dev_err(dp->dev, "no DP phy configured\n"); >> + return PTR_ERR(dp->phy); >> } >> >> -err: >> - of_node_put(dp_phy_node); >> - >> - return ret; >> + return 0; >> } >> >> static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) >> @@ -1278,8 +1237,16 @@ static int exynos_dp_bind(struct device *dev, struct >> device *master, void *data) >> return PTR_ERR(dp->video_info); >> >> ret = exynos_dp_dt_parse_phydata(dp); > > In your patch, exynos_dp_dt_parse_phydata() calls only devm_phy_get(). > Then, how about calling devm_phy_get() directly and removing > exynos_dp_dt_parse_phydata()? It looks simpler. Right, makes sense. Will send quic
[PATCH v2 2/2] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
DP PHY now require pmu-system-controller to handle PMU register to control PHY's power isolation. Adding the same to dp-phy node. Signed-off-by: Vivek Gautam Cc: Jingoo Han --- Changes from V1: - none. arch/arm/boot/dts/exynos5250.dtsi |2 +- arch/arm/boot/dts/exynos5420.dtsi |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 012b021..69f5eb0 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -732,7 +732,7 @@ dp_phy: video-phy at 10040720 { compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040720 4>; + samsung,pmu-syscon = <_system_controller>; #phy-cells = <0>; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index 8617a03..1353a09 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -503,8 +503,8 @@ }; dp_phy: video-phy at 10040728 { - compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040728 4>; + compatible = "samsung,exynos5420-dp-video-phy"; + samsung,pmu-syscon = <_system_controller>; #phy-cells = <0>; }; -- 1.7.10.4
[PATCH v2 1/2] drm/exynos: dp: Remove support for unused dptx-phy
Now that we have moved to generic phy based bindings, we don't need to have any code related to older dptx-phy. Nobody is using this dptx-phy anymore, so removing the same. Signed-off-by: Vivek Gautam Cc: Inki Dae Cc: Jingoo Han --- Changes from V1: - Reworked error handling in exynos_dp_dt_parse_phydata() as commented by Inki. drivers/gpu/drm/exynos/exynos_dp_core.c | 67 --- drivers/gpu/drm/exynos/exynos_dp_core.h |2 - 2 files changed, 17 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index cd50ece..206163b 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -1052,28 +1052,14 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, static void exynos_dp_phy_init(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_on(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg |= dp->enable_mask; - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_phy_exit(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_off(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg &= ~(dp->enable_mask); - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_poweron(struct exynos_drm_display *display) @@ -1212,40 +1198,13 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) { - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); - u32 phy_base; - int ret = 0; - - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); - if (!dp_phy_node) { - dp->phy = devm_phy_get(dp->dev, "dp"); - return PTR_ERR_OR_ZERO(dp->phy); - } - - if (of_property_read_u32(dp_phy_node, "reg", _base)) { - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", - >enable_mask)) { - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - dp->phy_addr = ioremap(phy_base, SZ_4); - if (!dp->phy_addr) { - dev_err(dp->dev, "failed to ioremap dp-phy\n"); - ret = -ENOMEM; - goto err; + dp->phy = devm_phy_get(dp->dev, "dp"); + if (IS_ERR(dp->phy)) { + dev_err(dp->dev, "no DP phy configured\n"); + return PTR_ERR(dp->phy); } -err: - of_node_put(dp_phy_node); - - return ret; + return 0; } static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) @@ -1278,8 +1237,16 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data) return PTR_ERR(dp->video_info); ret = exynos_dp_dt_parse_phydata(dp); - if (ret) - return ret; + if (ret) { + /* +* phy itself is not enabled, so we can move forward +* assigning NULL to phy pointer. +*/ + if (ret == -ENOSYS || ret == -ENODEV) + dp->phy = NULL; + else + return ret; + } if (!dp->panel) { ret = exynos_dp_dt_parse_panel(dp); diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h index a1aee69..6426201 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.h +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h @@ -153,8 +153,6 @@ struct exynos_dp_device { struct clk *clock; unsigned intirq; void __iomem*reg_base; - void __iomem*phy_addr; - unsigned intenable_mask; struct video_info *video_info; struct link_train link_train; -- 1.7.10.4
[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy
Hi Inki, On Thu, Oct 30, 2014 at 5:50 PM, Inki Dae wrote: > > Sorry for late. I missed this patch a little bit for long time. Thanks for reviewing. > > > On 2014ë 09ì 15ì¼ 22:13, Vivek Gautam wrote: >> Now that we have moved to generic phy based bindings, >> we don't need to have any code related to older dptx-phy. >> Nobody is using this dptx-phy anymore, so removing the >> same. >> >> Signed-off-by: Vivek Gautam >> Cc: Jingoo Han >> --- >> drivers/gpu/drm/exynos/exynos_dp_core.c | 58 >> +++ >> drivers/gpu/drm/exynos/exynos_dp_core.h |2 -- >> 2 files changed, 13 insertions(+), 47 deletions(-) >> >> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c >> b/drivers/gpu/drm/exynos/exynos_dp_core.c >> index 4f3c7eb..5ffc1b2 100644 >> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c >> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c >> @@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct >> exynos_drm_display *display, >> >> static void exynos_dp_phy_init(struct exynos_dp_device *dp) >> { >> - if (dp->phy) { >> + if (dp->phy) >> phy_power_on(dp->phy); >> - } else if (dp->phy_addr) { >> - u32 reg; >> - >> - reg = __raw_readl(dp->phy_addr); >> - reg |= dp->enable_mask; >> - __raw_writel(reg, dp->phy_addr); >> - } >> } >> >> static void exynos_dp_phy_exit(struct exynos_dp_device *dp) >> { >> - if (dp->phy) { >> + if (dp->phy) >> phy_power_off(dp->phy); >> - } else if (dp->phy_addr) { >> - u32 reg; >> - >> - reg = __raw_readl(dp->phy_addr); >> - reg &= ~(dp->enable_mask); >> - __raw_writel(reg, dp->phy_addr); >> - } >> } >> >> static void exynos_dp_poweron(struct exynos_drm_display *display) >> @@ -1210,39 +1196,21 @@ static struct video_info >> *exynos_dp_dt_parse_pdata(struct device *dev) >> >> static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) >> { >> - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); >> - u32 phy_base; >> int ret = 0; >> >> - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); >> - if (!dp_phy_node) { >> - dp->phy = devm_phy_get(dp->dev, "dp"); >> - return PTR_ERR_OR_ZERO(dp->phy); >> - } >> - >> - if (of_property_read_u32(dp_phy_node, "reg", _base)) { >> - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); >> - ret = -EINVAL; >> - goto err; >> - } >> - >> - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", >> - >enable_mask)) { >> - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); >> - ret = -EINVAL; >> - goto err; >> - } >> - >> - dp->phy_addr = ioremap(phy_base, SZ_4); >> - if (!dp->phy_addr) { >> - dev_err(dp->dev, "failed to ioremap dp-phy\n"); >> - ret = -ENOMEM; >> - goto err; >> + dp->phy = devm_phy_get(dp->dev, "dp"); >> + if (IS_ERR(dp->phy)) { >> + ret = PTR_ERR(dp->phy); >> + if (ret == -ENOSYS || ret == -ENODEV) { >> + dp->phy = NULL; >> + } else if (ret == -EPROBE_DEFER) { >> + return ret; >> + } else { > > WARNING: else is not generally useful after a break or return > #146: FILE: drivers/gpu/drm/exynos/exynos_dp_core.c:1208: > + return ret; > + } else { > > How about just returning ret like below? > if (IS_ERR(dp->phy)) { > dev_err(dp->dev, "no DP phy configured\n"); > return PTR_ERR(ret); > } > > And then you can handle the error at probe function properly. Right, point taken. Will post the reworked patch. [snip] -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH 0/3] drm-exynos-dp/phy-exynos-dp: Refactor to use pmu-system-controller and dp driver cleanup
Ajay, On Thu, Oct 9, 2014 at 3:48 PM, Ajay kumar wrote: > Hi, > > On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam > wrote: >> These patches are based on 'for-next' branch of kgene's linux-samsung tree. >> >> Refactoring the exynos-dp-video phy to use pmu-system-controller handle >> and access the register using mfd-syscon and regmap. >> Simultaneously, removing the support for older dptx-phy, since it's obsolete >> now and noone uses it. >> >> Vivek Gautam (3): >> phy: exynos-dp-video: Use syscon support to control pmu register >> drm/exynos: dp: Remove support for unused dptx-phy >> arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy >> >> .../devicetree/bindings/phy/samsung-phy.txt|7 +- >> arch/arm/boot/dts/exynos5250.dtsi |2 +- >> arch/arm/boot/dts/exynos5420.dtsi |4 +- >> drivers/gpu/drm/exynos/exynos_dp_core.c| 58 --- >> drivers/gpu/drm/exynos/exynos_dp_core.h|2 - >> drivers/phy/phy-exynos-dp-video.c | 76 >> ++-- >> 6 files changed, 75 insertions(+), 74 deletions(-) >> >> -- >> 1.7.10.4 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" >> in >> the body of a message to majordomo at vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > I have tested this patchset on exynos5800-peach-pi, and I can see DP > display with the above patches. we expect "Tested-by", if you have tested please give the same. -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy
Hi, CC'ing Kukjin, my bad, missed him while sending the patch. :-( On Wed, Oct 8, 2014 at 8:27 AM, Vivek Gautam wrote: > Hi, > > > On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam > wrote: >> Now that we have moved to generic phy based bindings, >> we don't need to have any code related to older dptx-phy. >> Nobody is using this dptx-phy anymore, so removing the >> same. >> >> Signed-off-by: Vivek Gautam >> Cc: Jingoo Han >> --- > > Is someone taking care of this patch ? We already have got the corresponsding > dp-phy patch merged, so we should also get this patch in. > >> drivers/gpu/drm/exynos/exynos_dp_core.c | 58 >> +++ >> drivers/gpu/drm/exynos/exynos_dp_core.h |2 -- >> 2 files changed, 13 insertions(+), 47 deletions(-) >> >> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c >> b/drivers/gpu/drm/exynos/exynos_dp_core.c >> index 4f3c7eb..5ffc1b2 100644 >> --- a/drivers/gpu/drm/exynos/exynos_dp_core.c >> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c >> @@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct >> exynos_drm_display *display, >> >> static void exynos_dp_phy_init(struct exynos_dp_device *dp) >> { >> - if (dp->phy) { >> + if (dp->phy) >> phy_power_on(dp->phy); >> - } else if (dp->phy_addr) { >> - u32 reg; >> - >> - reg = __raw_readl(dp->phy_addr); >> - reg |= dp->enable_mask; >> - __raw_writel(reg, dp->phy_addr); >> - } >> } >> >> static void exynos_dp_phy_exit(struct exynos_dp_device *dp) >> { >> - if (dp->phy) { >> + if (dp->phy) >> phy_power_off(dp->phy); >> - } else if (dp->phy_addr) { >> - u32 reg; >> - >> - reg = __raw_readl(dp->phy_addr); >> - reg &= ~(dp->enable_mask); >> - __raw_writel(reg, dp->phy_addr); >> - } >> } >> >> static void exynos_dp_poweron(struct exynos_drm_display *display) >> @@ -1210,39 +1196,21 @@ static struct video_info >> *exynos_dp_dt_parse_pdata(struct device *dev) >> >> static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) >> { >> - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); >> - u32 phy_base; >> int ret = 0; >> >> - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); >> - if (!dp_phy_node) { >> - dp->phy = devm_phy_get(dp->dev, "dp"); >> - return PTR_ERR_OR_ZERO(dp->phy); >> - } >> - >> - if (of_property_read_u32(dp_phy_node, "reg", _base)) { >> - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); >> - ret = -EINVAL; >> - goto err; >> - } >> - >> - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", >> - >enable_mask)) { >> - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); >> - ret = -EINVAL; >> - goto err; >> - } >> - >> - dp->phy_addr = ioremap(phy_base, SZ_4); >> - if (!dp->phy_addr) { >> - dev_err(dp->dev, "failed to ioremap dp-phy\n"); >> - ret = -ENOMEM; >> - goto err; >> + dp->phy = devm_phy_get(dp->dev, "dp"); >> + if (IS_ERR(dp->phy)) { >> + ret = PTR_ERR(dp->phy); >> + if (ret == -ENOSYS || ret == -ENODEV) { >> + dp->phy = NULL; >> + } else if (ret == -EPROBE_DEFER) { >> + return ret; >> + } else { >> + dev_err(dp->dev, "no DP phy configured\n"); >> + return ret; >> + } >> } >> >> -err: >> - of_node_put(dp_phy_node); >> - >> return ret; >> } >> >> diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h >> b/drivers/gpu/drm/exynos/exynos_dp_core.h >> index a1aee69..6426201 100644 >> --- a/drivers/gpu/drm/exynos/exynos_dp_core.h >> +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h >> @@ -153,8 +153,6 @@ struct exynos_dp_device { >> struct clk *clock; >> unsigned intirq; >> void __iomem*reg_base; >> - void __iomem*phy_addr; >> - unsigned intenable_mask; >> >> struct video_info *video_info; >> struct link_train link_train; >> -- >> 1.7.10.4 >> > > > > -- > Best Regards > Vivek Gautam > Samsung R Institute, Bangalore > India -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH 3/3] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
Hi, CC'ing Kukjin, my bad, missed him while sending the patch. :-( On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam wrote: > DP PHY now require pmu-system-controller to handle PMU register > to control PHY's power isolation. Adding the same to dp-phy > node. > > Signed-off-by: Vivek Gautam > Cc: Jingoo Han > --- Is someone taking care of this patch ? We already have got the corresponsding dp-phy patch merged, so we should also get this patch in. > arch/arm/boot/dts/exynos5250.dtsi |2 +- > arch/arm/boot/dts/exynos5420.dtsi |4 ++-- > 2 files changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/boot/dts/exynos5250.dtsi > b/arch/arm/boot/dts/exynos5250.dtsi > index f21b9aa..9b85a2b 100644 > --- a/arch/arm/boot/dts/exynos5250.dtsi > +++ b/arch/arm/boot/dts/exynos5250.dtsi > @@ -732,7 +732,7 @@ > > dp_phy: video-phy at 10040720 { > compatible = "samsung,exynos5250-dp-video-phy"; > - reg = <0x10040720 4>; > + samsung,pmu-syscon = <_system_controller>; > #phy-cells = <0>; > }; > > diff --git a/arch/arm/boot/dts/exynos5420.dtsi > b/arch/arm/boot/dts/exynos5420.dtsi > index bfe056d..a677812 100644 > --- a/arch/arm/boot/dts/exynos5420.dtsi > +++ b/arch/arm/boot/dts/exynos5420.dtsi > @@ -503,8 +503,8 @@ > }; > > dp_phy: video-phy at 10040728 { > - compatible = "samsung,exynos5250-dp-video-phy"; > - reg = <0x10040728 4>; > + compatible = "samsung,exynos5420-dp-video-phy"; > + samsung,pmu-syscon = <_system_controller>; > #phy-cells = <0>; > }; > > -- > 1.7.10.4 > -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy
Hi, On Mon, Sep 15, 2014 at 6:43 PM, Vivek Gautam wrote: > Now that we have moved to generic phy based bindings, > we don't need to have any code related to older dptx-phy. > Nobody is using this dptx-phy anymore, so removing the > same. > > Signed-off-by: Vivek Gautam > Cc: Jingoo Han > --- Is someone taking care of this patch ? We already have got the corresponsding dp-phy patch merged, so we should also get this patch in. > drivers/gpu/drm/exynos/exynos_dp_core.c | 58 > +++ > drivers/gpu/drm/exynos/exynos_dp_core.h |2 -- > 2 files changed, 13 insertions(+), 47 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c > b/drivers/gpu/drm/exynos/exynos_dp_core.c > index 4f3c7eb..5ffc1b2 100644 > --- a/drivers/gpu/drm/exynos/exynos_dp_core.c > +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c > @@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct > exynos_drm_display *display, > > static void exynos_dp_phy_init(struct exynos_dp_device *dp) > { > - if (dp->phy) { > + if (dp->phy) > phy_power_on(dp->phy); > - } else if (dp->phy_addr) { > - u32 reg; > - > - reg = __raw_readl(dp->phy_addr); > - reg |= dp->enable_mask; > - __raw_writel(reg, dp->phy_addr); > - } > } > > static void exynos_dp_phy_exit(struct exynos_dp_device *dp) > { > - if (dp->phy) { > + if (dp->phy) > phy_power_off(dp->phy); > - } else if (dp->phy_addr) { > - u32 reg; > - > - reg = __raw_readl(dp->phy_addr); > - reg &= ~(dp->enable_mask); > - __raw_writel(reg, dp->phy_addr); > - } > } > > static void exynos_dp_poweron(struct exynos_drm_display *display) > @@ -1210,39 +1196,21 @@ static struct video_info > *exynos_dp_dt_parse_pdata(struct device *dev) > > static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) > { > - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); > - u32 phy_base; > int ret = 0; > > - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); > - if (!dp_phy_node) { > - dp->phy = devm_phy_get(dp->dev, "dp"); > - return PTR_ERR_OR_ZERO(dp->phy); > - } > - > - if (of_property_read_u32(dp_phy_node, "reg", _base)) { > - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); > - ret = -EINVAL; > - goto err; > - } > - > - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", > - >enable_mask)) { > - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); > - ret = -EINVAL; > - goto err; > - } > - > - dp->phy_addr = ioremap(phy_base, SZ_4); > - if (!dp->phy_addr) { > - dev_err(dp->dev, "failed to ioremap dp-phy\n"); > - ret = -ENOMEM; > - goto err; > + dp->phy = devm_phy_get(dp->dev, "dp"); > + if (IS_ERR(dp->phy)) { > + ret = PTR_ERR(dp->phy); > + if (ret == -ENOSYS || ret == -ENODEV) { > + dp->phy = NULL; > + } else if (ret == -EPROBE_DEFER) { > + return ret; > + } else { > + dev_err(dp->dev, "no DP phy configured\n"); > + return ret; > + } > } > > -err: > - of_node_put(dp_phy_node); > - > return ret; > } > > diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h > b/drivers/gpu/drm/exynos/exynos_dp_core.h > index a1aee69..6426201 100644 > --- a/drivers/gpu/drm/exynos/exynos_dp_core.h > +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h > @@ -153,8 +153,6 @@ struct exynos_dp_device { > struct clk *clock; > unsigned intirq; > void __iomem*reg_base; > - void __iomem*phy_addr; > - unsigned intenable_mask; > > struct video_info *video_info; > struct link_train link_train; > -- > 1.7.10.4 > -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH v3 1/3] phy: exynos-dp-video: Use syscon support to control pmu register
Hi Kishon, On Wed, Sep 17, 2014 at 10:24 PM, Kishon Vijay Abraham I wrote: > > > On Tuesday 16 September 2014 10:32 AM, Vivek Gautam wrote: >> Currently the DP_PHY_ENABLE register is mapped in the driver, >> and accessed to control power to the PHY. >> With mfd-syscon and regmap interface available at our disposal, >> it's wise to use that instead of using a 'reg' property for the >> controller and allocating a memory resource for that. >> >> To facilitate this, we have added another compatible string >> for Exynso5420 SoC to acquire driver data which contains >> different DP-PHY-CONTROL register offset. >> >> Signed-off-by: Vivek Gautam >> Cc: Jingoo Han >> Cc: Kishon Vijay Abraham I > > Taking this in linux-phy tree. If someone has already taken this patch, please > let me know. Thanks for taking this. But just one check, i think i need to separate out the Documentation to a separate patch even before this driver patch. Isn't it ? > > Thanks > Kishon > >> --- >> >> Changes since v2: >> - Using 'EXYNOS5_PHY_ENABLE' macro instead of 'EXYNOS_DPTX_PHY_ENABLE' >>since that's available with us in "linux/mfd/syscon/exynos5-pmu.h" file. >> >> Changes since v1: >> - state->regs should have been "struct regmap *" instead of >>"void __iomem *". So corrected the same. >> >> .../devicetree/bindings/phy/samsung-phy.txt|7 +- >> drivers/phy/phy-exynos-dp-video.c | 79 >> +--- >> 2 files changed, 59 insertions(+), 27 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt >> b/Documentation/devicetree/bindings/phy/samsung-phy.txt >> index 7a6feea..15e0f2c 100644 >> --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt >> +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt >> @@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY >> - >> >> Required properties: >> -- compatible : should be "samsung,exynos5250-dp-video-phy"; >> -- reg : offset and length of the Display Port PHY register set; >> +- compatible : should be one of the following supported values: >> + - "samsung,exynos5250-dp-video-phy" >> + - "samsung,exynos5420-dp-video-phy" >> +- samsung,pmu-syscon: phandle for PMU system controller interface, used to >> + control pmu registers for power isolation. >> - #phy-cells : from the generic PHY bindings, must be 0; >> >> Samsung S5P/EXYNOS SoC series USB PHY >> diff --git a/drivers/phy/phy-exynos-dp-video.c >> b/drivers/phy/phy-exynos-dp-video.c >> index 8b3026e..53f44a0 100644 >> --- a/drivers/phy/phy-exynos-dp-video.c >> +++ b/drivers/phy/phy-exynos-dp-video.c >> @@ -13,44 +13,55 @@ >> #include >> #include >> #include >> +#include >> +#include >> #include >> #include >> #include >> #include >> +#include >> >> -/* DPTX_PHY_CONTROL register */ >> -#define EXYNOS_DPTX_PHY_ENABLE (1 << 0) >> +struct exynos_dp_video_phy_drvdata { >> + u32 phy_ctrl_offset; >> +}; >> >> struct exynos_dp_video_phy { >> - void __iomem *regs; >> + struct regmap *regs; >> + const struct exynos_dp_video_phy_drvdata *drvdata; >> }; >> >> -static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int >> on) >> +static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state, >> + unsigned int on) >> { >> - u32 reg; >> + unsigned int val; >> + >> + if (IS_ERR(state->regs)) >> + return; >> >> - reg = readl(state->regs); >> - if (on) >> - reg |= EXYNOS_DPTX_PHY_ENABLE; >> - else >> - reg &= ~EXYNOS_DPTX_PHY_ENABLE; >> - writel(reg, state->regs); >> + val = on ? 0 : EXYNOS5_PHY_ENABLE; >> >> - return 0; >> + regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, >> +EXYNOS5_PHY_ENABLE, val); >> } >> >> static int exynos_dp_video_phy_power_on(struct phy *phy) >> { >> struct exynos_dp_video_phy *state = phy_get_drvdata(phy); >> >> - return __set_phy_state(state, 1); >> + /* Disable power isolation on DP-PHY */ >> + exynos_dp_video_phy_pwr_is
[PATCH v3 1/3] phy: exynos-dp-video: Use syscon support to control pmu register
Currently the DP_PHY_ENABLE register is mapped in the driver, and accessed to control power to the PHY. With mfd-syscon and regmap interface available at our disposal, it's wise to use that instead of using a 'reg' property for the controller and allocating a memory resource for that. To facilitate this, we have added another compatible string for Exynso5420 SoC to acquire driver data which contains different DP-PHY-CONTROL register offset. Signed-off-by: Vivek Gautam Cc: Jingoo Han Cc: Kishon Vijay Abraham I --- Changes since v2: - Using 'EXYNOS5_PHY_ENABLE' macro instead of 'EXYNOS_DPTX_PHY_ENABLE' since that's available with us in "linux/mfd/syscon/exynos5-pmu.h" file. Changes since v1: - state->regs should have been "struct regmap *" instead of "void __iomem *". So corrected the same. .../devicetree/bindings/phy/samsung-phy.txt|7 +- drivers/phy/phy-exynos-dp-video.c | 79 +--- 2 files changed, 59 insertions(+), 27 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 7a6feea..15e0f2c 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY - Required properties: -- compatible : should be "samsung,exynos5250-dp-video-phy"; -- reg : offset and length of the Display Port PHY register set; +- compatible : should be one of the following supported values: +- "samsung,exynos5250-dp-video-phy" +- "samsung,exynos5420-dp-video-phy" +- samsung,pmu-syscon: phandle for PMU system controller interface, used to + control pmu registers for power isolation. - #phy-cells : from the generic PHY bindings, must be 0; Samsung S5P/EXYNOS SoC series USB PHY diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c index 8b3026e..53f44a0 100644 --- a/drivers/phy/phy-exynos-dp-video.c +++ b/drivers/phy/phy-exynos-dp-video.c @@ -13,44 +13,55 @@ #include #include #include +#include +#include #include #include #include #include +#include -/* DPTX_PHY_CONTROL register */ -#define EXYNOS_DPTX_PHY_ENABLE (1 << 0) +struct exynos_dp_video_phy_drvdata { + u32 phy_ctrl_offset; +}; struct exynos_dp_video_phy { - void __iomem *regs; + struct regmap *regs; + const struct exynos_dp_video_phy_drvdata *drvdata; }; -static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on) +static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state, + unsigned int on) { - u32 reg; + unsigned int val; + + if (IS_ERR(state->regs)) + return; - reg = readl(state->regs); - if (on) - reg |= EXYNOS_DPTX_PHY_ENABLE; - else - reg &= ~EXYNOS_DPTX_PHY_ENABLE; - writel(reg, state->regs); + val = on ? 0 : EXYNOS5_PHY_ENABLE; - return 0; + regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, + EXYNOS5_PHY_ENABLE, val); } static int exynos_dp_video_phy_power_on(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - return __set_phy_state(state, 1); + /* Disable power isolation on DP-PHY */ + exynos_dp_video_phy_pwr_isol(state, 0); + + return 0; } static int exynos_dp_video_phy_power_off(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - return __set_phy_state(state, 0); + /* Enable power isolation on DP-PHY */ + exynos_dp_video_phy_pwr_isol(state, 1); + + return 0; } static struct phy_ops exynos_dp_video_phy_ops = { @@ -59,11 +70,31 @@ static struct phy_ops exynos_dp_video_phy_ops = { .owner = THIS_MODULE, }; +static const struct exynos_dp_video_phy_drvdata exynos5250_dp_video_phy = { + .phy_ctrl_offset= EXYNOS5_DPTX_PHY_CONTROL, +}; + +static const struct exynos_dp_video_phy_drvdata exynos5420_dp_video_phy = { + .phy_ctrl_offset= EXYNOS5420_DPTX_PHY_CONTROL, +}; + +static const struct of_device_id exynos_dp_video_phy_of_match[] = { + { + .compatible = "samsung,exynos5250-dp-video-phy", + .data = _dp_video_phy, + }, { + .compatible = "samsung,exynos5420-dp-video-phy", + .data = _dp_video_phy, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match); + static int exynos_dp_video_phy_probe(struct platform_device *pdev) { struct exynos_dp_video_phy *state; struct device *dev = >dev; - struct resource
[PATCH v2 1/3] phy: exynos-dp-video: Use syscon support to control pmu register
Currently the DP_PHY_ENABLE register is mapped in the driver, and accessed to control power to the PHY. With mfd-syscon and regmap interface available at our disposal, it's wise to use that instead of using a 'reg' property for the controller and allocating a memory resource for that. To facilitate this, we have added another compatible string for Exynso5420 SoC to acquire driver data which contains different DP-PHY-CONTROL register offset. Signed-off-by: Vivek Gautam Cc: Jingoo Han Cc: Kishon Vijay Abraham I --- Changes since v1: - state->regs should have been "struct regmap *" instead of "void __iomem *". So corrected the same. .../devicetree/bindings/phy/samsung-phy.txt|7 +- drivers/phy/phy-exynos-dp-video.c | 78 ++-- 2 files changed, 60 insertions(+), 25 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 7a6feea..15e0f2c 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY - Required properties: -- compatible : should be "samsung,exynos5250-dp-video-phy"; -- reg : offset and length of the Display Port PHY register set; +- compatible : should be one of the following supported values: +- "samsung,exynos5250-dp-video-phy" +- "samsung,exynos5420-dp-video-phy" +- samsung,pmu-syscon: phandle for PMU system controller interface, used to + control pmu registers for power isolation. - #phy-cells : from the generic PHY bindings, must be 0; Samsung S5P/EXYNOS SoC series USB PHY diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c index 8b3026e..881ddb5 100644 --- a/drivers/phy/phy-exynos-dp-video.c +++ b/drivers/phy/phy-exynos-dp-video.c @@ -13,44 +13,58 @@ #include #include #include +#include +#include #include #include #include #include +#include /* DPTX_PHY_CONTROL register */ #define EXYNOS_DPTX_PHY_ENABLE (1 << 0) +struct exynos_dp_video_phy_drvdata { + u32 phy_ctrl_offset; +}; + struct exynos_dp_video_phy { - void __iomem *regs; + struct regmap *regs; + const struct exynos_dp_video_phy_drvdata *drvdata; }; -static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on) +static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state, + unsigned int on) { - u32 reg; + unsigned int val; - reg = readl(state->regs); - if (on) - reg |= EXYNOS_DPTX_PHY_ENABLE; - else - reg &= ~EXYNOS_DPTX_PHY_ENABLE; - writel(reg, state->regs); + if (IS_ERR(state->regs)) + return; - return 0; + val = on ? 0 : EXYNOS_DPTX_PHY_ENABLE; + + regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, + EXYNOS_DPTX_PHY_ENABLE, val); } static int exynos_dp_video_phy_power_on(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - return __set_phy_state(state, 1); + /* Disable power isolation on DP-PHY */ + exynos_dp_video_phy_pwr_isol(state, 0); + + return 0; } static int exynos_dp_video_phy_power_off(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - return __set_phy_state(state, 0); + /* Enable power isolation on DP-PHY */ + exynos_dp_video_phy_pwr_isol(state, 1); + + return 0; } static struct phy_ops exynos_dp_video_phy_ops = { @@ -59,11 +73,31 @@ static struct phy_ops exynos_dp_video_phy_ops = { .owner = THIS_MODULE, }; +static const struct exynos_dp_video_phy_drvdata exynos5250_dp_video_phy = { + .phy_ctrl_offset= EXYNOS5_DPTX_PHY_CONTROL, +}; + +static const struct exynos_dp_video_phy_drvdata exynos5420_dp_video_phy = { + .phy_ctrl_offset= EXYNOS5420_DPTX_PHY_CONTROL, +}; + +static const struct of_device_id exynos_dp_video_phy_of_match[] = { + { + .compatible = "samsung,exynos5250-dp-video-phy", + .data = _dp_video_phy, + }, { + .compatible = "samsung,exynos5420-dp-video-phy", + .data = _dp_video_phy, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match); + static int exynos_dp_video_phy_probe(struct platform_device *pdev) { struct exynos_dp_video_phy *state; struct device *dev = >dev; - struct resource *res; + const struct of_device_id *match; struct phy_provider *phy_provider; struct phy *phy; @@ -71,11 +105,15 @@ static int exynos_dp_video_p
[PATCH 3/3] arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy
DP PHY now require pmu-system-controller to handle PMU register to control PHY's power isolation. Adding the same to dp-phy node. Signed-off-by: Vivek Gautam Cc: Jingoo Han --- arch/arm/boot/dts/exynos5250.dtsi |2 +- arch/arm/boot/dts/exynos5420.dtsi |4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index f21b9aa..9b85a2b 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -732,7 +732,7 @@ dp_phy: video-phy at 10040720 { compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040720 4>; + samsung,pmu-syscon = <_system_controller>; #phy-cells = <0>; }; diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi index bfe056d..a677812 100644 --- a/arch/arm/boot/dts/exynos5420.dtsi +++ b/arch/arm/boot/dts/exynos5420.dtsi @@ -503,8 +503,8 @@ }; dp_phy: video-phy at 10040728 { - compatible = "samsung,exynos5250-dp-video-phy"; - reg = <0x10040728 4>; + compatible = "samsung,exynos5420-dp-video-phy"; + samsung,pmu-syscon = <_system_controller>; #phy-cells = <0>; }; -- 1.7.10.4
[PATCH 2/3] drm/exynos: dp: Remove support for unused dptx-phy
Now that we have moved to generic phy based bindings, we don't need to have any code related to older dptx-phy. Nobody is using this dptx-phy anymore, so removing the same. Signed-off-by: Vivek Gautam Cc: Jingoo Han --- drivers/gpu/drm/exynos/exynos_dp_core.c | 58 +++ drivers/gpu/drm/exynos/exynos_dp_core.h |2 -- 2 files changed, 13 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.c b/drivers/gpu/drm/exynos/exynos_dp_core.c index 4f3c7eb..5ffc1b2 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.c +++ b/drivers/gpu/drm/exynos/exynos_dp_core.c @@ -1050,28 +1050,14 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, static void exynos_dp_phy_init(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_on(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg |= dp->enable_mask; - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_phy_exit(struct exynos_dp_device *dp) { - if (dp->phy) { + if (dp->phy) phy_power_off(dp->phy); - } else if (dp->phy_addr) { - u32 reg; - - reg = __raw_readl(dp->phy_addr); - reg &= ~(dp->enable_mask); - __raw_writel(reg, dp->phy_addr); - } } static void exynos_dp_poweron(struct exynos_drm_display *display) @@ -1210,39 +1196,21 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) { - struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); - u32 phy_base; int ret = 0; - dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); - if (!dp_phy_node) { - dp->phy = devm_phy_get(dp->dev, "dp"); - return PTR_ERR_OR_ZERO(dp->phy); - } - - if (of_property_read_u32(dp_phy_node, "reg", _base)) { - dev_err(dp->dev, "failed to get reg for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", - >enable_mask)) { - dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); - ret = -EINVAL; - goto err; - } - - dp->phy_addr = ioremap(phy_base, SZ_4); - if (!dp->phy_addr) { - dev_err(dp->dev, "failed to ioremap dp-phy\n"); - ret = -ENOMEM; - goto err; + dp->phy = devm_phy_get(dp->dev, "dp"); + if (IS_ERR(dp->phy)) { + ret = PTR_ERR(dp->phy); + if (ret == -ENOSYS || ret == -ENODEV) { + dp->phy = NULL; + } else if (ret == -EPROBE_DEFER) { + return ret; + } else { + dev_err(dp->dev, "no DP phy configured\n"); + return ret; + } } -err: - of_node_put(dp_phy_node); - return ret; } diff --git a/drivers/gpu/drm/exynos/exynos_dp_core.h b/drivers/gpu/drm/exynos/exynos_dp_core.h index a1aee69..6426201 100644 --- a/drivers/gpu/drm/exynos/exynos_dp_core.h +++ b/drivers/gpu/drm/exynos/exynos_dp_core.h @@ -153,8 +153,6 @@ struct exynos_dp_device { struct clk *clock; unsigned intirq; void __iomem*reg_base; - void __iomem*phy_addr; - unsigned intenable_mask; struct video_info *video_info; struct link_train link_train; -- 1.7.10.4
[PATCH 1/3] phy: exynos-dp-video: Use syscon support to control pmu register
Currently the DP_PHY_ENABLE register is mapped in the driver, and accessed to control power to the PHY. With mfd-syscon and regmap interface available at our disposal, it's wise to use that instead of using a 'reg' property for the controller and allocating a memory resource for that. To facilitate this, we have added another compatible string for Exynso5420 SoC to acquire driver data which contains different DP-PHY-CONTROL register offset. Signed-off-by: Vivek Gautam Cc: Jingoo Han Cc: Kishon Vijay Abraham I --- .../devicetree/bindings/phy/samsung-phy.txt|7 +- drivers/phy/phy-exynos-dp-video.c | 76 ++-- 2 files changed, 59 insertions(+), 24 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/samsung-phy.txt b/Documentation/devicetree/bindings/phy/samsung-phy.txt index 7a6feea..15e0f2c 100644 --- a/Documentation/devicetree/bindings/phy/samsung-phy.txt +++ b/Documentation/devicetree/bindings/phy/samsung-phy.txt @@ -17,8 +17,11 @@ Samsung EXYNOS SoC series Display Port PHY - Required properties: -- compatible : should be "samsung,exynos5250-dp-video-phy"; -- reg : offset and length of the Display Port PHY register set; +- compatible : should be one of the following supported values: +- "samsung,exynos5250-dp-video-phy" +- "samsung,exynos5420-dp-video-phy" +- samsung,pmu-syscon: phandle for PMU system controller interface, used to + control pmu registers for power isolation. - #phy-cells : from the generic PHY bindings, must be 0; Samsung S5P/EXYNOS SoC series USB PHY diff --git a/drivers/phy/phy-exynos-dp-video.c b/drivers/phy/phy-exynos-dp-video.c index 8b3026e..f093719 100644 --- a/drivers/phy/phy-exynos-dp-video.c +++ b/drivers/phy/phy-exynos-dp-video.c @@ -13,44 +13,58 @@ #include #include #include +#include +#include #include #include #include #include +#include /* DPTX_PHY_CONTROL register */ #define EXYNOS_DPTX_PHY_ENABLE (1 << 0) +struct exynos_dp_video_phy_drvdata { + u32 phy_ctrl_offset; +}; + struct exynos_dp_video_phy { void __iomem *regs; + const struct exynos_dp_video_phy_drvdata *drvdata; }; -static int __set_phy_state(struct exynos_dp_video_phy *state, unsigned int on) +static void exynos_dp_video_phy_pwr_isol(struct exynos_dp_video_phy *state, + unsigned int on) { - u32 reg; + unsigned int val; - reg = readl(state->regs); - if (on) - reg |= EXYNOS_DPTX_PHY_ENABLE; - else - reg &= ~EXYNOS_DPTX_PHY_ENABLE; - writel(reg, state->regs); + if (IS_ERR(state->regs)) + return; - return 0; + val = on ? 0 : EXYNOS_DPTX_PHY_ENABLE; + + regmap_update_bits(state->regs, state->drvdata->phy_ctrl_offset, + EXYNOS_DPTX_PHY_ENABLE, val); } static int exynos_dp_video_phy_power_on(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - return __set_phy_state(state, 1); + /* Disable power isolation on DP-PHY */ + exynos_dp_video_phy_pwr_isol(state, 0); + + return 0; } static int exynos_dp_video_phy_power_off(struct phy *phy) { struct exynos_dp_video_phy *state = phy_get_drvdata(phy); - return __set_phy_state(state, 0); + /* Enable power isolation on DP-PHY */ + exynos_dp_video_phy_pwr_isol(state, 1); + + return 0; } static struct phy_ops exynos_dp_video_phy_ops = { @@ -59,11 +73,31 @@ static struct phy_ops exynos_dp_video_phy_ops = { .owner = THIS_MODULE, }; +static const struct exynos_dp_video_phy_drvdata exynos5250_dp_video_phy = { + .phy_ctrl_offset= EXYNOS5_DPTX_PHY_CONTROL, +}; + +static const struct exynos_dp_video_phy_drvdata exynos5420_dp_video_phy = { + .phy_ctrl_offset= EXYNOS5420_DPTX_PHY_CONTROL, +}; + +static const struct of_device_id exynos_dp_video_phy_of_match[] = { + { + .compatible = "samsung,exynos5250-dp-video-phy", + .data = _dp_video_phy, + }, { + .compatible = "samsung,exynos5420-dp-video-phy", + .data = _dp_video_phy, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, exynos_dp_video_phy_of_match); + static int exynos_dp_video_phy_probe(struct platform_device *pdev) { struct exynos_dp_video_phy *state; struct device *dev = >dev; - struct resource *res; + const struct of_device_id *match; struct phy_provider *phy_provider; struct phy *phy; @@ -71,11 +105,15 @@ static int exynos_dp_video_phy_probe(struct platform_device *pdev) if (!state) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - - state->re
[PATCH 0/3] drm-exynos-dp/phy-exynos-dp: Refactor to use pmu-system-controller and dp driver cleanup
These patches are based on 'for-next' branch of kgene's linux-samsung tree. Refactoring the exynos-dp-video phy to use pmu-system-controller handle and access the register using mfd-syscon and regmap. Simultaneously, removing the support for older dptx-phy, since it's obsolete now and noone uses it. Vivek Gautam (3): phy: exynos-dp-video: Use syscon support to control pmu register drm/exynos: dp: Remove support for unused dptx-phy arm: dts: Exynos5: Use pmu_system_controller phandle for dp phy .../devicetree/bindings/phy/samsung-phy.txt|7 +- arch/arm/boot/dts/exynos5250.dtsi |2 +- arch/arm/boot/dts/exynos5420.dtsi |4 +- drivers/gpu/drm/exynos/exynos_dp_core.c| 58 --- drivers/gpu/drm/exynos/exynos_dp_core.h|2 - drivers/phy/phy-exynos-dp-video.c | 76 ++-- 6 files changed, 75 insertions(+), 74 deletions(-) -- 1.7.10.4
[PATCH v3 13/15] ARM: dts: exynos5: add system register support
Hi YoungJun, On Thu, Jun 5, 2014 at 8:22 AM, YoungJun Cho wrote: > Hi Vivek, > > > On 06/04/2014 08:50 PM, Vivek Gautam wrote: >> >> On Mon, Jun 2, 2014 at 10:52 AM, YoungJun Cho >> wrote: >>> >>> This patch adds sysreg device node, and sysreg property >>> to fimd device node which is required to use I80 interface. >> >> >> Same here. The system register nodes have been added to exynos5250 and >> exynos5420 by the patch: >> dfbbdbf ARM: dts: Add sysreg sytem controller node to exynos5250 and >> exynos5420 >> >> May be, you may want to move those two nodes to this common file >> (exynos5.dtsi). >> > > Thank you for reporting. > I didn't check linux-samsung-soc. > > The exynos5410, 5420 and 5422 use system register with base address > 0x1005. > But exynos5260 and 5430 are different. > And I can't check exynos5250. Exynos5250 too starts with same register base address as Exynos5420, but as you say Exynos5430 and Exynos5260 starts with different base address then it make sense to keep them separate in their dtsi. (I couldn't check Exynos5430) > > So with this condition, it is reasonable to remove these sysreg relevant > patches. Sure. [snip] -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH v3 13/15] ARM: dts: exynos5: add system register support
On Mon, Jun 2, 2014 at 10:52 AM, YoungJun Cho wrote: > This patch adds sysreg device node, and sysreg property > to fimd device node which is required to use I80 interface. Same here. The system register nodes have been added to exynos5250 and exynos5420 by the patch: dfbbdbf ARM: dts: Add sysreg sytem controller node to exynos5250 and exynos5420 May be, you may want to move those two nodes to this common file (exynos5.dtsi). > > Signed-off-by: YoungJun Cho > Acked-by: Inki Dae > Acked-by: Kyungmin Park > --- > arch/arm/boot/dts/exynos5.dtsi |6 ++ > 1 file changed, 6 insertions(+) > > diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi > index 79d0608..95ee496 100644 > --- a/arch/arm/boot/dts/exynos5.dtsi > +++ b/arch/arm/boot/dts/exynos5.dtsi > @@ -81,12 +81,18 @@ > status = "disabled"; > }; > > + sys_reg: syscon at 1005 { > + compatible = "samsung,exynos5-sysreg", "syscon"; > + reg = <0x1005 0x500>; > + }; > + > fimd at 1440 { > compatible = "samsung,exynos5250-fimd"; > interrupt-parent = <>; > reg = <0x1440 0x4>; > interrupt-names = "fifo", "vsync", "lcd_sys"; > interrupts = <18 4>, <18 5>, <18 6>; > + samsung,sysreg = <_reg>; > status = "disabled"; > }; > > -- > 1.7.9.5 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" > in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India
[PATCH v3 03/15] ARM: dts: sysreg: add exynos5 compatible to DT bindings
Hi, On Mon, Jun 2, 2014 at 10:52 AM, YoungJun Cho wrote: > This patch adds relevant to exynos5 compatible for exynos5 SoCs. This change is not required. Please check the latest 'for-next' branch of linux-samsung tree. Recently a patch "dfbbdbf ARM: dts: Add sysreg sytem controller node to exynos5250 and exynos5420" has already updated this binding information. > > Signed-off-by: YoungJun Cho > Acked-by: Inki Dae > Acked-by: Kyungmin Park > --- > .../devicetree/bindings/arm/samsung/sysreg.txt |1 + > 1 file changed, 1 insertion(+) > > diff --git a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt > b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt > index 0ab3251..fd71581 100644 > --- a/Documentation/devicetree/bindings/arm/samsung/sysreg.txt > +++ b/Documentation/devicetree/bindings/arm/samsung/sysreg.txt > @@ -3,6 +3,7 @@ SAMSUNG S5P/Exynos SoC series System Registers (SYSREG) > Properties: > - compatible : should contain "samsung,-sysreg", "syscon"; > For Exynos4 SoC series it should be "samsung,exynos4-sysreg", "syscon"; > + For Exynos5 SoC series it should be "samsung,exynos5-sysreg", "syscon"; > - reg : offset and length of the register set. > > Example: > -- > 1.7.9.5 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" > in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- Best Regards Vivek Gautam Samsung R Institute, Bangalore India