Re: [Freedreno] [PATCH] of/device: add blacklist for iommu dma_ops

2019-06-03 Thread Vivek Gautam
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
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno

Re: [Freedreno] [PATCH] of/device: add blacklist for iommu dma_ops

2019-06-03 Thread Vivek Gautam
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: [Freedreno] [PATCH] of/device: add blacklist for iommu dma_ops

2019-06-03 Thread Vivek Gautam



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 

[Freedreno] [PATCH v2 1/1] drm/prime: Use sg_dma_len() macro to get sg's length

2019-01-07 Thread Vivek Gautam
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: [Freedreno] [PATCH 1/1] drm/prime: Use sg_dma_len() macro to get sg's length

2019-01-07 Thread Vivek Gautam
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
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 1/1] drm/prime: Use sg_dma_len() macro to get sg's length

2019-01-07 Thread Vivek Gautam
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);
 

Re: [Freedreno] [PATCH] of/device: add blacklist for iommu dma_ops

2018-12-03 Thread Vivek Gautam
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] 

[Freedreno] [PATCH v19 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-12-03 Thread Vivek Gautam
Add bindings doc for Qcom's smmu-v2 implementation.

Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Rob Herring 
Reviewed-by: Robin Murphy 
---

Changes since v18:
 None.

 .../devicetree/bindings/iommu/arm,smmu.txt | 39 ++
 1 file changed, 39 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..a6504b37cc21 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,16 @@ 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.
 
+  Qcom SoCs must contain, as below, SoC-specific compatibles
+  along with "qcom,smmu-v2":
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2",
+  "qcom,sdm845-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 +77,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +159,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu@d0 {
+   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";
+   };
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v19 3/5] iommu/arm-smmu: Add the device_link between masters and smmu

2018-12-03 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---

Changes since v18:
 None.

 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 1917d214c4d9..b6b11642b3a9 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1500,6 +1500,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v19 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-12-03 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements.
On msm8996, multiple cores, viz. mdss, video, etc. use this
smmu. On sdm845, this smmu is used with gpu.
Add bindings for the same.

Signed-off-by: Vivek Gautam 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---

Changes since v18:
 None.

 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index b6b11642b3a9..ba18d89d4732 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -120,6 +120,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -2030,6 +2031,7 @@ ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, 
GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
+ARM_SMMU_MATCH_DATA(qcom_smmuv2, ARM_SMMU_V2, QCOM_SMMUV2);
 
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
@@ -2038,6 +2040,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v19 2/5] iommu/arm-smmu: Invoke pm_runtime across the driver

2018-12-03 Thread Vivek Gautam
From: Sricharan R 

Enable pm-runtime on devices that implement a pm domain. Then,
add pm runtime hooks to several iommu_ops to power cycle the
smmu device for explicit TLB invalidation requests, and
register space accesses, etc.
We need these hooks when the smmu, linked to its master through
device links, has to be powered-up without the master device
being in context.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---

Changes since v18:
 None.

 drivers/iommu/arm-smmu.c | 108 ++-
 1 file changed, 98 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 602b67d4f2d6..1917d214c4d9 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -270,6 +270,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -929,11 +943,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -948,6 +966,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1229,10 +1249,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1242,49 +1267,74 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
 {
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+   struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-   if (smmu_domain->tlb_ops)
+   if (smm

[Freedreno] [PATCH v19 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-12-03 Thread Vivek Gautam
Changes since v18:
 - Addressing Stephen's comment [5]:
 Replaced the entire clock bulk data filling and handling with
 devm_clk_bulk_get_all().

Changes since v17:
 - Addressing Will's comment to embed Thor's change [2] for pulling
   clocks information from device tree. This is done by squashing
   Thor's change [2] in v17's 1/5 patch [3].
 - Another minor change is addition of runtime pm hooks to
   arm_smmu_iova_to_phys_hard().

Previous version of this patch series is @ [1].
Also refer to [4] for change logs for previous versions.

[1] https://lore.kernel.org/patchwork/cover/1017699/
[2] https://lore.kernel.org/patchwork/patch/996143/
[3] https://lore.kernel.org/patchwork/patch/1013167/
[4] https://lore.kernel.org/patchwork/cover/979429/
[5] https://lore.kernel.org/patchwork/patch/1017700/

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 (2):
  dt-bindings: arm-smmu: Add bindings for qcom,smmu-v2
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  39 +
 drivers/iommu/arm-smmu.c   | 170 +++--
 2 files changed, 197 insertions(+), 12 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v18 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-12-02 Thread Vivek Gautam
On Fri, Nov 30, 2018 at 11:45 PM Will Deacon  wrote:
>
> On Thu, Nov 29, 2018 at 08:25:20PM +0530, Vivek Gautam wrote:
> > On Wed, Nov 28, 2018 at 10:07 PM Robin Murphy  wrote:
> > >
> > > On 28/11/2018 16:24, Stephen Boyd wrote:
> > > > Quoting Vivek Gautam (2018-11-27 02:11:41)
> > > >> @@ -1966,6 +1970,23 @@ static const struct of_device_id 
> > > >> arm_smmu_of_match[] = {
> > > >>   };
> > > >>   MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
> > > >>
> > > >> +static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
> > > >> +  const char * const *clks)
> > > >> +{
> > > >> +   int i;
> > > >> +
> > > >> +   if (smmu->num_clks < 1)
> > > >> +   return;
> > > >> +
> > > >> +   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
> > > >> + sizeof(*smmu->clks), GFP_KERNEL);
> > > >> +   if (!smmu->clks)
> > > >> +   return;
> > > >> +
> > > >> +   for (i = 0; i < smmu->num_clks; i++)
> > > >> +   smmu->clks[i].id = clks[i];
> > > >
> > > > Is this clk_bulk_get_all()?
> >
> > From what I remember, and now I could go back to v7 and check [1], we parked
> > clk_bulk_get out of OF's sole purview as we also have
> > arm_smmu_device_acpi_probe() besides arm_smmu_device_dt_probe().
> >
> > arm_smmu_device_dt_probe() could get the clocks from dt and fill in
> > the clock bulk data, and
> > similarly, arm_smmu_device_acpi_probe() could fill the clock bulk data
> > by getting it from ACPI.
> >
> > clk_bulk_get_all() seems like going only the OF way.
> > Is there another way here to have something common between ACPI
> > and OF, and then do the clk_bulk_get?
>
> I'd say just go with clk_bulk_get_all() and if somebody really wants to
> mess with the SMMU clocks on a system booted via ACPI, then it's their
> problem to solve. My understanding is that the design of IORT makes this
> next to impossible to solve anyway, because a static table is used and
> therefore we're unable to run whatever ASL methods need to be invoked to
> mess with the clocks.

Sure then. I will respin this patch-series.

>
> Will



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v18 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-11-29 Thread Vivek Gautam
On Wed, Nov 28, 2018 at 10:07 PM Robin Murphy  wrote:
>
> On 28/11/2018 16:24, Stephen Boyd wrote:
> > Quoting Vivek Gautam (2018-11-27 02:11:41)
> >> @@ -1966,6 +1970,23 @@ static const struct of_device_id 
> >> arm_smmu_of_match[] = {
> >>   };
> >>   MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
> >>
> >> +static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
> >> +  const char * const *clks)
> >> +{
> >> +   int i;
> >> +
> >> +   if (smmu->num_clks < 1)
> >> +   return;
> >> +
> >> +   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
> >> + sizeof(*smmu->clks), GFP_KERNEL);
> >> +   if (!smmu->clks)
> >> +   return;
> >> +
> >> +   for (i = 0; i < smmu->num_clks; i++)
> >> +   smmu->clks[i].id = clks[i];
> >
> > Is this clk_bulk_get_all()?

From what I remember, and now I could go back to v7 and check [1], we parked
clk_bulk_get out of OF's sole purview as we also have
arm_smmu_device_acpi_probe() besides arm_smmu_device_dt_probe().

arm_smmu_device_dt_probe() could get the clocks from dt and fill in
the clock bulk data, and
similarly, arm_smmu_device_acpi_probe() could fill the clock bulk data
by getting it from ACPI.

clk_bulk_get_all() seems like going only the OF way.
Is there another way here to have something common between ACPI
and OF, and then do the clk_bulk_get?

[1] https://lore.kernel.org/patchwork/patch/881365/

Thanks & regards
Vivek

>
> Ooh, did that finally get merged while we weren't looking? Great!
>
> Much as I don't want to drag this series out to a v19, it *would* be
> neat if we no longer need to open-code that bit...
>
> Robin.
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v3 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-29 Thread Vivek Gautam
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-29 Thread Vivek Gautam
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
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v18 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-11-27 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements.
On msm8996, multiple cores, viz. mdss, video, etc. use this
smmu. On sdm845, this smmu is used with gpu.
Add bindings for the same.

Signed-off-by: Vivek Gautam 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index f02e0f58e696..29ce9e10abd4 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -121,6 +121,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -2031,6 +2032,7 @@ ARM_SMMU_MATCH_DATA(smmu_generic_v2, ARM_SMMU_V2, 
GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, GENERIC_SMMU);
 ARM_SMMU_MATCH_DATA(arm_mmu500, ARM_SMMU_V2, ARM_MMU500);
 ARM_SMMU_MATCH_DATA(cavium_smmuv2, ARM_SMMU_V2, CAVIUM_SMMUV2);
+ARM_SMMU_MATCH_DATA(qcom_smmuv2, ARM_SMMU_V2, QCOM_SMMUV2);
 
 static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,smmu-v1", .data = _generic_v1 },
@@ -2039,6 +2041,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v18 3/5] iommu/arm-smmu: Add the device_link between masters and smmu

2018-11-27 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 5610cc736f9d..f02e0f58e696 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1501,6 +1501,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v18 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-11-27 Thread Vivek Gautam
From: Sricharan R 

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.
Global locks are also initialized before enabling runtime pm as the
runtime_resume() calls device_reset() which does tlb_sync_global()
that ultimately requires locks to be initialized.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 108 ++-
 1 file changed, 98 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index e47c840fc6a8..5610cc736f9d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -271,6 +271,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -930,11 +944,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -949,6 +967,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1230,10 +1250,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1243,49 +1268,74 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
 {
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+   struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-   if (smmu_domai

[Freedreno] [PATCH v18 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-11-27 Thread Vivek Gautam
Looks like this is going to be the final respin before this support
finally lands.
The change isn't much from v17_resend series [1] besides taking
Thor's change [2] for clocks.

Changes since v17:
 - Addressing Will's comment to embed Thor's change [2] for pulling
   clocks information from device tree. This is done by squashing
   Thor's change [2] in v17's 1/5 patch [3].
 - Another minor change is addition of runtime pm hooks to
   arm_smmu_iova_to_phys_hard().

Previous version of this patch series is @ [1].
Also refer to [4] for change logs for previous versions.

[1] https://lore.kernel.org/patchwork/cover/1013166/
[2] https://lore.kernel.org/patchwork/patch/996143/
[3] https://lore.kernel.org/patchwork/patch/1013167/
[4] https://lore.kernel.org/patchwork/cover/979429/

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 (2):
  dt-bindings: arm-smmu: Add bindings for qcom,smmu-v2
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  39 
 drivers/iommu/arm-smmu.c   | 212 +++--
 2 files changed, 239 insertions(+), 12 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v18 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-11-27 Thread Vivek Gautam
From: Sricharan R 

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.
We pull all the information about clocks from device tree.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[Thor: Rework to get clocks from device tree]
Signed-off-by: Thor Thayer 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 100 +--
 1 file changed, 97 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 5a28ae892504..e47c840fc6a8 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -44,10 +44,12 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -206,6 +208,8 @@ struct arm_smmu_device {
u32 num_global_irqs;
u32 num_context_irqs;
unsigned int*irqs;
+   struct clk_bulk_data*clks;
+   int num_clks;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1947,7 +1951,7 @@ struct arm_smmu_match_data {
 };
 
 #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);
@@ -1966,6 +1970,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2038,6 +2059,7 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
const struct arm_smmu_match_data *data;
struct device *dev = >dev;
bool legacy_binding;
+   const char **parent_names;
 
if (of_property_read_u32(dev->of_node, "#global-interrupts",
 >num_global_irqs)) {
@@ -2048,6 +2070,26 @@ 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 = of_clk_get_parent_count(dev->of_node);
+   /* check to see if clocks were specified in DT */
+   if (smmu->num_clks) {
+   unsigned int i;
+
+   parent_names = kmalloc_array(smmu->num_clks,
+sizeof(*parent_names),
+GFP_KERNEL);
+   if (!parent_names)
+   return -ENOMEM;
+
+   for (i = 0; i < smmu->num_clks; i++) {
+   if (of_property_read_string_index(dev->of_node,
+ "clock-names", i,
+ _names[i]))
+   goto fail_clk_name;
+   }
+   arm_smmu_fill_clk_data(smmu, parent_names);
+   kfree(parent_names);
+   }
 
parse_driver_options(smmu);
 
@@ -2067,6 +2109,12 @@ static int arm_smmu_device_dt_probe(struct 
platform_device *pdev,
smmu->features |= ARM_SMMU_FEAT_COHERENT_WALK;
 
return 0;
+
+fail_clk_name:
+   kfree(parent_names);
+   /* clock-names required for clocks in devm_clk_bulk_get() */
+   dev_err(dev, "clock-names required in device tree\n");
+   return -ENODEV;

[Freedreno] [PATCH v2 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-26 Thread Vivek Gautam
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [RESEND PATCH v17 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-11-26 Thread Vivek Gautam

Hi Thor,


On 11/26/2018 8:11 PM, Thor Thayer wrote:

Hi Vivek,

On 11/26/18 4:55 AM, Vivek Gautam wrote:


On 11/24/2018 12:04 AM, Will Deacon wrote:

On Fri, Nov 23, 2018 at 03:06:29PM +0530, Vivek Gautam wrote:
On Fri, Nov 23, 2018 at 2:52 PM Tomasz Figa  
wrote:

On Fri, Nov 23, 2018 at 6:13 PM Vivek Gautam
 wrote:
On Wed, Nov 21, 2018 at 11:09 PM Will Deacon 
 wrote:

On Fri, Nov 16, 2018 at 04:54:30PM +0530, Vivek Gautam wrote:
@@ -2026,6 +2027,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, 
ARM_SMMU_V1_64K, GENERIC_SMMU);

  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),
+};
These seems redundant if we go down the route proposed by Thor, 
where we
just pull all of the clocks out of the device-tree. In which 
case, why

do we need this match_data at all?

Which is better? Driver relying solely on the device tree to tell
which all clocks
are required to be enabled,
or, the driver deciding itself based on the platform's match data,
that it should
have X, Y, & Z clocks that should be supplied from the device tree.

The former would simplify the driver, but would also make it
impossible to spot mistakes in DT, which would ultimately surface out
as very hard to debug bugs (likely complete system lockups).

Thanks.
Yea, this is how I understand things presently. Relying on device tree
puts the things out of driver's control.

But it also has the undesirable effect of having to update the driver
code whenever we want to add support for a new SMMU implementation. If
we do this all in the DT, as Thor is trying to do, then older kernels
will work well with new hardware.


Hi Will,
Am I unable to understand the intentions here for Thor's clock-fetch
design change?

I'm having trouble parsing your question, sorry. Please work with Thor
so that we have a single way to get the clock information. My 
preference

is to take it from the firmware, for the reason I stated above.

Hi Will,

Sure, thanks. I will work with Thor to get this going.

Hi Thor,
Does it sound okay to you to squash your patch [1] into my patch [2] 
with

your 'Signed-off-by' tag?
I will update the commit log to include the information about getting
clock details from device tree.

[1] https://patchwork.kernel.org/patch/10628725/
[2] https://patchwork.kernel.org/patch/10686061/



Yes, that would be great and easier to understand than my patch on top 
of yours.


Additionally, can you remove the "Error:" as Will requested as part of 
the squash?


Thanks for your consent. I have reworked the patch today, and have 
addressed Will's

comment. I will give a try on the board and post it by tomorrow.

Best regards
Vivek



Thank you!

Thor


Best regards
Vivek


Will







___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [RESEND PATCH v17 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-11-26 Thread Vivek Gautam



On 11/26/2018 11:33 AM, Vivek Gautam wrote:



On 11/24/2018 12:06 AM, Will Deacon wrote:

On Thu, Nov 22, 2018 at 05:32:24PM +0530, Vivek Gautam wrote:

Hi Will,

On Wed, Nov 21, 2018 at 11:09 PM Will Deacon  
wrote:

On Fri, Nov 16, 2018 at 04:54:27PM +0530, Vivek Gautam wrote:

From: Sricharan R 

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.
Global locks are also initialized before enabling runtime pm as the
runtime_resume() calls device_reset() which does tlb_sync_global()
that ultimately requires locks to be initialized.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
  drivers/iommu/arm-smmu.c | 101 
++-

  1 file changed, 91 insertions(+), 10 deletions(-)

Given that you're doing the get/put in the TLBI ops unconditionally:


  static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
  {
   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ struct arm_smmu_device *smmu = smmu_domain->smmu;

- if (smmu_domain->tlb_ops)
+ if (smmu_domain->tlb_ops) {
+ arm_smmu_rpm_get(smmu);
smmu_domain->tlb_ops->tlb_flush_all(smmu_domain);
+ arm_smmu_rpm_put(smmu);
+ }
  }

  static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
  {
   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+ struct arm_smmu_device *smmu = smmu_domain->smmu;

- if (smmu_domain->tlb_ops)
+ if (smmu_domain->tlb_ops) {
+ arm_smmu_rpm_get(smmu);
smmu_domain->tlb_ops->tlb_sync(smmu_domain);
+ arm_smmu_rpm_put(smmu);
+ }

Why do you need them around the map/unmap calls as well?

We still have .tlb_add_flush path?

Ok, so we could add the ops around that as well. Right now, we've got
the runtime pm hooks crossing two parts of the API.


Sure, will do that then, and remove the runtime pm hooks from map/unmap.


I missed this earlier -
We are adding runtime pm hooks in the 'iommu_ops' callbacks and not 
really to

'tlb_ops'. So how the runtime pm hooks crossing the paths?
'.map/.unmap' iommu_ops don't call '.flush_iotlb_all' or '.iotlb_sync' 
iommu_ops

anywhere.

E.g., only callers to domain->ops->flush_iotlb_all() are:
iommu_dma_flush_iotlb_all(), or iommu_flush_tlb_all() which are not in 
map/unmap paths.


Regards
Vivek



Thanks
Vivek


Will




___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [RESEND PATCH v17 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-11-26 Thread Vivek Gautam


On 11/24/2018 12:04 AM, Will Deacon wrote:

On Fri, Nov 23, 2018 at 03:06:29PM +0530, Vivek Gautam wrote:

On Fri, Nov 23, 2018 at 2:52 PM Tomasz Figa  wrote:

On Fri, Nov 23, 2018 at 6:13 PM Vivek Gautam
 wrote:

On Wed, Nov 21, 2018 at 11:09 PM Will Deacon  wrote:

On Fri, Nov 16, 2018 at 04:54:30PM +0530, Vivek Gautam wrote:

@@ -2026,6 +2027,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
  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),
+};

These seems redundant if we go down the route proposed by Thor, where we
just pull all of the clocks out of the device-tree. In which case, why
do we need this match_data at all?

Which is better? Driver relying solely on the device tree to tell
which all clocks
are required to be enabled,
or, the driver deciding itself based on the platform's match data,
that it should
have X, Y, & Z clocks that should be supplied from the device tree.

The former would simplify the driver, but would also make it
impossible to spot mistakes in DT, which would ultimately surface out
as very hard to debug bugs (likely complete system lockups).

Thanks.
Yea, this is how I understand things presently. Relying on device tree
puts the things out of driver's control.

But it also has the undesirable effect of having to update the driver
code whenever we want to add support for a new SMMU implementation. If
we do this all in the DT, as Thor is trying to do, then older kernels
will work well with new hardware.


Hi Will,
Am I unable to understand the intentions here for Thor's clock-fetch
design change?

I'm having trouble parsing your question, sorry. Please work with Thor
so that we have a single way to get the clock information. My preference
is to take it from the firmware, for the reason I stated above.

Hi Will,

Sure, thanks. I will work with Thor to get this going.

Hi Thor,
Does it sound okay to you to squash your patch [1] into my patch [2] with
your 'Signed-off-by' tag?
I will update the commit log to include the information about getting
clock details from device tree.

[1] https://patchwork.kernel.org/patch/10628725/
[2] https://patchwork.kernel.org/patch/10686061/

Best regards
Vivek


Will


___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [RESEND PATCH v17 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-11-23 Thread Vivek Gautam
Hi Tomasz,

On Fri, Nov 23, 2018 at 2:52 PM Tomasz Figa  wrote:
>
> Hi Vivek, Will,
>
> On Fri, Nov 23, 2018 at 6:13 PM Vivek Gautam
>  wrote:
> >
> > Hi Will,
> >
> > On Wed, Nov 21, 2018 at 11:09 PM Will Deacon  wrote:
> > >
> > > [+Thor]
> > >
> > > On Fri, Nov 16, 2018 at 04:54:30PM +0530, Vivek Gautam wrote:
> > > > qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
> > > > clock and power requirements.
> > > > On msm8996, multiple cores, viz. mdss, video, etc. use this
> > > > smmu. On sdm845, this smmu is used with gpu.
> > > > Add bindings for the same.
> > > >
> > > > Signed-off-by: Vivek Gautam 
> > > > Reviewed-by: Rob Herring 
> > > > Reviewed-by: Tomasz Figa 
> > > > Tested-by: Srinivas Kandagatla 
> > > > Reviewed-by: Robin Murphy 
> > > > ---
> > > >  drivers/iommu/arm-smmu.c | 13 +
> > > >  1 file changed, 13 insertions(+)
> > > >
> > > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> > > > index 2098c3141f5f..d315ca637097 100644
> > > > --- a/drivers/iommu/arm-smmu.c
> > > > +++ b/drivers/iommu/arm-smmu.c
> > > > @@ -120,6 +120,7 @@ enum arm_smmu_implementation {
> > > >   GENERIC_SMMU,
> > > >   ARM_MMU500,
> > > >   CAVIUM_SMMUV2,
> > > > + QCOM_SMMUV2,
> > > >  };
> > > >
> > > >  struct arm_smmu_s2cr {
> > > > @@ -2026,6 +2027,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
> > > > GENERIC_SMMU);
> > > >  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),
> > > > +};
> > >
> > > These seems redundant if we go down the route proposed by Thor, where we
> > > just pull all of the clocks out of the device-tree. In which case, why
> > > do we need this match_data at all?
> >
> > Which is better? Driver relying solely on the device tree to tell
> > which all clocks
> > are required to be enabled,
> > or, the driver deciding itself based on the platform's match data,
> > that it should
> > have X, Y, & Z clocks that should be supplied from the device tree.
>
> The former would simplify the driver, but would also make it
> impossible to spot mistakes in DT, which would ultimately surface out
> as very hard to debug bugs (likely complete system lockups).

Thanks.
Yea, this is how I understand things presently. Relying on device tree
puts the things out of driver's control.

Hi Will,
Am I unable to understand the intentions here for Thor's clock-fetch
design change?

>
> For qcom_smmuv2, I believe we're eventually going to end up with
> platform-specific quirks anyway, so specifying the clocks too wouldn't
> hurt. Given that, I'd recommend sticking to the latter, i.e. what this
> patch does.
>
> Best regards,
> Tomasz


Best regards
Vivek

> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [RESEND PATCH v17 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-11-23 Thread Vivek Gautam
Hi Will,

On Wed, Nov 21, 2018 at 11:09 PM Will Deacon  wrote:
>
> [+Thor]
>
> On Fri, Nov 16, 2018 at 04:54:30PM +0530, Vivek Gautam wrote:
> > qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
> > clock and power requirements.
> > On msm8996, multiple cores, viz. mdss, video, etc. use this
> > smmu. On sdm845, this smmu is used with gpu.
> > Add bindings for the same.
> >
> > Signed-off-by: Vivek Gautam 
> > Reviewed-by: Rob Herring 
> > Reviewed-by: Tomasz Figa 
> > Tested-by: Srinivas Kandagatla 
> > Reviewed-by: Robin Murphy 
> > ---
> >  drivers/iommu/arm-smmu.c | 13 +
> >  1 file changed, 13 insertions(+)
> >
> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> > index 2098c3141f5f..d315ca637097 100644
> > --- a/drivers/iommu/arm-smmu.c
> > +++ b/drivers/iommu/arm-smmu.c
> > @@ -120,6 +120,7 @@ enum arm_smmu_implementation {
> >   GENERIC_SMMU,
> >   ARM_MMU500,
> >   CAVIUM_SMMUV2,
> > + QCOM_SMMUV2,
> >  };
> >
> >  struct arm_smmu_s2cr {
> > @@ -2026,6 +2027,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
> > GENERIC_SMMU);
> >  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),
> > +};
>
> These seems redundant if we go down the route proposed by Thor, where we
> just pull all of the clocks out of the device-tree. In which case, why
> do we need this match_data at all?

Which is better? Driver relying solely on the device tree to tell
which all clocks
are required to be enabled,
or, the driver deciding itself based on the platform's match data,
that it should
have X, Y, & Z clocks that should be supplied from the device tree.

Thanks
Vivek

>
> Will
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [RESEND PATCH v17 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-11-22 Thread Vivek Gautam
Hi Will,

On Wed, Nov 21, 2018 at 11:09 PM Will Deacon  wrote:
>
> On Fri, Nov 16, 2018 at 04:54:27PM +0530, Vivek Gautam wrote:
> > From: Sricharan R 
> >
> > 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.
> > Global locks are also initialized before enabling runtime pm as the
> > runtime_resume() calls device_reset() which does tlb_sync_global()
> > that ultimately requires locks to be initialized.
> >
> > Signed-off-by: Sricharan R 
> > [vivek: Cleanup pm runtime calls]
> > Signed-off-by: Vivek Gautam 
> > Reviewed-by: Tomasz Figa 
> > Tested-by: Srinivas Kandagatla 
> > Reviewed-by: Robin Murphy 
> > ---
> >  drivers/iommu/arm-smmu.c | 101 
> > ++-
> >  1 file changed, 91 insertions(+), 10 deletions(-)
>
> Given that you're doing the get/put in the TLBI ops unconditionally:
>
> >  static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
> >  {
> >   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> > + struct arm_smmu_device *smmu = smmu_domain->smmu;
> >
> > - if (smmu_domain->tlb_ops)
> > + if (smmu_domain->tlb_ops) {
> > + arm_smmu_rpm_get(smmu);
> >   smmu_domain->tlb_ops->tlb_flush_all(smmu_domain);
> > + arm_smmu_rpm_put(smmu);
> > + }
> >  }
> >
> >  static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
> >  {
> >   struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> > + struct arm_smmu_device *smmu = smmu_domain->smmu;
> >
> > - if (smmu_domain->tlb_ops)
> > + if (smmu_domain->tlb_ops) {
> > + arm_smmu_rpm_get(smmu);
> >   smmu_domain->tlb_ops->tlb_sync(smmu_domain);
> > + arm_smmu_rpm_put(smmu);
> > + }
>
> Why do you need them around the map/unmap calls as well?

We still have .tlb_add_flush path?

Thanks
Vivek
>
> Will
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-22 Thread Vivek Gautam

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


___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH 1/1] drm: msm: Replace dma_map_sg with dma_sync_sg*

2018-11-20 Thread Vivek Gautam
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [RESEND PATCH v17 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-11-16 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements.
On msm8996, multiple cores, viz. mdss, video, etc. use this
smmu. On sdm845, this smmu is used with gpu.
Add bindings for the same.

Signed-off-by: Vivek Gautam 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 2098c3141f5f..d315ca637097 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -120,6 +120,7 @@ enum arm_smmu_implementation {
GENERIC_SMMU,
ARM_MMU500,
CAVIUM_SMMUV2,
+   QCOM_SMMUV2,
 };
 
 struct arm_smmu_s2cr {
@@ -2026,6 +2027,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 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 },
@@ -2033,6 +2045,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [RESEND PATCH v17 3/5] iommu/arm-smmu: Add the device_link between masters and smmu

2018-11-16 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index cae88c9f83ca..2098c3141f5f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1493,6 +1493,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [RESEND PATCH v17 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-11-16 Thread Vivek Gautam
Add bindings doc for Qcom's smmu-v2 implementation.

Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Rob Herring 
Reviewed-by: Robin Murphy 
---
 .../devicetree/bindings/iommu/arm,smmu.txt | 39 ++
 1 file changed, 39 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..a6504b37cc21 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,16 @@ 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.
 
+  Qcom SoCs must contain, as below, SoC-specific compatibles
+  along with "qcom,smmu-v2":
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2",
+  "qcom,sdm845-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 +77,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +159,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu@d0 {
+   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";
+   };
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [RESEND PATCH v17 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-11-16 Thread Vivek Gautam
From: Sricharan R 

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.
Global locks are also initialized before enabling runtime pm as the
runtime_resume() calls device_reset() which does tlb_sync_global()
that ultimately requires locks to be initialized.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 101 ++-
 1 file changed, 91 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index f7ab7ce87a94..cae88c9f83ca 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -270,6 +270,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -929,11 +943,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -948,6 +966,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1229,10 +1249,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1242,49 +1267,74 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
 {
struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
+   struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-   if (smmu_domai

[Freedreno] [RESEND PATCH v17 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-11-16 Thread Vivek Gautam
From: Sricharan R 

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.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---
 drivers/iommu/arm-smmu.c | 77 ++--
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 5a28ae892504..f7ab7ce87a94 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -48,6 +48,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -206,6 +207,8 @@ struct arm_smmu_device {
u32 num_global_irqs;
u32 num_context_irqs;
unsigned int*irqs;
+   struct clk_bulk_data*clks;
+   int num_clks;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1944,10 +1947,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);
@@ -1966,6 +1971,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2048,6 +2070,9 @@ 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;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2150,6 +2175,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare_enable(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2236,6 +2269,9 @@ 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);
+
+   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2244,15 +2280,50 @@ static void arm_smmu_device_shutdown(struct 
platform_device *pdev)
arm_smmu_device_remove(pdev);
 }
 
-static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
 {
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
+   if (ret)
+   return ret;
 
arm_smmu_device_reset(smmu);
+
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable(smmu->num_clks, smmu->clks);
+

[Freedreno] [RESEND PATCH v17 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-11-16 Thread Vivek Gautam
Hi Will,
I am resending this series after we concluded on comments [1,2] on v16 of
this patch-series, and the subsequent patch [3] was posted.
Kindly merge this series.

Thanks
Vivek

Previous version of this patch series is @ [4].
Also refer to [4] for change logs for previous versions.

[1] https://lore.kernel.org/patchwork/patch/979430/
[2] https://lore.kernel.org/patchwork/patch/979433/
[3] https://lore.kernel.org/patchwork/patch/994194/
[4] https://lore.kernel.org/patchwork/cover/979429/

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 (2):
  dt-bindings: arm-smmu: Add bindings for qcom,smmu-v2
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  39 +
 drivers/iommu/arm-smmu.c   | 192 +++--
 2 files changed, 219 insertions(+), 12 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v17 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-10-02 Thread Vivek Gautam
From: Sricharan R 

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.
Global locks are also initialized before enabling runtime pm as the
runtime_resume() calls device_reset() which does tlb_sync_global()
that ultimately requires locks to be initialized.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
Reviewed-by: Robin Murphy 
---

Changes since v16:
 - Rebased on Will's tree for arm-smmu updates [1].
 - Added rpm{get|put} calls to .flush_iotlb_all, and .iotlb_sync
   callbacks to take care of non-strict tlb flush queue updates.

 drivers/iommu/arm-smmu.c | 101 ++-
 1 file changed, 91 insertions(+), 10 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 59d1430a9f2d..bf106688ab7a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -269,6 +269,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -928,11 +942,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -947,6 +965,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1228,10 +1248,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1241,49 +1266,74 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_s

Re: [Freedreno] [PATCH v16 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-10-01 Thread Vivek Gautam
On Tue, Oct 2, 2018 at 9:44 AM Vivek Gautam  wrote:
>
> Hi Will,
>
> On Mon, Oct 1, 2018 at 6:29 PM Will Deacon  wrote:
> >
> > Hi Vivek,
> >
> > On Thu, Aug 30, 2018 at 08:15:38PM +0530, Vivek Gautam wrote:
> > > From: Sricharan R 
> > >
> > > 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.
> > > Global locks are also initialized before enabling runtime pm as the
> > > runtime_resume() calls device_reset() which does tlb_sync_global()
> > > that ultimately requires locks to be initialized.
> > >
> > > Signed-off-by: Sricharan R 
> > > [vivek: Cleanup pm runtime calls]
> > > Signed-off-by: Vivek Gautam 
> > > Reviewed-by: Tomasz Figa 
> > > Tested-by: Srinivas Kandagatla 
> > > ---
> > >  drivers/iommu/arm-smmu.c | 89 
> > > +++-
> > >  1 file changed, 81 insertions(+), 8 deletions(-)
> >
> > This doesn't apply on my tree[1], possibly because I've got Robin's 
> > non-strict
> > invalidation queued there. However, that got me thinking -- how does this
> > work in conjunction with the timer-based TLB invalidation? Do we need to
> > rpm_{get,put} around flush_iotlb_all()? If so, do we still need the calls
> > in map/unmap when non-strict mode is in use?

For map/unmap(), i think there would be no harm in having additional
power.usage_count even for the non-strict mode.
So, I will just add rpm{get,put} in arm_smmu_flush_iotlb_all(), and
arm_smmu_iotlb_sync().

Regards
Vivek

>
> I haven't tested things with flush queues, but from what it looks like
> both .flush_iotlb_all, and .iotlb_sync callbacks need rpm_get/put().
> I will respin the patches.
>
> Thanks
> Vivek
> >
> > Will
> >
> > [1] 
> > https://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git/log/?h=for-joerg/arm-smmu/updates
>
>
>
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-10-01 Thread Vivek Gautam
Hi Will,

On Mon, Oct 1, 2018 at 6:29 PM Will Deacon  wrote:
>
> Hi Vivek,
>
> On Thu, Aug 30, 2018 at 08:15:38PM +0530, Vivek Gautam wrote:
> > From: Sricharan R 
> >
> > 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.
> > Global locks are also initialized before enabling runtime pm as the
> > runtime_resume() calls device_reset() which does tlb_sync_global()
> > that ultimately requires locks to be initialized.
> >
> > Signed-off-by: Sricharan R 
> > [vivek: Cleanup pm runtime calls]
> > Signed-off-by: Vivek Gautam 
> > Reviewed-by: Tomasz Figa 
> > Tested-by: Srinivas Kandagatla 
> > ---
> >  drivers/iommu/arm-smmu.c | 89 
> > +++-
> >  1 file changed, 81 insertions(+), 8 deletions(-)
>
> This doesn't apply on my tree[1], possibly because I've got Robin's non-strict
> invalidation queued there. However, that got me thinking -- how does this
> work in conjunction with the timer-based TLB invalidation? Do we need to
> rpm_{get,put} around flush_iotlb_all()? If so, do we still need the calls
> in map/unmap when non-strict mode is in use?

I haven't tested things with flush queues, but from what it looks like
both .flush_iotlb_all, and .iotlb_sync callbacks need rpm_get/put().
I will respin the patches.

Thanks
Vivek
>
> Will
>
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git/log/?h=for-joerg/arm-smmu/updates



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-10-01 Thread Vivek Gautam
On Mon, Oct 1, 2018 at 11:19 AM Vivek Gautam
 wrote:
>
> HI Ulf,
>
> On Fri, Sep 28, 2018 at 5:30 PM Ulf Hansson  wrote:
> >
> > On 30 August 2018 at 16:45, Vivek Gautam  
> > wrote:
> > > From: Sricharan R 
> > >
> > > 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.
> > >
> > > Also, while we enable the runtime pm add a pm sleep suspend
> > > callback that pushes devices to low power state by turning
> > > the clocks off in a system sleep.
> > > Also add corresponding clock enable path in resume callback.
> > >
> > > Signed-off-by: Sricharan R 
> > > Signed-off-by: Archit Taneja 
> > > [vivek: rework for clock and pm ops]
> > > Signed-off-by: Vivek Gautam 
> > > Reviewed-by: Tomasz Figa 
> > > Tested-by: Srinivas Kandagatla 
> > > ---
> > >  drivers/iommu/arm-smmu.c | 77 
> > > ++--
> > >  1 file changed, 74 insertions(+), 3 deletions(-)
> > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> >
> > [...]
> >
> > > -static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> > > +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
> > >  {
> > > struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> > > +   int ret;
> > > +
> > > +   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
> > > +   if (ret)
> > > +   return ret;
> > >
> > > arm_smmu_device_reset(smmu);
> > > +
> > > return 0;
> > >  }
> > >
> > > -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
> > > +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
> > > +{
> > > +   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> > > +
> > > +   clk_bulk_disable(smmu->num_clks, smmu->clks);
> > > +
> > > +   return 0;
> > > +}
> > > +
> > > +static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> > > +{
> > > +   if (pm_runtime_suspended(dev))
> > > +   return 0;
> >
> > Looks like you should be able use pm_runtime_force_resume(), instead
> > of using this local trick. Unless I am missing something, of course.
> >
> > In other words, just assign the system sleep callbacks for resume, to
> > pm_runtime_force_resume(). And vice verse for the system suspend
> > callbacks, pm_runtime_force_suspend(), of course.
>
> Thanks for the review. I will change this as suggested.

Coming back at this - actually Rafael suggested _not_ to use
pm_runtime_force_suspend/resume() when Marek had suggested
the same [1].
He also mentioned few caveats/limitations of using these APIs
for system sleep ops.
Let me know your opinion. Thanks.

[1] https://lkml.org/lkml/2018/7/11/978
[2] https://lkml.org/lkml/2018/7/23/334

Best regards
Vivek
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-10-01 Thread Vivek Gautam
On Mon, Oct 1, 2018 at 3:09 PM Ulf Hansson  wrote:
>
> On 1 October 2018 at 07:49, Vivek Gautam  wrote:
> > HI Ulf,
> >
> > On Fri, Sep 28, 2018 at 5:30 PM Ulf Hansson  wrote:
> >>
> >> On 30 August 2018 at 16:45, Vivek Gautam  
> >> wrote:
> >> > From: Sricharan R 
> >> >
> >> > 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.
> >> >
> >> > Also, while we enable the runtime pm add a pm sleep suspend
> >> > callback that pushes devices to low power state by turning
> >> > the clocks off in a system sleep.
> >> > Also add corresponding clock enable path in resume callback.
> >> >
> >> > Signed-off-by: Sricharan R 
> >> > Signed-off-by: Archit Taneja 
> >> > [vivek: rework for clock and pm ops]
> >> > Signed-off-by: Vivek Gautam 
> >> > Reviewed-by: Tomasz Figa 
> >> > Tested-by: Srinivas Kandagatla 
> >> > ---
> >> >  drivers/iommu/arm-smmu.c | 77 
> >> > ++--
> >> >  1 file changed, 74 insertions(+), 3 deletions(-)
> >> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> >>
> >> [...]
> >>
> >> > -static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> >> > +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
> >> >  {
> >> > struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> >> > +   int ret;
> >> > +
> >> > +   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
> >> > +   if (ret)
> >> > +   return ret;
> >> >
> >> > arm_smmu_device_reset(smmu);
> >> > +
> >> > return 0;
> >> >  }
> >> >
> >> > -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
> >> > +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
> >> > +{
> >> > +   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> >> > +
> >> > +   clk_bulk_disable(smmu->num_clks, smmu->clks);
> >> > +
> >> > +   return 0;
> >> > +}
> >> > +
> >> > +static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> >> > +{
> >> > +   if (pm_runtime_suspended(dev))
> >> > +   return 0;
> >>
> >> Looks like you should be able use pm_runtime_force_resume(), instead
> >> of using this local trick. Unless I am missing something, of course.
> >>
> >> In other words, just assign the system sleep callbacks for resume, to
> >> pm_runtime_force_resume(). And vice verse for the system suspend
> >> callbacks, pm_runtime_force_suspend(), of course.
> >
> > Thanks for the review. I will change this as suggested.
> >
> >>
> >> > +
> >> > +   return arm_smmu_runtime_resume(dev);
> >> > +}
> >> > +
> >> > +static int __maybe_unused arm_smmu_pm_suspend(struct device *dev)
> >> > +{
> >> > +   if (pm_runtime_suspended(dev))
> >> > +   return 0;
> >> > +
> >> > +   return arm_smmu_runtime_suspend(dev);
> >> > +}
> >> > +
> >> > +static const struct dev_pm_ops arm_smmu_pm_ops = {
> >> > +   SET_SYSTEM_SLEEP_PM_OPS(arm_smmu_pm_suspend, arm_smmu_pm_resume)
> >>
> >> I am wondering if using the ->suspend|resume() callback is really
> >> "late/early" enough in the device suspend phase?
> >>
> >> Others is using the noirq phase and some is even using the syscore
> >> ops. Of course it depends on the behavior of the consumers of iommu
> >> device, and I guess not everyone is using device links, which for sure
> >> improves things in this regards as well.
> >
> > Well yes, as you said the device links should be able to take care of
> > maintaining the correct suspend/resume order of smmu and its clients,
> > or am I missing your point here?
> > Let me know and I will be happy to incorporate any suggestions.
> > Thanks
>
> If it works fine, then you may keep it as is.
>
> Just wanted to point out that if any consumers relies on the iommu to
> operational to say until the suspend-late phase, then this doesn't
> play. Then you need to move your callbacks to the corresponding same
> phase.

Although I have no means to test the suspend-late phase, tests with graphics
and display on db820 haven't shown any anomaly.

[snip]

Best regards
Vivek

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-10-01 Thread Vivek Gautam
Hi Will,

On Fri, Sep 28, 2018 at 7:27 PM Will Deacon  wrote:
>
> Hi Vivek,
>
> On Thu, Aug 30, 2018 at 08:15:36PM +0530, 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
> > device links between smmu and client devices. The device link
> > framework keeps the two devices in correct order for power-cycling
> > across runtime PM or across system-wide PM.
> >
> > With addition of a new device link flag DL_FLAG_AUTOREMOVE_SUPPLIER [7],
> > the device links created between arm-smmu and its clients will be
> > automatically purged when arm-smmu driver unbinds from its device.
> >
> > As not all implementations support clock/power gating, we are checking
> > for a valid 'smmu->dev's pm_domain' to conditionally enable the runtime
> > power management for such smmu implementations that can support it.
> > Otherwise, the clocks are turned to be always on in .probe until .remove.
> > With conditional runtime pm now, we avoid touching dev->power.lock
> > in fastpaths for smmu implementations that don't need to do anything
> > useful with pm_runtime.
> > This lets us to use the much-argued pm_runtime_get_sync/put_sync()
> > calls in map/unmap callbacks so that the clients do not have to
> > worry about handling any of the arm-smmu's power.
> >
> > This series also adds support for Qcom's arm-smmu-v2 variant that
> > has different clocks and power requirements.
> >
> > Previous version of this patch series is @ [1].
> >
> > Build tested the series based on 4.19-rc1.
>
> I'm going to send my pull request to Joerg early next week (probably
> Monday), but I'm not keen to include this whilst it has outstanding comments
> from Ulf. Your errata workaround patch is in a similar situation, with
> outstanding comments from Robin.

I am going to address Ulf's comments for pm_runtime_force_suspend/resume()
calls in system sleep callbacks and respin the series unless he has any more
comments regarding the early/late nature of suspend/resume.
So will it do if I respin the series today after waiting for Ulf?

The workaround series is going for a discussion now, so i think it can wait.
Thanks

Best regards
Vivek
>
> Will
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-09-30 Thread Vivek Gautam
HI Ulf,

On Fri, Sep 28, 2018 at 5:30 PM Ulf Hansson  wrote:
>
> On 30 August 2018 at 16:45, Vivek Gautam  wrote:
> > From: Sricharan R 
> >
> > 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.
> >
> > Also, while we enable the runtime pm add a pm sleep suspend
> > callback that pushes devices to low power state by turning
> > the clocks off in a system sleep.
> > Also add corresponding clock enable path in resume callback.
> >
> > Signed-off-by: Sricharan R 
> > Signed-off-by: Archit Taneja 
> > [vivek: rework for clock and pm ops]
> > Signed-off-by: Vivek Gautam 
> > Reviewed-by: Tomasz Figa 
> > Tested-by: Srinivas Kandagatla 
> > ---
> >  drivers/iommu/arm-smmu.c | 77 
> > ++--
> >  1 file changed, 74 insertions(+), 3 deletions(-)
> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>
> [...]
>
> > -static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> > +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
> >  {
> > struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> > +   int ret;
> > +
> > +   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
> > +   if (ret)
> > +   return ret;
> >
> > arm_smmu_device_reset(smmu);
> > +
> > return 0;
> >  }
> >
> > -static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
> > +static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
> > +{
> > +   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
> > +
> > +   clk_bulk_disable(smmu->num_clks, smmu->clks);
> > +
> > +   return 0;
> > +}
> > +
> > +static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
> > +{
> > +   if (pm_runtime_suspended(dev))
> > +   return 0;
>
> Looks like you should be able use pm_runtime_force_resume(), instead
> of using this local trick. Unless I am missing something, of course.
>
> In other words, just assign the system sleep callbacks for resume, to
> pm_runtime_force_resume(). And vice verse for the system suspend
> callbacks, pm_runtime_force_suspend(), of course.

Thanks for the review. I will change this as suggested.

>
> > +
> > +   return arm_smmu_runtime_resume(dev);
> > +}
> > +
> > +static int __maybe_unused arm_smmu_pm_suspend(struct device *dev)
> > +{
> > +   if (pm_runtime_suspended(dev))
> > +   return 0;
> > +
> > +   return arm_smmu_runtime_suspend(dev);
> > +}
> > +
> > +static const struct dev_pm_ops arm_smmu_pm_ops = {
> > +   SET_SYSTEM_SLEEP_PM_OPS(arm_smmu_pm_suspend, arm_smmu_pm_resume)
>
> I am wondering if using the ->suspend|resume() callback is really
> "late/early" enough in the device suspend phase?
>
> Others is using the noirq phase and some is even using the syscore
> ops. Of course it depends on the behavior of the consumers of iommu
> device, and I guess not everyone is using device links, which for sure
> improves things in this regards as well.

Well yes, as you said the device links should be able to take care of
maintaining the correct suspend/resume order of smmu and its clients,
or am I missing your point here?
Let me know and I will be happy to incorporate any suggestions.
Thanks

Regards
Vivek

>
> > +   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
> >
>
> BTW, apologize for very late review comments.
>
> Besides the above comments, the series looks good to me.
>
> Kind regards
> Uffe
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-09-27 Thread Vivek Gautam
On Wed, Sep 26, 2018 at 8:57 PM Robin Murphy  wrote:
>
> On 30/08/18 15:45, Vivek Gautam wrote:
> > From: Sricharan R 
> >
> > 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.
> >
> > Also, while we enable the runtime pm add a pm sleep suspend
> > callback that pushes devices to low power state by turning
> > the clocks off in a system sleep.
> > Also add corresponding clock enable path in resume callback.
> >
> > Signed-off-by: Sricharan R 
> > Signed-off-by: Archit Taneja 
> > [vivek: rework for clock and pm ops]
> > Signed-off-by: Vivek Gautam 
> > Reviewed-by: Tomasz Figa 
> > Tested-by: Srinivas Kandagatla 
> > ---
> >   drivers/iommu/arm-smmu.c | 77 
> > ++--
> >   1 file changed, 74 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> > index fd1b80ef9490..d900e007c3c9 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*clks;
> > + int num_clks;
> >
> >   u32 cavium_id_base; /* Specific to Cavium 
> > */
> >
> > @@ -1896,10 +1899,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);
> > @@ -1918,6 +1923,23 @@ static const struct of_device_id arm_smmu_of_match[] 
> > = {
> >   };
> >   MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
> >
> > +static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
> > +const char * const *clks)
> > +{
> > + int i;
> > +
> > + if (smmu->num_clks < 1)
> > + return;
> > +
> > + smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
> > +   sizeof(*smmu->clks), GFP_KERNEL);
> > + if (!smmu->clks)
> > + return;
> > +
> > + for (i = 0; i < smmu->num_clks; i++)
> > + smmu->clks[i].id = clks[i];
> > +}
> > +
> >   #ifdef CONFIG_ACPI
> >   static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
> >   {
> > @@ -2000,6 +2022,9 @@ 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;
> > +
> > + arm_smmu_fill_clk_data(smmu, data->clks);
> >
> >   parse_driver_options(smmu);
> >
> > @@ -2098,6 +2123,14 @@ static int arm_smmu_device_probe(struct 
> > platform_device *pdev)
> >   smmu->irqs[i] = irq;
> >   }
> >
> > + err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
> > + if (err)
> > + return err;
> > +
> > + err = clk_bulk_prepare_enable(smmu->num_clks, smmu->clks);
> > + if (err)
> > + return err;
> > +
>
> Hmm, if we error out 

Re: [Freedreno] [PATCH v16 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-09-27 Thread Vivek Gautam
Hi Robin,

On Wed, Sep 26, 2018 at 9:29 PM Robin Murphy  wrote:
>
> On 30/08/18 15:45, Vivek Gautam wrote:
> > qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
> > clock and power requirements.
> > On msm8996, multiple cores, viz. mdss, video, etc. use this
> > smmu. On sdm845, this smmu is used with gpu.
> > Add bindings for the same.
> >
> > Signed-off-by: Vivek Gautam 
> > Reviewed-by: Rob Herring 
> > Reviewed-by: Tomasz Figa 
> > Tested-by: Srinivas Kandagatla 
> > ---
> >   drivers/iommu/arm-smmu.c | 13 +
> >   1 file changed, 13 insertions(+)
> >
> > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> > index 166c8c6da24f..411e5ac57c64 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,
>
> Hmm, it seems we don't actually need this right now, but maybe that just
> means there's more imp-def registers and/or errata to come ;)
>
> Either way I guess there's no real harm in having it.

Thanks for the review.

Best regards
Vivek

>
> Reviewed-by: Robin Murphy 
>
> >   };
> >
> >   struct arm_smmu_s2cr {
> > @@ -1970,6 +1971,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
> > GENERIC_SMMU);
> >   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 },
> > @@ -1977,6 +1989,7 @@ static const struct of_device_id arm_smmu_of_match[] 
> > = {
> >   { .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);
> >
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-09-24 Thread Vivek Gautam
Hi Robin, Will,

On Tue, Sep 18, 2018 at 8:41 AM Vivek Gautam
 wrote:
>
> Hi Robin,
>
> On Fri, Sep 7, 2018 at 3:52 PM Vivek Gautam  
> wrote:
> >
> > On Fri, Sep 7, 2018 at 3:22 PM Tomasz Figa  wrote:
> > >
> > > On Fri, Sep 7, 2018 at 6:38 PM Vivek Gautam  
> > > wrote:
> > > >
> > > > Hi Tomasz,
> > > >
> > > >
> > > > On 9/7/2018 2:46 PM, Tomasz Figa wrote:
> > > > > Hi Vivek,
> > > > >
> > > > > On Thu, Aug 30, 2018 at 11:46 PM Vivek Gautam
> > > > >  wrote:
> > > > >> From: Sricharan R 
> > > > >>
> > > > >> 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.
> > > > >> Global locks are also initialized before enabling runtime pm as the
> > > > >> runtime_resume() calls device_reset() which does tlb_sync_global()
> > > > >> that ultimately requires locks to be initialized.
> > > > >>
> > > > >> Signed-off-by: Sricharan R 
> > > > >> [vivek: Cleanup pm runtime calls]
> > > > >> Signed-off-by: Vivek Gautam 
> > > > >> Reviewed-by: Tomasz Figa 
> > > > >> Tested-by: Srinivas Kandagatla 
> > > > >> ---
> > > > >>   drivers/iommu/arm-smmu.c | 89 
> > > > >> +++-
> > > > >>   1 file changed, 81 insertions(+), 8 deletions(-)
> > > > > [snip]
> > > > >> @@ -2215,10 +2281,17 @@ 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");
> > > > >>
> > > > >> +   arm_smmu_rpm_get(smmu);
> > > > >>  /* Turn the thing off */
> > > > >>  writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + 
> > > > >> ARM_SMMU_GR0_sCR0);
> > > > >> +   arm_smmu_rpm_put(smmu);
> > > > >> +
> > > > >> +   if (pm_runtime_enabled(smmu->dev))
> > > > >> +   pm_runtime_force_suspend(smmu->dev);
> > > > >> +   else
> > > > >> +   clk_bulk_disable(smmu->num_clks, smmu->clks);
> > > > >>
> > > > >> -   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clks);
> > > > >> +   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
> > > > > Aren't we missing pm_runtime_disable() here? We'll have the enable
> > > > > count unbalanced if the driver is removed and probed again.
> > > >
> > > > pm_runtime_force_suspend() does a pm_runtime_disable() also if i am not
> > > > wrong.
> > > > And, as mentioned in a previous thread [1], we were seeing a warning
> > > > which we avoided
> > > > by keeping force_suspend().
> > > >
> > > > [1] https://lkml.org/lkml/2018/7/8/124
> > >
> > > I see, thanks. I didn't realize that pm_runtime_force_suspend()
> > > already disables runtime PM indeed. Sorry for the noise.
> >
> > Hi Tomasz,
> > No problem. Thanks for looking back at it.
> >
> > Hi Robin,
> > If you are fine with this series, then can you please consider giving
> > Reviewed-by, so that we are certain that this series will go in the next 
> > merge
> > window.
> > Thanks
>
> Gentle ping.
> You ack will be very helpful in letting Will pull this series for 4.20.
> Thanks.

I would really appreciate if you could provide your ack for this series.
Or if there are any concerns, I am willing to address them.
Thanks.

Best regards
Vivek



>
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation



--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-09-17 Thread Vivek Gautam
Hi Robin,

On Fri, Sep 7, 2018 at 3:52 PM Vivek Gautam  wrote:
>
> On Fri, Sep 7, 2018 at 3:22 PM Tomasz Figa  wrote:
> >
> > On Fri, Sep 7, 2018 at 6:38 PM Vivek Gautam  
> > wrote:
> > >
> > > Hi Tomasz,
> > >
> > >
> > > On 9/7/2018 2:46 PM, Tomasz Figa wrote:
> > > > Hi Vivek,
> > > >
> > > > On Thu, Aug 30, 2018 at 11:46 PM Vivek Gautam
> > > >  wrote:
> > > >> From: Sricharan R 
> > > >>
> > > >> 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.
> > > >> Global locks are also initialized before enabling runtime pm as the
> > > >> runtime_resume() calls device_reset() which does tlb_sync_global()
> > > >> that ultimately requires locks to be initialized.
> > > >>
> > > >> Signed-off-by: Sricharan R 
> > > >> [vivek: Cleanup pm runtime calls]
> > > >> Signed-off-by: Vivek Gautam 
> > > >> Reviewed-by: Tomasz Figa 
> > > >> Tested-by: Srinivas Kandagatla 
> > > >> ---
> > > >>   drivers/iommu/arm-smmu.c | 89 
> > > >> +++-
> > > >>   1 file changed, 81 insertions(+), 8 deletions(-)
> > > > [snip]
> > > >> @@ -2215,10 +2281,17 @@ 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");
> > > >>
> > > >> +   arm_smmu_rpm_get(smmu);
> > > >>  /* Turn the thing off */
> > > >>  writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + 
> > > >> ARM_SMMU_GR0_sCR0);
> > > >> +   arm_smmu_rpm_put(smmu);
> > > >> +
> > > >> +   if (pm_runtime_enabled(smmu->dev))
> > > >> +   pm_runtime_force_suspend(smmu->dev);
> > > >> +   else
> > > >> +   clk_bulk_disable(smmu->num_clks, smmu->clks);
> > > >>
> > > >> -   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clks);
> > > >> +   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
> > > > Aren't we missing pm_runtime_disable() here? We'll have the enable
> > > > count unbalanced if the driver is removed and probed again.
> > >
> > > pm_runtime_force_suspend() does a pm_runtime_disable() also if i am not
> > > wrong.
> > > And, as mentioned in a previous thread [1], we were seeing a warning
> > > which we avoided
> > > by keeping force_suspend().
> > >
> > > [1] https://lkml.org/lkml/2018/7/8/124
> >
> > I see, thanks. I didn't realize that pm_runtime_force_suspend()
> > already disables runtime PM indeed. Sorry for the noise.
>
> Hi Tomasz,
> No problem. Thanks for looking back at it.
>
> Hi Robin,
> If you are fine with this series, then can you please consider giving
> Reviewed-by, so that we are certain that this series will go in the next merge
> window.
> Thanks

Gentle ping.
You ack will be very helpful in letting Will pull this series for 4.20.
Thanks.

Best regards
Vivek


--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-09-11 Thread Vivek Gautam
On Mon, Sep 10, 2018 at 11:32 PM Rob Herring  wrote:
>
> On Thu, 30 Aug 2018 20:15:40 +0530, Vivek Gautam wrote:
> > Add bindings doc for Qcom's smmu-v2 implementation.
> >
> > Signed-off-by: Vivek Gautam 
> > Reviewed-by: Tomasz Figa 
> > Tested-by: Srinivas Kandagatla 
> > ---
> >  .../devicetree/bindings/iommu/arm,smmu.txt | 39 
> > ++
> >  1 file changed, 39 insertions(+)
> >
>
> Reviewed-by: Rob Herring 

Thanks Rob.

Best regards
Vivek


-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-09-07 Thread Vivek Gautam
On Fri, Sep 7, 2018 at 3:22 PM Tomasz Figa  wrote:
>
> On Fri, Sep 7, 2018 at 6:38 PM Vivek Gautam  
> wrote:
> >
> > Hi Tomasz,
> >
> >
> > On 9/7/2018 2:46 PM, Tomasz Figa wrote:
> > > Hi Vivek,
> > >
> > > On Thu, Aug 30, 2018 at 11:46 PM Vivek Gautam
> > >  wrote:
> > >> From: Sricharan R 
> > >>
> > >> 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.
> > >> Global locks are also initialized before enabling runtime pm as the
> > >> runtime_resume() calls device_reset() which does tlb_sync_global()
> > >> that ultimately requires locks to be initialized.
> > >>
> > >> Signed-off-by: Sricharan R 
> > >> [vivek: Cleanup pm runtime calls]
> > >> Signed-off-by: Vivek Gautam 
> > >> Reviewed-by: Tomasz Figa 
> > >> Tested-by: Srinivas Kandagatla 
> > >> ---
> > >>   drivers/iommu/arm-smmu.c | 89 
> > >> +++-
> > >>   1 file changed, 81 insertions(+), 8 deletions(-)
> > > [snip]
> > >> @@ -2215,10 +2281,17 @@ 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");
> > >>
> > >> +   arm_smmu_rpm_get(smmu);
> > >>  /* Turn the thing off */
> > >>  writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + 
> > >> ARM_SMMU_GR0_sCR0);
> > >> +   arm_smmu_rpm_put(smmu);
> > >> +
> > >> +   if (pm_runtime_enabled(smmu->dev))
> > >> +   pm_runtime_force_suspend(smmu->dev);
> > >> +   else
> > >> +   clk_bulk_disable(smmu->num_clks, smmu->clks);
> > >>
> > >> -   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clks);
> > >> +   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
> > > Aren't we missing pm_runtime_disable() here? We'll have the enable
> > > count unbalanced if the driver is removed and probed again.
> >
> > pm_runtime_force_suspend() does a pm_runtime_disable() also if i am not
> > wrong.
> > And, as mentioned in a previous thread [1], we were seeing a warning
> > which we avoided
> > by keeping force_suspend().
> >
> > [1] https://lkml.org/lkml/2018/7/8/124
>
> I see, thanks. I didn't realize that pm_runtime_force_suspend()
> already disables runtime PM indeed. Sorry for the noise.

Hi Tomasz,
No problem. Thanks for looking back at it.

Hi Robin,
If you are fine with this series, then can you please consider giving
Reviewed-by, so that we are certain that this series will go in the next merge
window.
Thanks

Best regards
Vivek




-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-09-07 Thread Vivek Gautam

Hi Tomasz,


On 9/7/2018 2:46 PM, Tomasz Figa wrote:

Hi Vivek,

On Thu, Aug 30, 2018 at 11:46 PM Vivek Gautam
 wrote:

From: Sricharan R 

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.
Global locks are also initialized before enabling runtime pm as the
runtime_resume() calls device_reset() which does tlb_sync_global()
that ultimately requires locks to be initialized.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---
  drivers/iommu/arm-smmu.c | 89 +++-
  1 file changed, 81 insertions(+), 8 deletions(-)

[snip]

@@ -2215,10 +2281,17 @@ 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");

+   arm_smmu_rpm_get(smmu);
 /* Turn the thing off */
 writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+   arm_smmu_rpm_put(smmu);
+
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_force_suspend(smmu->dev);
+   else
+   clk_bulk_disable(smmu->num_clks, smmu->clks);

-   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clks);
+   clk_bulk_unprepare(smmu->num_clks, smmu->clks);

Aren't we missing pm_runtime_disable() here? We'll have the enable
count unbalanced if the driver is removed and probed again.


pm_runtime_force_suspend() does a pm_runtime_disable() also if i am not 
wrong.
And, as mentioned in a previous thread [1], we were seeing a warning 
which we avoided

by keeping force_suspend().

[1] https://lkml.org/lkml/2018/7/8/124

Thanks
Vivek


Also, if we add pm_runtime_disable(), we can reorder things a bit and
simplify into:

arm_smmu_rpm_get(smmu);

/* Turn the thing off */
writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);

if (pm_runtime_enabled())
pm_runtime_disable();
 arm_smmu_rpm_put(smmu);

 clk_bulk_disable_unprepare(smmu->num_clks, smmu->clks);

Best regards,
Tomasz


___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v16 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-09-05 Thread Vivek Gautam
Hi Rob,

On Thu, Aug 30, 2018 at 8:16 PM Vivek Gautam
 wrote:
>
> Add bindings doc for Qcom's smmu-v2 implementation.
>
> Signed-off-by: Vivek Gautam 
> Reviewed-by: Tomasz Figa 
> Tested-by: Srinivas Kandagatla 
> ---

I removed your reviewed-by for this particular patch.
Can you please consider giving your review if you find the changes okay now.
Thanks.

Best regards
Vivek

>  .../devicetree/bindings/iommu/arm,smmu.txt | 39 
> ++
>  1 file changed, 39 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
> b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> index 8a6ffce12af5..a6504b37cc21 100644
> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> @@ -17,10 +17,16 @@ 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.
>
> +  Qcom SoCs must contain, as below, SoC-specific compatibles
> +  along with "qcom,smmu-v2":
> +  "qcom,msm8996-smmu-v2", "qcom,smmu-v2",
> +  "qcom,sdm845-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 +77,22 @@ conditions.
>or using stream matching with #iommu-cells = <2>, and
>may be ignored if present in such cases.
>
> +- clock-names:List of the names of clocks input to the device. The
> +  required list depends on particular implementation and
> +  is as follows:
> +  - for "qcom,smmu-v2":
> +- "bus": clock required for downstream bus access and
> + for the smmu ptw,
> +- "iface": clock required to access smmu's registers
> +   through the TCU's programming interface.
> +  - unspecified for other implementations.
> +
> +- clocks: Specifiers for all clocks listed in the clock-names 
> property,
> +  as per generic clock bindings.
> +
> +- power-domains:  Specifiers for power domains required to be powered on for
> +  the SMMU to operate, as per generic power domain bindings.
> +
>  ** Deprecated properties:
>
>  - mmu-masters (deprecated in favour of the generic "iommus" binding) :
> @@ -137,3 +159,20 @@ conditions.
>  iommu-map = <0  0 0x400>;
>  ...
>  };
> +
> +   /* Qcom's arm,smmu-v2 implementation */
> +   smmu4: iommu@d0 {
> +   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";
> +   };
> --
> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
> of Code Aurora Forum, hosted by The Linux Foundation
>
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [Patch v15 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-08-31 Thread Vivek Gautam

Hi Rob,


On 8/30/2018 6:13 AM, Rob Herring wrote:

On Wed, Aug 29, 2018 at 6:23 AM Vivek Gautam
 wrote:

On Wed, Aug 29, 2018 at 2:05 PM Vivek Gautam
 wrote:

Hi Rob,


On 8/29/2018 2:04 AM, Rob Herring wrote:

On Mon, Aug 27, 2018 at 04:25:50PM +0530, Vivek Gautam wrote:

Add bindings doc for Qcom's smmu-v2 implementation.

Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
   - This is a new patch added in v15 after noticing the new
 checkpatch warning for separate dt-bindings doc.
   - This patch also addresses comments given by Rob and Robin to add
 a list of valid values of '' in "qcom,-smmu-v2"
 compatible string.

   .../devicetree/bindings/iommu/arm,smmu.txt | 47 
++
   1 file changed, 47 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..52198a539606 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,24 @@ conditions.
   "arm,mmu-401"
   "arm,mmu-500"
   "cavium,smmu-v2"
+"qcom,-smmu-v2", "qcom,smmu-v2"

The v2 in the compatible string is kind of redundant unless the SoC has
other SMMU types.

sdm845 has smmu-v2, and smmu-500 [1].


 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.
+  '' string in "qcom,-smmu-v2" should be one of the
+  following:
+  msm8996 - for msm8996 Qcom SoC.
+  sdm845 - for sdm845 Qcom Soc.

Rather than all this prose, it would be simpler to just add 2 lines with
the full compatibles rather than . The  thing is not going to
work when/if we move bindings to json-schema also.

then we keep adding
   "qcom,msm8996-smmu-v2", "qcom,smmu-v2"
   "qcom,msm8998-smmu-v2", "qcom,smmu-v2"
   "qcom,sdm845-smmu-v2", "qcom,smmu-v2",
and from [1]
   "qcom,sdm845-smmu-500", "arm,mmu-500", etc.
for each SoCs?

How about following diff on top of this patch?

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 52198a539606..5e6c04876533 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,23 +17,18 @@ conditions.
  "arm,mmu-401"
  "arm,mmu-500"
  "cavium,smmu-v2"
-"qcom,-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.
-  '' string in "qcom,-smmu-v2" should be one of the
-  following:
-  msm8996 - for msm8996 Qcom SoC.
-  sdm845 - for sdm845 Qcom Soc.
-
-  An example string would be -
-  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
+  Qcom SoCs using qcom,smmu-v2 must have soc specific
+  compatible string attached to "qcom,smmu-v2" to take care
+  of SoC specific clocks/power connections and to address
+  specific bug fixes.
+  Precisely, it should be one of the following:
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2",
+  "qcom,sdm845-smmu-v2", "qcom,smmu-v2".

We don't need an explanation of why we need specific compatibles in
each binding document (though maybe we need a better explanation
somewhere). We just need to know what are valid values for compatibles
and this includes any combinations. Generally, this is just a list of
combinations.

[snip]

Fixed this in v16. Thanks.

Best regards
Vivek
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v16 3/5] iommu/arm-smmu: Add the device_link between masters and smmu

2018-08-30 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---
 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 1bf542010be7..166c8c6da24f 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,6 +1461,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v16 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-08-30 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements.
On msm8996, multiple cores, viz. mdss, video, etc. use this
smmu. On sdm845, this smmu is used with gpu.
Add bindings for the same.

Signed-off-by: Vivek Gautam 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---
 drivers/iommu/arm-smmu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 166c8c6da24f..411e5ac57c64 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 {
@@ -1970,6 +1971,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 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 },
@@ -1977,6 +1989,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v16 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-08-30 Thread Vivek Gautam
Add bindings doc for Qcom's smmu-v2 implementation.

Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---
 .../devicetree/bindings/iommu/arm,smmu.txt | 39 ++
 1 file changed, 39 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..a6504b37cc21 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,16 @@ 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.
 
+  Qcom SoCs must contain, as below, SoC-specific compatibles
+  along with "qcom,smmu-v2":
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2",
+  "qcom,sdm845-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 +77,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +159,20 @@ conditions.
 iommu-map = <0  0 0x400>;
 ...
 };
+
+   /* Qcom's arm,smmu-v2 implementation */
+   smmu4: iommu@d0 {
+   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";
+   };
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v16 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-08-30 Thread Vivek Gautam
From: Sricharan R 

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.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---
 drivers/iommu/arm-smmu.c | 77 ++--
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fd1b80ef9490..d900e007c3c9 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*clks;
+   int num_clks;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1896,10 +1899,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);
@@ -1918,6 +1923,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2000,6 +2022,9 @@ 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;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2098,6 +2123,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare_enable(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2184,6 +2217,9 @@ 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);
+
+   clk_bulk_disable_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2192,15 +2228,50 @@ static void arm_smmu_device_shutdown(struct 
platform_device *pdev)
arm_smmu_device_remove(pdev);
 }
 
-static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
 {
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
+   if (ret)
+   return ret;
 
arm_smmu_device_reset(smmu);
+
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable(smmu->num_clks, smmu->clks);
+
+   return 0;
+}
+
+static int __

[Freedreno] [PATCH v16 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-08-30 Thread Vivek Gautam
From: Sricharan R 

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.
Global locks are also initialized before enabling runtime pm as the
runtime_resume() calls device_reset() which does tlb_sync_global()
that ultimately requires locks to be initialized.

Signed-off-by: Sricharan R 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---
 drivers/iommu/arm-smmu.c | 89 +++-
 1 file changed, 81 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index d900e007c3c9..1bf542010be7 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -268,6 +268,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -913,11 +927,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -932,6 +950,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1213,10 +1233,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1226,33 +1251,50 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
@@ -1407,7 +1449,13 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
+   ret = arm_smmu

[Freedreno] [PATCH v16 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-08-30 Thread Vivek Gautam
   * Dropped the patch [5] that was adding device_link_find() API to
 device core layer. device_link_del_dev() serves the purpose to
 directly delete the link between two given devices.

[v9]
   * Removed 'rpm_supported' flag, instead checking on pm_domain
 to enable runtime pm.
   * Creating device link only when the runtime pm is enabled, as we
 don't need a device link besides managing the power dependency
 between supplier and consumer devices.
   * Introducing a patch to add device_link_find() API that finds
 and existing link between supplier and consumer devices.
 Also, made necessary change to device_link_add() to use this API.
   * arm_smmu_remove_device() now uses this device_link_find() to find
 the device link between smmu device and the master device, and then
 delete this link.
   * Dropped the destroy_domain_context() fix [4] as it was rather,
 introducing catastrophically bad problem by destroying
 'good dev's domain context.
   * Added 'Reviwed-by' tag for Tomasz's review.

[v8]
   * Major change -
 - Added a flag 'rpm_supported' which each platform that supports
   runtime pm, can enable, and we enable runtime_pm over arm-smmu
   only when this flag is set.
 - Adding the conditional pm_runtime_get/put() calls to .map, .unmap
   and .attach_dev ops.
 - Dropped the patch [2] that exported pm_runtim_get/put_suupliers(),
   and also dropped the user driver patch [3] for these APIs.

   * Clock code further cleanup
 - doing only clk_bulk_enable() and clk_bulk_disable() in runtime pm
   callbacks. We shouldn't be taking a slow path (clk_prepare/unprepare())
   from these runtime pm callbacks. Thereby, moved clk_bulk_prepare() to
   arm_smmu_device_probe(), and clk_bulk_unprepare() to
   arm_smmu_device_remove().
 - clk data filling to a common method arm_smmu_fill_clk_data() that
   fills the clock ids and number of clocks.

   * Addressed other nits and comments
 - device_link_add() error path fixed.
 - Fix for checking negative error value from pm_runtime_get_sync().
 - Documentation redo.

   * Added another patch fixing the error path in arm_smmu_attach_dev()
 to destroy allocated domain context.

** Change logs for previous versions is available in previous series [9].

[1] https://patchwork.kernel.org/cover/10576921/
[2] https://patchwork.kernel.org/patch/10204945/
[3] https://patchwork.kernel.org/patch/10204925/
[4] https://patchwork.kernel.org/patch/10254105/
[5] https://patchwork.kernel.org/patch/10277975/
[6] https://patchwork.kernel.org/patch/10281613/
[7] https://patchwork.kernel.org/patch/10491481/
[8] https://lore.kernel.org/patchwork/patch/974116/
[9] https://lkml.org/lkml/2018/7/8/124

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 (2):
  dt-bindings: arm-smmu: Add bindings for qcom,smmu-v2
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  39 +
 drivers/iommu/arm-smmu.c   | 180 +++--
 2 files changed, 209 insertions(+), 10 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [Patch v15 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-08-30 Thread Vivek Gautam
On Thu, Aug 30, 2018 at 3:04 PM Tomasz Figa  wrote:
>
> On Thu, Aug 30, 2018 at 6:22 PM Vivek Gautam
>  wrote:
> >
> > On Mon, Aug 27, 2018 at 4:27 PM Vivek Gautam
> >  wrote:
> > >
> > > From: Sricharan R 
> > >
> > > 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 
> > > [vivek: Cleanup pm runtime calls]
> > > Signed-off-by: Vivek Gautam 
> > > Reviewed-by: Tomasz Figa 
> > > Tested-by: Srinivas Kandagatla 
> > > ---
> > >
> > > Changes since v14:
> > >  - none.
> > >
> > >  drivers/iommu/arm-smmu.c | 101 
> > > +++
> > >  1 file changed, 93 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> > > index a81224bc6637..23b4a60149b6 100644
> > > --- a/drivers/iommu/arm-smmu.c
> > > +++ b/drivers/iommu/arm-smmu.c
> >
> > [snip]
> >
> > > @@ -2131,6 +2188,26 @@ static int arm_smmu_device_probe(struct 
> > > platform_device *pdev)
> > > if (err)
> > > return err;
> > >
> > > +   /*
> > > +* We want to avoid touching dev->power.lock in fastpaths unless
> > > +* it's really going to do something useful - pm_runtime_enabled()
> > > +* can serve as an ideal proxy for that decision. So, 
> > > conditionally
> > > +* enable pm_runtime.
> > > +*/
> > > +   if (dev->pm_domain)
> > > +   pm_runtime_enable(dev);
> > > +
> > > +   err = arm_smmu_rpm_get(smmu);
> >
> > We shouldn't be doing a runtime_get() yet, as this eventually calls
> > arm_smmu_device_reset().
> > arm_smmu_device_reset() should be called only after 
> > arm_smmu_device_cfg_probe().
> > So, I plan to replace the pm_runtime_get/put() calls in probe() with
> > simple clk_bulk_enable()
> > to let the driver initialize smmu, and at the end of the probe we can
> > disable the clocks and
> > enable runtime pm over the device to let it take care of the device 
> > further-on.
> >
>
> We can avoid the explicit clock disable by just calling
> pm_runtime_set_active() before pm_runtime_enable(), assuming that what
> probe does is symmetrical with the suspend callback, which would be
> called after the latter.

Sure, that sounds reasonable. Will use pm_runtime_set_active() instead
of explicitly disabling the clocks.Thanks.

Best regards
Vivek

>
> Best regards,
> Tomasz
> ___
> iommu mailing list
> io...@lists.linux-foundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [Patch v15 2/5] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-08-30 Thread Vivek Gautam
On Mon, Aug 27, 2018 at 4:27 PM Vivek Gautam
 wrote:
>
> From: Sricharan R 
>
> 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 
> [vivek: Cleanup pm runtime calls]
> Signed-off-by: Vivek Gautam 
> Reviewed-by: Tomasz Figa 
> Tested-by: Srinivas Kandagatla 
> ---
>
> Changes since v14:
>  - none.
>
>  drivers/iommu/arm-smmu.c | 101 
> +++
>  1 file changed, 93 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index a81224bc6637..23b4a60149b6 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c

[snip]

> @@ -2131,6 +2188,26 @@ static int arm_smmu_device_probe(struct 
> platform_device *pdev)
> if (err)
> return err;
>
> +   /*
> +* We want to avoid touching dev->power.lock in fastpaths unless
> +* it's really going to do something useful - pm_runtime_enabled()
> +* can serve as an ideal proxy for that decision. So, conditionally
> +* enable pm_runtime.
> +*/
> +   if (dev->pm_domain)
> +   pm_runtime_enable(dev);
> +
> +   err = arm_smmu_rpm_get(smmu);

We shouldn't be doing a runtime_get() yet, as this eventually calls
arm_smmu_device_reset().
arm_smmu_device_reset() should be called only after arm_smmu_device_cfg_probe().
So, I plan to replace the pm_runtime_get/put() calls in probe() with
simple clk_bulk_enable()
to let the driver initialize smmu, and at the end of the probe we can
disable the clocks and
enable runtime pm over the device to let it take care of the device further-on.

> +   if (err < 0)
> +   return err;
> +
> +   /* Enable clocks explicitly if runtime PM is disabled */
> +   if (!pm_runtime_enabled(dev)) {
> +   err = clk_bulk_enable(smmu->num_clks, smmu->clks);
> +   if (err)
> +   return err;
> +   }
> +
> err = arm_smmu_device_cfg_probe(smmu);
> if (err)
> return err;

[snip]

Best regards
Vivek
--
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [Patch v15 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-08-29 Thread Vivek Gautam
On Wed, Aug 29, 2018 at 2:05 PM Vivek Gautam
 wrote:
>
> Hi Rob,
>
>
> On 8/29/2018 2:04 AM, Rob Herring wrote:
> > On Mon, Aug 27, 2018 at 04:25:50PM +0530, Vivek Gautam wrote:
> >> Add bindings doc for Qcom's smmu-v2 implementation.
> >>
> >> Signed-off-by: Vivek Gautam 
> >> Reviewed-by: Tomasz Figa 
> >> Tested-by: Srinivas Kandagatla 
> >> ---
> >>
> >> Changes since v14:
> >>   - This is a new patch added in v15 after noticing the new
> >> checkpatch warning for separate dt-bindings doc.
> >>   - This patch also addresses comments given by Rob and Robin to add
> >> a list of valid values of '' in "qcom,-smmu-v2"
> >> compatible string.
> >>
> >>   .../devicetree/bindings/iommu/arm,smmu.txt | 47 
> >> ++
> >>   1 file changed, 47 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
> >> b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> >> index 8a6ffce12af5..52198a539606 100644
> >> --- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> >> +++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
> >> @@ -17,10 +17,24 @@ conditions.
> >>   "arm,mmu-401"
> >>   "arm,mmu-500"
> >>   "cavium,smmu-v2"
> >> +"qcom,-smmu-v2", "qcom,smmu-v2"
> > The v2 in the compatible string is kind of redundant unless the SoC has
> > other SMMU types.
>
> sdm845 has smmu-v2, and smmu-500 [1].
>
> >>
> >> 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.
> >> +  '' string in "qcom,-smmu-v2" should be one of 
> >> the
> >> +  following:
> >> +  msm8996 - for msm8996 Qcom SoC.
> >> +  sdm845 - for sdm845 Qcom Soc.
> > Rather than all this prose, it would be simpler to just add 2 lines with
> > the full compatibles rather than . The  thing is not going to
> > work when/if we move bindings to json-schema also.
>
> then we keep adding
>   "qcom,msm8996-smmu-v2", "qcom,smmu-v2"
>   "qcom,msm8998-smmu-v2", "qcom,smmu-v2"
>   "qcom,sdm845-smmu-v2", "qcom,smmu-v2",
> and from [1]
>   "qcom,sdm845-smmu-500", "arm,mmu-500", etc.
> for each SoCs?

How about following diff on top of this patch?

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 52198a539606..5e6c04876533 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,23 +17,18 @@ conditions.
 "arm,mmu-401"
 "arm,mmu-500"
 "cavium,smmu-v2"
-"qcom,-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.
-  '' string in "qcom,-smmu-v2" should be one of the
-  following:
-  msm8996 - for msm8996 Qcom SoC.
-  sdm845 - for sdm845 Qcom Soc.
-
-  An example string would be -
-  "qcom,msm8996-smmu-v2", "qcom,smmu-v2".
+  Qcom SoCs using qcom,smmu-v2 must have soc specific
+  compatible string attached to "qcom,smmu-v2" to take care
+  of SoC specific clocks/power connections and to address
+  specific bug fixes.
+  Precisely, it should be one of the following:
+  "qcom,msm8996-smmu-v2", "qcom,smmu-v2",
+  "qcom,sdm845-smmu-v2", "qcom,smmu-v2".

Thanks!
Best regards
Vivek

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 5/9] arm64: dts: sdm845: Add gpu and gmu device nodes

2018-08-28 Thread Vivek Gautam
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
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [Patch v15 5/5] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-08-27 Thread Vivek Gautam
qcom,smmu-v2 is an arm,smmu-v2 implementation with specific
clock and power requirements.
On msm8996, multiple cores, viz. mdss, video, etc. use this
smmu. On sdm845, this smmu is used with gpu.
Add bindings for the same.

Signed-off-by: Vivek Gautam 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - Moved out dt-bindings change to separate patch.

 drivers/iommu/arm-smmu.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index b5e7f72d418c..c0177ea32678 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 {
@@ -1970,6 +1971,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 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 },
@@ -1977,6 +1989,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [Patch v15 4/5] dt-bindings: arm-smmu: Add bindings for qcom, smmu-v2

2018-08-27 Thread Vivek Gautam
Add bindings doc for Qcom's smmu-v2 implementation.

Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - This is a new patch added in v15 after noticing the new
   checkpatch warning for separate dt-bindings doc.
 - This patch also addresses comments given by Rob and Robin to add
   a list of valid values of '' in "qcom,-smmu-v2"
   compatible string.

 .../devicetree/bindings/iommu/arm,smmu.txt | 47 ++
 1 file changed, 47 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..52198a539606 100644
--- a/Documentation/devicetree/bindings/iommu/arm,smmu.txt
+++ b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
@@ -17,10 +17,24 @@ 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.
+  '' string in "qcom,-smmu-v2" should be one of the
+  following:
+  msm8996 - for msm8996 Qcom SoC.
+  sdm845 - for sdm845 Qcom Soc.
+
+  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 +85,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +167,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";
+   };
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [Patch v15 3/5] iommu/arm-smmu: Add the device_link between masters and smmu

2018-08-27 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - none.

 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 23b4a60149b6..b5e7f72d418c 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,6 +1461,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [Patch v15 1/5] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-08-27 Thread Vivek Gautam
From: Sricharan R 

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.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Tested-by: Srinivas Kandagatla 
---

Changes since v14:
 - none.

 drivers/iommu/arm-smmu.c | 77 ++--
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index fd1b80ef9490..a81224bc6637 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*clks;
+   int num_clks;
 
u32 cavium_id_base; /* Specific to Cavium */
 
@@ -1896,10 +1899,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);
@@ -1918,6 +1923,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2000,6 +2022,9 @@ 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;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2098,6 +2123,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2184,6 +2217,9 @@ 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);
+
+   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2192,15 +2228,50 @@ static void arm_smmu_device_shutdown(struct 
platform_device *pdev)
arm_smmu_device_remove(pdev);
 }
 
-static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
 {
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
+   if (ret)
+   return ret;
 
arm_smmu_device_reset(smmu);
+
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable(smmu->num_clks, smmu->clks);
+

[Freedreno] [Patch v15 0/5] iommu/arm-smmu: Add runtime pm/sleep support

2018-08-27 Thread Vivek Gautam
Introducing a patch to add device_link_find() API that finds
 and existing link between supplier and consumer devices.
 Also, made necessary change to device_link_add() to use this API.
   * arm_smmu_remove_device() now uses this device_link_find() to find
 the device link between smmu device and the master device, and then
 delete this link.
   * Dropped the destroy_domain_context() fix [5] as it was rather,
 introducing catastrophically bad problem by destroying
 'good dev's domain context.
   * Added 'Reviwed-by' tag for Tomasz's review.

[v8]
   * Major change -
 - Added a flag 'rpm_supported' which each platform that supports
   runtime pm, can enable, and we enable runtime_pm over arm-smmu
   only when this flag is set.
 - Adding the conditional pm_runtime_get/put() calls to .map, .unmap
   and .attach_dev ops.
 - Dropped the patch [3] that exported pm_runtim_get/put_suupliers(),
   and also dropped the user driver patch [4] for these APIs.

   * Clock code further cleanup
 - doing only clk_bulk_enable() and clk_bulk_disable() in runtime pm
   callbacks. We shouldn't be taking a slow path (clk_prepare/unprepare())
   from these runtime pm callbacks. Thereby, moved clk_bulk_prepare() to
   arm_smmu_device_probe(), and clk_bulk_unprepare() to
   arm_smmu_device_remove().
 - clk data filling to a common method arm_smmu_fill_clk_data() that
   fills the clock ids and number of clocks.

   * Addressed other nits and comments
 - device_link_add() error path fixed.
 - Fix for checking negative error value from pm_runtime_get_sync().
 - Documentation redo.

   * Added another patch fixing the error path in arm_smmu_attach_dev()
 to destroy allocated domain context.

[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.

** Change logs for previous versions is available in previous series [4].

[1] https://patchwork.kernel.org/patch/10204925/
[2] https://lore.kernel.org/patchwork/cover/968013/
[3] https://patchwork.kernel.org/patch/10204945/
[4] https://patchwork.kernel.org/patch/10204925/
[5] https://patchwork.kernel.org/patch/10254105/
[6] https://patchwork.kernel.org/patch/10277975/
[7] https://patchwork.kernel.org/patch/10281613/
[8] https://patchwork.kernel.org/patch/10491481/
[9] https://lore.kernel.org/patchwork/patch/974116/

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 (2):
  dt-bindings: arm-smmu: Add bindings for qcom,smmu-v2
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  47 +
 drivers/iommu/arm-smmu.c   | 194 +++--
 2 files changed, 230 insertions(+), 11 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v14 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-27 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

Change since v13:
 - No change.

 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 1efa5681b905..e558abf1ecfc 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,6 +1461,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v14 4/4] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-07-27 Thread Vivek Gautam
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 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
---

Change since v13:
 - No change.

 .../devicetree/bindings/iommu/arm,smmu.txt | 42 ++
 drivers/iommu/arm-smmu.c   | 13 +++
 2 files changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..7c71a6ed465a 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,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +162,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 e558abf1ecfc..2b4edba188a5 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 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 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 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ 

[Freedreno] [PATCH v14 2/4] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-07-27 Thread Vivek Gautam
From: Sricharan R 

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 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

Change since v13:
 - No change.

 drivers/iommu/arm-smmu.c | 101 +++
 1 file changed, 93 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 5f6a9e3c0079..1efa5681b905 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -268,6 +268,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -913,11 +927,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -932,6 +950,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1213,10 +1233,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1226,33 +1251,50 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
@@ -1407,7 +1449,13 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   goto out_cfg_free;
+
ret = arm_smmu_master_alloc_smes(dev);
+   arm_smmu_rpm_put(smmu);
+
if (ret)
goto out

[Freedreno] [PATCH v14 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-27 Thread Vivek Gautam
From: Sricharan R 

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.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

Changes since v13:
 - Moved arm_smmu_device_reset() from arm_smmu_pm_resume() to
   arm_smmu_runtime_resume(). arm_smmu_pm_resume() calls just
   runtime_resume() now.

 drivers/iommu/arm-smmu.c | 77 ++--
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index c73cfce1ccc0..5f6a9e3c0079 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*clks;
+   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);
@@ -1919,6 +1924,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2001,6 +2023,9 @@ 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;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2099,6 +2124,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2181,6 +2214,9 @@ 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);
+
+   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2189,15 +2225,50 @@ static void arm_smmu_device_shutdown(struct 
platform_device *pdev)
arm_smmu_device_remove(pdev);
 }
 
-static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
 {
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+   int ret;
+
+   ret = clk_bulk_enable(smmu->num_clks, smmu->clks);
+   if (ret)
+   return ret;
 
arm_smmu_device_reset(smmu);
+
return 0;
 }
 
-static SIMPLE_DEV_PM_OPS(arm_smmu_pm_ops, NULL, arm_smmu_pm_resume);
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *s

[Freedreno] [PATCH v14 0/4] iommu/arm-smmu: Add runtime pm/sleep support

2018-07-27 Thread Vivek Gautam
ink_add() to use this API.
   * arm_smmu_remove_device() now uses this device_link_find() to find
 the device link between smmu device and the master device, and then
 delete this link.
   * Dropped the destroy_domain_context() fix [5] as it was rather,
 introducing catastrophically bad problem by destroying
 'good dev's domain context.
   * Added 'Reviwed-by' tag for Tomasz's review.

[v8]
   * Major change -
 - Added a flag 'rpm_supported' which each platform that supports
   runtime pm, can enable, and we enable runtime_pm over arm-smmu
   only when this flag is set.
 - Adding the conditional pm_runtime_get/put() calls to .map, .unmap
   and .attach_dev ops.
 - Dropped the patch [3] that exported pm_runtim_get/put_suupliers(),
   and also dropped the user driver patch [4] for these APIs.

   * Clock code further cleanup
 - doing only clk_bulk_enable() and clk_bulk_disable() in runtime pm
   callbacks. We shouldn't be taking a slow path (clk_prepare/unprepare())
   from these runtime pm callbacks. Thereby, moved clk_bulk_prepare() to
   arm_smmu_device_probe(), and clk_bulk_unprepare() to
   arm_smmu_device_remove().
 - clk data filling to a common method arm_smmu_fill_clk_data() that
   fills the clock ids and number of clocks.

   * Addressed other nits and comments
 - device_link_add() error path fixed.
 - Fix for checking negative error value from pm_runtime_get_sync().
 - Documentation redo.

   * Added another patch fixing the error path in arm_smmu_attach_dev()
 to destroy allocated domain context.

[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.

** Change logs for previous versions is available in last series [4].


[1] https://patchwork.kernel.org/patch/10204925/
[2] https://lore.kernel.org/patchwork/cover/964655/
[3] https://patchwork.kernel.org/patch/10204945/
[4] https://patchwork.kernel.org/patch/10204925/
[5] https://patchwork.kernel.org/patch/10254105/
[6] https://patchwork.kernel.org/patch/10277975/
[7] https://patchwork.kernel.org/patch/10281613/
[8] https://patchwork.kernel.org/patch/10491481/
[9] 
https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/log/?h=linux-next
[10] https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git/log/?h=next


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 (1):
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  42 +
 drivers/iommu/arm-smmu.c   | 194 +++--
 2 files changed, 225 insertions(+), 11 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v13 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-26 Thread Vivek Gautam



On 7/26/2018 9:00 PM, Robin Murphy wrote:

On 26/07/18 08:12, Vivek Gautam wrote:

On Wed, Jul 25, 2018 at 11:46 PM, Vivek Gautam
 wrote:
On Tue, Jul 24, 2018 at 8:51 PM, Robin Murphy  
wrote:

On 19/07/18 11:15, Vivek Gautam wrote:


From: Sricharan R 

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.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

Changes since v12:
   - Added pm sleep .suspend callback. This disables the clocks.
   - Added corresponding change to enable clocks in .resume
    pm sleep callback.

   drivers/iommu/arm-smmu.c | 75
++--
   1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index c73cfce1ccc0..9138a6fffe04 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c


[snip]


platform_device *pdev)
 arm_smmu_device_remove(pdev);
   }
   +static int __maybe_unused arm_smmu_runtime_resume(struct 
device *dev)

+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   return clk_bulk_enable(smmu->num_clks, smmu->clks);



If there's a power domain being automatically switched by genpd 
then we need
a reset here because we may have lost state entirely. Since I 
remembered the
otherwise-useless GPU SMMU on Juno is in a separate power domain, I 
gave it
a poking via sysfs with some debug stuff to dump sCR0 in these 
callbacks,

and the problem is clear:

...
[    4.625551] arm-smmu 2b40.iommu: genpd_runtime_suspend()
[    4.631163] arm-smmu 2b40.iommu: arm_smmu_runtime_suspend: 
0x00201936
[    4.637897] arm-smmu 2b40.iommu: suspend latency exceeded, 
6733980 ns

[   21.566983] arm-smmu 2b40.iommu: genpd_runtime_resume()
[   21.584796] arm-smmu 2b40.iommu: arm_smmu_runtime_resume: 
0x00220101
[   21.591452] arm-smmu 2b40.iommu: resume latency exceeded, 
6658020 ns

...


Qualcomm SoCs have retention enabled for SMMU registers so they don't
lose state.
...
[  256.013367] arm-smmu b4.arm,smmu: arm_smmu_runtime_suspend
SCR0 = 0x201e36
[  256.013367]
[  256.019160] arm-smmu b4.arm,smmu: arm_smmu_runtime_resume
SCR0 = 0x201e36
[  256.019160]
[  256.027368] arm-smmu b4.arm,smmu: arm_smmu_runtime_suspend
SCR0 = 0x201e36
[  256.027368]
[  256.036786] arm-smmu b4.arm,smmu: arm_smmu_runtime_resume
SCR0 = 0x201e36
...

However after adding arm_smmu_device_reset() in runtime_resume() I 
observe

some performance degradation when kill an instance of 'kmscube' and
start it again.
The launch time with arm_smmu_device_reset() in runtime_resume() 
change is

more.
Could this be because of frequent TLB invalidation and sync?


Probably. Plus the reset procedure is a big chunk of MMIO accesses, 
which for a non-trivial SMMU configuration probably isn't negligible 
in itself. Unfortunately, unless you know for absolute certain that 
you don't need to do that, you do.



Some more information that i gathered.
On Qcom SoCs besides the registers retention, TCU invalidates TLB 
cache on

a CX power collapse exit, which is the system wide suspend case.
The arm-smmu software is not aware of this CX power collapse /
auto-invalidation.

So wouldn't doing an explicit TLB invalidations during runtime resume be
detrimental to performance?


Indeed it would be, but resuming with TLBs full of random 
valid-looking junk is even more so.



I have one more doubt here -
We do runtime power cycle around arm_smmu_map/unmap() too.
Now during map/unmap we selectively do TLB maintenance (either
tlb_sync or tlb_add_flush).
But with runtime pm we want to do TLBIALL*. Is that a problem?


It's technically redundant to do both, true, but as we've covered in 
previous rounds of discussion it's very difficult to know *which* one 
is sufficient at any given time, so in order to make progress for now 
I think we have to settle with doing both.


Thanks Robin. I will respin the patches as Tomasz also suggested;

arm_smmu_runtime_resume() will look like:

    if (pm_runtime_suspended(dev))
        return 0;
    return arm_smmu_runtime_resume(dev);

and,
arm_smmu_runtime_resume() will have arm_smmu_device_reset().

Best regards
Vivek


Robin.
--
To unsubscribe from this list: send the line "unsubsc

Re: [Freedreno] [PATCH v13 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-26 Thread Vivek Gautam
On Wed, Jul 25, 2018 at 11:46 PM, Vivek Gautam
 wrote:
> On Tue, Jul 24, 2018 at 8:51 PM, Robin Murphy  wrote:
>> On 19/07/18 11:15, Vivek Gautam wrote:
>>>
>>> From: Sricharan R 
>>>
>>> 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.
>>>
>>> Also, while we enable the runtime pm add a pm sleep suspend
>>> callback that pushes devices to low power state by turning
>>> the clocks off in a system sleep.
>>> Also add corresponding clock enable path in resume callback.
>>>
>>> Signed-off-by: Sricharan R 
>>> Signed-off-by: Archit Taneja 
>>> [vivek: rework for clock and pm ops]
>>> Signed-off-by: Vivek Gautam 
>>> Reviewed-by: Tomasz Figa 
>>> ---
>>>
>>> Changes since v12:
>>>   - Added pm sleep .suspend callback. This disables the clocks.
>>>   - Added corresponding change to enable clocks in .resume
>>>pm sleep callback.
>>>
>>>   drivers/iommu/arm-smmu.c | 75
>>> ++--
>>>   1 file changed, 73 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>>> index c73cfce1ccc0..9138a6fffe04 100644
>>> --- a/drivers/iommu/arm-smmu.c
>>> +++ b/drivers/iommu/arm-smmu.c

[snip]

>>> platform_device *pdev)
>>> arm_smmu_device_remove(pdev);
>>>   }
>>>   +static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
>>> +{
>>> +   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
>>> +
>>> +   return clk_bulk_enable(smmu->num_clks, smmu->clks);
>>
>>
>> If there's a power domain being automatically switched by genpd then we need
>> a reset here because we may have lost state entirely. Since I remembered the
>> otherwise-useless GPU SMMU on Juno is in a separate power domain, I gave it
>> a poking via sysfs with some debug stuff to dump sCR0 in these callbacks,
>> and the problem is clear:
>>
>> ...
>> [4.625551] arm-smmu 2b40.iommu: genpd_runtime_suspend()
>> [4.631163] arm-smmu 2b40.iommu: arm_smmu_runtime_suspend: 0x00201936
>> [4.637897] arm-smmu 2b40.iommu: suspend latency exceeded, 6733980 ns
>> [   21.566983] arm-smmu 2b40.iommu: genpd_runtime_resume()
>> [   21.584796] arm-smmu 2b40.iommu: arm_smmu_runtime_resume: 0x00220101
>> [   21.591452] arm-smmu 2b40.iommu: resume latency exceeded, 6658020 ns
>> ...
>
> Qualcomm SoCs have retention enabled for SMMU registers so they don't
> lose state.
> ...
> [  256.013367] arm-smmu b4.arm,smmu: arm_smmu_runtime_suspend
> SCR0 = 0x201e36
> [  256.013367]
> [  256.019160] arm-smmu b4.arm,smmu: arm_smmu_runtime_resume
> SCR0 = 0x201e36
> [  256.019160]
> [  256.027368] arm-smmu b4.arm,smmu: arm_smmu_runtime_suspend
> SCR0 = 0x201e36
> [  256.027368]
> [  256.036786] arm-smmu b4.arm,smmu: arm_smmu_runtime_resume
> SCR0 = 0x201e36
> ...
>
> However after adding arm_smmu_device_reset() in runtime_resume() I observe
> some performance degradation when kill an instance of 'kmscube' and
> start it again.
> The launch time with arm_smmu_device_reset() in runtime_resume() change is
> more.
> Could this be because of frequent TLB invalidation and sync?

Some more information that i gathered.
On Qcom SoCs besides the registers retention, TCU invalidates TLB cache on
a CX power collapse exit, which is the system wide suspend case.
The arm-smmu software is not aware of this CX power collapse /
auto-invalidation.

So wouldn't doing an explicit TLB invalidations during runtime resume be
detrimental to performance?

I have one more doubt here -
We do runtime power cycle around arm_smmu_map/unmap() too.
Now during map/unmap we selectively do TLB maintenance (either
tlb_sync or tlb_add_flush).
But with runtime pm we want to do TLBIALL*. Is that a problem?

Best regards
Vivek

>
> 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
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v13 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-25 Thread Vivek Gautam
On Tue, Jul 24, 2018 at 8:51 PM, Robin Murphy  wrote:
> On 19/07/18 11:15, Vivek Gautam wrote:
>>
>> From: Sricharan R 
>>
>> 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.
>>
>> Also, while we enable the runtime pm add a pm sleep suspend
>> callback that pushes devices to low power state by turning
>> the clocks off in a system sleep.
>> Also add corresponding clock enable path in resume callback.
>>
>> Signed-off-by: Sricharan R 
>> Signed-off-by: Archit Taneja 
>> [vivek: rework for clock and pm ops]
>> Signed-off-by: Vivek Gautam 
>> Reviewed-by: Tomasz Figa 
>> ---
>>
>> Changes since v12:
>>   - Added pm sleep .suspend callback. This disables the clocks.
>>   - Added corresponding change to enable clocks in .resume
>>pm sleep callback.
>>
>>   drivers/iommu/arm-smmu.c | 75
>> ++--
>>   1 file changed, 73 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index c73cfce1ccc0..9138a6fffe04 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*clks;
>> +   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);
>> @@ -1919,6 +1924,23 @@ static const struct of_device_id
>> arm_smmu_of_match[] = {
>>   };
>>   MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
>>   +static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
>> +  const char * const *clks)
>> +{
>> +   int i;
>> +
>> +   if (smmu->num_clks < 1)
>> +   return;
>> +
>> +   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
>> + sizeof(*smmu->clks), GFP_KERNEL);
>> +   if (!smmu->clks)
>> +   return;
>> +
>> +   for (i = 0; i < smmu->num_clks; i++)
>> +   smmu->clks[i].id = clks[i];
>> +}
>> +
>>   #ifdef CONFIG_ACPI
>>   static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
>>   {
>> @@ -2001,6 +2023,9 @@ 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;
>> +
>> +   arm_smmu_fill_clk_data(smmu, data->clks);
>> parse_driver_options(smmu);
>>   @@ -2099,6 +2124,14 @@ static int arm_smmu_device_probe(struct
>> platform_device *pdev)
>> smmu->irqs[i] = irq;
>> }
>>   + err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
>> +   if (err)
>> +   return err;
>> +
>> +   err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
>> +   if (err)
>> +  

Re: [Freedreno] [PATCH v13 0/4] iommu/arm-smmu: Add runtime pm/sleep support

2018-07-22 Thread Vivek Gautam
On Thu, Jul 19, 2018 at 3:45 PM, 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
> device links between smmu and client devices. The device link
> framework keeps the two devices in correct order for power-cycling
> across runtime PM or across system-wide PM.
>
> With addition of a new device link flag DL_FLAG_AUTOREMOVE_SUPPLIER [8]
> (available in linux-next of Rafael's linux-pm tree [9]), the device links
> created between arm-smmu and its clients will be automatically purged
> when arm-smmu driver unbinds from its device.
>
> As not all implementations support clock/power gating, we are checking
> for a valid 'smmu->dev's pm_domain' to conditionally enable the runtime
> power management for such smmu implementations that can support it.
> Otherwise, the clocks are turned to be always on in .probe until .remove.
> With conditional runtime pm now, we avoid touching dev->power.lock
> in fastpaths for smmu implementations that don't need to do anything
> useful with pm_runtime.
> This lets us to use the much-argued pm_runtime_get_sync/put_sync()
> calls in map/unmap callbacks so that the clients do not have to
> worry about handling any of the arm-smmu's power.
>
> This series also adds support for Qcom's arm-smmu-v2 variant that
> has different clocks and power requirements.
>
> Previous version of this patch series is @ [2].
>
> Tested this series on msm8996, and sdm845 after pulling in Rafael's linux-pm
> linux-next[9] and Joerg's iommu next[10] branches.

Hi Rafael,

If the changes look good to you now, can you please consider giving your Ack.
Thanks.

Hi Robin, Will,
If the series looks good to you, and if there's a chance, can you
please consider
picking this series for 4.19. Thanks.

Best regards
Vivek

>
> [v13]
>Addressing Rafael's comments:
>* Added .suspend pm callback to disable the clocks in system wide suspend.
>* Added corresponding clock enable in .resume pm callback.
>* Explicitly enabling/disabling the clocks now when runtime PM is disabled.
>* device_link_add() doesn't depend on pm_runtime_enabled() as we can
>  use device links across system suspend/resume too.
>
>Addressing Robin's comments:
>* Making device_link_add failures as non-fatal.
>
>* Removed IOMMU_OF_DECLARE() declaration as we don't need this after Rob's
>  patch that removed all of these declarations.
>
> [v12]
>* Use new device link's flag introduced in [8] -
>  DL_FLAG_AUTOREMOVE_SUPPLIER. With this devices links are automatically
>  purged when arm-smmu driver unbinds.
>* Using pm_runtime_force_suspend() instead of pm_runtime_disable() to
>  avoid following warning from arm_smmu_device_remove()
>
>  [295711.537507] [ cut here ]
>  [295711.544226] Unpreparing enabled smmu_mdp_ahb_clk
>  [295711.549099] WARNING: CPU: 0 PID: 1 at ../drivers/clk/clk.c:697
>  clk_core_unprepare+0xd8/0xe0
>  ...
>  [295711.674073] Call trace:
>  [295711.679454]  clk_core_unprepare+0xd8/0xe0
>  [295711.682059]  clk_unprepare+0x28/0x40
>  [295711.685964]  clk_bulk_unprepare+0x28/0x40
>  [295711.689701]  arm_smmu_device_remove+0x88/0xd8
>  [295711.693692]  arm_smmu_device_shutdown+0xc/0x18
>  [295711.698120]  platform_drv_shutdown+0x20/0x30
>
> [v11]
>* Some more cleanups for device link. We don't need an explicit
>  delete for device link from the driver, but just set the flag
>  DL_FLAG_AUTOREMOVE.
>  device_link_add() API description says -
>  "If the DL_FLAG_AUTOREMOVE is set, the link will be removed
>  automatically when the consumer device driver unbinds."
>* Addressed the comments for 'smmu' in arm_smmu_map/unmap().
>* Dropped the patch [7] that introduced device_link_del_dev() API.
>
> [v10]
>* Introduce device_link_del_dev() API to delete the link between
>  given consumer and supplier devices. The users of device link
>  do not need to store link pointer to delete the link later.
>  They can straightaway use this API by passing consumer and
>  supplier devices.
>* Made corresponding changes to arm-smmu driver patch handling the
>  device links.
>* Dropped the patch [6] that was adding device_link_find() API to
>  device core layer. device_link_del_dev() serves the purpose to
>  directly delete the link between two given devices.
>
> [v9]
>* Removed 'rpm_supported' flag, instead checking on pm_domain
>  to enable runtime pm.
>* Creating device link only when the runtime pm is enabled, as we
>  don't need a device lin

[Freedreno] [PATCH v13 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-19 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

Changes since v12:
 - device_link_add() doesn't depend on pm_runtime_enabled() now.
 - Treat failure in device link addition as non-fatal.

 drivers/iommu/arm-smmu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 15b20941441a..25ff3bdbf7a3 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,6 +1461,9 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER);
+
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

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v13 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-19 Thread Vivek Gautam
From: Sricharan R 

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.

Also, while we enable the runtime pm add a pm sleep suspend
callback that pushes devices to low power state by turning
the clocks off in a system sleep.
Also add corresponding clock enable path in resume callback.

Signed-off-by: Sricharan R 
Signed-off-by: Archit Taneja 
[vivek: rework for clock and pm ops]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

Changes since v12:
 - Added pm sleep .suspend callback. This disables the clocks.
 - Added corresponding change to enable clocks in .resume
  pm sleep callback.

 drivers/iommu/arm-smmu.c | 75 ++--
 1 file changed, 73 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index c73cfce1ccc0..9138a6fffe04 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*clks;
+   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);
@@ -1919,6 +1924,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2001,6 +2023,9 @@ 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;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2099,6 +2124,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2181,6 +2214,9 @@ 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);
+
+   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2189,15 +2225,50 @@ static void arm_smmu_device_shutdown(struct 
platform_device *pdev)
arm_smmu_device_remove(pdev);
 }
 
+static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   return clk_bulk_enable(smmu->num_clks, smmu->clks);
+}
+
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable(smmu->num_clks, smmu->clks);
+
+   return 0;
+}
+
 static int __maybe_unused arm_smmu_pm_resume(struct device *dev)
 {
struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+   int ret;
+
+   

[Freedreno] [PATCH v13 4/4] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-07-19 Thread Vivek Gautam
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 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
---

Change since v12:
 - Removed IOMMU_OF_DECLARE() definition after Rob H's patch that is merged
   in driver-core-next.

 .../devicetree/bindings/iommu/arm,smmu.txt | 42 ++
 drivers/iommu/arm-smmu.c   | 13 +++
 2 files changed, 55 insertions(+)

diff --git a/Documentation/devicetree/bindings/iommu/arm,smmu.txt 
b/Documentation/devicetree/bindings/iommu/arm,smmu.txt
index 8a6ffce12af5..7c71a6ed465a 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,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +162,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 25ff3bdbf7a3..7c69736a30f8 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 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 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 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
 

[Freedreno] [PATCH v13 2/4] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-07-19 Thread Vivek Gautam
From: Sricharan R 

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 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

Changes since v12:
 - Explicitly enabling and disabling clocks in probe and remove routines
   if runtime PM is disabled,

 drivers/iommu/arm-smmu.c | 101 +++
 1 file changed, 93 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 9138a6fffe04..15b20941441a 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -268,6 +268,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -913,11 +927,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -932,6 +950,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1213,10 +1233,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1226,33 +1251,50 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
@@ -1407,7 +1449,13 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   goto out_cfg_free;
+
ret = arm_smmu_master_alloc_smes(de

[Freedreno] [PATCH v13 0/4] iommu/arm-smmu: Add runtime pm/sleep support

2018-07-19 Thread Vivek Gautam
  runtime pm, can enable, and we enable runtime_pm over arm-smmu
   only when this flag is set.
 - Adding the conditional pm_runtime_get/put() calls to .map, .unmap
   and .attach_dev ops.
 - Dropped the patch [3] that exported pm_runtim_get/put_suupliers(),
   and also dropped the user driver patch [4] for these APIs.

   * Clock code further cleanup
 - doing only clk_bulk_enable() and clk_bulk_disable() in runtime pm
   callbacks. We shouldn't be taking a slow path (clk_prepare/unprepare())
   from these runtime pm callbacks. Thereby, moved clk_bulk_prepare() to
   arm_smmu_device_probe(), and clk_bulk_unprepare() to
   arm_smmu_device_remove().
 - clk data filling to a common method arm_smmu_fill_clk_data() that
   fills the clock ids and number of clocks.

   * Addressed other nits and comments
 - device_link_add() error path fixed.
 - Fix for checking negative error value from pm_runtime_get_sync().
 - Documentation redo.

   * Added another patch fixing the error path in arm_smmu_attach_dev()
 to destroy allocated domain context.

[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.

** Change logs for previous versions is available in last series [4].


[1] https://patchwork.kernel.org/patch/10204925/
[2] https://lkml.org/lkml/2018/7/8/124
[3] https://patchwork.kernel.org/patch/10204945/
[4] https://patchwork.kernel.org/patch/10204925/
[5] https://patchwork.kernel.org/patch/10254105/
[6] https://patchwork.kernel.org/patch/10277975/
[7] https://patchwork.kernel.org/patch/10281613/
[8] https://patchwork.kernel.org/patch/10491481/
[9] 
https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git/log/?h=linux-next
[10] https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git/log/?h=next

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 (1):
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  42 +
 drivers/iommu/arm-smmu.c   | 192 +++--
 2 files changed, 224 insertions(+), 10 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v12 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-18 Thread Vivek Gautam
On Wed, Jul 11, 2018 at 3:23 PM, Rafael J. Wysocki  wrote:
> On Sunday, July 8, 2018 7:34:12 PM CEST Vivek Gautam wrote:
>> From: Sricharan R 
>>
>> 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 
>> Signed-off-by: Vivek Gautam 
>> Reviewed-by: Tomasz Figa 
>> Cc: Rafael J. Wysocki 
>> Cc: Lukas Wunner 
>> ---
>>
>>  - Change since v11
>>* Replaced DL_FLAG_AUTOREMOVE flag with DL_FLAG_AUTOREMOVE_SUPPLIER.
>>
>>  drivers/iommu/arm-smmu.c | 12 
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index 09265e206e2d..916cde4954d2 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -1461,8 +1461,20 @@ static int arm_smmu_add_device(struct device *dev)
>>
>>   iommu_device_link(>iommu, dev);
>>
>> + if (pm_runtime_enabled(smmu->dev) &&
>
> Why does the creation of the link depend on whether or not runtime PM
> is enabled for the MMU device?
>
> What about system-wide PM and system shutdown?  Are they always guaranteed
> to happen in the right order without the link?

Hi Robin,

As Rafael pointed, we should the device link creation should not depend on
runtime PM being enabled or not, as we would also want to guarantee
that system wide PM callbacks are called in the right order for smmu
and clients.

Does this change of removing the check for pm_runtime_enabled() from here
looks okay to you?

FYI, as discussed in the first patch [1] of this series, I will add a
system wide
suspend callback - arm_smmu_pm_suspend, that would do clock disable, and will
add corresponding clock enable calls in arm_smmu_pm_resume().

[1] https://lore.kernel.org/patchwork/patch/960460/


Best regards
Vivek

>
>> + !device_link_add(dev, smmu->dev,
>> + DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER)) {
>> + dev_err(smmu->dev, "Unable to add link to the consumer %s\n",
>> + dev_name(dev));
>> + ret = -ENODEV;
>> + goto out_unlink;
>> + }
>> +
>>   return 0;
>>
>> +out_unlink:
>> + iommu_device_unlink(>iommu, dev);
>> + arm_smmu_master_free_smes(fwspec);
>>  out_cfg_free:
>>   kfree(cfg);
>>  out_free:
>>
>
>



-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v12 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-17 Thread Vivek Gautam



On 7/17/2018 1:16 PM, Rafael J. Wysocki wrote:

On Mon, Jul 16, 2018 at 1:46 PM, Vivek Gautam
 wrote:


On 7/16/2018 2:25 PM, Rafael J. Wysocki wrote:

On Thu, Jul 12, 2018 at 2:41 PM, Vivek Gautam
 wrote:

Hi Rafael,


On Wed, Jul 11, 2018 at 4:06 PM, Vivek Gautam
 wrote:

Hi Rafael,



On 7/11/2018 3:23 PM, Rafael J. Wysocki wrote:

On Sunday, July 8, 2018 7:34:12 PM CEST Vivek Gautam wrote:

From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Cc: Rafael J. Wysocki 
Cc: Lukas Wunner 
---

- Change since v11
  * Replaced DL_FLAG_AUTOREMOVE flag with
DL_FLAG_AUTOREMOVE_SUPPLIER.

drivers/iommu/arm-smmu.c | 12 
1 file changed, 12 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 09265e206e2d..916cde4954d2 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,8 +1461,20 @@ static int arm_smmu_add_device(struct device
*dev)
  iommu_device_link(>iommu, dev);
+ if (pm_runtime_enabled(smmu->dev) &&

Why does the creation of the link depend on whether or not runtime PM
is enabled for the MMU device?


The main purpose of this device link is to handle the runtime PM
synchronization
between the supplier (iommu) and consumer (client devices, such as
GPU/display).
Moreover, the runtime pm is conditionally enabled for smmu devices that
support
such [1].

Is there something you would like me to modify in this patch?

Not really, as long as you are sure that it is correct. :-)

You need to remember, however, that if you add system-wide PM
callbacks to the driver, the ordering between them and the client
device callbacks during system-wide suspend matters as well.  Don't
you need the link the ensure the correct system-wide suspend ordering
too?


The fact that currently we handle clocks only through runtime pm callbacks,
would it be better to call runtime pm put/get in system-wide PM callbacks.
This would be same as i mentioned in the other thread.

Well, my point is that there's no reason for system-wide suspend to
depend directly on runtime PM (which can be effectively disabled by
user space as mentioned for multiple times in this thread).

It simply is not efficient to let the clock run while the system as a
whole is sleeping (even if power/control has been set to "on" for this
particular device) and it should not be too hard to prevent that from
happening.  You may need an additional flag in the driver for that or
similar, but it definitely should be doable.


Right, I will modify the things are required. Thanks again for pointing 
this out.


Best regards
Vivek



Now, that's my advice and I'm not the maintainer of that code, so it
is your call (as long as the maintainer agrees with it).

Thanks,
Rafael


___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v12 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-16 Thread Vivek Gautam



On 7/16/2018 2:25 PM, Rafael J. Wysocki wrote:

On Thu, Jul 12, 2018 at 2:41 PM, Vivek Gautam
 wrote:

Hi Rafael,


On Wed, Jul 11, 2018 at 4:06 PM, Vivek Gautam
 wrote:

Hi Rafael,



On 7/11/2018 3:23 PM, Rafael J. Wysocki wrote:

On Sunday, July 8, 2018 7:34:12 PM CEST Vivek Gautam wrote:

From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Cc: Rafael J. Wysocki 
Cc: Lukas Wunner 
---

   - Change since v11
 * Replaced DL_FLAG_AUTOREMOVE flag with DL_FLAG_AUTOREMOVE_SUPPLIER.

   drivers/iommu/arm-smmu.c | 12 
   1 file changed, 12 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 09265e206e2d..916cde4954d2 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,8 +1461,20 @@ static int arm_smmu_add_device(struct device *dev)
 iommu_device_link(>iommu, dev);
   + if (pm_runtime_enabled(smmu->dev) &&

Why does the creation of the link depend on whether or not runtime PM
is enabled for the MMU device?


The main purpose of this device link is to handle the runtime PM
synchronization
between the supplier (iommu) and consumer (client devices, such as
GPU/display).
Moreover, the runtime pm is conditionally enabled for smmu devices that
support
such [1].

Is there something you would like me to modify in this patch?

Not really, as long as you are sure that it is correct. :-)

You need to remember, however, that if you add system-wide PM
callbacks to the driver, the ordering between them and the client
device callbacks during system-wide suspend matters as well.  Don't
you need the link the ensure the correct system-wide suspend ordering
too?


The fact that currently we handle clocks only through runtime pm callbacks,
would it be better to call runtime pm put/get in system-wide PM callbacks.
This would be same as i mentioned in the other thread.

Best regards
Vivek


--
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


___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v12 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-16 Thread Vivek Gautam

HI Rafael,


On 7/16/2018 2:21 PM, Rafael J. Wysocki wrote:

On Thu, Jul 12, 2018 at 12:57 PM, Vivek Gautam
 wrote:

Hi,


On Wed, Jul 11, 2018 at 6:21 PM, Tomasz Figa  wrote:

On Wed, Jul 11, 2018 at 8:11 PM Rafael J. Wysocki  wrote:

On Wed, Jul 11, 2018 at 12:55 PM, Vivek Gautam
 wrote:

Hi Rafael,


On Wed, Jul 11, 2018 at 3:20 PM, Rafael J. Wysocki  wrote:

On Sunday, July 8, 2018 7:34:10 PM CEST Vivek Gautam wrote:

From: Sricharan R 

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 
Signed-off-by: Archit Taneja 
[vivek: Clock rework to request bulk of clocks]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

  - No change since v11.

  drivers/iommu/arm-smmu.c | 60 ++--
  1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index f7a96bcf94a6..a01d0dde21dd 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*clks;
+ 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);
@@ -1919,6 +1924,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
  };
  MODULE_DEVICE_TABLE(of, arm_smmu_of_match);

+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+const char * const *clks)
+{
+ int i;
+
+ if (smmu->num_clks < 1)
+ return;
+
+ smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+   sizeof(*smmu->clks), GFP_KERNEL);
+ if (!smmu->clks)
+ return;
+
+ for (i = 0; i < smmu->num_clks; i++)
+ smmu->clks[i].id = clks[i];
+}
+
  #ifdef CONFIG_ACPI
  static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
  {
@@ -2001,6 +2023,9 @@ 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;
+
+ arm_smmu_fill_clk_data(smmu, data->clks);

   parse_driver_options(smmu);

@@ -2099,6 +2124,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
   smmu->irqs[i] = irq;
   }

+ err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+ if (err)
+ return err;
+
+ err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
+ if (err)
+ return err;
+
   err = arm_smmu_device_cfg_probe(smmu);
   if (err)
   return err;
@@ -2181,6 +2214,9 @@ 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);
+
+ clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+
   return 0;
  }

@@ -2197,7 +2233,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_enable(smmu->num_clks, smmu->clks);
+}
+
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+ struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+ clk_bulk_disable(smmu->num_clks, smmu->clks);
+
+ return 0;
+}
+
+static const struct dev_pm_ops arm_smmu_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(NULL, arm

Re: [Freedreno] [PATCH v12 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-12 Thread Vivek Gautam
Hi Rafael,


On Wed, Jul 11, 2018 at 4:06 PM, Vivek Gautam
 wrote:
> Hi Rafael,
>
>
>
> On 7/11/2018 3:23 PM, Rafael J. Wysocki wrote:
>>
>> On Sunday, July 8, 2018 7:34:12 PM CEST Vivek Gautam wrote:
>>>
>>> From: Sricharan R 
>>>
>>> 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 
>>> Signed-off-by: Vivek Gautam 
>>> Reviewed-by: Tomasz Figa 
>>> Cc: Rafael J. Wysocki 
>>> Cc: Lukas Wunner 
>>> ---
>>>
>>>   - Change since v11
>>> * Replaced DL_FLAG_AUTOREMOVE flag with DL_FLAG_AUTOREMOVE_SUPPLIER.
>>>
>>>   drivers/iommu/arm-smmu.c | 12 
>>>   1 file changed, 12 insertions(+)
>>>
>>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>>> index 09265e206e2d..916cde4954d2 100644
>>> --- a/drivers/iommu/arm-smmu.c
>>> +++ b/drivers/iommu/arm-smmu.c
>>> @@ -1461,8 +1461,20 @@ static int arm_smmu_add_device(struct device *dev)
>>> iommu_device_link(>iommu, dev);
>>>   + if (pm_runtime_enabled(smmu->dev) &&
>>
>> Why does the creation of the link depend on whether or not runtime PM
>> is enabled for the MMU device?
>
>
> The main purpose of this device link is to handle the runtime PM
> synchronization
> between the supplier (iommu) and consumer (client devices, such as
> GPU/display).
> Moreover, the runtime pm is conditionally enabled for smmu devices that
> support
> such [1].

Is there something you would like me to modify in this patch?

Best regards
Vivek

>>
>>
>> What about system-wide PM and system shutdown?  Are they always guaranteed
>> to happen in the right order without the link?
>
>
> When there's no runtime PM, there's no clocks, and other resources to be
> handled.
> So, we don't need device link for system-wide PM and system shutdown to work
> correctly.
> That's the case with current arm-smmu driver.
> Is it something that i am missing here?
>
> [1] https://lkml.org/lkml/2018/3/8/775
>
> Thanks
> Vivek
>>>
>>> +   !device_link_add(dev, smmu->dev,
>>> +   DL_FLAG_PM_RUNTIME |
>>> DL_FLAG_AUTOREMOVE_SUPPLIER)) {
>>> +   dev_err(smmu->dev, "Unable to add link to the consumer
>>> %s\n",
>>> +   dev_name(dev));
>>> +   ret = -ENODEV;
>>> +   goto out_unlink;
>>> +   }
>>> +
>>> return 0;
>>>   +out_unlink:
>>> +   iommu_device_unlink(>iommu, dev);
>>> +   arm_smmu_master_free_smes(fwspec);
>>>   out_cfg_free:
>>> kfree(cfg);
>>>   out_free:
>>>
>>
>
> --
> 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
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v12 2/4] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-07-11 Thread Vivek Gautam



On 7/11/2018 4:29 PM, Rafael J. Wysocki wrote:

On Wed, Jul 11, 2018 at 12:05 PM, Tomasz Figa  wrote:

Hi Rafael,

Thanks for review.

On Wed, Jul 11, 2018 at 6:53 PM Rafael J. Wysocki  wrote:

On Sunday, July 8, 2018 7:34:11 PM CEST Vivek Gautam wrote:

From: Sricharan R 

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 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

  - Change since v11
* Replaced pm_runtime_disable() with pm_runtime_force_suspend()
  to avoid warning about " Unpreparing enabled clock".
  Full warning text mentioned in cover patch.

  drivers/iommu/arm-smmu.c | 92 +++-
  1 file changed, 84 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a01d0dde21dd..09265e206e2d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -268,6 +268,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
   { 0, NULL},
  };

+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+ if (pm_runtime_enabled(smmu->dev))

Why do you need the pm_runtime_enabled() checks here and below?

pm_runtime_get_sync() and pm_runtime_put() should work just fine if
runtime PM is not enabled.

Because pm_runtime_get_sync() acquires a spin lock, even if only for
the short time of checking if runtime PM is enabled and SMMU driver
maintainers didn't want any spin locks in certain IOMMU API code paths
on hardware implementations that don't need runtime PM, while we still
need to be able to control runtime PM there on hardware
implementations that need so.

OK, so it is an optimization.  It would be good to put a comment in
there to that effect.


Yea, actually there's a comment placed in arm_smmu_device_probe()
 where the runtime PM is conditionally enabled.
I can add comments for these wrappers too if you would like.

Thanks & Regards
Vivek
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH v12 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-11 Thread Vivek Gautam
Hi Rafael,


On Wed, Jul 11, 2018 at 3:20 PM, Rafael J. Wysocki  wrote:
> On Sunday, July 8, 2018 7:34:10 PM CEST Vivek Gautam wrote:
>> From: Sricharan R 
>>
>> 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 
>> Signed-off-by: Archit Taneja 
>> [vivek: Clock rework to request bulk of clocks]
>> Signed-off-by: Vivek Gautam 
>> Reviewed-by: Tomasz Figa 
>> ---
>>
>>  - No change since v11.
>>
>>  drivers/iommu/arm-smmu.c | 60 
>> ++--
>>  1 file changed, 58 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index f7a96bcf94a6..a01d0dde21dd 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*clks;
>> + 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);
>> @@ -1919,6 +1924,23 @@ static const struct of_device_id arm_smmu_of_match[] 
>> = {
>>  };
>>  MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
>>
>> +static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
>> +const char * const *clks)
>> +{
>> + int i;
>> +
>> + if (smmu->num_clks < 1)
>> + return;
>> +
>> + smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
>> +   sizeof(*smmu->clks), GFP_KERNEL);
>> + if (!smmu->clks)
>> + return;
>> +
>> + for (i = 0; i < smmu->num_clks; i++)
>> + smmu->clks[i].id = clks[i];
>> +}
>> +
>>  #ifdef CONFIG_ACPI
>>  static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
>>  {
>> @@ -2001,6 +2023,9 @@ 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;
>> +
>> + arm_smmu_fill_clk_data(smmu, data->clks);
>>
>>   parse_driver_options(smmu);
>>
>> @@ -2099,6 +2124,14 @@ static int arm_smmu_device_probe(struct 
>> platform_device *pdev)
>>   smmu->irqs[i] = irq;
>>   }
>>
>> + err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
>> + if (err)
>> + return err;
>> +
>> + err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
>> + if (err)
>> + return err;
>> +
>>   err = arm_smmu_device_cfg_probe(smmu);
>>   if (err)
>>   return err;
>> @@ -2181,6 +2214,9 @@ 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);

Re: [Freedreno] [PATCH v12 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-11 Thread Vivek Gautam

Hi Rafael,


On 7/11/2018 3:23 PM, Rafael J. Wysocki wrote:

On Sunday, July 8, 2018 7:34:12 PM CEST Vivek Gautam wrote:

From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Cc: Rafael J. Wysocki 
Cc: Lukas Wunner 
---

  - Change since v11
* Replaced DL_FLAG_AUTOREMOVE flag with DL_FLAG_AUTOREMOVE_SUPPLIER.

  drivers/iommu/arm-smmu.c | 12 
  1 file changed, 12 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 09265e206e2d..916cde4954d2 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,8 +1461,20 @@ static int arm_smmu_add_device(struct device *dev)
  
  	iommu_device_link(>iommu, dev);
  
+	if (pm_runtime_enabled(smmu->dev) &&

Why does the creation of the link depend on whether or not runtime PM
is enabled for the MMU device?


The main purpose of this device link is to handle the runtime PM 
synchronization
between the supplier (iommu) and consumer (client devices, such as 
GPU/display).
Moreover, the runtime pm is conditionally enabled for smmu devices that 
support

such [1].


What about system-wide PM and system shutdown?  Are they always guaranteed
to happen in the right order without the link?


When there's no runtime PM, there's no clocks, and other resources to be 
handled.
So, we don't need device link for system-wide PM and system shutdown to 
work correctly.

That's the case with current arm-smmu driver.
Is it something that i am missing here?

[1] https://lkml.org/lkml/2018/3/8/775

Thanks
Vivek

+   !device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER)) {
+   dev_err(smmu->dev, "Unable to add link to the consumer %s\n",
+   dev_name(dev));
+   ret = -ENODEV;
+   goto out_unlink;
+   }
+
return 0;
  
+out_unlink:

+   iommu_device_unlink(>iommu, dev);
+   arm_smmu_master_free_smes(fwspec);
  out_cfg_free:
kfree(cfg);
  out_free:





___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v12 3/4] iommu/arm-smmu: Add the device_link between masters and smmu

2018-07-08 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
Cc: Rafael J. Wysocki 
Cc: Lukas Wunner 
---

 - Change since v11
   * Replaced DL_FLAG_AUTOREMOVE flag with DL_FLAG_AUTOREMOVE_SUPPLIER.

 drivers/iommu/arm-smmu.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 09265e206e2d..916cde4954d2 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -1461,8 +1461,20 @@ static int arm_smmu_add_device(struct device *dev)
 
iommu_device_link(>iommu, dev);
 
+   if (pm_runtime_enabled(smmu->dev) &&
+   !device_link_add(dev, smmu->dev,
+   DL_FLAG_PM_RUNTIME | DL_FLAG_AUTOREMOVE_SUPPLIER)) {
+   dev_err(smmu->dev, "Unable to add link to the consumer %s\n",
+   dev_name(dev));
+   ret = -ENODEV;
+   goto out_unlink;
+   }
+
return 0;
 
+out_unlink:
+   iommu_device_unlink(>iommu, dev);
+   arm_smmu_master_free_smes(fwspec);
 out_cfg_free:
kfree(cfg);
 out_free:
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v12 0/4] iommu/arm-smmu: Add runtime pm/sleep support

2018-07-08 Thread Vivek Gautam
me pm
   callbacks. We shouldn't be taking a slow path (clk_prepare/unprepare())
   from these runtime pm callbacks. Thereby, moved clk_bulk_prepare() to
   arm_smmu_device_probe(), and clk_bulk_unprepare() to
   arm_smmu_device_remove().
 - clk data filling to a common method arm_smmu_fill_clk_data() that
   fills the clock ids and number of clocks.

   * Addressed other nits and comments
 - device_link_add() error path fixed.
 - Fix for checking negative error value from pm_runtime_get_sync().
 - Documentation redo.

   * Added another patch fixing the error path in arm_smmu_attach_dev()
 to destroy allocated domain context.

[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/10204925/
[4] https://patchwork.kernel.org/patch/10102445/
[5] https://lkml.org/lkml/2018/3/22/191
[6] https://patchwork.kernel.org/patch/10204945/
[7] https://patchwork.kernel.org/patch/10204925/
[8] https://patchwork.kernel.org/patch/10254105/
[9] https://patchwork.kernel.org/patch/10277975/
[10] https://patchwork.kernel.org/patch/10281613/
[11] https://patchwork.kernel.org/patch/10491481/

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 (1):
  iommu/arm-smmu: Add support for qcom,smmu-v2 variant

 .../devicetree/bindings/iommu/arm,smmu.txt |  42 +
 drivers/iommu/arm-smmu.c   | 178 +++--
 2 files changed, 210 insertions(+), 10 deletions(-)

-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member
of Code Aurora Forum, hosted by The Linux Foundation

___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


[Freedreno] [PATCH v12 2/4] iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device

2018-07-08 Thread Vivek Gautam
From: Sricharan R 

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 
[vivek: Cleanup pm runtime calls]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

 - Change since v11
   * Replaced pm_runtime_disable() with pm_runtime_force_suspend()
 to avoid warning about " Unpreparing enabled clock".
 Full warning text mentioned in cover patch.

 drivers/iommu/arm-smmu.c | 92 +++-
 1 file changed, 84 insertions(+), 8 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index a01d0dde21dd..09265e206e2d 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -268,6 +268,20 @@ static struct arm_smmu_option_prop arm_smmu_options[] = {
{ 0, NULL},
 };
 
+static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   return pm_runtime_get_sync(smmu->dev);
+
+   return 0;
+}
+
+static inline void arm_smmu_rpm_put(struct arm_smmu_device *smmu)
+{
+   if (pm_runtime_enabled(smmu->dev))
+   pm_runtime_put(smmu->dev);
+}
+
 static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
 {
return container_of(dom, struct arm_smmu_domain, domain);
@@ -913,11 +927,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 = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return;
+
/*
 * Disable the context bank and free the page tables before freeing
 * it.
@@ -932,6 +950,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);
+
+   arm_smmu_rpm_put(smmu);
 }
 
 static struct iommu_domain *arm_smmu_domain_alloc(unsigned type)
@@ -1213,10 +1233,15 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
return -ENODEV;
 
smmu = fwspec_smmu(fwspec);
+
+   ret = arm_smmu_rpm_get(smmu);
+   if (ret < 0)
+   return ret;
+
/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (ret < 0)
-   return ret;
+   goto rpm_put;
 
/*
 * Sanity check the domain. We don't support domains across
@@ -1226,33 +1251,50 @@ static int arm_smmu_attach_dev(struct iommu_domain 
*domain, struct device *dev)
dev_err(dev,
"cannot attach to SMMU %s whilst already attached to 
domain on SMMU %s\n",
dev_name(smmu_domain->smmu->dev), dev_name(smmu->dev));
-   return -EINVAL;
+   ret = -EINVAL;
+   goto rpm_put;
}
 
/* Looks ok, so add the device to the domain */
-   return arm_smmu_domain_add_master(smmu_domain, fwspec);
+   ret = arm_smmu_domain_add_master(smmu_domain, fwspec);
+
+rpm_put:
+   arm_smmu_rpm_put(smmu);
+   return ret;
 }
 
 static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
phys_addr_t paddr, size_t size, int prot)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   int ret;
 
if (!ops)
return -ENODEV;
 
-   return ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->map(ops, iova, paddr, size, prot);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
 size_t size)
 {
struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
+   struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+   size_t ret;
 
if (!ops)
return 0;
 
-   return ops->unmap(ops, iova, size);
+   arm_smmu_rpm_get(smmu);
+   ret = ops->unmap(ops, iova, size);
+   arm_smmu_rpm_put(smmu);
+
+   return ret;
 }
 
 static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
@@ -1407,7 +1449,13 @@ static int arm_smmu_add_device(struct device *dev)
while (i--)
cfg->smendx[i] = INVALID_SMENDX;
 
+   ret = arm_smmu_rpm_get(smmu);
+  

[Freedreno] [PATCH v12 4/4] iommu/arm-smmu: Add support for qcom, smmu-v2 variant

2018-07-08 Thread Vivek Gautam
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 
Reviewed-by: Rob Herring 
Reviewed-by: Tomasz Figa 
---

 - No change since v11.

 .../devicetree/bindings/iommu/arm,smmu.txt | 42 ++
 drivers/iommu/arm-smmu.c   | 14 
 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..7c71a6ed465a 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,22 @@ conditions.
   or using stream matching with #iommu-cells = <2>, and
   may be ignored if present in such cases.
 
+- clock-names:List of the names of clocks input to the device. The
+  required list depends on particular implementation and
+  is as follows:
+  - for "qcom,smmu-v2":
+- "bus": clock required for downstream bus access and
+ for the smmu ptw,
+- "iface": clock required to access smmu's registers
+   through the TCU's programming interface.
+  - unspecified for other implementations.
+
+- clocks: Specifiers for all clocks listed in the clock-names property,
+  as per generic clock bindings.
+
+- power-domains:  Specifiers for power domains required to be powered on for
+  the SMMU to operate, as per generic power domain bindings.
+
 ** Deprecated properties:
 
 - mmu-masters (deprecated in favour of the generic "iommus" binding) :
@@ -137,3 +162,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 916cde4954d2..a9edb17f09bf 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 {
@@ -1980,6 +1981,17 @@ ARM_SMMU_MATCH_DATA(arm_mmu401, ARM_SMMU_V1_64K, 
GENERIC_SMMU);
 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 },
@@ -1987,6 +1999,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
{ .compatible = "arm,mmu-401", .data = _mmu401 },
{ .compatible = "arm,mmu-500", .data = _mmu500 },
{ .co

[Freedreno] [PATCH v12 1/4] iommu/arm-smmu: Add pm_runtime/sleep ops

2018-07-08 Thread Vivek Gautam
From: Sricharan R 

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 
Signed-off-by: Archit Taneja 
[vivek: Clock rework to request bulk of clocks]
Signed-off-by: Vivek Gautam 
Reviewed-by: Tomasz Figa 
---

 - No change since v11.

 drivers/iommu/arm-smmu.c | 60 ++--
 1 file changed, 58 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index f7a96bcf94a6..a01d0dde21dd 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*clks;
+   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);
@@ -1919,6 +1924,23 @@ static const struct of_device_id arm_smmu_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
+static void arm_smmu_fill_clk_data(struct arm_smmu_device *smmu,
+  const char * const *clks)
+{
+   int i;
+
+   if (smmu->num_clks < 1)
+   return;
+
+   smmu->clks = devm_kcalloc(smmu->dev, smmu->num_clks,
+ sizeof(*smmu->clks), GFP_KERNEL);
+   if (!smmu->clks)
+   return;
+
+   for (i = 0; i < smmu->num_clks; i++)
+   smmu->clks[i].id = clks[i];
+}
+
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
 {
@@ -2001,6 +2023,9 @@ 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;
+
+   arm_smmu_fill_clk_data(smmu, data->clks);
 
parse_driver_options(smmu);
 
@@ -2099,6 +2124,14 @@ static int arm_smmu_device_probe(struct platform_device 
*pdev)
smmu->irqs[i] = irq;
}
 
+   err = devm_clk_bulk_get(smmu->dev, smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
+   err = clk_bulk_prepare(smmu->num_clks, smmu->clks);
+   if (err)
+   return err;
+
err = arm_smmu_device_cfg_probe(smmu);
if (err)
return err;
@@ -2181,6 +2214,9 @@ 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);
+
+   clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+
return 0;
 }
 
@@ -2197,7 +2233,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_enable(smmu->num_clks, smmu->clks);
+}
+
+static int __maybe_unused arm_smmu_runtime_suspend(struct device *dev)
+{
+   struct arm_smmu_device *smmu = dev_get_drvdata(dev);
+
+   clk_bulk_disable(smmu->num_clks, smmu->clks);
+
+   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

___

Re: [Freedreno] [PATCH 1/5] drm/msm: Remove pm_runtime operations from msm_iommu

2018-06-14 Thread Vivek Gautam
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
___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 5/5] drm/msm/A6xx: Add support for using system cache(llc)

2018-04-05 Thread Vivek Gautam

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: [Freedreno] [PATCH 2/5] arm64:dts:sdm845: Add support for GPU LLCC

2018-04-05 Thread Vivek Gautam

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>;


___
Freedreno mailing list
Freedreno@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/freedreno


Re: [Freedreno] [PATCH 4/5] drm/msm: Pass mmu features to generic layers

2018-04-05 Thread Vivek Gautam

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 Masetty 


Just 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

2018-02-23 Thread Vivek Gautam
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: [Freedreno] [PATCH v7 6/6] drm/msm: iommu: Replace runtime calls with runtime suppliers

2018-02-14 Thread Vivek Gautam
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 

  1   2   >