All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
@ 2020-10-25 22:16 ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Hello,

This series brings initial support for memory interconnect to Tegra20,
Tegra30 and Tegra124 SoCs.

For the starter only display controllers and devfreq devices are getting
interconnect API support, others could be supported later on. The display
controllers have the biggest demand for interconnect API right now because
dynamic memory frequency scaling can't be done safely without taking into
account bandwidth requirement from the displays. In particular this series
fixes distorted display output on T30 Ouya and T124 TK1 devices.

Changelog:

v6: - This series was massively reworked in comparison to v5, most of the
      patches that previously got r-b need a new round of a review (!).

    - Added missed clk-rounding to the set() callback of EMC ICC providers.
      Now clk_set_min_rate() doesn't error out on rate overflow.

    - Now peak bandwidth is properly taken into account by the set() callback
      of EMC ICC providers.

    - EMC runs at 2x of the DRAM bus only on Tegra20, this now taken in account
      properly by the EMC ICC set() callbacks.

    - ICC drivers use new icc_sync_state() and xlate_extended().

    - ICC drivers support new TEGRA_MC_ICC_TAG_ISO for ICC paths, which
      conveys to ICC driver that memory path uses isochronous transfers.

    - Added support for memory latency scaling to Tegra30 ICC provider.
      It's required for fixing display FIFO underflows on T30.

    - Added basic interconnect support to Tegra124 drivers.

    - Tegra20/30/124 EMC drivers now support voltage scaling using generic
      OPP API.

    - The display bandwidth management is reworked and improved. It now
      supports both bandwidth and latency allocations. The nv-display is
      now also taken into account properly, i.e. it's kept untouched.
      The extra bandwidth reservation required for ISO clients is moved
      from DC driver to the ICC drivers.

    - Dropped patch that tuned T20 display controller memory client because
      turned out that it kills ~30% of memory bandwidth. It should be possible
      to support client tuning, but it's too complicated for now.

    - Corrected display's cursor and winb-vfilter ICC clients.
      The winb-vfilter was erroneously used in place of cursor's client
      in device-trees.

    - Added devm_tegra_get_memory_controller() and switched drivers to
      use it.

    - Device-tree OPP tables are now supported by memory and devfreq
      drivers.

    - Tegra20-devfeq driver is reworked and now uses EMC-stats instead
      of IMC-stats (which are nearly identical modules) because previously
      I failed to understand how EMC-stats work and succeeded this time,
      thinking that it simply doesn't work. This removes a bit icky dependency
      on using both EMC and MC drivers simultaneously by the devfreq driver.

    - Tegra20-devfeq driver now is a sub-device of the EMC, it also now uses
      interconnect API for driving memory bandwidth.

    - Tegra30-devfreq got interconnect support.

    - Devfreq patches now use dev_err_probe(), which was suggested by
      Chanwoo Choi.

    - Added acks from Chanwoo Choi and Rob Herring to the reviewed and
      unchanged patches.

    - Added tested-by from Peter Geis and Nicolas Chauvet, who tested this
      series on Ouya and TK1 devices, reporting that it fixes display
      corruption on these devices which happened due to insufficient memory
      bandwidth.

    - Added patches to fix T20 EMC registers size.

    - Fixed missing LA entry for PTC in the Tegra MC drivers.

    - New and updated patches in v6:

        dt-bindings: memory: tegra20: emc: Correct registers range in example
        dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
        dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
        dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
        dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
        dt-bindings: memory: tegra124: mc: Document new interconnect property
        dt-bindings: memory: tegra124: emc: Document new interconnect property
        dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
        dt-bindings: tegra30-actmon: Document OPP and interconnect properties
        dt-bindings: memory: tegra124: Add memory client IDs
        ARM: tegra: Correct EMC registers size in Tegra20 device-tree
        ARM: tegra: Add interconnect properties to Tegra124 device-tree
        ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC device-tree
        ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
        ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes
        ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes
        memory: tegra: Add and use devm_tegra_get_memory_controller()
        memory: tegra-mc: Add interconnect framework
        memory: tegra20: Support interconnect framework
        memory: tegra20-emc: Skip parsing of emc-stats DT sub-node
        memory: tegra: Add missing latency allowness entry for Page Table Cache
        memory: tegra: Add FIFO sizes to Tegra30 memory clients
        memory: tegra30: Support interconnect framework
        memory: tegra124-emc: Make driver modular
        memory: tegra124: Support interconnect framework
        memory: tegra: Remove superfluous error messages around platform_get_irq()
        drm/tegra: dc: Support memory bandwidth management
        drm/tegra: dc: Extend debug stats with total number of events
        PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
        PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
        PM / devfreq: tegra30: Separate configurations per-SoC generation
        opp: Put interconnect paths outside of opp_table_lock

v5: - The devfreq drivers now won't probe if memory timings aren't specified
      in a device-tree, like was suggested by Chanwoo Choi in a review comment
      to v4. Initially I wanted to always probe the driver even with a single
      fixed memory freq, but after a closer look turned out it can't be done
      easily for Tegra20 driver.

    - The "interconnect: Relax requirement in of_icc_get_from_provider()"
      patch was already applied, hence one less patch in comparison to v4.

    - Renamed display interconnect paths in accordance to the names that
      were used by Thierry Reding in one of his recent patches that supposed
      to update the Host1x's DT binding.

    - Added acks from Chanwoo Choi.

    - Added clarifying comment to tegra_mc_icc_set() about why it's a dummy
      function, this is done in a response to the review comment made by
      Georgi Djakov to v4.

v4: - All drivers that use interconnect API now select it in the Kconfig in
      order to properly express the build dependency.

    - The IS_ENABLED(CONFIG_INTERCONNECT) is dropped now from all patches.

    - Added MODULE_AUTHOR() to the modularized drivers, for completeness.

    - Added missed TEGRA_MC Kconfig dependency for the Tegra20 EMC driver.

    - Added more acks from Rob Herring that I accidentally missed to add in v3.

v3: - Added acks from Rob Herring that were given to some of the v2 patches.

    - Specified name of the TRM documentation chapter in the patch
      "dt-bindings: host1x: Document new interconnect properties", which was
      suggested by Rob Herring in the review comment to v2.

    - Added patches that allow EMC drivers to be compiled as a loadable kernel
      modules. This came up during of the v2 review when Georgi Djakov pointed
      out that interconnect-core could be compiled as a kernel module. Please
      note that the Tegra124 EMC driver is compile-tested only, I don't have
      Tegra124 HW.

    - In the review comment to [1] Stephen Boyd suggested that it will be
      better not to make changes to clk API, which was needed in order to
      avoid clashing of the interconnect driver with the devfreq in regards
      to memory clk-rate rounding.

      [1] https://patchwork.ozlabs.org/project/linux-tegra/patch/20200330231617.17079-3-digetx@gmail.com/

      Stephen Boyd suggested that instead we should provide OPP table via DT.
      I tried to investigate whether this could be done and turned out
      it's a bit complicated. Technically it should be doable, but:

        1. For now we don't fully support voltage scaling of the CORE regulator
           and so OPP table in the DT isn't really needed today. We can
           generate table from the memory timings, which is what Tegra devfreq
           drivers already do.

        2. The OPP table should be defined in the DT for the Memory Controller
           node and then its usage somehow should be shared by both interconnect
           and devfreq drivers. It's not obvious what's the best way to do it.

      So, it will be much better to postpone the DT OPP table addition
      until these questions are resolved. We can infer OPPs from the
      memory timings and we could get the memory rates from the memory
      driver directly, avoiding the problems induced by the clk API usage.
      This idea is implemented in v3, see these patches:

        PM / devfreq: tegra20: Use MC timings for building OPP table
        PM / devfreq: tegra30: Use MC timings for building OPP table

v2: - Instead of a single dma-mem interconnect path, the paths are now
      defined per memory client.

    - The EMC provider now uses #interconnect-cells=<0>.

    - Dropped Tegra124 because there is no enough information about how to
      properly calculate required EMC clock rate for it and I don't have
      hardware for testing. Somebody else will have to work on it.

    - Moved interconnect providers code into drivers/memory/tegra/*.

    - Added "Create tegra20-devfreq device" patch because interconnect
      is not very usable without the devfreq memory auto-scaling since
      memory freq will be fixed to the display's requirement.

Dmitry Osipenko (52):
  clk: tegra: Export Tegra20 EMC kernel symbols
  soc/tegra: fuse: Export tegra_read_ram_code()
  dt-bindings: memory: tegra20: emc: Correct registers range in example
  dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller
    property
  dt-bindings: memory: tegra20: mc: Document new interconnect property
  dt-bindings: memory: tegra20: emc: Document new interconnect property
  dt-bindings: memory: tegra20: emc: Document OPP table and voltage
    regulator
  dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and
    statistics sub-device
  dt-bindings: memory: tegra30: mc: Document new interconnect property
  dt-bindings: memory: tegra30: emc: Document new interconnect property
  dt-bindings: memory: tegra30: emc: Document OPP table and voltage
    regulator
  dt-bindings: memory: tegra124: mc: Document new interconnect property
  dt-bindings: memory: tegra124: emc: Document new interconnect property
  dt-bindings: memory: tegra124: emc: Document OPP table and voltage
    regulator
  dt-bindings: tegra30-actmon: Document OPP and interconnect properties
  dt-bindings: host1x: Document new interconnect properties
  dt-bindings: memory: tegra20: Add memory client IDs
  dt-bindings: memory: tegra30: Add memory client IDs
  dt-bindings: memory: tegra124: Add memory client IDs
  ARM: tegra: Correct EMC registers size in Tegra20 device-tree
  ARM: tegra: Add interconnect properties to Tegra20 device-tree
  ARM: tegra: Add interconnect properties to Tegra30 device-tree
  ARM: tegra: Add interconnect properties to Tegra124 device-tree
  ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC
    device-tree
  ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
  ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree
    nodes
  ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree
    nodes
  memory: tegra: Add and use devm_tegra_get_memory_controller()
  memory: tegra-mc: Add interconnect framework
  memory: tegra20-emc: Make driver modular
  memory: tegra20-emc: Use devm_platform_ioremap_resource()
  memory: tegra20-emc: Continue probing if timings are missing in
    device-tree
  memory: tegra20: Support interconnect framework
  memory: tegra20-emc: Don't parse emc-stats node
  memory: tegra: Add missing latency allowness entry for Page Table
    Cache
  memory: tegra: Add FIFO sizes to Tegra30 memory clients
  memory: tegra30-emc: Make driver modular
  memory: tegra30-emc: Continue probing if timings are missing in
    device-tree
  memory: tegra30: Support interconnect framework
  memory: tegra124-emc: Make driver modular
  memory: tegra124-emc: Use devm_platform_ioremap_resource()
  memory: tegra124: Support interconnect framework
  memory: tegra: Remove superfluous error messages around
    platform_get_irq()
  drm/tegra: dc: Support memory bandwidth management
  drm/tegra: dc: Extend debug stats with total number of events
  opp: Put interconnect paths outside of opp_table_lock
  PM / devfreq: tegra20: Silence deferred probe error
  PM / devfreq: tegra20: Relax Kconfig dependency
  PM / devfreq: tegra20: Convert to EMC_STAT driver, support
    interconnect and device-tree
  PM / devfreq: tegra30: Silence deferred probe error
  PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  PM / devfreq: tegra30: Separate configurations per-SoC generation

 .../arm/tegra/nvidia,tegra30-actmon.txt       |  25 ++
 .../display/tegra/nvidia,tegra20-host1x.txt   |  68 +++
 .../nvidia,tegra124-emc.yaml                  |  18 +
 .../nvidia,tegra124-mc.yaml                   |   5 +
 .../memory-controllers/nvidia,tegra20-emc.txt |  63 ++-
 .../memory-controllers/nvidia,tegra20-mc.txt  |   3 +
 .../nvidia,tegra30-emc.yaml                   |  18 +
 .../memory-controllers/nvidia,tegra30-mc.yaml |   5 +
 arch/arm/boot/dts/tegra124-apalis-emc.dtsi    |   8 +
 .../arm/boot/dts/tegra124-jetson-tk1-emc.dtsi |   8 +
 arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi  |  10 +
 .../boot/dts/tegra124-peripherals-opp.dtsi    | 419 ++++++++++++++++++
 arch/arm/boot/dts/tegra124.dtsi               |  31 ++
 .../boot/dts/tegra20-acer-a500-picasso.dts    |  12 +
 arch/arm/boot/dts/tegra20-colibri.dtsi        |   8 +
 arch/arm/boot/dts/tegra20-paz00.dts           |  10 +
 .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 181 ++++++++
 arch/arm/boot/dts/tegra20.dtsi                |  42 +-
 .../tegra30-asus-nexus7-grouper-common.dtsi   |  16 +
 .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 383 ++++++++++++++++
 arch/arm/boot/dts/tegra30.dtsi                |  33 +-
 drivers/clk/tegra/Makefile                    |   2 +-
 drivers/clk/tegra/clk-tegra124-emc.c          |  41 +-
 drivers/clk/tegra/clk-tegra124.c              |  27 +-
 drivers/clk/tegra/clk-tegra20-emc.c           |   3 +
 drivers/clk/tegra/clk.h                       |  16 +-
 drivers/devfreq/Kconfig                       |   3 +-
 drivers/devfreq/tegra20-devfreq.c             | 186 ++++----
 drivers/devfreq/tegra30-devfreq.c             | 166 ++++---
 drivers/gpu/drm/tegra/Kconfig                 |   1 +
 drivers/gpu/drm/tegra/dc.c                    | 340 ++++++++++++++
 drivers/gpu/drm/tegra/dc.h                    |  11 +
 drivers/gpu/drm/tegra/drm.c                   |  14 +
 drivers/gpu/drm/tegra/hub.c                   |   3 +
 drivers/gpu/drm/tegra/plane.c                 | 122 +++++
 drivers/gpu/drm/tegra/plane.h                 |  15 +
 drivers/memory/tegra/Kconfig                  |  12 +-
 drivers/memory/tegra/mc.c                     | 184 +++++++-
 drivers/memory/tegra/mc.h                     |  20 +
 drivers/memory/tegra/tegra114.c               |   6 +
 drivers/memory/tegra/tegra124-emc.c           | 235 ++++++++--
 drivers/memory/tegra/tegra124.c               |  37 ++
 drivers/memory/tegra/tegra20-emc.c            | 244 ++++++++--
 drivers/memory/tegra/tegra20.c                |  34 ++
 drivers/memory/tegra/tegra210-emc-core.c      |  39 +-
 drivers/memory/tegra/tegra30-emc.c            | 245 ++++++++--
 drivers/memory/tegra/tegra30.c                | 191 ++++++++
 drivers/opp/core.c                            |  21 +-
 drivers/soc/tegra/fuse/tegra-apbmisc.c        |   2 +
 include/dt-bindings/memory/tegra124-mc.h      |  68 +++
 include/dt-bindings/memory/tegra20-mc.h       |  53 +++
 include/dt-bindings/memory/tegra30-mc.h       |  67 +++
 include/linux/clk/tegra.h                     |   9 +
 include/soc/tegra/emc.h                       |  16 -
 include/soc/tegra/mc.h                        |  26 ++
 55 files changed, 3477 insertions(+), 348 deletions(-)
 create mode 100644 arch/arm/boot/dts/tegra124-peripherals-opp.dtsi
 create mode 100644 arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
 create mode 100644 arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
 delete mode 100644 include/soc/tegra/emc.h

-- 
2.27.0


^ permalink raw reply	[flat|nested] 290+ messages in thread

* [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
@ 2020-10-25 22:16 ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Hello,

This series brings initial support for memory interconnect to Tegra20,
Tegra30 and Tegra124 SoCs.

For the starter only display controllers and devfreq devices are getting
interconnect API support, others could be supported later on. The display
controllers have the biggest demand for interconnect API right now because
dynamic memory frequency scaling can't be done safely without taking into
account bandwidth requirement from the displays. In particular this series
fixes distorted display output on T30 Ouya and T124 TK1 devices.

Changelog:

v6: - This series was massively reworked in comparison to v5, most of the
      patches that previously got r-b need a new round of a review (!).

    - Added missed clk-rounding to the set() callback of EMC ICC providers.
      Now clk_set_min_rate() doesn't error out on rate overflow.

    - Now peak bandwidth is properly taken into account by the set() callback
      of EMC ICC providers.

    - EMC runs at 2x of the DRAM bus only on Tegra20, this now taken in account
      properly by the EMC ICC set() callbacks.

    - ICC drivers use new icc_sync_state() and xlate_extended().

    - ICC drivers support new TEGRA_MC_ICC_TAG_ISO for ICC paths, which
      conveys to ICC driver that memory path uses isochronous transfers.

    - Added support for memory latency scaling to Tegra30 ICC provider.
      It's required for fixing display FIFO underflows on T30.

    - Added basic interconnect support to Tegra124 drivers.

    - Tegra20/30/124 EMC drivers now support voltage scaling using generic
      OPP API.

    - The display bandwidth management is reworked and improved. It now
      supports both bandwidth and latency allocations. The nv-display is
      now also taken into account properly, i.e. it's kept untouched.
      The extra bandwidth reservation required for ISO clients is moved
      from DC driver to the ICC drivers.

    - Dropped patch that tuned T20 display controller memory client because
      turned out that it kills ~30% of memory bandwidth. It should be possible
      to support client tuning, but it's too complicated for now.

    - Corrected display's cursor and winb-vfilter ICC clients.
      The winb-vfilter was erroneously used in place of cursor's client
      in device-trees.

    - Added devm_tegra_get_memory_controller() and switched drivers to
      use it.

    - Device-tree OPP tables are now supported by memory and devfreq
      drivers.

    - Tegra20-devfeq driver is reworked and now uses EMC-stats instead
      of IMC-stats (which are nearly identical modules) because previously
      I failed to understand how EMC-stats work and succeeded this time,
      thinking that it simply doesn't work. This removes a bit icky dependency
      on using both EMC and MC drivers simultaneously by the devfreq driver.

    - Tegra20-devfeq driver now is a sub-device of the EMC, it also now uses
      interconnect API for driving memory bandwidth.

    - Tegra30-devfreq got interconnect support.

    - Devfreq patches now use dev_err_probe(), which was suggested by
      Chanwoo Choi.

    - Added acks from Chanwoo Choi and Rob Herring to the reviewed and
      unchanged patches.

    - Added tested-by from Peter Geis and Nicolas Chauvet, who tested this
      series on Ouya and TK1 devices, reporting that it fixes display
      corruption on these devices which happened due to insufficient memory
      bandwidth.

    - Added patches to fix T20 EMC registers size.

    - Fixed missing LA entry for PTC in the Tegra MC drivers.

    - New and updated patches in v6:

        dt-bindings: memory: tegra20: emc: Correct registers range in example
        dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
        dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
        dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
        dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
        dt-bindings: memory: tegra124: mc: Document new interconnect property
        dt-bindings: memory: tegra124: emc: Document new interconnect property
        dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
        dt-bindings: tegra30-actmon: Document OPP and interconnect properties
        dt-bindings: memory: tegra124: Add memory client IDs
        ARM: tegra: Correct EMC registers size in Tegra20 device-tree
        ARM: tegra: Add interconnect properties to Tegra124 device-tree
        ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC device-tree
        ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
        ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes
        ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes
        memory: tegra: Add and use devm_tegra_get_memory_controller()
        memory: tegra-mc: Add interconnect framework
        memory: tegra20: Support interconnect framework
        memory: tegra20-emc: Skip parsing of emc-stats DT sub-node
        memory: tegra: Add missing latency allowness entry for Page Table Cache
        memory: tegra: Add FIFO sizes to Tegra30 memory clients
        memory: tegra30: Support interconnect framework
        memory: tegra124-emc: Make driver modular
        memory: tegra124: Support interconnect framework
        memory: tegra: Remove superfluous error messages around platform_get_irq()
        drm/tegra: dc: Support memory bandwidth management
        drm/tegra: dc: Extend debug stats with total number of events
        PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
        PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
        PM / devfreq: tegra30: Separate configurations per-SoC generation
        opp: Put interconnect paths outside of opp_table_lock

v5: - The devfreq drivers now won't probe if memory timings aren't specified
      in a device-tree, like was suggested by Chanwoo Choi in a review comment
      to v4. Initially I wanted to always probe the driver even with a single
      fixed memory freq, but after a closer look turned out it can't be done
      easily for Tegra20 driver.

    - The "interconnect: Relax requirement in of_icc_get_from_provider()"
      patch was already applied, hence one less patch in comparison to v4.

    - Renamed display interconnect paths in accordance to the names that
      were used by Thierry Reding in one of his recent patches that supposed
      to update the Host1x's DT binding.

    - Added acks from Chanwoo Choi.

    - Added clarifying comment to tegra_mc_icc_set() about why it's a dummy
      function, this is done in a response to the review comment made by
      Georgi Djakov to v4.

v4: - All drivers that use interconnect API now select it in the Kconfig in
      order to properly express the build dependency.

    - The IS_ENABLED(CONFIG_INTERCONNECT) is dropped now from all patches.

    - Added MODULE_AUTHOR() to the modularized drivers, for completeness.

    - Added missed TEGRA_MC Kconfig dependency for the Tegra20 EMC driver.

    - Added more acks from Rob Herring that I accidentally missed to add in v3.

v3: - Added acks from Rob Herring that were given to some of the v2 patches.

    - Specified name of the TRM documentation chapter in the patch
      "dt-bindings: host1x: Document new interconnect properties", which was
      suggested by Rob Herring in the review comment to v2.

    - Added patches that allow EMC drivers to be compiled as a loadable kernel
      modules. This came up during of the v2 review when Georgi Djakov pointed
      out that interconnect-core could be compiled as a kernel module. Please
      note that the Tegra124 EMC driver is compile-tested only, I don't have
      Tegra124 HW.

    - In the review comment to [1] Stephen Boyd suggested that it will be
      better not to make changes to clk API, which was needed in order to
      avoid clashing of the interconnect driver with the devfreq in regards
      to memory clk-rate rounding.

      [1] https://patchwork.ozlabs.org/project/linux-tegra/patch/20200330231617.17079-3-digetx@gmail.com/

      Stephen Boyd suggested that instead we should provide OPP table via DT.
      I tried to investigate whether this could be done and turned out
      it's a bit complicated. Technically it should be doable, but:

        1. For now we don't fully support voltage scaling of the CORE regulator
           and so OPP table in the DT isn't really needed today. We can
           generate table from the memory timings, which is what Tegra devfreq
           drivers already do.

        2. The OPP table should be defined in the DT for the Memory Controller
           node and then its usage somehow should be shared by both interconnect
           and devfreq drivers. It's not obvious what's the best way to do it.

      So, it will be much better to postpone the DT OPP table addition
      until these questions are resolved. We can infer OPPs from the
      memory timings and we could get the memory rates from the memory
      driver directly, avoiding the problems induced by the clk API usage.
      This idea is implemented in v3, see these patches:

        PM / devfreq: tegra20: Use MC timings for building OPP table
        PM / devfreq: tegra30: Use MC timings for building OPP table

v2: - Instead of a single dma-mem interconnect path, the paths are now
      defined per memory client.

    - The EMC provider now uses #interconnect-cells=<0>.

    - Dropped Tegra124 because there is no enough information about how to
      properly calculate required EMC clock rate for it and I don't have
      hardware for testing. Somebody else will have to work on it.

    - Moved interconnect providers code into drivers/memory/tegra/*.

    - Added "Create tegra20-devfreq device" patch because interconnect
      is not very usable without the devfreq memory auto-scaling since
      memory freq will be fixed to the display's requirement.

Dmitry Osipenko (52):
  clk: tegra: Export Tegra20 EMC kernel symbols
  soc/tegra: fuse: Export tegra_read_ram_code()
  dt-bindings: memory: tegra20: emc: Correct registers range in example
  dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller
    property
  dt-bindings: memory: tegra20: mc: Document new interconnect property
  dt-bindings: memory: tegra20: emc: Document new interconnect property
  dt-bindings: memory: tegra20: emc: Document OPP table and voltage
    regulator
  dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and
    statistics sub-device
  dt-bindings: memory: tegra30: mc: Document new interconnect property
  dt-bindings: memory: tegra30: emc: Document new interconnect property
  dt-bindings: memory: tegra30: emc: Document OPP table and voltage
    regulator
  dt-bindings: memory: tegra124: mc: Document new interconnect property
  dt-bindings: memory: tegra124: emc: Document new interconnect property
  dt-bindings: memory: tegra124: emc: Document OPP table and voltage
    regulator
  dt-bindings: tegra30-actmon: Document OPP and interconnect properties
  dt-bindings: host1x: Document new interconnect properties
  dt-bindings: memory: tegra20: Add memory client IDs
  dt-bindings: memory: tegra30: Add memory client IDs
  dt-bindings: memory: tegra124: Add memory client IDs
  ARM: tegra: Correct EMC registers size in Tegra20 device-tree
  ARM: tegra: Add interconnect properties to Tegra20 device-tree
  ARM: tegra: Add interconnect properties to Tegra30 device-tree
  ARM: tegra: Add interconnect properties to Tegra124 device-tree
  ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC
    device-tree
  ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
  ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree
    nodes
  ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree
    nodes
  memory: tegra: Add and use devm_tegra_get_memory_controller()
  memory: tegra-mc: Add interconnect framework
  memory: tegra20-emc: Make driver modular
  memory: tegra20-emc: Use devm_platform_ioremap_resource()
  memory: tegra20-emc: Continue probing if timings are missing in
    device-tree
  memory: tegra20: Support interconnect framework
  memory: tegra20-emc: Don't parse emc-stats node
  memory: tegra: Add missing latency allowness entry for Page Table
    Cache
  memory: tegra: Add FIFO sizes to Tegra30 memory clients
  memory: tegra30-emc: Make driver modular
  memory: tegra30-emc: Continue probing if timings are missing in
    device-tree
  memory: tegra30: Support interconnect framework
  memory: tegra124-emc: Make driver modular
  memory: tegra124-emc: Use devm_platform_ioremap_resource()
  memory: tegra124: Support interconnect framework
  memory: tegra: Remove superfluous error messages around
    platform_get_irq()
  drm/tegra: dc: Support memory bandwidth management
  drm/tegra: dc: Extend debug stats with total number of events
  opp: Put interconnect paths outside of opp_table_lock
  PM / devfreq: tegra20: Silence deferred probe error
  PM / devfreq: tegra20: Relax Kconfig dependency
  PM / devfreq: tegra20: Convert to EMC_STAT driver, support
    interconnect and device-tree
  PM / devfreq: tegra30: Silence deferred probe error
  PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  PM / devfreq: tegra30: Separate configurations per-SoC generation

 .../arm/tegra/nvidia,tegra30-actmon.txt       |  25 ++
 .../display/tegra/nvidia,tegra20-host1x.txt   |  68 +++
 .../nvidia,tegra124-emc.yaml                  |  18 +
 .../nvidia,tegra124-mc.yaml                   |   5 +
 .../memory-controllers/nvidia,tegra20-emc.txt |  63 ++-
 .../memory-controllers/nvidia,tegra20-mc.txt  |   3 +
 .../nvidia,tegra30-emc.yaml                   |  18 +
 .../memory-controllers/nvidia,tegra30-mc.yaml |   5 +
 arch/arm/boot/dts/tegra124-apalis-emc.dtsi    |   8 +
 .../arm/boot/dts/tegra124-jetson-tk1-emc.dtsi |   8 +
 arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi  |  10 +
 .../boot/dts/tegra124-peripherals-opp.dtsi    | 419 ++++++++++++++++++
 arch/arm/boot/dts/tegra124.dtsi               |  31 ++
 .../boot/dts/tegra20-acer-a500-picasso.dts    |  12 +
 arch/arm/boot/dts/tegra20-colibri.dtsi        |   8 +
 arch/arm/boot/dts/tegra20-paz00.dts           |  10 +
 .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 181 ++++++++
 arch/arm/boot/dts/tegra20.dtsi                |  42 +-
 .../tegra30-asus-nexus7-grouper-common.dtsi   |  16 +
 .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 383 ++++++++++++++++
 arch/arm/boot/dts/tegra30.dtsi                |  33 +-
 drivers/clk/tegra/Makefile                    |   2 +-
 drivers/clk/tegra/clk-tegra124-emc.c          |  41 +-
 drivers/clk/tegra/clk-tegra124.c              |  27 +-
 drivers/clk/tegra/clk-tegra20-emc.c           |   3 +
 drivers/clk/tegra/clk.h                       |  16 +-
 drivers/devfreq/Kconfig                       |   3 +-
 drivers/devfreq/tegra20-devfreq.c             | 186 ++++----
 drivers/devfreq/tegra30-devfreq.c             | 166 ++++---
 drivers/gpu/drm/tegra/Kconfig                 |   1 +
 drivers/gpu/drm/tegra/dc.c                    | 340 ++++++++++++++
 drivers/gpu/drm/tegra/dc.h                    |  11 +
 drivers/gpu/drm/tegra/drm.c                   |  14 +
 drivers/gpu/drm/tegra/hub.c                   |   3 +
 drivers/gpu/drm/tegra/plane.c                 | 122 +++++
 drivers/gpu/drm/tegra/plane.h                 |  15 +
 drivers/memory/tegra/Kconfig                  |  12 +-
 drivers/memory/tegra/mc.c                     | 184 +++++++-
 drivers/memory/tegra/mc.h                     |  20 +
 drivers/memory/tegra/tegra114.c               |   6 +
 drivers/memory/tegra/tegra124-emc.c           | 235 ++++++++--
 drivers/memory/tegra/tegra124.c               |  37 ++
 drivers/memory/tegra/tegra20-emc.c            | 244 ++++++++--
 drivers/memory/tegra/tegra20.c                |  34 ++
 drivers/memory/tegra/tegra210-emc-core.c      |  39 +-
 drivers/memory/tegra/tegra30-emc.c            | 245 ++++++++--
 drivers/memory/tegra/tegra30.c                | 191 ++++++++
 drivers/opp/core.c                            |  21 +-
 drivers/soc/tegra/fuse/tegra-apbmisc.c        |   2 +
 include/dt-bindings/memory/tegra124-mc.h      |  68 +++
 include/dt-bindings/memory/tegra20-mc.h       |  53 +++
 include/dt-bindings/memory/tegra30-mc.h       |  67 +++
 include/linux/clk/tegra.h                     |   9 +
 include/soc/tegra/emc.h                       |  16 -
 include/soc/tegra/mc.h                        |  26 ++
 55 files changed, 3477 insertions(+), 348 deletions(-)
 create mode 100644 arch/arm/boot/dts/tegra124-peripherals-opp.dtsi
 create mode 100644 arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
 create mode 100644 arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
 delete mode 100644 include/soc/tegra/emc.h

-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* [PATCH v6 01/52] clk: tegra: Export Tegra20 EMC kernel symbols
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

We're going to modularize Tegra EMC drivers and some of the EMC clk driver
symbols need to be exported, let's export them.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/clk/tegra/clk-tegra20-emc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clk/tegra/clk-tegra20-emc.c b/drivers/clk/tegra/clk-tegra20-emc.c
index 03bf0009a33c..dd74b8543bf1 100644
--- a/drivers/clk/tegra/clk-tegra20-emc.c
+++ b/drivers/clk/tegra/clk-tegra20-emc.c
@@ -13,6 +13,7 @@
 #include <linux/clk-provider.h>
 #include <linux/clk/tegra.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -235,6 +236,7 @@ void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
 		emc->cb_arg = cb_arg;
 	}
 }
+EXPORT_SYMBOL_GPL(tegra20_clk_set_emc_round_callback);
 
 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw)
 {
@@ -291,3 +293,4 @@ int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(tegra20_clk_prepare_emc_mc_same_freq);
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 01/52] clk: tegra: Export Tegra20 EMC kernel symbols
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

We're going to modularize Tegra EMC drivers and some of the EMC clk driver
symbols need to be exported, let's export them.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/clk/tegra/clk-tegra20-emc.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clk/tegra/clk-tegra20-emc.c b/drivers/clk/tegra/clk-tegra20-emc.c
index 03bf0009a33c..dd74b8543bf1 100644
--- a/drivers/clk/tegra/clk-tegra20-emc.c
+++ b/drivers/clk/tegra/clk-tegra20-emc.c
@@ -13,6 +13,7 @@
 #include <linux/clk-provider.h>
 #include <linux/clk/tegra.h>
 #include <linux/err.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -235,6 +236,7 @@ void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
 		emc->cb_arg = cb_arg;
 	}
 }
+EXPORT_SYMBOL_GPL(tegra20_clk_set_emc_round_callback);
 
 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw)
 {
@@ -291,3 +293,4 @@ int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(tegra20_clk_prepare_emc_mc_same_freq);
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 02/52] soc/tegra: fuse: Export tegra_read_ram_code()
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

The tegra_read_ram_code() is used by EMC drivers and we're going to make
these driver modular, hence this function needs to be exported.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/fuse/tegra-apbmisc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c
index cee207d10024..590c862538d0 100644
--- a/drivers/soc/tegra/fuse/tegra-apbmisc.c
+++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
  */
 
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -90,6 +91,7 @@ u32 tegra_read_ram_code(void)
 
 	return straps >> PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT;
 }
+EXPORT_SYMBOL_GPL(tegra_read_ram_code);
 
 static const struct of_device_id apbmisc_match[] __initconst = {
 	{ .compatible = "nvidia,tegra20-apbmisc", },
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 02/52] soc/tegra: fuse: Export tegra_read_ram_code()
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

The tegra_read_ram_code() is used by EMC drivers and we're going to make
these driver modular, hence this function needs to be exported.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/soc/tegra/fuse/tegra-apbmisc.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c
index cee207d10024..590c862538d0 100644
--- a/drivers/soc/tegra/fuse/tegra-apbmisc.c
+++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
  */
 
+#include <linux/export.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -90,6 +91,7 @@ u32 tegra_read_ram_code(void)
 
 	return straps >> PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT;
 }
+EXPORT_SYMBOL_GPL(tegra_read_ram_code);
 
 static const struct of_device_id apbmisc_match[] __initconst = {
 	{ .compatible = "nvidia,tegra20-apbmisc", },
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 03/52] dt-bindings: memory: tegra20: emc: Correct registers range in example
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

There is superfluous zero in the registers base address and registers
size should be twice bigger.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index add95367640b..567cffd37f3f 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -21,7 +21,7 @@ Example:
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
 		compatible = "nvidia,tegra20-emc";
-		reg = <0x7000f4000 0x200>;
+		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 03/52] dt-bindings: memory: tegra20: emc: Correct registers range in example
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

There is superfluous zero in the registers base address and registers
size should be twice bigger.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index add95367640b..567cffd37f3f 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -21,7 +21,7 @@ Example:
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
 		compatible = "nvidia,tegra20-emc";
-		reg = <0x7000f4000 0x200>;
+		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 	}
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Tegra20 External Memory Controller talks to DRAM chips and it needs to be
reprogrammed when memory frequency changes. Tegra Memory Controller sits
behind EMC and these controllers are tightly coupled. This patch adds the
new phandle property which allows to properly express connection of EMC
and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
par with Tegra30+ EMC bindings, which is handy to have.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 567cffd37f3f..1b0d4417aad8 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -12,6 +12,7 @@ Properties:
   irrespective of ram-code configuration.
 - interrupts : Should contain EMC General interrupt.
 - clocks : Should contain EMC clock.
+- nvidia,memory-controller : Phandle of the Memory Controller node.
 
 Child device nodes describe the memory settings for different configurations and clock rates.
 
@@ -24,6 +25,7 @@ Example:
 		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
+		nvidia,memory-controller = <&mc>;
 	}
 
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia, memory-controller property
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Tegra20 External Memory Controller talks to DRAM chips and it needs to be
reprogrammed when memory frequency changes. Tegra Memory Controller sits
behind EMC and these controllers are tightly coupled. This patch adds the
new phandle property which allows to properly express connection of EMC
and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
par with Tegra30+ EMC bindings, which is handy to have.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 567cffd37f3f..1b0d4417aad8 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -12,6 +12,7 @@ Properties:
   irrespective of ram-code configuration.
 - interrupts : Should contain EMC General interrupt.
 - clocks : Should contain EMC clock.
+- nvidia,memory-controller : Phandle of the Memory Controller node.
 
 Child device nodes describe the memory settings for different configurations and clock rates.
 
@@ -24,6 +25,7 @@ Example:
 		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
+		nvidia,memory-controller = <&mc>;
 	}
 
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Memory controller is interconnected with memory clients and with the
External Memory Controller. Document new interconnect property which
turns memory controller into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
index e55328237df4..739b7c6f2e26 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
@@ -16,6 +16,8 @@ Required properties:
   IOMMU specifier needed to encode an address. GART supports only a single
   address space that is shared by all devices, therefore no additional
   information needed for the address encoding.
+- #interconnect-cells : Should be 1. This cell represents memory client.
+  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.
 
 Example:
 	mc: memory-controller@7000f000 {
@@ -27,6 +29,7 @@ Example:
 		interrupts = <GIC_SPI 77 0x04>;
 		#reset-cells = <1>;
 		#iommu-cells = <0>;
+		#interconnect-cells = <1>;
 	};
 
 	video-codec@6001a000 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Memory controller is interconnected with memory clients and with the
External Memory Controller. Document new interconnect property which
turns memory controller into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
index e55328237df4..739b7c6f2e26 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
@@ -16,6 +16,8 @@ Required properties:
   IOMMU specifier needed to encode an address. GART supports only a single
   address space that is shared by all devices, therefore no additional
   information needed for the address encoding.
+- #interconnect-cells : Should be 1. This cell represents memory client.
+  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.
 
 Example:
 	mc: memory-controller@7000f000 {
@@ -27,6 +29,7 @@ Example:
 		interrupts = <GIC_SPI 77 0x04>;
 		#reset-cells = <1>;
 		#iommu-cells = <0>;
+		#interconnect-cells = <1>;
 	};
 
 	video-codec@6001a000 {
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 06/52] dt-bindings: memory: tegra20: emc: Document new interconnect property
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

External Memory Controller is interconnected with memory controller and
with external memory. Document new interconnect property which turns EMC
into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 1b0d4417aad8..0a53adc6ccba 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -13,6 +13,7 @@ Properties:
 - interrupts : Should contain EMC General interrupt.
 - clocks : Should contain EMC clock.
 - nvidia,memory-controller : Phandle of the Memory Controller node.
+- #interconnect-cells : Should be 0.
 
 Child device nodes describe the memory settings for different configurations and clock rates.
 
@@ -21,6 +22,7 @@ Example:
 	memory-controller@7000f400 {
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
+		#interconnect-cells = < 0 >;
 		compatible = "nvidia,tegra20-emc";
 		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 06/52] dt-bindings: memory: tegra20: emc: Document new interconnect property
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

External Memory Controller is interconnected with memory controller and
with external memory. Document new interconnect property which turns EMC
into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 1b0d4417aad8..0a53adc6ccba 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -13,6 +13,7 @@ Properties:
 - interrupts : Should contain EMC General interrupt.
 - clocks : Should contain EMC clock.
 - nvidia,memory-controller : Phandle of the Memory Controller node.
+- #interconnect-cells : Should be 0.
 
 Child device nodes describe the memory settings for different configurations and clock rates.
 
@@ -21,6 +22,7 @@ Example:
 	memory-controller@7000f400 {
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
+		#interconnect-cells = < 0 >;
 		compatible = "nvidia,tegra20-emc";
 		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 07/52] dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

The SoC core voltage can't be changed without taking into account the
clock rate of External Memory Controller. Document OPP table that will
be used for dynamic voltage frequency scaling, taking into account EMC
voltage requirement. Document optional core voltage regulator, which is
optional because some boards may have a fixed core regulator and still
frequency scaling may be desired to have.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra20-emc.txt      | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 0a53adc6ccba..8d09b228ac42 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -14,11 +14,23 @@ Properties:
 - clocks : Should contain EMC clock.
 - nvidia,memory-controller : Phandle of the Memory Controller node.
 - #interconnect-cells : Should be 0.
+- core-supply: Phandle of voltage regulator of the SoC "core" power domain.
+- operating-points-v2: See ../bindings/opp/opp.txt for details.
 
 Child device nodes describe the memory settings for different configurations and clock rates.
 
 Example:
 
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <36000000>;
+		};
+		...
+	};
+
 	memory-controller@7000f400 {
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
@@ -28,6 +40,8 @@ Example:
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		nvidia,memory-controller = <&mc>;
+		core-supply = <&core_vdd_reg>;
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 	}
 
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 07/52] dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

The SoC core voltage can't be changed without taking into account the
clock rate of External Memory Controller. Document OPP table that will
be used for dynamic voltage frequency scaling, taking into account EMC
voltage requirement. Document optional core voltage regulator, which is
optional because some boards may have a fixed core regulator and still
frequency scaling may be desired to have.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra20-emc.txt      | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 0a53adc6ccba..8d09b228ac42 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -14,11 +14,23 @@ Properties:
 - clocks : Should contain EMC clock.
 - nvidia,memory-controller : Phandle of the Memory Controller node.
 - #interconnect-cells : Should be 0.
+- core-supply: Phandle of voltage regulator of the SoC "core" power domain.
+- operating-points-v2: See ../bindings/opp/opp.txt for details.
 
 Child device nodes describe the memory settings for different configurations and clock rates.
 
 Example:
 
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <36000000>;
+		};
+		...
+	};
+
 	memory-controller@7000f400 {
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
@@ -28,6 +40,8 @@ Example:
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		nvidia,memory-controller = <&mc>;
+		core-supply = <&core_vdd_reg>;
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 	}
 
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

External Memory Controller can gather various hardware statistics that
are intended to be used for debugging purposes and for dynamic frequency
scaling of memory bus.

Document the new mfd-simple compatible and EMC statistics sub-device.
The subdev contains EMC DFS OPP table and interconnect paths to be used
for dynamic scaling of system's memory bandwidth based on EMC utilization
statistics.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 8d09b228ac42..382aabcd6952 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -4,7 +4,7 @@ Properties:
 - name : Should be emc
 - #address-cells : Should be 1
 - #size-cells : Should be 0
-- compatible : Should contain "nvidia,tegra20-emc".
+- compatible : Should contain "nvidia,tegra20-emc" and "simple-mfd".
 - reg : Offset and length of the register set for the device
 - nvidia,use-ram-code : If present, the sub-nodes will be addressed
   and chosen using the ramcode board selector. If omitted, only one
@@ -17,7 +17,8 @@ Properties:
 - core-supply: Phandle of voltage regulator of the SoC "core" power domain.
 - operating-points-v2: See ../bindings/opp/opp.txt for details.
 
-Child device nodes describe the memory settings for different configurations and clock rates.
+Child device nodes describe the memory settings for different configurations and clock rates,
+as well as EMC activity statistics collection sub-device.
 
 Example:
 
@@ -31,17 +32,34 @@ Example:
 		...
 	};
 
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-hz = /bits/ 64 <36000000>;
+			opp-peak-kBps = <144000>;
+		};
+		...
+	};
+
 	memory-controller@7000f400 {
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
 		#interconnect-cells = < 0 >;
-		compatible = "nvidia,tegra20-emc";
+		compatible = "nvidia,tegra20-emc", "simple-mfd";
 		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		nvidia,memory-controller = <&mc>;
 		core-supply = <&core_vdd_reg>;
 		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
+
+		emc-stats {
+			compatible = "nvidia,tegra20-emc-statistics";
+			operating-points-v2 = <&emc_bw_dfs_opp_table>;
+			interconnects = <&mc TEGRA20_MC_MPCORER &emc>;
+			interconnect-names = "cpu";
+		};
 	}
 
 
@@ -120,3 +138,22 @@ Properties:
 						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 						 0 0 0 0 >;
 		};
+
+
+
+Embedded Memory Controller statistics gathering sub-device
+
+EMC statistics subdev gathers information about hardware utilization
+which is intended to be used for debugging purposes and for dynamic
+frequency scaling based on the collected stats.
+
+Properties:
+- name : Should be emc-stats.
+- compatible : Should contain "nvidia,tegra20-emc-statistics".
+- operating-points-v2: See ../bindings/opp/opp.txt for details.
+- interconnects: Should contain entries for memory clients sitting on
+                 MC->EMC memory interconnect path.
+- interconnect-names: Should include name of the interconnect path for each
+                      interconnect entry. Consult TRM documentation for
+                      information about available memory clients, see MEMORY
+                      CONTROLLER section.
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

External Memory Controller can gather various hardware statistics that
are intended to be used for debugging purposes and for dynamic frequency
scaling of memory bus.

Document the new mfd-simple compatible and EMC statistics sub-device.
The subdev contains EMC DFS OPP table and interconnect paths to be used
for dynamic scaling of system's memory bandwidth based on EMC utilization
statistics.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
index 8d09b228ac42..382aabcd6952 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
@@ -4,7 +4,7 @@ Properties:
 - name : Should be emc
 - #address-cells : Should be 1
 - #size-cells : Should be 0
-- compatible : Should contain "nvidia,tegra20-emc".
+- compatible : Should contain "nvidia,tegra20-emc" and "simple-mfd".
 - reg : Offset and length of the register set for the device
 - nvidia,use-ram-code : If present, the sub-nodes will be addressed
   and chosen using the ramcode board selector. If omitted, only one
@@ -17,7 +17,8 @@ Properties:
 - core-supply: Phandle of voltage regulator of the SoC "core" power domain.
 - operating-points-v2: See ../bindings/opp/opp.txt for details.
 
-Child device nodes describe the memory settings for different configurations and clock rates.
+Child device nodes describe the memory settings for different configurations and clock rates,
+as well as EMC activity statistics collection sub-device.
 
 Example:
 
@@ -31,17 +32,34 @@ Example:
 		...
 	};
 
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-hz = /bits/ 64 <36000000>;
+			opp-peak-kBps = <144000>;
+		};
+		...
+	};
+
 	memory-controller@7000f400 {
 		#address-cells = < 1 >;
 		#size-cells = < 0 >;
 		#interconnect-cells = < 0 >;
-		compatible = "nvidia,tegra20-emc";
+		compatible = "nvidia,tegra20-emc", "simple-mfd";
 		reg = <0x7000f400 0x400>;
 		interrupts = <0 78 0x04>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		nvidia,memory-controller = <&mc>;
 		core-supply = <&core_vdd_reg>;
 		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
+
+		emc-stats {
+			compatible = "nvidia,tegra20-emc-statistics";
+			operating-points-v2 = <&emc_bw_dfs_opp_table>;
+			interconnects = <&mc TEGRA20_MC_MPCORER &emc>;
+			interconnect-names = "cpu";
+		};
 	}
 
 
@@ -120,3 +138,22 @@ Properties:
 						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 						 0 0 0 0 >;
 		};
+
+
+
+Embedded Memory Controller statistics gathering sub-device
+
+EMC statistics subdev gathers information about hardware utilization
+which is intended to be used for debugging purposes and for dynamic
+frequency scaling based on the collected stats.
+
+Properties:
+- name : Should be emc-stats.
+- compatible : Should contain "nvidia,tegra20-emc-statistics".
+- operating-points-v2: See ../bindings/opp/opp.txt for details.
+- interconnects: Should contain entries for memory clients sitting on
+                 MC->EMC memory interconnect path.
+- interconnect-names: Should include name of the interconnect path for each
+                      interconnect entry. Consult TRM documentation for
+                      information about available memory clients, see MEMORY
+                      CONTROLLER section.
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Memory controller is interconnected with memory clients and with the
External Memory Controller. Document new interconnect property which
turns memory controller into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
index 84fd57bcf0dc..5436e6d420bc 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
@@ -57,6 +57,9 @@ properties:
   "#iommu-cells":
     const: 1
 
+  "#interconnect-cells":
+    const: 1
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -120,6 +123,7 @@ required:
   - clock-names
   - "#reset-cells"
   - "#iommu-cells"
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -135,6 +139,7 @@ examples:
 
         #iommu-cells = <1>;
         #reset-cells = <1>;
+        #interconnect-cells = <1>;
 
         emc-timings-1 {
             nvidia,ram-code = <1>;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Memory controller is interconnected with memory clients and with the
External Memory Controller. Document new interconnect property which
turns memory controller into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
index 84fd57bcf0dc..5436e6d420bc 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
@@ -57,6 +57,9 @@ properties:
   "#iommu-cells":
     const: 1
 
+  "#interconnect-cells":
+    const: 1
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -120,6 +123,7 @@ required:
   - clock-names
   - "#reset-cells"
   - "#iommu-cells"
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -135,6 +139,7 @@ examples:
 
         #iommu-cells = <1>;
         #reset-cells = <1>;
+        #interconnect-cells = <1>;
 
         emc-timings-1 {
             nvidia,ram-code = <1>;
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 10/52] dt-bindings: memory: tegra30: emc: Document new interconnect property
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

External memory controller is interconnected with memory controller and
with external memory. Document new interconnect property which turns
External Memory Controller into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra30-emc.yaml     | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
index 112bae2fcbbd..c243986db420 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
@@ -31,6 +31,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  "#interconnect-cells":
+    const: 0
+
   nvidia,memory-controller:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
@@ -214,6 +217,7 @@ required:
   - interrupts
   - clocks
   - nvidia,memory-controller
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -227,6 +231,8 @@ examples:
 
         nvidia,memory-controller = <&mc>;
 
+        #interconnect-cells = <0>;
+
         emc-timings-1 {
             nvidia,ram-code = <1>;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 10/52] dt-bindings: memory: tegra30: emc: Document new interconnect property
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

External memory controller is interconnected with memory controller and
with external memory. Document new interconnect property which turns
External Memory Controller into interconnect provider.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra30-emc.yaml     | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
index 112bae2fcbbd..c243986db420 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
@@ -31,6 +31,9 @@ properties:
   interrupts:
     maxItems: 1
 
+  "#interconnect-cells":
+    const: 0
+
   nvidia,memory-controller:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
@@ -214,6 +217,7 @@ required:
   - interrupts
   - clocks
   - nvidia,memory-controller
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -227,6 +231,8 @@ examples:
 
         nvidia,memory-controller = <&mc>;
 
+        #interconnect-cells = <0>;
+
         emc-timings-1 {
             nvidia,ram-code = <1>;
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 11/52] dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Document new OPP table and voltage regulator properties which are needed
for supporting dynamic voltage-frequency scaling of the memory controller.
Some boards may have a fixed core voltage regulator, hence it's optional
because frequency scaling still may be desired.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra30-emc.yaml       | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
index c243986db420..0a2e2c0d0fdd 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
@@ -39,6 +39,15 @@ properties:
     description:
       Phandle of the Memory Controller node.
 
+  core-supply:
+    description:
+      Phandle of voltage regulator of the SoC "core" power domain.
+
+  operating-points-v2:
+    description:
+      Should contain freqs and voltages and opp-supported-hw property, which
+      is a bitfield indicating SoC speedo ID mask.
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -218,6 +227,7 @@ required:
   - clocks
   - nvidia,memory-controller
   - "#interconnect-cells"
+  - operating-points-v2
 
 additionalProperties: false
 
@@ -230,6 +240,8 @@ examples:
         clocks = <&tegra_car 57>;
 
         nvidia,memory-controller = <&mc>;
+        operating-points-v2 = <&dvfs_opp_table>;
+        core-supply = <&vdd_core>;
 
         #interconnect-cells = <0>;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 11/52] dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Document new OPP table and voltage regulator properties which are needed
for supporting dynamic voltage-frequency scaling of the memory controller.
Some boards may have a fixed core voltage regulator, hence it's optional
because frequency scaling still may be desired.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra30-emc.yaml       | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
index c243986db420..0a2e2c0d0fdd 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-emc.yaml
@@ -39,6 +39,15 @@ properties:
     description:
       Phandle of the Memory Controller node.
 
+  core-supply:
+    description:
+      Phandle of voltage regulator of the SoC "core" power domain.
+
+  operating-points-v2:
+    description:
+      Should contain freqs and voltages and opp-supported-hw property, which
+      is a bitfield indicating SoC speedo ID mask.
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -218,6 +227,7 @@ required:
   - clocks
   - nvidia,memory-controller
   - "#interconnect-cells"
+  - operating-points-v2
 
 additionalProperties: false
 
@@ -230,6 +240,8 @@ examples:
         clocks = <&tegra_car 57>;
 
         nvidia,memory-controller = <&mc>;
+        operating-points-v2 = <&dvfs_opp_table>;
+        core-supply = <&vdd_core>;
 
         #interconnect-cells = <0>;
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 12/52] dt-bindings: memory: tegra124: mc: Document new interconnect property
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Memory controller is interconnected with memory clients and with the
External Memory Controller. Document new interconnect property which
turns memory controller into interconnect provider.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra124-mc.yaml      | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
index 84d0339505b1..7b18b4d11e0a 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
@@ -40,6 +40,9 @@ properties:
   "#iommu-cells":
     const: 1
 
+  "#interconnect-cells":
+    const: 1
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -104,6 +107,7 @@ required:
   - clock-names
   - "#reset-cells"
   - "#iommu-cells"
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -119,6 +123,7 @@ examples:
 
         #iommu-cells = <1>;
         #reset-cells = <1>;
+        #interconnect-cells = <1>;
 
         emc-timings-3 {
             nvidia,ram-code = <3>;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 12/52] dt-bindings: memory: tegra124: mc: Document new interconnect property
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Memory controller is interconnected with memory clients and with the
External Memory Controller. Document new interconnect property which
turns memory controller into interconnect provider.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra124-mc.yaml      | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
index 84d0339505b1..7b18b4d11e0a 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
@@ -40,6 +40,9 @@ properties:
   "#iommu-cells":
     const: 1
 
+  "#interconnect-cells":
+    const: 1
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -104,6 +107,7 @@ required:
   - clock-names
   - "#reset-cells"
   - "#iommu-cells"
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -119,6 +123,7 @@ examples:
 
         #iommu-cells = <1>;
         #reset-cells = <1>;
+        #interconnect-cells = <1>;
 
         emc-timings-3 {
             nvidia,ram-code = <3>;
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

External memory controller is interconnected with memory controller and
with external memory. Document new interconnect property which turns
External Memory Controller into interconnect provider.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
index 278549f9e051..ac00832ceac1 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
@@ -29,6 +29,9 @@ properties:
     items:
       - const: emc
 
+  "#interconnect-cells":
+    const: 0
+
   nvidia,memory-controller:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
@@ -327,6 +330,7 @@ required:
   - clocks
   - clock-names
   - nvidia,memory-controller
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -345,6 +349,7 @@ examples:
 
         #iommu-cells = <1>;
         #reset-cells = <1>;
+        #interconnect-cells = <1>;
     };
 
     external-memory-controller@7001b000 {
@@ -355,6 +360,8 @@ examples:
 
         nvidia,memory-controller = <&mc>;
 
+        #interconnect-cells = <0>;
+
         emc-timings-0 {
             nvidia,ram-code = <3>;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

External memory controller is interconnected with memory controller and
with external memory. Document new interconnect property which turns
External Memory Controller into interconnect provider.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
index 278549f9e051..ac00832ceac1 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
@@ -29,6 +29,9 @@ properties:
     items:
       - const: emc
 
+  "#interconnect-cells":
+    const: 0
+
   nvidia,memory-controller:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
@@ -327,6 +330,7 @@ required:
   - clocks
   - clock-names
   - nvidia,memory-controller
+  - "#interconnect-cells"
 
 additionalProperties: false
 
@@ -345,6 +349,7 @@ examples:
 
         #iommu-cells = <1>;
         #reset-cells = <1>;
+        #interconnect-cells = <1>;
     };
 
     external-memory-controller@7001b000 {
@@ -355,6 +360,8 @@ examples:
 
         nvidia,memory-controller = <&mc>;
 
+        #interconnect-cells = <0>;
+
         emc-timings-0 {
             nvidia,ram-code = <3>;
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 14/52] dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Document new OPP table and voltage regulator properties which are needed
for supporting dynamic voltage-frequency scaling of the memory controller.
Some boards may have a fixed core voltage regulator, hence it's optional
because frequency scaling still may be desired.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra124-emc.yaml       | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
index ac00832ceac1..3f74cd173ba0 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
@@ -37,6 +37,15 @@ properties:
     description:
       phandle of the memory controller node
 
+  core-supply:
+    description:
+      Phandle of voltage regulator of the SoC "core" power domain.
+
+  operating-points-v2:
+    description:
+      Should contain freqs and voltages and opp-supported-hw property, which
+      is a bitfield indicating SoC speedo ID mask.
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -359,6 +368,8 @@ examples:
         clock-names = "emc";
 
         nvidia,memory-controller = <&mc>;
+        operating-points-v2 = <&dvfs_opp_table>;
+        core-supply = <&vdd_core>;
 
         #interconnect-cells = <0>;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 14/52] dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Document new OPP table and voltage regulator properties which are needed
for supporting dynamic voltage-frequency scaling of the memory controller.
Some boards may have a fixed core voltage regulator, hence it's optional
because frequency scaling still may be desired.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../memory-controllers/nvidia,tegra124-emc.yaml       | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
index ac00832ceac1..3f74cd173ba0 100644
--- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
+++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
@@ -37,6 +37,15 @@ properties:
     description:
       phandle of the memory controller node
 
+  core-supply:
+    description:
+      Phandle of voltage regulator of the SoC "core" power domain.
+
+  operating-points-v2:
+    description:
+      Should contain freqs and voltages and opp-supported-hw property, which
+      is a bitfield indicating SoC speedo ID mask.
+
 patternProperties:
   "^emc-timings-[0-9]+$":
     type: object
@@ -359,6 +368,8 @@ examples:
         clock-names = "emc";
 
         nvidia,memory-controller = <&mc>;
+        operating-points-v2 = <&dvfs_opp_table>;
+        core-supply = <&vdd_core>;
 
         #interconnect-cells = <0>;
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 15/52] dt-bindings: tegra30-actmon: Document OPP and interconnect properties
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Document EMC DFS OPP table and interconnect paths that will be used
for scaling of system's memory bandwidth based on memory utilization
statistics. Previously ACTMON was supposed to drive EMC clock rate
directly, but now it should do it using interconnect framework in order
to support shared voltage scaling in addition to the frequency scaling.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../arm/tegra/nvidia,tegra30-actmon.txt       | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt
index ea670a5d7ee3..412e939c65cb 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt
@@ -18,8 +18,30 @@ clock-names. See ../../clock/clock-bindings.txt for details.
 ../../reset/reset.txt for details.
 - reset-names: Must include the following entries:
   - actmon
+- operating-points-v2: See ../bindings/opp/opp.txt for details.
+- interconnects: Should contain entries for memory clients sitting on
+                 MC->EMC memory interconnect path.
+- interconnect-names: Should include name of the interconnect path for each
+                      interconnect entry. Consult TRM documentation for
+                      information about available memory clients, see MEMORY
+                      CONTROLLER section.
+
+For each opp entry in 'operating-points-v2' table:
+- opp-supported-hw: bitfield indicating SoC speedo ID mask
+- opp-peak-kBps: peak bandwidth of the memory channel
 
 Example:
+	dfs_opp_table: opp_table {
+		compatible = "operating-points-v2";
+
+		opp@12750000 {
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <51000>;
+		};
+		...
+	};
+
 	actmon@6000c800 {
 		compatible = "nvidia,tegra124-actmon";
 		reg = <0x0 0x6000c800 0x0 0x400>;
@@ -29,4 +51,7 @@ Example:
 		clock-names = "actmon", "emc";
 		resets = <&tegra_car 119>;
 		reset-names = "actmon";
+		operating-points-v2 = <&dfs_opp_table>;
+		interconnects = <&mc TEGRA124_MC_MPCORER &emc>;
+		interconnect-names = "cpu";
 	};
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 15/52] dt-bindings: tegra30-actmon: Document OPP and interconnect properties
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Document EMC DFS OPP table and interconnect paths that will be used
for scaling of system's memory bandwidth based on memory utilization
statistics. Previously ACTMON was supposed to drive EMC clock rate
directly, but now it should do it using interconnect framework in order
to support shared voltage scaling in addition to the frequency scaling.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../arm/tegra/nvidia,tegra30-actmon.txt       | 25 +++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt
index ea670a5d7ee3..412e939c65cb 100644
--- a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra30-actmon.txt
@@ -18,8 +18,30 @@ clock-names. See ../../clock/clock-bindings.txt for details.
 ../../reset/reset.txt for details.
 - reset-names: Must include the following entries:
   - actmon
+- operating-points-v2: See ../bindings/opp/opp.txt for details.
+- interconnects: Should contain entries for memory clients sitting on
+                 MC->EMC memory interconnect path.
+- interconnect-names: Should include name of the interconnect path for each
+                      interconnect entry. Consult TRM documentation for
+                      information about available memory clients, see MEMORY
+                      CONTROLLER section.
+
+For each opp entry in 'operating-points-v2' table:
+- opp-supported-hw: bitfield indicating SoC speedo ID mask
+- opp-peak-kBps: peak bandwidth of the memory channel
 
 Example:
+	dfs_opp_table: opp_table {
+		compatible = "operating-points-v2";
+
+		opp@12750000 {
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <51000>;
+		};
+		...
+	};
+
 	actmon@6000c800 {
 		compatible = "nvidia,tegra124-actmon";
 		reg = <0x0 0x6000c800 0x0 0x400>;
@@ -29,4 +51,7 @@ Example:
 		clock-names = "actmon", "emc";
 		resets = <&tegra_car 119>;
 		reset-names = "actmon";
+		operating-points-v2 = <&dfs_opp_table>;
+		interconnects = <&mc TEGRA124_MC_MPCORER &emc>;
+		interconnect-names = "cpu";
 	};
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 16/52] dt-bindings: host1x: Document new interconnect properties
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:16   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Most of Host1x devices have at least one memory client. These clients
are directly connected to the memory controller. The new interconnect
properties represent the memory client's connection to the memory
controller.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../display/tegra/nvidia,tegra20-host1x.txt   | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index ac63ae4a3861..814246e51954 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -20,6 +20,10 @@ Required properties:
 - reset-names: Must include the following entries:
   - host1x
 
+Each host1x client module having to perform DMA through the Memory Controller
+should have the interconnect endpoints set to the Memory Client and External
+Memory respectively.
+
 The host1x top-level node defines a number of children, each representing one
 of the following host1x client modules:
 
@@ -36,6 +40,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - mpe
 
+  Optional properties:
+  - interconnects: Must contain entry for the MPE memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - vi: video input
 
   Required properties:
@@ -113,6 +123,12 @@ of the following host1x client modules:
 	  Required properties:
 	  - remote-endpoint: phandle to vi port 'endpoint' node.
 
+  Optional properties:
+  - interconnects: Must contain entry for the VI memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - epp: encoder pre-processor
 
   Required properties:
@@ -126,6 +142,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - epp
 
+  Optional properties:
+  - interconnects: Must contain entry for the EPP memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - isp: image signal processor
 
   Required properties:
@@ -139,6 +161,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - isp
 
+  Optional properties:
+  - interconnects: Must contain entry for the ISP memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - gr2d: 2D graphics engine
 
   Required properties:
@@ -152,6 +180,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - 2d
 
+  Optional properties:
+  - interconnects: Must contain entry for the GR2D memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - gr3d: 3D graphics engine
 
   Required properties:
@@ -170,6 +204,12 @@ of the following host1x client modules:
     - 3d
     - 3d2 (Only required on SoCs with two 3D clocks)
 
+  Optional properties:
+  - interconnects: Must contain entry for the GR3D memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - dc: display controller
 
   Required properties:
@@ -197,6 +237,10 @@ of the following host1x client modules:
   - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
   - nvidia,edid: supplies a binary EDID blob
   - nvidia,panel: phandle of a display panel
+  - interconnects: Must contain entry for the DC memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
 
 - hdmi: High Definition Multimedia Interface
 
@@ -345,6 +389,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - vic
 
+  Optional properties:
+  - interconnects: Must contain entry for the VIC memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 Example:
 
 / {
@@ -498,6 +548,15 @@ Example:
 			resets = <&tegra_car 27>;
 			reset-names = "dc";
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
+					<&mc TEGRA20_MC_DISPLAY0B &emc>,
+					<&mc TEGRA20_MC_DISPLAY0C &emc>,
+					<&mc TEGRA20_MC_DISPLAY1B &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -513,6 +572,15 @@ Example:
 			resets = <&tegra_car 26>;
 			reset-names = "dc";
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA20_MC_DISPLAY1BB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 16/52] dt-bindings: host1x: Document new interconnect properties
@ 2020-10-25 22:16   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:16 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Most of Host1x devices have at least one memory client. These clients
are directly connected to the memory controller. The new interconnect
properties represent the memory client's connection to the memory
controller.

Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../display/tegra/nvidia,tegra20-host1x.txt   | 68 +++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
index ac63ae4a3861..814246e51954 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.txt
@@ -20,6 +20,10 @@ Required properties:
 - reset-names: Must include the following entries:
   - host1x
 
+Each host1x client module having to perform DMA through the Memory Controller
+should have the interconnect endpoints set to the Memory Client and External
+Memory respectively.
+
 The host1x top-level node defines a number of children, each representing one
 of the following host1x client modules:
 
@@ -36,6 +40,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - mpe
 
+  Optional properties:
+  - interconnects: Must contain entry for the MPE memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - vi: video input
 
   Required properties:
@@ -113,6 +123,12 @@ of the following host1x client modules:
 	  Required properties:
 	  - remote-endpoint: phandle to vi port 'endpoint' node.
 
+  Optional properties:
+  - interconnects: Must contain entry for the VI memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - epp: encoder pre-processor
 
   Required properties:
@@ -126,6 +142,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - epp
 
+  Optional properties:
+  - interconnects: Must contain entry for the EPP memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - isp: image signal processor
 
   Required properties:
@@ -139,6 +161,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - isp
 
+  Optional properties:
+  - interconnects: Must contain entry for the ISP memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - gr2d: 2D graphics engine
 
   Required properties:
@@ -152,6 +180,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - 2d
 
+  Optional properties:
+  - interconnects: Must contain entry for the GR2D memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - gr3d: 3D graphics engine
 
   Required properties:
@@ -170,6 +204,12 @@ of the following host1x client modules:
     - 3d
     - 3d2 (Only required on SoCs with two 3D clocks)
 
+  Optional properties:
+  - interconnects: Must contain entry for the GR3D memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 - dc: display controller
 
   Required properties:
@@ -197,6 +237,10 @@ of the following host1x client modules:
   - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
   - nvidia,edid: supplies a binary EDID blob
   - nvidia,panel: phandle of a display panel
+  - interconnects: Must contain entry for the DC memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
 
 - hdmi: High Definition Multimedia Interface
 
@@ -345,6 +389,12 @@ of the following host1x client modules:
   - reset-names: Must include the following entries:
     - vic
 
+  Optional properties:
+  - interconnects: Must contain entry for the VIC memory clients.
+  - interconnect-names: Must include name of the interconnect path for each
+    interconnect entry. Consult TRM documentation for information about
+    available memory clients, see MEMORY CONTROLLER section.
+
 Example:
 
 / {
@@ -498,6 +548,15 @@ Example:
 			resets = <&tegra_car 27>;
 			reset-names = "dc";
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
+					<&mc TEGRA20_MC_DISPLAY0B &emc>,
+					<&mc TEGRA20_MC_DISPLAY0C &emc>,
+					<&mc TEGRA20_MC_DISPLAY1B &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -513,6 +572,15 @@ Example:
 			resets = <&tegra_car 26>;
 			reset-names = "dc";
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA20_MC_DISPLAY1BB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 17/52] dt-bindings: memory: tegra20: Add memory client IDs
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Each memory client have a unique hardware ID, this patch adds these IDs.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 include/dt-bindings/memory/tegra20-mc.h | 53 +++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/include/dt-bindings/memory/tegra20-mc.h b/include/dt-bindings/memory/tegra20-mc.h
index 35e131eee198..6f8829508ad0 100644
--- a/include/dt-bindings/memory/tegra20-mc.h
+++ b/include/dt-bindings/memory/tegra20-mc.h
@@ -18,4 +18,57 @@
 #define TEGRA20_MC_RESET_VDE		13
 #define TEGRA20_MC_RESET_VI		14
 
+#define TEGRA20_MC_DISPLAY0A		0
+#define TEGRA20_MC_DISPLAY0AB		1
+#define TEGRA20_MC_DISPLAY0B		2
+#define TEGRA20_MC_DISPLAY0BB		3
+#define TEGRA20_MC_DISPLAY0C		4
+#define TEGRA20_MC_DISPLAY0CB		5
+#define TEGRA20_MC_DISPLAY1B		6
+#define TEGRA20_MC_DISPLAY1BB		7
+#define TEGRA20_MC_EPPUP		8
+#define TEGRA20_MC_G2PR			9
+#define TEGRA20_MC_G2SR			10
+#define TEGRA20_MC_MPEUNIFBR		11
+#define TEGRA20_MC_VIRUV		12
+#define TEGRA20_MC_AVPCARM7R		13
+#define TEGRA20_MC_DISPLAYHC		14
+#define TEGRA20_MC_DISPLAYHCB		15
+#define TEGRA20_MC_FDCDRD		16
+#define TEGRA20_MC_G2DR			17
+#define TEGRA20_MC_HOST1XDMAR		18
+#define TEGRA20_MC_HOST1XR		19
+#define TEGRA20_MC_IDXSRD		20
+#define TEGRA20_MC_MPCORER		21
+#define TEGRA20_MC_MPE_IPRED		22
+#define TEGRA20_MC_MPEAMEMRD		23
+#define TEGRA20_MC_MPECSRD		24
+#define TEGRA20_MC_PPCSAHBDMAR		25
+#define TEGRA20_MC_PPCSAHBSLVR		26
+#define TEGRA20_MC_TEXSRD		27
+#define TEGRA20_MC_VDEBSEVR		28
+#define TEGRA20_MC_VDEMBER		29
+#define TEGRA20_MC_VDEMCER		30
+#define TEGRA20_MC_VDETPER		31
+#define TEGRA20_MC_EPPU			32
+#define TEGRA20_MC_EPPV			33
+#define TEGRA20_MC_EPPY			34
+#define TEGRA20_MC_MPEUNIFBW		35
+#define TEGRA20_MC_VIWSB		36
+#define TEGRA20_MC_VIWU			37
+#define TEGRA20_MC_VIWV			38
+#define TEGRA20_MC_VIWY			39
+#define TEGRA20_MC_G2DW			40
+#define TEGRA20_MC_AVPCARM7W		41
+#define TEGRA20_MC_FDCDWR		42
+#define TEGRA20_MC_HOST1XW		43
+#define TEGRA20_MC_ISPW			44
+#define TEGRA20_MC_MPCOREW		45
+#define TEGRA20_MC_MPECSWR		46
+#define TEGRA20_MC_PPCSAHBDMAW		47
+#define TEGRA20_MC_PPCSAHBSLVW		48
+#define TEGRA20_MC_VDEBSEVW		49
+#define TEGRA20_MC_VDEMBEW		50
+#define TEGRA20_MC_VDETPMW		51
+
 #endif
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 17/52] dt-bindings: memory: tegra20: Add memory client IDs
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Each memory client have a unique hardware ID, this patch adds these IDs.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 include/dt-bindings/memory/tegra20-mc.h | 53 +++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/include/dt-bindings/memory/tegra20-mc.h b/include/dt-bindings/memory/tegra20-mc.h
index 35e131eee198..6f8829508ad0 100644
--- a/include/dt-bindings/memory/tegra20-mc.h
+++ b/include/dt-bindings/memory/tegra20-mc.h
@@ -18,4 +18,57 @@
 #define TEGRA20_MC_RESET_VDE		13
 #define TEGRA20_MC_RESET_VI		14
 
+#define TEGRA20_MC_DISPLAY0A		0
+#define TEGRA20_MC_DISPLAY0AB		1
+#define TEGRA20_MC_DISPLAY0B		2
+#define TEGRA20_MC_DISPLAY0BB		3
+#define TEGRA20_MC_DISPLAY0C		4
+#define TEGRA20_MC_DISPLAY0CB		5
+#define TEGRA20_MC_DISPLAY1B		6
+#define TEGRA20_MC_DISPLAY1BB		7
+#define TEGRA20_MC_EPPUP		8
+#define TEGRA20_MC_G2PR			9
+#define TEGRA20_MC_G2SR			10
+#define TEGRA20_MC_MPEUNIFBR		11
+#define TEGRA20_MC_VIRUV		12
+#define TEGRA20_MC_AVPCARM7R		13
+#define TEGRA20_MC_DISPLAYHC		14
+#define TEGRA20_MC_DISPLAYHCB		15
+#define TEGRA20_MC_FDCDRD		16
+#define TEGRA20_MC_G2DR			17
+#define TEGRA20_MC_HOST1XDMAR		18
+#define TEGRA20_MC_HOST1XR		19
+#define TEGRA20_MC_IDXSRD		20
+#define TEGRA20_MC_MPCORER		21
+#define TEGRA20_MC_MPE_IPRED		22
+#define TEGRA20_MC_MPEAMEMRD		23
+#define TEGRA20_MC_MPECSRD		24
+#define TEGRA20_MC_PPCSAHBDMAR		25
+#define TEGRA20_MC_PPCSAHBSLVR		26
+#define TEGRA20_MC_TEXSRD		27
+#define TEGRA20_MC_VDEBSEVR		28
+#define TEGRA20_MC_VDEMBER		29
+#define TEGRA20_MC_VDEMCER		30
+#define TEGRA20_MC_VDETPER		31
+#define TEGRA20_MC_EPPU			32
+#define TEGRA20_MC_EPPV			33
+#define TEGRA20_MC_EPPY			34
+#define TEGRA20_MC_MPEUNIFBW		35
+#define TEGRA20_MC_VIWSB		36
+#define TEGRA20_MC_VIWU			37
+#define TEGRA20_MC_VIWV			38
+#define TEGRA20_MC_VIWY			39
+#define TEGRA20_MC_G2DW			40
+#define TEGRA20_MC_AVPCARM7W		41
+#define TEGRA20_MC_FDCDWR		42
+#define TEGRA20_MC_HOST1XW		43
+#define TEGRA20_MC_ISPW			44
+#define TEGRA20_MC_MPCOREW		45
+#define TEGRA20_MC_MPECSWR		46
+#define TEGRA20_MC_PPCSAHBDMAW		47
+#define TEGRA20_MC_PPCSAHBSLVW		48
+#define TEGRA20_MC_VDEBSEVW		49
+#define TEGRA20_MC_VDEMBEW		50
+#define TEGRA20_MC_VDETPMW		51
+
 #endif
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 18/52] dt-bindings: memory: tegra30: Add memory client IDs
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Each memory client have a unique hardware ID, this patch adds these IDs.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 include/dt-bindings/memory/tegra30-mc.h | 67 +++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/include/dt-bindings/memory/tegra30-mc.h b/include/dt-bindings/memory/tegra30-mc.h
index 169f005fbc78..930f708aca17 100644
--- a/include/dt-bindings/memory/tegra30-mc.h
+++ b/include/dt-bindings/memory/tegra30-mc.h
@@ -41,4 +41,71 @@
 #define TEGRA30_MC_RESET_VDE		16
 #define TEGRA30_MC_RESET_VI		17
 
+#define TEGRA30_MC_PTCR			0
+#define TEGRA30_MC_DISPLAY0A		1
+#define TEGRA30_MC_DISPLAY0AB		2
+#define TEGRA30_MC_DISPLAY0B		3
+#define TEGRA30_MC_DISPLAY0BB		4
+#define TEGRA30_MC_DISPLAY0C		5
+#define TEGRA30_MC_DISPLAY0CB		6
+#define TEGRA30_MC_DISPLAY1B		7
+#define TEGRA30_MC_DISPLAY1BB		8
+#define TEGRA30_MC_EPPUP		9
+#define TEGRA30_MC_G2PR			10
+#define TEGRA30_MC_G2SR			11
+#define TEGRA30_MC_MPEUNIFBR		12
+#define TEGRA30_MC_VIRUV		13
+#define TEGRA30_MC_AFIR			14
+#define TEGRA30_MC_AVPCARM7R		15
+#define TEGRA30_MC_DISPLAYHC		16
+#define TEGRA30_MC_DISPLAYHCB		17
+#define TEGRA30_MC_FDCDRD		18
+#define TEGRA30_MC_FDCDRD2		19
+#define TEGRA30_MC_G2DR			20
+#define TEGRA30_MC_HDAR			21
+#define TEGRA30_MC_HOST1XDMAR		22
+#define TEGRA30_MC_HOST1XR		23
+#define TEGRA30_MC_IDXSRD		24
+#define TEGRA30_MC_IDXSRD2		25
+#define TEGRA30_MC_MPE_IPRED		26
+#define TEGRA30_MC_MPEAMEMRD		27
+#define TEGRA30_MC_MPECSRD		28
+#define TEGRA30_MC_PPCSAHBDMAR		29
+#define TEGRA30_MC_PPCSAHBSLVR		30
+#define TEGRA30_MC_SATAR		31
+#define TEGRA30_MC_TEXSRD		32
+#define TEGRA30_MC_TEXSRD2		33
+#define TEGRA30_MC_VDEBSEVR		34
+#define TEGRA30_MC_VDEMBER		35
+#define TEGRA30_MC_VDEMCER		36
+#define TEGRA30_MC_VDETPER		37
+#define TEGRA30_MC_MPCORELPR		38
+#define TEGRA30_MC_MPCORER		39
+#define TEGRA30_MC_EPPU			40
+#define TEGRA30_MC_EPPV			41
+#define TEGRA30_MC_EPPY			42
+#define TEGRA30_MC_MPEUNIFBW		43
+#define TEGRA30_MC_VIWSB		44
+#define TEGRA30_MC_VIWU			45
+#define TEGRA30_MC_VIWV			46
+#define TEGRA30_MC_VIWY			47
+#define TEGRA30_MC_G2DW			48
+#define TEGRA30_MC_AFIW			49
+#define TEGRA30_MC_AVPCARM7W		50
+#define TEGRA30_MC_FDCDWR		51
+#define TEGRA30_MC_FDCDWR2		52
+#define TEGRA30_MC_HDAW			53
+#define TEGRA30_MC_HOST1XW		54
+#define TEGRA30_MC_ISPW			55
+#define TEGRA30_MC_MPCORELPW		56
+#define TEGRA30_MC_MPCOREW		57
+#define TEGRA30_MC_MPECSWR		58
+#define TEGRA30_MC_PPCSAHBDMAW		59
+#define TEGRA30_MC_PPCSAHBSLVW		60
+#define TEGRA30_MC_SATAW		61
+#define TEGRA30_MC_VDEBSEVW		62
+#define TEGRA30_MC_VDEDBGW		63
+#define TEGRA30_MC_VDEMBEW		64
+#define TEGRA30_MC_VDETPMW		65
+
 #endif
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 18/52] dt-bindings: memory: tegra30: Add memory client IDs
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Each memory client have a unique hardware ID, this patch adds these IDs.

Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 include/dt-bindings/memory/tegra30-mc.h | 67 +++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/include/dt-bindings/memory/tegra30-mc.h b/include/dt-bindings/memory/tegra30-mc.h
index 169f005fbc78..930f708aca17 100644
--- a/include/dt-bindings/memory/tegra30-mc.h
+++ b/include/dt-bindings/memory/tegra30-mc.h
@@ -41,4 +41,71 @@
 #define TEGRA30_MC_RESET_VDE		16
 #define TEGRA30_MC_RESET_VI		17
 
+#define TEGRA30_MC_PTCR			0
+#define TEGRA30_MC_DISPLAY0A		1
+#define TEGRA30_MC_DISPLAY0AB		2
+#define TEGRA30_MC_DISPLAY0B		3
+#define TEGRA30_MC_DISPLAY0BB		4
+#define TEGRA30_MC_DISPLAY0C		5
+#define TEGRA30_MC_DISPLAY0CB		6
+#define TEGRA30_MC_DISPLAY1B		7
+#define TEGRA30_MC_DISPLAY1BB		8
+#define TEGRA30_MC_EPPUP		9
+#define TEGRA30_MC_G2PR			10
+#define TEGRA30_MC_G2SR			11
+#define TEGRA30_MC_MPEUNIFBR		12
+#define TEGRA30_MC_VIRUV		13
+#define TEGRA30_MC_AFIR			14
+#define TEGRA30_MC_AVPCARM7R		15
+#define TEGRA30_MC_DISPLAYHC		16
+#define TEGRA30_MC_DISPLAYHCB		17
+#define TEGRA30_MC_FDCDRD		18
+#define TEGRA30_MC_FDCDRD2		19
+#define TEGRA30_MC_G2DR			20
+#define TEGRA30_MC_HDAR			21
+#define TEGRA30_MC_HOST1XDMAR		22
+#define TEGRA30_MC_HOST1XR		23
+#define TEGRA30_MC_IDXSRD		24
+#define TEGRA30_MC_IDXSRD2		25
+#define TEGRA30_MC_MPE_IPRED		26
+#define TEGRA30_MC_MPEAMEMRD		27
+#define TEGRA30_MC_MPECSRD		28
+#define TEGRA30_MC_PPCSAHBDMAR		29
+#define TEGRA30_MC_PPCSAHBSLVR		30
+#define TEGRA30_MC_SATAR		31
+#define TEGRA30_MC_TEXSRD		32
+#define TEGRA30_MC_TEXSRD2		33
+#define TEGRA30_MC_VDEBSEVR		34
+#define TEGRA30_MC_VDEMBER		35
+#define TEGRA30_MC_VDEMCER		36
+#define TEGRA30_MC_VDETPER		37
+#define TEGRA30_MC_MPCORELPR		38
+#define TEGRA30_MC_MPCORER		39
+#define TEGRA30_MC_EPPU			40
+#define TEGRA30_MC_EPPV			41
+#define TEGRA30_MC_EPPY			42
+#define TEGRA30_MC_MPEUNIFBW		43
+#define TEGRA30_MC_VIWSB		44
+#define TEGRA30_MC_VIWU			45
+#define TEGRA30_MC_VIWV			46
+#define TEGRA30_MC_VIWY			47
+#define TEGRA30_MC_G2DW			48
+#define TEGRA30_MC_AFIW			49
+#define TEGRA30_MC_AVPCARM7W		50
+#define TEGRA30_MC_FDCDWR		51
+#define TEGRA30_MC_FDCDWR2		52
+#define TEGRA30_MC_HDAW			53
+#define TEGRA30_MC_HOST1XW		54
+#define TEGRA30_MC_ISPW			55
+#define TEGRA30_MC_MPCORELPW		56
+#define TEGRA30_MC_MPCOREW		57
+#define TEGRA30_MC_MPECSWR		58
+#define TEGRA30_MC_PPCSAHBDMAW		59
+#define TEGRA30_MC_PPCSAHBSLVW		60
+#define TEGRA30_MC_SATAW		61
+#define TEGRA30_MC_VDEBSEVW		62
+#define TEGRA30_MC_VDEDBGW		63
+#define TEGRA30_MC_VDEMBEW		64
+#define TEGRA30_MC_VDETPMW		65
+
 #endif
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 19/52] dt-bindings: memory: tegra124: Add memory client IDs
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Each memory client have a unique hardware ID, this patch adds these IDs.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 include/dt-bindings/memory/tegra124-mc.h | 68 ++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/include/dt-bindings/memory/tegra124-mc.h b/include/dt-bindings/memory/tegra124-mc.h
index 186e6b7e9b35..7e73bb400eca 100644
--- a/include/dt-bindings/memory/tegra124-mc.h
+++ b/include/dt-bindings/memory/tegra124-mc.h
@@ -54,4 +54,72 @@
 #define TEGRA124_MC_RESET_ISP2B		22
 #define TEGRA124_MC_RESET_GPU		23
 
+#define TEGRA124_MC_PTCR		0
+#define TEGRA124_MC_DISPLAY0A		1
+#define TEGRA124_MC_DISPLAY0AB		2
+#define TEGRA124_MC_DISPLAY0B		3
+#define TEGRA124_MC_DISPLAY0BB		4
+#define TEGRA124_MC_DISPLAY0C		5
+#define TEGRA124_MC_DISPLAY0CB		6
+#define TEGRA124_MC_AFIR		14
+#define TEGRA124_MC_AVPCARM7R		15
+#define TEGRA124_MC_DISPLAYHC		16
+#define TEGRA124_MC_DISPLAYHCB		17
+#define TEGRA124_MC_HDAR		21
+#define TEGRA124_MC_HOST1XDMAR		22
+#define TEGRA124_MC_HOST1XR		23
+#define TEGRA124_MC_MSENCSRD		28
+#define TEGRA124_MC_PPCSAHBDMAR		29
+#define TEGRA124_MC_PPCSAHBSLVR		30
+#define TEGRA124_MC_SATAR		31
+#define TEGRA124_MC_VDEBSEVR		34
+#define TEGRA124_MC_VDEMBER		35
+#define TEGRA124_MC_VDEMCER		36
+#define TEGRA124_MC_VDETPER		37
+#define TEGRA124_MC_MPCORELPR		38
+#define TEGRA124_MC_MPCORER		39
+#define TEGRA124_MC_MSENCSWR		43
+#define TEGRA124_MC_AFIW		49
+#define TEGRA124_MC_AVPCARM7W		50
+#define TEGRA124_MC_HDAW		53
+#define TEGRA124_MC_HOST1XW		54
+#define TEGRA124_MC_MPCORELPW		56
+#define TEGRA124_MC_MPCOREW		57
+#define TEGRA124_MC_PPCSAHBDMAW		59
+#define TEGRA124_MC_PPCSAHBSLVW		60
+#define TEGRA124_MC_SATAW		61
+#define TEGRA124_MC_VDEBSEVW		62
+#define TEGRA124_MC_VDEDBGW		63
+#define TEGRA124_MC_VDEMBEW		64
+#define TEGRA124_MC_VDETPMW		65
+#define TEGRA124_MC_ISPRA		68
+#define TEGRA124_MC_ISPWA		70
+#define TEGRA124_MC_ISPWB		71
+#define TEGRA124_MC_XUSB_HOSTR		74
+#define TEGRA124_MC_XUSB_HOSTW		75
+#define TEGRA124_MC_XUSB_DEVR		76
+#define TEGRA124_MC_XUSB_DEVW		77
+#define TEGRA124_MC_ISPRAB		78
+#define TEGRA124_MC_ISPWAB		80
+#define TEGRA124_MC_ISPWBB		81
+#define TEGRA124_MC_TSECSRD		84
+#define TEGRA124_MC_TSECSWR		85
+#define TEGRA124_MC_A9AVPSCR		86
+#define TEGRA124_MC_A9AVPSCW		87
+#define TEGRA124_MC_GPUSRD		88
+#define TEGRA124_MC_GPUSWR		89
+#define TEGRA124_MC_DISPLAYT		90
+#define TEGRA124_MC_SDMMCRA		96
+#define TEGRA124_MC_SDMMCRAA		97
+#define TEGRA124_MC_SDMMCR		98
+#define TEGRA124_MC_SDMMCRAB		99
+#define TEGRA124_MC_SDMMCWA		100
+#define TEGRA124_MC_SDMMCWAA		101
+#define TEGRA124_MC_SDMMCW		102
+#define TEGRA124_MC_SDMMCWAB		103
+#define TEGRA124_MC_VICSRD		108
+#define TEGRA124_MC_VICSWR		109
+#define TEGRA124_MC_VIW			114
+#define TEGRA124_MC_DISPLAYD		115
+
 #endif
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 19/52] dt-bindings: memory: tegra124: Add memory client IDs
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Each memory client have a unique hardware ID, this patch adds these IDs.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 include/dt-bindings/memory/tegra124-mc.h | 68 ++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/include/dt-bindings/memory/tegra124-mc.h b/include/dt-bindings/memory/tegra124-mc.h
index 186e6b7e9b35..7e73bb400eca 100644
--- a/include/dt-bindings/memory/tegra124-mc.h
+++ b/include/dt-bindings/memory/tegra124-mc.h
@@ -54,4 +54,72 @@
 #define TEGRA124_MC_RESET_ISP2B		22
 #define TEGRA124_MC_RESET_GPU		23
 
+#define TEGRA124_MC_PTCR		0
+#define TEGRA124_MC_DISPLAY0A		1
+#define TEGRA124_MC_DISPLAY0AB		2
+#define TEGRA124_MC_DISPLAY0B		3
+#define TEGRA124_MC_DISPLAY0BB		4
+#define TEGRA124_MC_DISPLAY0C		5
+#define TEGRA124_MC_DISPLAY0CB		6
+#define TEGRA124_MC_AFIR		14
+#define TEGRA124_MC_AVPCARM7R		15
+#define TEGRA124_MC_DISPLAYHC		16
+#define TEGRA124_MC_DISPLAYHCB		17
+#define TEGRA124_MC_HDAR		21
+#define TEGRA124_MC_HOST1XDMAR		22
+#define TEGRA124_MC_HOST1XR		23
+#define TEGRA124_MC_MSENCSRD		28
+#define TEGRA124_MC_PPCSAHBDMAR		29
+#define TEGRA124_MC_PPCSAHBSLVR		30
+#define TEGRA124_MC_SATAR		31
+#define TEGRA124_MC_VDEBSEVR		34
+#define TEGRA124_MC_VDEMBER		35
+#define TEGRA124_MC_VDEMCER		36
+#define TEGRA124_MC_VDETPER		37
+#define TEGRA124_MC_MPCORELPR		38
+#define TEGRA124_MC_MPCORER		39
+#define TEGRA124_MC_MSENCSWR		43
+#define TEGRA124_MC_AFIW		49
+#define TEGRA124_MC_AVPCARM7W		50
+#define TEGRA124_MC_HDAW		53
+#define TEGRA124_MC_HOST1XW		54
+#define TEGRA124_MC_MPCORELPW		56
+#define TEGRA124_MC_MPCOREW		57
+#define TEGRA124_MC_PPCSAHBDMAW		59
+#define TEGRA124_MC_PPCSAHBSLVW		60
+#define TEGRA124_MC_SATAW		61
+#define TEGRA124_MC_VDEBSEVW		62
+#define TEGRA124_MC_VDEDBGW		63
+#define TEGRA124_MC_VDEMBEW		64
+#define TEGRA124_MC_VDETPMW		65
+#define TEGRA124_MC_ISPRA		68
+#define TEGRA124_MC_ISPWA		70
+#define TEGRA124_MC_ISPWB		71
+#define TEGRA124_MC_XUSB_HOSTR		74
+#define TEGRA124_MC_XUSB_HOSTW		75
+#define TEGRA124_MC_XUSB_DEVR		76
+#define TEGRA124_MC_XUSB_DEVW		77
+#define TEGRA124_MC_ISPRAB		78
+#define TEGRA124_MC_ISPWAB		80
+#define TEGRA124_MC_ISPWBB		81
+#define TEGRA124_MC_TSECSRD		84
+#define TEGRA124_MC_TSECSWR		85
+#define TEGRA124_MC_A9AVPSCR		86
+#define TEGRA124_MC_A9AVPSCW		87
+#define TEGRA124_MC_GPUSRD		88
+#define TEGRA124_MC_GPUSWR		89
+#define TEGRA124_MC_DISPLAYT		90
+#define TEGRA124_MC_SDMMCRA		96
+#define TEGRA124_MC_SDMMCRAA		97
+#define TEGRA124_MC_SDMMCR		98
+#define TEGRA124_MC_SDMMCRAB		99
+#define TEGRA124_MC_SDMMCWA		100
+#define TEGRA124_MC_SDMMCWAA		101
+#define TEGRA124_MC_SDMMCW		102
+#define TEGRA124_MC_SDMMCWAB		103
+#define TEGRA124_MC_VICSRD		108
+#define TEGRA124_MC_VICSWR		109
+#define TEGRA124_MC_VIW			114
+#define TEGRA124_MC_DISPLAYD		115
+
 #endif
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 20/52] ARM: tegra: Correct EMC registers size in Tegra20 device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

The Tegra20 EMC registers size should be twice bigger. This patch fixes
the size.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 72a4211a618f..9347f7789245 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -634,7 +634,7 @@ mc: memory-controller@7000f000 {
 
 	memory-controller@7000f400 {
 		compatible = "nvidia,tegra20-emc";
-		reg = <0x7000f400 0x200>;
+		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		#address-cells = <1>;
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 20/52] ARM: tegra: Correct EMC registers size in Tegra20 device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

The Tegra20 EMC registers size should be twice bigger. This patch fixes
the size.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 72a4211a618f..9347f7789245 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -634,7 +634,7 @@ mc: memory-controller@7000f000 {
 
 	memory-controller@7000f400 {
 		compatible = "nvidia,tegra20-emc";
-		reg = <0x7000f400 0x200>;
+		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		#address-cells = <1>;
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 21/52] ARM: tegra: Add interconnect properties to Tegra20 device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Add interconnect properties to the Memory Controller, External Memory
Controller and the Display Controller nodes in order to describe hardware
interconnection.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 9347f7789245..2e1304493f7d 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -111,6 +111,17 @@ dc@54200000 {
 
 			nvidia,head = <0>;
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
+					<&mc TEGRA20_MC_DISPLAY0B &emc>,
+					<&mc TEGRA20_MC_DISPLAY1B &emc>,
+					<&mc TEGRA20_MC_DISPLAY0C &emc>,
+					<&mc TEGRA20_MC_DISPLAYHC &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -128,6 +139,17 @@ dc@54240000 {
 
 			nvidia,head = <1>;
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA20_MC_DISPLAY1BB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA20_MC_DISPLAYHCB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -630,15 +652,17 @@ mc: memory-controller@7000f000 {
 		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 		#reset-cells = <1>;
 		#iommu-cells = <0>;
+		#interconnect-cells = <1>;
 	};
 
-	memory-controller@7000f400 {
+	emc: memory-controller@7000f400 {
 		compatible = "nvidia,tegra20-emc";
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		#interconnect-cells = <0>;
 	};
 
 	fuse@7000f800 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 21/52] ARM: tegra: Add interconnect properties to Tegra20 device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Add interconnect properties to the Memory Controller, External Memory
Controller and the Display Controller nodes in order to describe hardware
interconnection.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 9347f7789245..2e1304493f7d 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -111,6 +111,17 @@ dc@54200000 {
 
 			nvidia,head = <0>;
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
+					<&mc TEGRA20_MC_DISPLAY0B &emc>,
+					<&mc TEGRA20_MC_DISPLAY1B &emc>,
+					<&mc TEGRA20_MC_DISPLAY0C &emc>,
+					<&mc TEGRA20_MC_DISPLAYHC &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -128,6 +139,17 @@ dc@54240000 {
 
 			nvidia,head = <1>;
 
+			interconnects = <&mc TEGRA20_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA20_MC_DISPLAY1BB &emc>,
+					<&mc TEGRA20_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA20_MC_DISPLAYHCB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -630,15 +652,17 @@ mc: memory-controller@7000f000 {
 		interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
 		#reset-cells = <1>;
 		#iommu-cells = <0>;
+		#interconnect-cells = <1>;
 	};
 
-	memory-controller@7000f400 {
+	emc: memory-controller@7000f400 {
 		compatible = "nvidia,tegra20-emc";
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
 		#address-cells = <1>;
 		#size-cells = <0>;
+		#interconnect-cells = <0>;
 	};
 
 	fuse@7000f800 {
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 22/52] ARM: tegra: Add interconnect properties to Tegra30 device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Add interconnect properties to the Memory Controller, External Memory
Controller and the Display Controller nodes in order to describe hardware
interconnection.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra30.dtsi | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index aeae8c092d41..2caf6cc6f4b1 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -210,6 +210,17 @@ dc@54200000 {
 
 			nvidia,head = <0>;
 
+			interconnects = <&mc TEGRA30_MC_DISPLAY0A &emc>,
+					<&mc TEGRA30_MC_DISPLAY0B &emc>,
+					<&mc TEGRA30_MC_DISPLAY1B &emc>,
+					<&mc TEGRA30_MC_DISPLAY0C &emc>,
+					<&mc TEGRA30_MC_DISPLAYHC &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -229,6 +240,17 @@ dc@54240000 {
 
 			nvidia,head = <1>;
 
+			interconnects = <&mc TEGRA30_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA30_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA30_MC_DISPLAY1BB &emc>,
+					<&mc TEGRA30_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA30_MC_DISPLAYHCB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -748,15 +770,18 @@ mc: memory-controller@7000f000 {
 
 		#iommu-cells = <1>;
 		#reset-cells = <1>;
+		#interconnect-cells = <1>;
 	};
 
-	memory-controller@7000f400 {
+	emc: memory-controller@7000f400 {
 		compatible = "nvidia,tegra30-emc";
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_EMC>;
 
 		nvidia,memory-controller = <&mc>;
+
+		#interconnect-cells = <0>;
 	};
 
 	fuse@7000f800 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 22/52] ARM: tegra: Add interconnect properties to Tegra30 device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Add interconnect properties to the Memory Controller, External Memory
Controller and the Display Controller nodes in order to describe hardware
interconnection.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra30.dtsi | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index aeae8c092d41..2caf6cc6f4b1 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -210,6 +210,17 @@ dc@54200000 {
 
 			nvidia,head = <0>;
 
+			interconnects = <&mc TEGRA30_MC_DISPLAY0A &emc>,
+					<&mc TEGRA30_MC_DISPLAY0B &emc>,
+					<&mc TEGRA30_MC_DISPLAY1B &emc>,
+					<&mc TEGRA30_MC_DISPLAY0C &emc>,
+					<&mc TEGRA30_MC_DISPLAYHC &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -229,6 +240,17 @@ dc@54240000 {
 
 			nvidia,head = <1>;
 
+			interconnects = <&mc TEGRA30_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA30_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA30_MC_DISPLAY1BB &emc>,
+					<&mc TEGRA30_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA30_MC_DISPLAYHCB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winb-vfilter",
+					     "winc",
+					     "cursor";
+
 			rgb {
 				status = "disabled";
 			};
@@ -748,15 +770,18 @@ mc: memory-controller@7000f000 {
 
 		#iommu-cells = <1>;
 		#reset-cells = <1>;
+		#interconnect-cells = <1>;
 	};
 
-	memory-controller@7000f400 {
+	emc: memory-controller@7000f400 {
 		compatible = "nvidia,tegra30-emc";
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA30_CLK_EMC>;
 
 		nvidia,memory-controller = <&mc>;
+
+		#interconnect-cells = <0>;
 	};
 
 	fuse@7000f800 {
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 23/52] ARM: tegra: Add interconnect properties to Tegra124 device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Add interconnect properties to the Memory Controller, External Memory
Controller and the Display Controller nodes in order to describe hardware
interconnection.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra124.dtsi | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 64f488ba1e72..1801e30b1d3a 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -113,6 +113,19 @@ dc@54200000 {
 			iommus = <&mc TEGRA_SWGROUP_DC>;
 
 			nvidia,head = <0>;
+
+			interconnects = <&mc TEGRA124_MC_DISPLAY0A &emc>,
+					<&mc TEGRA124_MC_DISPLAY0B &emc>,
+					<&mc TEGRA124_MC_DISPLAY0C &emc>,
+					<&mc TEGRA124_MC_DISPLAYHC &emc>,
+					<&mc TEGRA124_MC_DISPLAYD &emc>,
+					<&mc TEGRA124_MC_DISPLAYT &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor",
+					     "wind",
+					     "wint";
 		};
 
 		dc@54240000 {
@@ -127,6 +140,15 @@ dc@54240000 {
 			iommus = <&mc TEGRA_SWGROUP_DCB>;
 
 			nvidia,head = <1>;
+
+			interconnects = <&mc TEGRA124_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA124_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA124_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA124_MC_DISPLAYHCB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor";
 		};
 
 		hdmi: hdmi@54280000 {
@@ -628,6 +650,7 @@ mc: memory-controller@70019000 {
 
 		#iommu-cells = <1>;
 		#reset-cells = <1>;
+		#interconnect-cells = <1>;
 	};
 
 	emc: external-memory-controller@7001b000 {
@@ -637,6 +660,8 @@ emc: external-memory-controller@7001b000 {
 		clock-names = "emc";
 
 		nvidia,memory-controller = <&mc>;
+
+		#interconnect-cells = <0>;
 	};
 
 	sata@70020000 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 23/52] ARM: tegra: Add interconnect properties to Tegra124 device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Add interconnect properties to the Memory Controller, External Memory
Controller and the Display Controller nodes in order to describe hardware
interconnection.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra124.dtsi | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 64f488ba1e72..1801e30b1d3a 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -113,6 +113,19 @@ dc@54200000 {
 			iommus = <&mc TEGRA_SWGROUP_DC>;
 
 			nvidia,head = <0>;
+
+			interconnects = <&mc TEGRA124_MC_DISPLAY0A &emc>,
+					<&mc TEGRA124_MC_DISPLAY0B &emc>,
+					<&mc TEGRA124_MC_DISPLAY0C &emc>,
+					<&mc TEGRA124_MC_DISPLAYHC &emc>,
+					<&mc TEGRA124_MC_DISPLAYD &emc>,
+					<&mc TEGRA124_MC_DISPLAYT &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor",
+					     "wind",
+					     "wint";
 		};
 
 		dc@54240000 {
@@ -127,6 +140,15 @@ dc@54240000 {
 			iommus = <&mc TEGRA_SWGROUP_DCB>;
 
 			nvidia,head = <1>;
+
+			interconnects = <&mc TEGRA124_MC_DISPLAY0AB &emc>,
+					<&mc TEGRA124_MC_DISPLAY0BB &emc>,
+					<&mc TEGRA124_MC_DISPLAY0CB &emc>,
+					<&mc TEGRA124_MC_DISPLAYHCB &emc>;
+			interconnect-names = "wina",
+					     "winb",
+					     "winc",
+					     "cursor";
 		};
 
 		hdmi: hdmi@54280000 {
@@ -628,6 +650,7 @@ mc: memory-controller@70019000 {
 
 		#iommu-cells = <1>;
 		#reset-cells = <1>;
+		#interconnect-cells = <1>;
 	};
 
 	emc: external-memory-controller@7001b000 {
@@ -637,6 +660,8 @@ emc: external-memory-controller@7001b000 {
 		clock-names = "emc";
 
 		nvidia,memory-controller = <&mc>;
+
+		#interconnect-cells = <0>;
 	};
 
 	sata@70020000 {
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 24/52] ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Add nvidia,memory-controller to the Tegra20 External Memory Controller
node. This allows to perform a direct lookup of the Memory Controller
instead of walking up the whole tree. This puts Tegra20 device-tree on
par with Tegra30+.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 2e1304493f7d..8f8ad81916e7 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -663,6 +663,8 @@ emc: memory-controller@7000f400 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interconnect-cells = <0>;
+
+		nvidia,memory-controller = <&mc>;
 	};
 
 	fuse@7000f800 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 24/52] ARM: tegra: Add nvidia, memory-controller phandle to Tegra20 EMC device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Add nvidia,memory-controller to the Tegra20 External Memory Controller
node. This allows to perform a direct lookup of the Memory Controller
instead of walking up the whole tree. This puts Tegra20 device-tree on
par with Tegra30+.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra20.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 2e1304493f7d..8f8ad81916e7 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -663,6 +663,8 @@ emc: memory-controller@7000f400 {
 		#address-cells = <1>;
 		#size-cells = <0>;
 		#interconnect-cells = <0>;
+
+		nvidia,memory-controller = <&mc>;
 	};
 
 	fuse@7000f800 {
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 25/52] ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Add EMC OPP DVFS/DFS tables and emc-stats subdev that will be used for
dynamic memory bandwidth scaling, while EMC itself will perform voltage
scaling. Update board device-trees with optional EMC core supply and
remove unsupported OPPs.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../boot/dts/tegra20-acer-a500-picasso.dts    |  12 ++
 arch/arm/boot/dts/tegra20-colibri.dtsi        |   8 +
 arch/arm/boot/dts/tegra20-paz00.dts           |  10 +
 .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 181 ++++++++++++++++++
 arch/arm/boot/dts/tegra20.dtsi                |  12 +-
 5 files changed, 222 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/tegra20-peripherals-opp.dtsi

diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
index a0b829738e8f..f5c1591c8ea8 100644
--- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
+++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
@@ -1058,9 +1058,21 @@ map0 {
 		};
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@666000000;
+		/delete-node/ opp@760000000;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@666000000;
+		/delete-node/ opp@760000000;
+	};
+
 	memory-controller@7000f400 {
 		nvidia,use-ram-code;
 
+		core-supply = <&vdd_core>;
+
 		emc-tables@0 {
 			nvidia,ram-code = <0>; /* elpida-8gb */
 
diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi
index 6162d193e12c..78a2210bf9ae 100644
--- a/arch/arm/boot/dts/tegra20-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra20-colibri.dtsi
@@ -611,6 +611,14 @@ i2c-thermtrip {
 		};
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@760000000;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@760000000;
+	};
+
 	memory-controller@7000f400 {
 		emc-table@83250 {
 			reg = <83250>;
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
index ada2bed8b1b5..7b9f0f279744 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -311,9 +311,19 @@ nvec@7000c500 {
 		reset-names = "i2c";
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@760000000;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@760000000;
+	};
+
 	memory-controller@7000f400 {
 		nvidia,use-ram-code;
 
+		core-supply = <&core_vdd_reg>;
+
 		emc-tables@0 {
 			nvidia,ram-code = <0x0>;
 			#address-cells = <1>;
diff --git a/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
new file mode 100644
index 000000000000..d10c61107702
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <36000000>;
+		};
+
+		opp@47500000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <47500000>;
+		};
+
+		opp@50000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <50000000>;
+		};
+
+		opp@54000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <54000000>;
+		};
+
+		opp@57000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <57000000>;
+		};
+
+		opp@100000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <100000000>;
+		};
+
+		opp@108000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <108000000>;
+		};
+
+		opp@126666000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <126666000>;
+		};
+
+		opp@150000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <150000000>;
+		};
+
+		opp@190000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <190000000>;
+		};
+
+		opp@216000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <216000000>;
+		};
+
+		opp@300000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+		};
+
+		opp@333000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <333000000>;
+		};
+
+		opp@380000000 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <380000000>;
+		};
+
+		opp@600000000 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <600000000>;
+		};
+
+		opp@666000000 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <666000000>;
+		};
+
+		opp@760000000 {
+			opp-microvolt = <1300000 1300000 1300000>;
+			opp-hz = /bits/ 64 <760000000>;
+		};
+	};
+
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-hz = /bits/ 64 <36000000>;
+			opp-peak-kBps = <144000>;
+		};
+
+		opp@47500000 {
+			opp-hz = /bits/ 64 <47500000>;
+			opp-peak-kBps = <190000>;
+		};
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+			opp-peak-kBps = <200000>;
+		};
+
+		opp@54000000 {
+			opp-hz = /bits/ 64 <54000000>;
+			opp-peak-kBps = <216000>;
+		};
+
+		opp@57000000 {
+			opp-hz = /bits/ 64 <57000000>;
+			opp-peak-kBps = <228000>;
+		};
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-peak-kBps = <400000>;
+		};
+
+		opp@108000000 {
+			opp-hz = /bits/ 64 <108000000>;
+			opp-peak-kBps = <432000>;
+		};
+
+		opp@126666000 {
+			opp-hz = /bits/ 64 <126666000>;
+			opp-peak-kBps = <506664>;
+		};
+
+		opp@150000000 {
+			opp-hz = /bits/ 64 <150000000>;
+			opp-peak-kBps = <600000>;
+		};
+
+		opp@190000000 {
+			opp-hz = /bits/ 64 <190000000>;
+			opp-peak-kBps = <760000>;
+		};
+
+		opp@216000000 {
+			opp-hz = /bits/ 64 <216000000>;
+			opp-peak-kBps = <864000>;
+		};
+
+		opp@300000000 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-peak-kBps = <1200000>;
+		};
+
+		opp@333000000 {
+			opp-hz = /bits/ 64 <333000000>;
+			opp-peak-kBps = <1332000>;
+		};
+
+		opp@380000000 {
+			opp-hz = /bits/ 64 <380000000>;
+			opp-peak-kBps = <1520000>;
+		};
+
+		opp@600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-peak-kBps = <2400000>;
+		};
+
+		opp@666000000 {
+			opp-hz = /bits/ 64 <666000000>;
+			opp-peak-kBps = <2664000>;
+		};
+
+		opp@760000000 {
+			opp-hz = /bits/ 64 <760000000>;
+			opp-peak-kBps = <3040000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 8f8ad81916e7..8a90d96c8773 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -6,6 +6,8 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/soc/tegra-pmc.h>
 
+#include "tegra20-peripherals-opp.dtsi"
+
 / {
 	compatible = "nvidia,tegra20";
 	interrupt-parent = <&lic>;
@@ -656,7 +658,7 @@ mc: memory-controller@7000f000 {
 	};
 
 	emc: memory-controller@7000f400 {
-		compatible = "nvidia,tegra20-emc";
+		compatible = "nvidia,tegra20-emc", "simple-mfd";
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
@@ -664,7 +666,15 @@ emc: memory-controller@7000f400 {
 		#size-cells = <0>;
 		#interconnect-cells = <0>;
 
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 		nvidia,memory-controller = <&mc>;
+
+		emc-stats {
+			compatible = "nvidia,tegra20-emc-statistics";
+			operating-points-v2 = <&emc_bw_dfs_opp_table>;
+			interconnects = <&mc TEGRA20_MC_MPCORER &emc>;
+			interconnect-names = "cpu-read";
+		};
 	};
 
 	fuse@7000f800 {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 25/52] ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Add EMC OPP DVFS/DFS tables and emc-stats subdev that will be used for
dynamic memory bandwidth scaling, while EMC itself will perform voltage
scaling. Update board device-trees with optional EMC core supply and
remove unsupported OPPs.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../boot/dts/tegra20-acer-a500-picasso.dts    |  12 ++
 arch/arm/boot/dts/tegra20-colibri.dtsi        |   8 +
 arch/arm/boot/dts/tegra20-paz00.dts           |  10 +
 .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 181 ++++++++++++++++++
 arch/arm/boot/dts/tegra20.dtsi                |  12 +-
 5 files changed, 222 insertions(+), 1 deletion(-)
 create mode 100644 arch/arm/boot/dts/tegra20-peripherals-opp.dtsi

diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
index a0b829738e8f..f5c1591c8ea8 100644
--- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
+++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
@@ -1058,9 +1058,21 @@ map0 {
 		};
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@666000000;
+		/delete-node/ opp@760000000;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@666000000;
+		/delete-node/ opp@760000000;
+	};
+
 	memory-controller@7000f400 {
 		nvidia,use-ram-code;
 
+		core-supply = <&vdd_core>;
+
 		emc-tables@0 {
 			nvidia,ram-code = <0>; /* elpida-8gb */
 
diff --git a/arch/arm/boot/dts/tegra20-colibri.dtsi b/arch/arm/boot/dts/tegra20-colibri.dtsi
index 6162d193e12c..78a2210bf9ae 100644
--- a/arch/arm/boot/dts/tegra20-colibri.dtsi
+++ b/arch/arm/boot/dts/tegra20-colibri.dtsi
@@ -611,6 +611,14 @@ i2c-thermtrip {
 		};
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@760000000;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@760000000;
+	};
+
 	memory-controller@7000f400 {
 		emc-table@83250 {
 			reg = <83250>;
diff --git a/arch/arm/boot/dts/tegra20-paz00.dts b/arch/arm/boot/dts/tegra20-paz00.dts
index ada2bed8b1b5..7b9f0f279744 100644
--- a/arch/arm/boot/dts/tegra20-paz00.dts
+++ b/arch/arm/boot/dts/tegra20-paz00.dts
@@ -311,9 +311,19 @@ nvec@7000c500 {
 		reset-names = "i2c";
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@760000000;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@760000000;
+	};
+
 	memory-controller@7000f400 {
 		nvidia,use-ram-code;
 
+		core-supply = <&core_vdd_reg>;
+
 		emc-tables@0 {
 			nvidia,ram-code = <0x0>;
 			#address-cells = <1>;
diff --git a/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
new file mode 100644
index 000000000000..d10c61107702
--- /dev/null
+++ b/arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <36000000>;
+		};
+
+		opp@47500000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <47500000>;
+		};
+
+		opp@50000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <50000000>;
+		};
+
+		opp@54000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <54000000>;
+		};
+
+		opp@57000000 {
+			opp-microvolt = <950000 950000 1300000>;
+			opp-hz = /bits/ 64 <57000000>;
+		};
+
+		opp@100000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <100000000>;
+		};
+
+		opp@108000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <108000000>;
+		};
+
+		opp@126666000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <126666000>;
+		};
+
+		opp@150000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <150000000>;
+		};
+
+		opp@190000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <190000000>;
+		};
+
+		opp@216000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <216000000>;
+		};
+
+		opp@300000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <300000000>;
+		};
+
+		opp@333000000 {
+			opp-microvolt = <1000000 1000000 1300000>;
+			opp-hz = /bits/ 64 <333000000>;
+		};
+
+		opp@380000000 {
+			opp-microvolt = <1100000 1100000 1300000>;
+			opp-hz = /bits/ 64 <380000000>;
+		};
+
+		opp@600000000 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <600000000>;
+		};
+
+		opp@666000000 {
+			opp-microvolt = <1200000 1200000 1300000>;
+			opp-hz = /bits/ 64 <666000000>;
+		};
+
+		opp@760000000 {
+			opp-microvolt = <1300000 1300000 1300000>;
+			opp-hz = /bits/ 64 <760000000>;
+		};
+	};
+
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@36000000 {
+			opp-hz = /bits/ 64 <36000000>;
+			opp-peak-kBps = <144000>;
+		};
+
+		opp@47500000 {
+			opp-hz = /bits/ 64 <47500000>;
+			opp-peak-kBps = <190000>;
+		};
+
+		opp@50000000 {
+			opp-hz = /bits/ 64 <50000000>;
+			opp-peak-kBps = <200000>;
+		};
+
+		opp@54000000 {
+			opp-hz = /bits/ 64 <54000000>;
+			opp-peak-kBps = <216000>;
+		};
+
+		opp@57000000 {
+			opp-hz = /bits/ 64 <57000000>;
+			opp-peak-kBps = <228000>;
+		};
+
+		opp@100000000 {
+			opp-hz = /bits/ 64 <100000000>;
+			opp-peak-kBps = <400000>;
+		};
+
+		opp@108000000 {
+			opp-hz = /bits/ 64 <108000000>;
+			opp-peak-kBps = <432000>;
+		};
+
+		opp@126666000 {
+			opp-hz = /bits/ 64 <126666000>;
+			opp-peak-kBps = <506664>;
+		};
+
+		opp@150000000 {
+			opp-hz = /bits/ 64 <150000000>;
+			opp-peak-kBps = <600000>;
+		};
+
+		opp@190000000 {
+			opp-hz = /bits/ 64 <190000000>;
+			opp-peak-kBps = <760000>;
+		};
+
+		opp@216000000 {
+			opp-hz = /bits/ 64 <216000000>;
+			opp-peak-kBps = <864000>;
+		};
+
+		opp@300000000 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-peak-kBps = <1200000>;
+		};
+
+		opp@333000000 {
+			opp-hz = /bits/ 64 <333000000>;
+			opp-peak-kBps = <1332000>;
+		};
+
+		opp@380000000 {
+			opp-hz = /bits/ 64 <380000000>;
+			opp-peak-kBps = <1520000>;
+		};
+
+		opp@600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-peak-kBps = <2400000>;
+		};
+
+		opp@666000000 {
+			opp-hz = /bits/ 64 <666000000>;
+			opp-peak-kBps = <2664000>;
+		};
+
+		opp@760000000 {
+			opp-hz = /bits/ 64 <760000000>;
+			opp-peak-kBps = <3040000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 8f8ad81916e7..8a90d96c8773 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -6,6 +6,8 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/soc/tegra-pmc.h>
 
+#include "tegra20-peripherals-opp.dtsi"
+
 / {
 	compatible = "nvidia,tegra20";
 	interrupt-parent = <&lic>;
@@ -656,7 +658,7 @@ mc: memory-controller@7000f000 {
 	};
 
 	emc: memory-controller@7000f400 {
-		compatible = "nvidia,tegra20-emc";
+		compatible = "nvidia,tegra20-emc", "simple-mfd";
 		reg = <0x7000f400 0x400>;
 		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
 		clocks = <&tegra_car TEGRA20_CLK_EMC>;
@@ -664,7 +666,15 @@ emc: memory-controller@7000f400 {
 		#size-cells = <0>;
 		#interconnect-cells = <0>;
 
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 		nvidia,memory-controller = <&mc>;
+
+		emc-stats {
+			compatible = "nvidia,tegra20-emc-statistics";
+			operating-points-v2 = <&emc_bw_dfs_opp_table>;
+			interconnects = <&mc TEGRA20_MC_MPCORER &emc>;
+			interconnect-names = "cpu-read";
+		};
 	};
 
 	fuse@7000f800 {
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 26/52] ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Add EMC OPP DVFS/DFS tables and interconnect paths that will be used for
dynamic memory bandwidth scaling based on memory utilization statistics.
Update board device-trees with optional EMC core supply and remove
unsupported OPPs.

Note that ACTMON watches all memory interconnect paths, but we use a
single CPU-READ interconnect path for driving memory bandwidth, for
simplicity.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../tegra30-asus-nexus7-grouper-common.dtsi   |  16 +
 .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 383 ++++++++++++++++++
 arch/arm/boot/dts/tegra30.dtsi                |   6 +
 3 files changed, 405 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra30-peripherals-opp.dtsi

diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
index 88ca03f57b3b..8758bd39e0db 100644
--- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
+++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
@@ -956,6 +956,22 @@ pmc@7000e400 {
 		nvidia,sys-clock-req-active-high;
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@750000000,1300;
+		/delete-node/ opp@800000000,1300;
+		/delete-node/ opp@900000000,1350;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@750000000;
+		/delete-node/ opp@800000000;
+		/delete-node/ opp@900000000;
+	};
+
+	memory-controller@7000f400 {
+		core-supply = <&vdd_core>;
+	};
+
 	ahub@70080000 {
 		i2s@70080400 {
 			status = "okay";
diff --git a/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
new file mode 100644
index 000000000000..a6e171f65f6c
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@12750000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@12750000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@12750000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@25500000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@25500000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@25500000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@27000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@27000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@27000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@51000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@51000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@51000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@54000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@54000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@54000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@102000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@102000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@102000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@108000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <108000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@108000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <108000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@204000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@204000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@333500000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@333500000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@333500000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@375000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@375000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@375000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@400000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@400000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@400000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@416000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@450000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <450000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@450000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <450000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@533000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@533000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@625000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <625000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@625000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <625000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@667000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <667000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@750000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <750000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@800000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@900000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <900000000>;
+			opp-supported-hw = <0x0004>;
+		};
+	};
+
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@12750000 {
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <102000>;
+		};
+
+		opp@25500000 {
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <204000>;
+		};
+
+		opp@27000000 {
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <216000>;
+		};
+
+		opp@51000000 {
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <408000>;
+		};
+
+		opp@54000000 {
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <432000>;
+		};
+
+		opp@102000000 {
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <816000>;
+		};
+
+		opp@108000000 {
+			opp-hz = /bits/ 64 <108000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <864000>;
+		};
+
+		opp@204000000 {
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <1632000>;
+		};
+
+		opp@333500000 {
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <2668000>;
+		};
+
+		opp@375000000 {
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3000000>;
+		};
+
+		opp@400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3200000>;
+		};
+
+		opp@416000000 {
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3328000>;
+		};
+
+		opp@450000000 {
+			opp-hz = /bits/ 64 <450000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3600000>;
+		};
+
+		opp@533000000 {
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <4264000>;
+		};
+
+		opp@625000000 {
+			opp-hz = /bits/ 64 <625000000>;
+			opp-supported-hw = <0x000E>;
+			opp-peak-kBps = <5000000>;
+		};
+
+		opp@667000000 {
+			opp-hz = /bits/ 64 <667000000>;
+			opp-supported-hw = <0x0006>;
+			opp-peak-kBps = <5336000>;
+		};
+
+		opp@750000000 {
+			opp-hz = /bits/ 64 <750000000>;
+			opp-supported-hw = <0x0004>;
+			opp-peak-kBps = <6000000>;
+		};
+
+		opp@800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x0004>;
+			opp-peak-kBps = <6400000>;
+		};
+
+		opp@900000000 {
+			opp-hz = /bits/ 64 <900000000>;
+			opp-supported-hw = <0x0004>;
+			opp-peak-kBps = <7200000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 2caf6cc6f4b1..44a6dbba7081 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -6,6 +6,8 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/soc/tegra-pmc.h>
 
+#include "tegra30-peripherals-opp.dtsi"
+
 / {
 	compatible = "nvidia,tegra30";
 	interrupt-parent = <&lic>;
@@ -417,6 +419,9 @@ actmon@6000c800 {
 		clock-names = "actmon", "emc";
 		resets = <&tegra_car TEGRA30_CLK_ACTMON>;
 		reset-names = "actmon";
+		operating-points-v2 = <&emc_bw_dfs_opp_table>;
+		interconnects = <&mc TEGRA30_MC_MPCORER &emc>;
+		interconnect-names = "cpu-read";
 	};
 
 	gpio: gpio@6000d000 {
@@ -780,6 +785,7 @@ emc: memory-controller@7000f400 {
 		clocks = <&tegra_car TEGRA30_CLK_EMC>;
 
 		nvidia,memory-controller = <&mc>;
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 
 		#interconnect-cells = <0>;
 	};
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 26/52] ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Add EMC OPP DVFS/DFS tables and interconnect paths that will be used for
dynamic memory bandwidth scaling based on memory utilization statistics.
Update board device-trees with optional EMC core supply and remove
unsupported OPPs.

Note that ACTMON watches all memory interconnect paths, but we use a
single CPU-READ interconnect path for driving memory bandwidth, for
simplicity.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 .../tegra30-asus-nexus7-grouper-common.dtsi   |  16 +
 .../arm/boot/dts/tegra30-peripherals-opp.dtsi | 383 ++++++++++++++++++
 arch/arm/boot/dts/tegra30.dtsi                |   6 +
 3 files changed, 405 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra30-peripherals-opp.dtsi

diff --git a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
index 88ca03f57b3b..8758bd39e0db 100644
--- a/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
+++ b/arch/arm/boot/dts/tegra30-asus-nexus7-grouper-common.dtsi
@@ -956,6 +956,22 @@ pmc@7000e400 {
 		nvidia,sys-clock-req-active-high;
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@750000000,1300;
+		/delete-node/ opp@800000000,1300;
+		/delete-node/ opp@900000000,1350;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@750000000;
+		/delete-node/ opp@800000000;
+		/delete-node/ opp@900000000;
+	};
+
+	memory-controller@7000f400 {
+		core-supply = <&vdd_core>;
+	};
+
 	ahub@70080000 {
 		i2s@70080400 {
 			status = "okay";
diff --git a/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
new file mode 100644
index 000000000000..a6e171f65f6c
--- /dev/null
+++ b/arch/arm/boot/dts/tegra30-peripherals-opp.dtsi
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@12750000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@12750000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@12750000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@25500000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@25500000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@25500000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@27000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@27000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@27000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@51000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@51000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@51000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@54000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@54000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@54000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@102000000,950 {
+			opp-microvolt = <950000 950000 1350000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@102000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@102000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@108000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <108000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@108000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <108000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@204000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@204000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@333500000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@333500000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@333500000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@375000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@375000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@375000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@400000000,1000 {
+			opp-microvolt = <1000000 1000000 1350000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@400000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0001>;
+		};
+
+		opp@400000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@416000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@416000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@450000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <450000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@450000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <450000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@533000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x0007>;
+		};
+
+		opp@533000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@625000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <625000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@625000000,1250 {
+			opp-microvolt = <1250000 1250000 1350000>;
+			opp-hz = /bits/ 64 <625000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@667000000,1200 {
+			opp-microvolt = <1200000 1200000 1350000>;
+			opp-hz = /bits/ 64 <667000000>;
+			opp-supported-hw = <0x0006>;
+		};
+
+		opp@750000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <750000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@800000000,1300 {
+			opp-microvolt = <1300000 1300000 1350000>;
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@900000000,1350 {
+			opp-microvolt = <1350000 1350000 1350000>;
+			opp-hz = /bits/ 64 <900000000>;
+			opp-supported-hw = <0x0004>;
+		};
+	};
+
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@12750000 {
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <102000>;
+		};
+
+		opp@25500000 {
+			opp-hz = /bits/ 64 <25500000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <204000>;
+		};
+
+		opp@27000000 {
+			opp-hz = /bits/ 64 <27000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <216000>;
+		};
+
+		opp@51000000 {
+			opp-hz = /bits/ 64 <51000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <408000>;
+		};
+
+		opp@54000000 {
+			opp-hz = /bits/ 64 <54000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <432000>;
+		};
+
+		opp@102000000 {
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <816000>;
+		};
+
+		opp@108000000 {
+			opp-hz = /bits/ 64 <108000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <864000>;
+		};
+
+		opp@204000000 {
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <1632000>;
+		};
+
+		opp@333500000 {
+			opp-hz = /bits/ 64 <333500000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <2668000>;
+		};
+
+		opp@375000000 {
+			opp-hz = /bits/ 64 <375000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3000000>;
+		};
+
+		opp@400000000 {
+			opp-hz = /bits/ 64 <400000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3200000>;
+		};
+
+		opp@416000000 {
+			opp-hz = /bits/ 64 <416000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3328000>;
+		};
+
+		opp@450000000 {
+			opp-hz = /bits/ 64 <450000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <3600000>;
+		};
+
+		opp@533000000 {
+			opp-hz = /bits/ 64 <533000000>;
+			opp-supported-hw = <0x000F>;
+			opp-peak-kBps = <4264000>;
+		};
+
+		opp@625000000 {
+			opp-hz = /bits/ 64 <625000000>;
+			opp-supported-hw = <0x000E>;
+			opp-peak-kBps = <5000000>;
+		};
+
+		opp@667000000 {
+			opp-hz = /bits/ 64 <667000000>;
+			opp-supported-hw = <0x0006>;
+			opp-peak-kBps = <5336000>;
+		};
+
+		opp@750000000 {
+			opp-hz = /bits/ 64 <750000000>;
+			opp-supported-hw = <0x0004>;
+			opp-peak-kBps = <6000000>;
+		};
+
+		opp@800000000 {
+			opp-hz = /bits/ 64 <800000000>;
+			opp-supported-hw = <0x0004>;
+			opp-peak-kBps = <6400000>;
+		};
+
+		opp@900000000 {
+			opp-hz = /bits/ 64 <900000000>;
+			opp-supported-hw = <0x0004>;
+			opp-peak-kBps = <7200000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index 2caf6cc6f4b1..44a6dbba7081 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -6,6 +6,8 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/soc/tegra-pmc.h>
 
+#include "tegra30-peripherals-opp.dtsi"
+
 / {
 	compatible = "nvidia,tegra30";
 	interrupt-parent = <&lic>;
@@ -417,6 +419,9 @@ actmon@6000c800 {
 		clock-names = "actmon", "emc";
 		resets = <&tegra_car TEGRA30_CLK_ACTMON>;
 		reset-names = "actmon";
+		operating-points-v2 = <&emc_bw_dfs_opp_table>;
+		interconnects = <&mc TEGRA30_MC_MPCORER &emc>;
+		interconnect-names = "cpu-read";
 	};
 
 	gpio: gpio@6000d000 {
@@ -780,6 +785,7 @@ emc: memory-controller@7000f400 {
 		clocks = <&tegra_car TEGRA30_CLK_EMC>;
 
 		nvidia,memory-controller = <&mc>;
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 
 		#interconnect-cells = <0>;
 	};
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 27/52] ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Add EMC OPP DVFS/DFS tables and interconnect paths that will be used for
dynamic memory bandwidth scaling based on memory utilization statistics.
Remove unsupported EMC OPPs from board device-trees.

Note that ACTMON watches all memory interconnect paths, but we use a
single CPU-READ interconnect path for driving memory bandwidth, for
simplicity.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra124-apalis-emc.dtsi    |   8 +
 .../arm/boot/dts/tegra124-jetson-tk1-emc.dtsi |   8 +
 arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi  |  10 +
 .../boot/dts/tegra124-peripherals-opp.dtsi    | 419 ++++++++++++++++++
 arch/arm/boot/dts/tegra124.dtsi               |   6 +
 5 files changed, 451 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra124-peripherals-opp.dtsi

diff --git a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi
index 32401457ae71..29312cffdb3a 100644
--- a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi
+++ b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi
@@ -5,6 +5,14 @@
  */
 
 / {
+	emc_opp_table0 {
+		/delete-node/ opp@1200000000,1100;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@1200000000;
+	};
+
 	clock@60006000 {
 		emc-timings-1 {
 			nvidia,ram-code = <1>;
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
index 861d3f22116b..fc8a089cd4dd 100644
--- a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
@@ -1,5 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
 / {
+	emc_opp_table0 {
+		/delete-node/ opp@1200000000,1100;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@1200000000;
+	};
+
 	clock@60006000 {
 		emc-timings-3 {
 			nvidia,ram-code = <3>;
diff --git a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
index c91647d13a50..20c1ae284280 100644
--- a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
+++ b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
@@ -4,6 +4,16 @@ apbmisc@70000800 {
 		nvidia,long-ram-code;
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@924000000,1100;
+		/delete-node/ opp@1200000000,1100;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@924000000;
+		/delete-node/ opp@1200000000;
+	};
+
 	clock@60006000 {
 		emc-timings-1 {
 			nvidia,ram-code = <1>;
diff --git a/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi
new file mode 100644
index 000000000000..d2b4d8e9cb13
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@12750000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@12750000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@12750000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@12750000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@20400000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@20400000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@20400000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@20400000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@40800000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@40800000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@40800000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@40800000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@68000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@68000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@68000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@68000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@102000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@102000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@102000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@102000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@204000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@204000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@204000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@204000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@264000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@264000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@264000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@264000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@300000000,850 {
+			opp-microvolt = <850000 850000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@300000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@300000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@300000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@348000000,850 {
+			opp-microvolt = <850000 850000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@348000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@348000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@348000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@396000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@396000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@396000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@396000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@528000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@528000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@528000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@528000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@600000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@600000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@600000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@600000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@792000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x000B>;
+		};
+
+		opp@792000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@792000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@924000000,1100 {
+			opp-microvolt = <1100000 1100000 1150000>;
+			opp-hz = /bits/ 64 <924000000>;
+			opp-supported-hw = <0x0013>;
+		};
+
+		opp@1200000000,1100 {
+			opp-microvolt = <1100000 1100000 1150000>;
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-supported-hw = <0x0003>;
+		};
+	};
+
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@12750000 {
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <204000>;
+		};
+
+		opp@20400000 {
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <326400>;
+		};
+
+		opp@40800000 {
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <652800>;
+		};
+
+		opp@68000000 {
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <1088000>;
+		};
+
+		opp@102000000 {
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <1632000>;
+		};
+
+		opp@204000000 {
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <3264000>;
+		};
+
+		opp@264000000 {
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <4224000>;
+		};
+
+		opp@300000000 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <4800000>;
+		};
+
+		opp@348000000 {
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <5568000>;
+		};
+
+		opp@396000000 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <6336000>;
+		};
+
+		opp@528000000 {
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <8448000>;
+		};
+
+		opp@600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <9600000>;
+		};
+
+		opp@792000000 {
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <12672000>;
+		};
+
+		opp@924000000 {
+			opp-hz = /bits/ 64 <924000000>;
+			opp-supported-hw = <0x0013>;
+			opp-peak-kBps = <14784000>;
+		};
+
+		opp@1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-supported-hw = <0x0003>;
+			opp-peak-kBps = <19200000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 1801e30b1d3a..46441d10a3fc 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -8,6 +8,8 @@
 #include <dt-bindings/thermal/tegra124-soctherm.h>
 #include <dt-bindings/soc/tegra-pmc.h>
 
+#include "tegra124-peripherals-opp.dtsi"
+
 / {
 	compatible = "nvidia,tegra124";
 	interrupt-parent = <&lic>;
@@ -290,6 +292,9 @@ actmon@6000c800 {
 		clock-names = "actmon", "emc";
 		resets = <&tegra_car 119>;
 		reset-names = "actmon";
+		operating-points-v2 = <&emc_bw_dfs_opp_table>;
+		interconnects = <&mc TEGRA124_MC_MPCORER &emc>;
+		interconnect-names = "cpu-read";
 	};
 
 	gpio: gpio@6000d000 {
@@ -660,6 +665,7 @@ emc: external-memory-controller@7001b000 {
 		clock-names = "emc";
 
 		nvidia,memory-controller = <&mc>;
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 
 		#interconnect-cells = <0>;
 	};
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 27/52] ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Add EMC OPP DVFS/DFS tables and interconnect paths that will be used for
dynamic memory bandwidth scaling based on memory utilization statistics.
Remove unsupported EMC OPPs from board device-trees.

Note that ACTMON watches all memory interconnect paths, but we use a
single CPU-READ interconnect path for driving memory bandwidth, for
simplicity.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 arch/arm/boot/dts/tegra124-apalis-emc.dtsi    |   8 +
 .../arm/boot/dts/tegra124-jetson-tk1-emc.dtsi |   8 +
 arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi  |  10 +
 .../boot/dts/tegra124-peripherals-opp.dtsi    | 419 ++++++++++++++++++
 arch/arm/boot/dts/tegra124.dtsi               |   6 +
 5 files changed, 451 insertions(+)
 create mode 100644 arch/arm/boot/dts/tegra124-peripherals-opp.dtsi

diff --git a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi
index 32401457ae71..29312cffdb3a 100644
--- a/arch/arm/boot/dts/tegra124-apalis-emc.dtsi
+++ b/arch/arm/boot/dts/tegra124-apalis-emc.dtsi
@@ -5,6 +5,14 @@
  */
 
 / {
+	emc_opp_table0 {
+		/delete-node/ opp@1200000000,1100;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@1200000000;
+	};
+
 	clock@60006000 {
 		emc-timings-1 {
 			nvidia,ram-code = <1>;
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
index 861d3f22116b..fc8a089cd4dd 100644
--- a/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
@@ -1,5 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0
 / {
+	emc_opp_table0 {
+		/delete-node/ opp@1200000000,1100;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@1200000000;
+	};
+
 	clock@60006000 {
 		emc-timings-3 {
 			nvidia,ram-code = <3>;
diff --git a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
index c91647d13a50..20c1ae284280 100644
--- a/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
+++ b/arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
@@ -4,6 +4,16 @@ apbmisc@70000800 {
 		nvidia,long-ram-code;
 	};
 
+	emc_opp_table0 {
+		/delete-node/ opp@924000000,1100;
+		/delete-node/ opp@1200000000,1100;
+	};
+
+	emc_opp_table1 {
+		/delete-node/ opp@924000000;
+		/delete-node/ opp@1200000000;
+	};
+
 	clock@60006000 {
 		emc-timings-1 {
 			nvidia,ram-code = <1>;
diff --git a/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi
new file mode 100644
index 000000000000..d2b4d8e9cb13
--- /dev/null
+++ b/arch/arm/boot/dts/tegra124-peripherals-opp.dtsi
@@ -0,0 +1,419 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/ {
+	emc_icc_dvfs_opp_table: emc_opp_table0 {
+		compatible = "operating-points-v2";
+
+		opp@12750000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@12750000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@12750000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@12750000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@20400000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@20400000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@20400000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@20400000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@40800000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@40800000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@40800000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@40800000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@68000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@68000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@68000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@68000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@102000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@102000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@102000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@102000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@204000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@204000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@204000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@204000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@264000000,800 {
+			opp-microvolt = <800000 800000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@264000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@264000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@264000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@300000000,850 {
+			opp-microvolt = <850000 850000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@300000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@300000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@300000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@348000000,850 {
+			opp-microvolt = <850000 850000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@348000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@348000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@348000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@396000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@396000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@396000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@396000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@528000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@528000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@528000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@528000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@600000000,950 {
+			opp-microvolt = <950000 950000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0008>;
+		};
+
+		opp@600000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0003>;
+		};
+
+		opp@600000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@600000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@792000000,1000 {
+			opp-microvolt = <1000000 1000000 1150000>;
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x000B>;
+		};
+
+		opp@792000000,1050 {
+			opp-microvolt = <1050000 1050000 1150000>;
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x0010>;
+		};
+
+		opp@792000000,1110 {
+			opp-microvolt = <1110000 1110000 1150000>;
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x0004>;
+		};
+
+		opp@924000000,1100 {
+			opp-microvolt = <1100000 1100000 1150000>;
+			opp-hz = /bits/ 64 <924000000>;
+			opp-supported-hw = <0x0013>;
+		};
+
+		opp@1200000000,1100 {
+			opp-microvolt = <1100000 1100000 1150000>;
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-supported-hw = <0x0003>;
+		};
+	};
+
+	emc_bw_dfs_opp_table: emc_opp_table1 {
+		compatible = "operating-points-v2";
+
+		opp@12750000 {
+			opp-hz = /bits/ 64 <12750000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <204000>;
+		};
+
+		opp@20400000 {
+			opp-hz = /bits/ 64 <20400000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <326400>;
+		};
+
+		opp@40800000 {
+			opp-hz = /bits/ 64 <40800000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <652800>;
+		};
+
+		opp@68000000 {
+			opp-hz = /bits/ 64 <68000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <1088000>;
+		};
+
+		opp@102000000 {
+			opp-hz = /bits/ 64 <102000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <1632000>;
+		};
+
+		opp@204000000 {
+			opp-hz = /bits/ 64 <204000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <3264000>;
+		};
+
+		opp@264000000 {
+			opp-hz = /bits/ 64 <264000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <4224000>;
+		};
+
+		opp@300000000 {
+			opp-hz = /bits/ 64 <300000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <4800000>;
+		};
+
+		opp@348000000 {
+			opp-hz = /bits/ 64 <348000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <5568000>;
+		};
+
+		opp@396000000 {
+			opp-hz = /bits/ 64 <396000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <6336000>;
+		};
+
+		opp@528000000 {
+			opp-hz = /bits/ 64 <528000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <8448000>;
+		};
+
+		opp@600000000 {
+			opp-hz = /bits/ 64 <600000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <9600000>;
+		};
+
+		opp@792000000 {
+			opp-hz = /bits/ 64 <792000000>;
+			opp-supported-hw = <0x001F>;
+			opp-peak-kBps = <12672000>;
+		};
+
+		opp@924000000 {
+			opp-hz = /bits/ 64 <924000000>;
+			opp-supported-hw = <0x0013>;
+			opp-peak-kBps = <14784000>;
+		};
+
+		opp@1200000000 {
+			opp-hz = /bits/ 64 <1200000000>;
+			opp-supported-hw = <0x0003>;
+			opp-peak-kBps = <19200000>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
index 1801e30b1d3a..46441d10a3fc 100644
--- a/arch/arm/boot/dts/tegra124.dtsi
+++ b/arch/arm/boot/dts/tegra124.dtsi
@@ -8,6 +8,8 @@
 #include <dt-bindings/thermal/tegra124-soctherm.h>
 #include <dt-bindings/soc/tegra-pmc.h>
 
+#include "tegra124-peripherals-opp.dtsi"
+
 / {
 	compatible = "nvidia,tegra124";
 	interrupt-parent = <&lic>;
@@ -290,6 +292,9 @@ actmon@6000c800 {
 		clock-names = "actmon", "emc";
 		resets = <&tegra_car 119>;
 		reset-names = "actmon";
+		operating-points-v2 = <&emc_bw_dfs_opp_table>;
+		interconnects = <&mc TEGRA124_MC_MPCORER &emc>;
+		interconnect-names = "cpu-read";
 	};
 
 	gpio: gpio@6000d000 {
@@ -660,6 +665,7 @@ emc: external-memory-controller@7001b000 {
 		clock-names = "emc";
 
 		nvidia,memory-controller = <&mc>;
+		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
 
 		#interconnect-cells = <0>;
 	};
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Multiple Tegra drivers need to retrieve Memory Controller and there is
duplication of the retrieval code among the drivers. This patch removes
the duplication and fixes put_device() which was missed in the duplicated
code.

EMC drivers now use new common devm_tegra_get_memory_controller() helper
instead of opencoding the MC retrieval.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
 drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
 drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
 drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
 include/soc/tegra/mc.h                   | 10 +++++
 5 files changed, 74 insertions(+), 59 deletions(-)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index ec8403557ed4..12ea2c79205a 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -42,6 +42,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
 
+static void tegra_mc_devm_action_put_device(void *data)
+{
+	struct tegra_mc *mc = data;
+
+	put_device(mc->dev);
+}
+
+/**
+ * devm_tegra_get_memory_controller() - get Tegra Memory Controller handle
+ * @dev: device pointer for the consumer device
+ *
+ * This function will search for the Memory Controller node in a device-tree
+ * and retrieve the Memory Controller handle.
+ *
+ * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
+ */
+struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct device_node *np;
+	struct tegra_mc *mc;
+	int err;
+
+	np = of_parse_phandle(dev->of_node, "nvidia,memory-controller", 0);
+	if (!np)
+		return ERR_PTR(-ENOENT);
+
+	pdev = of_find_device_by_node(np);
+	of_node_put(np);
+	if (!pdev)
+		return ERR_PTR(-ENODEV);
+
+	mc = platform_get_drvdata(pdev);
+	if (!mc) {
+		put_device(&pdev->dev);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	err = devm_add_action(dev, tegra_mc_devm_action_put_device, mc);
+	if (err) {
+		put_device(mc->dev);
+		return ERR_PTR(err);
+	}
+
+	return mc;
+}
+EXPORT_SYMBOL_GPL(devm_tegra_get_memory_controller);
+
 static int tegra_mc_block_dma_common(struct tegra_mc *mc,
 				     const struct tegra_mc_reset *rst)
 {
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 76ace42a688a..b92259d4fbd1 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1177,7 +1177,6 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
-	struct platform_device *mc;
 	struct device_node *np;
 	struct tegra_emc *emc;
 	struct resource *res;
@@ -1195,20 +1194,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	if (IS_ERR(emc->regs))
 		return PTR_ERR(emc->regs);
 
-	np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-	if (!np) {
-		dev_err(&pdev->dev, "could not get memory controller\n");
-		return -ENOENT;
-	}
-
-	mc = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!mc)
-		return -ENOENT;
-
-	emc->mc = platform_get_drvdata(mc);
-	if (!emc->mc)
-		return -EPROBE_DEFER;
+	emc->mc = devm_tegra_get_memory_controller(&pdev->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
 
 	ram_code = tegra_read_ram_code();
 
diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
index cdd663ba4733..8c6ea634e05a 100644
--- a/drivers/memory/tegra/tegra210-emc-core.c
+++ b/drivers/memory/tegra/tegra210-emc-core.c
@@ -1828,7 +1828,6 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 {
 	struct thermal_cooling_device *cd;
 	unsigned long current_rate;
-	struct platform_device *mc;
 	struct tegra210_emc *emc;
 	struct device_node *np;
 	unsigned int i;
@@ -1846,35 +1845,19 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 	spin_lock_init(&emc->lock);
 	emc->dev = &pdev->dev;
 
-	np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-	if (!np) {
-		dev_err(&pdev->dev, "could not get memory controller\n");
-		return -ENOENT;
-	}
-
-	mc = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!mc)
-		return -ENOENT;
-
-	emc->mc = platform_get_drvdata(mc);
-	if (!emc->mc) {
-		put_device(&mc->dev);
-		return -EPROBE_DEFER;
-	}
+	emc->mc = devm_tegra_get_memory_controller(&pdev->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
 
 	emc->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(emc->regs)) {
-		err = PTR_ERR(emc->regs);
-		goto put_mc;
-	}
+	if (IS_ERR(emc->regs))
+		return PTR_ERR(emc->regs);
 
 	for (i = 0; i < 2; i++) {
 		emc->channel[i] = devm_platform_ioremap_resource(pdev, 1 + i);
-		if (IS_ERR(emc->channel[i])) {
-			err = PTR_ERR(emc->channel[i]);
-			goto put_mc;
-		}
+		if (IS_ERR(emc->channel[i]))
+			return PTR_ERR(emc->channel[i]);
+
 	}
 
 	tegra210_emc_detect(emc);
@@ -1884,7 +1867,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 	err = of_reserved_mem_device_init_by_name(emc->dev, np, "nominal");
 	if (err < 0) {
 		dev_err(emc->dev, "failed to get nominal EMC table: %d\n", err);
-		goto put_mc;
+		return err;
 	}
 
 	err = of_reserved_mem_device_init_by_name(emc->dev, np, "derated");
@@ -2015,8 +1998,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 	tegra210_clk_emc_detach(emc->clk);
 release:
 	of_reserved_mem_device_release(emc->dev);
-put_mc:
-	put_device(emc->mc->dev);
+
 	return err;
 }
 
@@ -2027,7 +2009,6 @@ static int tegra210_emc_remove(struct platform_device *pdev)
 	debugfs_remove_recursive(emc->debugfs.root);
 	tegra210_clk_emc_detach(emc->clk);
 	of_reserved_mem_device_release(emc->dev);
-	put_device(emc->mc->dev);
 
 	return 0;
 }
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 055af0e08a2e..602dc4e08c61 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1258,7 +1258,6 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
-	struct platform_device *mc;
 	struct device_node *np;
 	struct tegra_emc *emc;
 	int err;
@@ -1269,17 +1268,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-	if (!np) {
-		dev_err(&pdev->dev, "could not get memory controller node\n");
-		return -ENOENT;
-	}
-
-	mc = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!mc)
-		return -ENOENT;
-
 	np = emc_find_node_by_ram_code(&pdev->dev);
 	if (!np)
 		return -EINVAL;
@@ -1290,9 +1278,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	emc->mc = platform_get_drvdata(mc);
-	if (!emc->mc)
-		return -EPROBE_DEFER;
+	emc->mc = devm_tegra_get_memory_controller(&pdev->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
 
 	emc->clk_nb.notifier_call = emc_clk_change_notify;
 	emc->dev = &pdev->dev;
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 1238e35653d1..1b7dfed6afb8 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -184,4 +184,14 @@ struct tegra_mc {
 int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
 unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
 
+#ifdef CONFIG_TEGRA_MC
+struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev);
+#else
+static inline struct tegra_mc *
+devm_tegra_get_memory_controller(struct device *dev)
+{
+	ERR_PTR(-ENODEV);
+}
+#endif
+
 #endif /* __SOC_TEGRA_MC_H__ */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Multiple Tegra drivers need to retrieve Memory Controller and there is
duplication of the retrieval code among the drivers. This patch removes
the duplication and fixes put_device() which was missed in the duplicated
code.

EMC drivers now use new common devm_tegra_get_memory_controller() helper
instead of opencoding the MC retrieval.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
 drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
 drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
 drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
 include/soc/tegra/mc.h                   | 10 +++++
 5 files changed, 74 insertions(+), 59 deletions(-)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index ec8403557ed4..12ea2c79205a 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -42,6 +42,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
 
+static void tegra_mc_devm_action_put_device(void *data)
+{
+	struct tegra_mc *mc = data;
+
+	put_device(mc->dev);
+}
+
+/**
+ * devm_tegra_get_memory_controller() - get Tegra Memory Controller handle
+ * @dev: device pointer for the consumer device
+ *
+ * This function will search for the Memory Controller node in a device-tree
+ * and retrieve the Memory Controller handle.
+ *
+ * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
+ */
+struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev)
+{
+	struct platform_device *pdev;
+	struct device_node *np;
+	struct tegra_mc *mc;
+	int err;
+
+	np = of_parse_phandle(dev->of_node, "nvidia,memory-controller", 0);
+	if (!np)
+		return ERR_PTR(-ENOENT);
+
+	pdev = of_find_device_by_node(np);
+	of_node_put(np);
+	if (!pdev)
+		return ERR_PTR(-ENODEV);
+
+	mc = platform_get_drvdata(pdev);
+	if (!mc) {
+		put_device(&pdev->dev);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	err = devm_add_action(dev, tegra_mc_devm_action_put_device, mc);
+	if (err) {
+		put_device(mc->dev);
+		return ERR_PTR(err);
+	}
+
+	return mc;
+}
+EXPORT_SYMBOL_GPL(devm_tegra_get_memory_controller);
+
 static int tegra_mc_block_dma_common(struct tegra_mc *mc,
 				     const struct tegra_mc_reset *rst)
 {
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 76ace42a688a..b92259d4fbd1 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1177,7 +1177,6 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
-	struct platform_device *mc;
 	struct device_node *np;
 	struct tegra_emc *emc;
 	struct resource *res;
@@ -1195,20 +1194,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	if (IS_ERR(emc->regs))
 		return PTR_ERR(emc->regs);
 
-	np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-	if (!np) {
-		dev_err(&pdev->dev, "could not get memory controller\n");
-		return -ENOENT;
-	}
-
-	mc = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!mc)
-		return -ENOENT;
-
-	emc->mc = platform_get_drvdata(mc);
-	if (!emc->mc)
-		return -EPROBE_DEFER;
+	emc->mc = devm_tegra_get_memory_controller(&pdev->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
 
 	ram_code = tegra_read_ram_code();
 
diff --git a/drivers/memory/tegra/tegra210-emc-core.c b/drivers/memory/tegra/tegra210-emc-core.c
index cdd663ba4733..8c6ea634e05a 100644
--- a/drivers/memory/tegra/tegra210-emc-core.c
+++ b/drivers/memory/tegra/tegra210-emc-core.c
@@ -1828,7 +1828,6 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 {
 	struct thermal_cooling_device *cd;
 	unsigned long current_rate;
-	struct platform_device *mc;
 	struct tegra210_emc *emc;
 	struct device_node *np;
 	unsigned int i;
@@ -1846,35 +1845,19 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 	spin_lock_init(&emc->lock);
 	emc->dev = &pdev->dev;
 
-	np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-	if (!np) {
-		dev_err(&pdev->dev, "could not get memory controller\n");
-		return -ENOENT;
-	}
-
-	mc = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!mc)
-		return -ENOENT;
-
-	emc->mc = platform_get_drvdata(mc);
-	if (!emc->mc) {
-		put_device(&mc->dev);
-		return -EPROBE_DEFER;
-	}
+	emc->mc = devm_tegra_get_memory_controller(&pdev->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
 
 	emc->regs = devm_platform_ioremap_resource(pdev, 0);
-	if (IS_ERR(emc->regs)) {
-		err = PTR_ERR(emc->regs);
-		goto put_mc;
-	}
+	if (IS_ERR(emc->regs))
+		return PTR_ERR(emc->regs);
 
 	for (i = 0; i < 2; i++) {
 		emc->channel[i] = devm_platform_ioremap_resource(pdev, 1 + i);
-		if (IS_ERR(emc->channel[i])) {
-			err = PTR_ERR(emc->channel[i]);
-			goto put_mc;
-		}
+		if (IS_ERR(emc->channel[i]))
+			return PTR_ERR(emc->channel[i]);
+
 	}
 
 	tegra210_emc_detect(emc);
@@ -1884,7 +1867,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 	err = of_reserved_mem_device_init_by_name(emc->dev, np, "nominal");
 	if (err < 0) {
 		dev_err(emc->dev, "failed to get nominal EMC table: %d\n", err);
-		goto put_mc;
+		return err;
 	}
 
 	err = of_reserved_mem_device_init_by_name(emc->dev, np, "derated");
@@ -2015,8 +1998,7 @@ static int tegra210_emc_probe(struct platform_device *pdev)
 	tegra210_clk_emc_detach(emc->clk);
 release:
 	of_reserved_mem_device_release(emc->dev);
-put_mc:
-	put_device(emc->mc->dev);
+
 	return err;
 }
 
@@ -2027,7 +2009,6 @@ static int tegra210_emc_remove(struct platform_device *pdev)
 	debugfs_remove_recursive(emc->debugfs.root);
 	tegra210_clk_emc_detach(emc->clk);
 	of_reserved_mem_device_release(emc->dev);
-	put_device(emc->mc->dev);
 
 	return 0;
 }
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 055af0e08a2e..602dc4e08c61 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1258,7 +1258,6 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
 
 static int tegra_emc_probe(struct platform_device *pdev)
 {
-	struct platform_device *mc;
 	struct device_node *np;
 	struct tegra_emc *emc;
 	int err;
@@ -1269,17 +1268,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
-	np = of_parse_phandle(pdev->dev.of_node, "nvidia,memory-controller", 0);
-	if (!np) {
-		dev_err(&pdev->dev, "could not get memory controller node\n");
-		return -ENOENT;
-	}
-
-	mc = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!mc)
-		return -ENOENT;
-
 	np = emc_find_node_by_ram_code(&pdev->dev);
 	if (!np)
 		return -EINVAL;
@@ -1290,9 +1278,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
-	emc->mc = platform_get_drvdata(mc);
-	if (!emc->mc)
-		return -EPROBE_DEFER;
+	emc->mc = devm_tegra_get_memory_controller(&pdev->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
 
 	emc->clk_nb.notifier_call = emc_clk_change_notify;
 	emc->dev = &pdev->dev;
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 1238e35653d1..1b7dfed6afb8 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -184,4 +184,14 @@ struct tegra_mc {
 int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
 unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
 
+#ifdef CONFIG_TEGRA_MC
+struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev);
+#else
+static inline struct tegra_mc *
+devm_tegra_get_memory_controller(struct device *dev)
+{
+	ERR_PTR(-ENODEV);
+}
+#endif
+
 #endif /* __SOC_TEGRA_MC_H__ */
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 29/52] memory: tegra-mc: Add interconnect framework
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Now Memory Controller is a memory interconnection provider. This allows
us to use interconnect API for tuning of memory configuration. This patch
adds common ICC core and adds hooks which should be implemented by the SoC
drivers.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig |   1 +
 drivers/memory/tegra/mc.c    | 129 +++++++++++++++++++++++++++++++++++
 drivers/memory/tegra/mc.h    |   8 +++
 include/soc/tegra/mc.h       |  16 +++++
 4 files changed, 154 insertions(+)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 9f0a96bf9ccc..b38e5255effe 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -3,6 +3,7 @@ config TEGRA_MC
 	bool "NVIDIA Tegra Memory Controller support"
 	default y
 	depends on ARCH_TEGRA
+	select INTERCONNECT
 	help
 	  This driver supports the Memory Controller (MC) hardware found on
 	  NVIDIA Tegra SoCs.
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 12ea2c79205a..53d61b05ebf8 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -639,6 +639,133 @@ static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static struct icc_node_data *
+tegra_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	unsigned int idx = spec->args[0];
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != idx)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		ndata->node = node;
+
+		/* these clients are isochronous by default on all SoCs */
+		if (strstarts(node->name, "display") ||
+		    strstarts(node->name, "ptc") ||
+		    strstarts(node->name, "vi"))
+			ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+
+		return ndata;
+	}
+
+	pr_err("%s: invalid client index %u\n", __func__, idx);
+
+	return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Memory Controller (MC) has few Memory Clients that are issuing memory
+ * bandwidth allocation requests to the MC interconnect provider. The MC
+ * provider aggregates the requests and then sends the aggregated request
+ * up to the External Memory Controller (EMC) interconnect provider which
+ * re-configures hardware interface to External Memory (EMEM) in accordance
+ * to the required bandwidth. Each MC interconnect node represents an
+ * individual Memory Client.
+ *
+ * Memory interconnect topology:
+ *
+ *               +----+
+ * +--------+    |    |
+ * | TEXSRD +--->+    |
+ * +--------+    |    |
+ *               |    |    +-----+    +------+
+ *    ...        | MC +--->+ EMC +--->+ EMEM |
+ *               |    |    +-----+    +------+
+ * +--------+    |    |
+ * | DISP.. +--->+    |
+ * +--------+    |    |
+ *               +----+
+ */
+static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
+{
+	struct icc_node *node;
+	unsigned int i;
+	int err;
+
+	/* older device-trees don't have interconnect properties */
+	if (!of_find_property(mc->dev->of_node, "#interconnect-cells", NULL) ||
+	    !mc->soc->icc_ops)
+		return 0;
+
+	mc->provider.dev = mc->dev;
+	mc->provider.data = &mc->provider;
+	mc->provider.set = mc->soc->icc_ops->set;
+	mc->provider.aggregate = mc->soc->icc_ops->aggregate;
+	mc->provider.xlate_extended = tegra_mc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&mc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_MC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "Memory Controller";
+	icc_node_add(node, &mc->provider);
+
+	/* link Memory Controller to External Memory Controller */
+	err = icc_link_create(node, TEGRA_ICC_EMC);
+	if (err)
+		goto remove_nodes;
+
+	for (i = 0; i < mc->soc->num_clients; i++) {
+		/* create MC client node */
+		node = icc_node_create(mc->soc->clients[i].id);
+		err = PTR_ERR_OR_ZERO(node);
+		if (err)
+			goto remove_nodes;
+
+		node->name = mc->soc->clients[i].name;
+		icc_node_add(node, &mc->provider);
+
+		/* link Memory Client to Memory Controller */
+		err = icc_link_create(node, TEGRA_ICC_MC);
+		if (err)
+			goto remove_nodes;
+	}
+
+	/*
+	 * MC driver is registered too early, so early that generic driver
+	 * syncing doesn't work for the MC. But it doesn't really matter
+	 * since syncing works for the EMC drivers, hence the we can sync
+	 * the MC driver by ourselves and then EMC will complete syncing of
+	 * the whole ICC state.
+	 */
+	icc_sync_state(mc->dev);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&mc->provider);
+del_provider:
+	icc_provider_del(&mc->provider);
+err_msg:
+	dev_err(mc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
 static int tegra_mc_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -747,6 +874,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
 		}
 	}
 
+	tegra_mc_interconnect_setup(mc);
+
 	return 0;
 }
 
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index afa3ba45c9e6..abeb6a2cc36a 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -115,4 +115,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
 extern const struct tegra_mc_soc tegra210_mc_soc;
 #endif
 
+/*
+ * These IDs are for internal use of Tegra's ICC, the values are chosen
+ * such that they don't conflict with the device-tree ICC node IDs.
+ */
+#define TEGRA_ICC_EMC		1000
+#define TEGRA_ICC_EMEM		2000
+#define TEGRA_ICC_MC		3000
+
 #endif /* MEMORY_TEGRA_MC_H */
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 1b7dfed6afb8..09b3fe30c8e7 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -7,6 +7,7 @@
 #define __SOC_TEGRA_MC_H__
 
 #include <linux/err.h>
+#include <linux/interconnect-provider.h>
 #include <linux/reset-controller.h>
 #include <linux/types.h>
 
@@ -141,6 +142,17 @@ struct tegra_mc_reset_ops {
 			    const struct tegra_mc_reset *rst);
 };
 
+enum terga_mc_icc_tag {
+	TEGRA_MC_ICC_TAG_DEFAULT,
+	TEGRA_MC_ICC_TAG_ISO,
+};
+
+struct tegra_mc_icc_ops {
+	int (*set)(struct icc_node *src, struct icc_node *dst);
+	int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
+			 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
+};
+
 struct tegra_mc_soc {
 	const struct tegra_mc_client *clients;
 	unsigned int num_clients;
@@ -160,6 +172,8 @@ struct tegra_mc_soc {
 	const struct tegra_mc_reset_ops *reset_ops;
 	const struct tegra_mc_reset *resets;
 	unsigned int num_resets;
+
+	const struct tegra_mc_icc_ops *icc_ops;
 };
 
 struct tegra_mc {
@@ -178,6 +192,8 @@ struct tegra_mc {
 
 	struct reset_controller_dev reset;
 
+	struct icc_provider provider;
+
 	spinlock_t lock;
 };
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 29/52] memory: tegra-mc: Add interconnect framework
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Now Memory Controller is a memory interconnection provider. This allows
us to use interconnect API for tuning of memory configuration. This patch
adds common ICC core and adds hooks which should be implemented by the SoC
drivers.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig |   1 +
 drivers/memory/tegra/mc.c    | 129 +++++++++++++++++++++++++++++++++++
 drivers/memory/tegra/mc.h    |   8 +++
 include/soc/tegra/mc.h       |  16 +++++
 4 files changed, 154 insertions(+)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 9f0a96bf9ccc..b38e5255effe 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -3,6 +3,7 @@ config TEGRA_MC
 	bool "NVIDIA Tegra Memory Controller support"
 	default y
 	depends on ARCH_TEGRA
+	select INTERCONNECT
 	help
 	  This driver supports the Memory Controller (MC) hardware found on
 	  NVIDIA Tegra SoCs.
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 12ea2c79205a..53d61b05ebf8 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -639,6 +639,133 @@ static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+static struct icc_node_data *
+tegra_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	unsigned int idx = spec->args[0];
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != idx)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		ndata->node = node;
+
+		/* these clients are isochronous by default on all SoCs */
+		if (strstarts(node->name, "display") ||
+		    strstarts(node->name, "ptc") ||
+		    strstarts(node->name, "vi"))
+			ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+
+		return ndata;
+	}
+
+	pr_err("%s: invalid client index %u\n", __func__, idx);
+
+	return ERR_PTR(-EINVAL);
+}
+
+/*
+ * Memory Controller (MC) has few Memory Clients that are issuing memory
+ * bandwidth allocation requests to the MC interconnect provider. The MC
+ * provider aggregates the requests and then sends the aggregated request
+ * up to the External Memory Controller (EMC) interconnect provider which
+ * re-configures hardware interface to External Memory (EMEM) in accordance
+ * to the required bandwidth. Each MC interconnect node represents an
+ * individual Memory Client.
+ *
+ * Memory interconnect topology:
+ *
+ *               +----+
+ * +--------+    |    |
+ * | TEXSRD +--->+    |
+ * +--------+    |    |
+ *               |    |    +-----+    +------+
+ *    ...        | MC +--->+ EMC +--->+ EMEM |
+ *               |    |    +-----+    +------+
+ * +--------+    |    |
+ * | DISP.. +--->+    |
+ * +--------+    |    |
+ *               +----+
+ */
+static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
+{
+	struct icc_node *node;
+	unsigned int i;
+	int err;
+
+	/* older device-trees don't have interconnect properties */
+	if (!of_find_property(mc->dev->of_node, "#interconnect-cells", NULL) ||
+	    !mc->soc->icc_ops)
+		return 0;
+
+	mc->provider.dev = mc->dev;
+	mc->provider.data = &mc->provider;
+	mc->provider.set = mc->soc->icc_ops->set;
+	mc->provider.aggregate = mc->soc->icc_ops->aggregate;
+	mc->provider.xlate_extended = tegra_mc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&mc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_MC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "Memory Controller";
+	icc_node_add(node, &mc->provider);
+
+	/* link Memory Controller to External Memory Controller */
+	err = icc_link_create(node, TEGRA_ICC_EMC);
+	if (err)
+		goto remove_nodes;
+
+	for (i = 0; i < mc->soc->num_clients; i++) {
+		/* create MC client node */
+		node = icc_node_create(mc->soc->clients[i].id);
+		err = PTR_ERR_OR_ZERO(node);
+		if (err)
+			goto remove_nodes;
+
+		node->name = mc->soc->clients[i].name;
+		icc_node_add(node, &mc->provider);
+
+		/* link Memory Client to Memory Controller */
+		err = icc_link_create(node, TEGRA_ICC_MC);
+		if (err)
+			goto remove_nodes;
+	}
+
+	/*
+	 * MC driver is registered too early, so early that generic driver
+	 * syncing doesn't work for the MC. But it doesn't really matter
+	 * since syncing works for the EMC drivers, hence the we can sync
+	 * the MC driver by ourselves and then EMC will complete syncing of
+	 * the whole ICC state.
+	 */
+	icc_sync_state(mc->dev);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&mc->provider);
+del_provider:
+	icc_provider_del(&mc->provider);
+err_msg:
+	dev_err(mc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
 static int tegra_mc_probe(struct platform_device *pdev)
 {
 	struct resource *res;
@@ -747,6 +874,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
 		}
 	}
 
+	tegra_mc_interconnect_setup(mc);
+
 	return 0;
 }
 
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index afa3ba45c9e6..abeb6a2cc36a 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -115,4 +115,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
 extern const struct tegra_mc_soc tegra210_mc_soc;
 #endif
 
+/*
+ * These IDs are for internal use of Tegra's ICC, the values are chosen
+ * such that they don't conflict with the device-tree ICC node IDs.
+ */
+#define TEGRA_ICC_EMC		1000
+#define TEGRA_ICC_EMEM		2000
+#define TEGRA_ICC_MC		3000
+
 #endif /* MEMORY_TEGRA_MC_H */
diff --git a/include/soc/tegra/mc.h b/include/soc/tegra/mc.h
index 1b7dfed6afb8..09b3fe30c8e7 100644
--- a/include/soc/tegra/mc.h
+++ b/include/soc/tegra/mc.h
@@ -7,6 +7,7 @@
 #define __SOC_TEGRA_MC_H__
 
 #include <linux/err.h>
+#include <linux/interconnect-provider.h>
 #include <linux/reset-controller.h>
 #include <linux/types.h>
 
@@ -141,6 +142,17 @@ struct tegra_mc_reset_ops {
 			    const struct tegra_mc_reset *rst);
 };
 
+enum terga_mc_icc_tag {
+	TEGRA_MC_ICC_TAG_DEFAULT,
+	TEGRA_MC_ICC_TAG_ISO,
+};
+
+struct tegra_mc_icc_ops {
+	int (*set)(struct icc_node *src, struct icc_node *dst);
+	int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
+			 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
+};
+
 struct tegra_mc_soc {
 	const struct tegra_mc_client *clients;
 	unsigned int num_clients;
@@ -160,6 +172,8 @@ struct tegra_mc_soc {
 	const struct tegra_mc_reset_ops *reset_ops;
 	const struct tegra_mc_reset *resets;
 	unsigned int num_resets;
+
+	const struct tegra_mc_icc_ops *icc_ops;
 };
 
 struct tegra_mc {
@@ -178,6 +192,8 @@ struct tegra_mc {
 
 	struct reset_controller_dev reset;
 
+	struct icc_provider provider;
+
 	spinlock_t lock;
 };
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 30/52] memory: tegra20-emc: Make driver modular
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

This patch adds modularization support to the Tegra20 EMC driver. Driver
now can be compiled as a loadable kernel module.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |  2 +-
 drivers/memory/tegra/tegra20-emc.c | 17 ++++++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index b38e5255effe..ff426747cd7d 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -9,7 +9,7 @@ config TEGRA_MC
 	  NVIDIA Tegra SoCs.
 
 config TEGRA20_EMC
-	bool "NVIDIA Tegra20 External Memory Controller driver"
+	tristate "NVIDIA Tegra20 External Memory Controller driver"
 	default y
 	depends on ARCH_TEGRA_2x_SOC
 	help
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 027f46287dbf..0baa6590adea 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -724,6 +724,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
 
+	/*
+	 * Don't allow the kernel module to be unloaded. Unloading adds some
+	 * extra complexity which doesn't really worth the effort in a case of
+	 * this driver.
+	 */
+	try_module_get(THIS_MODULE);
+
 	return 0;
 
 unset_cb:
@@ -736,6 +743,7 @@ static const struct of_device_id tegra_emc_of_match[] = {
 	{ .compatible = "nvidia,tegra20-emc", },
 	{},
 };
+MODULE_DEVICE_TABLE(of, tegra_emc_of_match);
 
 static struct platform_driver tegra_emc_driver = {
 	.probe = tegra_emc_probe,
@@ -745,9 +753,8 @@ static struct platform_driver tegra_emc_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
+module_platform_driver(tegra_emc_driver);
 
-static int __init tegra_emc_init(void)
-{
-	return platform_driver_register(&tegra_emc_driver);
-}
-subsys_initcall(tegra_emc_init);
+MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra20 EMC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 30/52] memory: tegra20-emc: Make driver modular
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

This patch adds modularization support to the Tegra20 EMC driver. Driver
now can be compiled as a loadable kernel module.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |  2 +-
 drivers/memory/tegra/tegra20-emc.c | 17 ++++++++++++-----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index b38e5255effe..ff426747cd7d 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -9,7 +9,7 @@ config TEGRA_MC
 	  NVIDIA Tegra SoCs.
 
 config TEGRA20_EMC
-	bool "NVIDIA Tegra20 External Memory Controller driver"
+	tristate "NVIDIA Tegra20 External Memory Controller driver"
 	default y
 	depends on ARCH_TEGRA_2x_SOC
 	help
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 027f46287dbf..0baa6590adea 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -724,6 +724,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
 
+	/*
+	 * Don't allow the kernel module to be unloaded. Unloading adds some
+	 * extra complexity which doesn't really worth the effort in a case of
+	 * this driver.
+	 */
+	try_module_get(THIS_MODULE);
+
 	return 0;
 
 unset_cb:
@@ -736,6 +743,7 @@ static const struct of_device_id tegra_emc_of_match[] = {
 	{ .compatible = "nvidia,tegra20-emc", },
 	{},
 };
+MODULE_DEVICE_TABLE(of, tegra_emc_of_match);
 
 static struct platform_driver tegra_emc_driver = {
 	.probe = tegra_emc_probe,
@@ -745,9 +753,8 @@ static struct platform_driver tegra_emc_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
+module_platform_driver(tegra_emc_driver);
 
-static int __init tegra_emc_init(void)
-{
-	return platform_driver_register(&tegra_emc_driver);
-}
-subsys_initcall(tegra_emc_init);
+MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra20 EMC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 31/52] memory: tegra20-emc: Use devm_platform_ioremap_resource()
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Use devm_platform_ioremap_resource() helper which makes code a bit
cleaner.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra20-emc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 0baa6590adea..ce22ca7cfb77 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -654,7 +654,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
 	struct tegra_emc *emc;
-	struct resource *res;
 	int irq, err;
 
 	/* driver has nothing to do in a case of memory timing absence */
@@ -689,8 +688,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	emc->regs = devm_ioremap_resource(&pdev->dev, res);
+	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
 		return PTR_ERR(emc->regs);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 31/52] memory: tegra20-emc: Use devm_platform_ioremap_resource()
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Use devm_platform_ioremap_resource() helper which makes code a bit
cleaner.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra20-emc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 0baa6590adea..ce22ca7cfb77 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -654,7 +654,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
 	struct tegra_emc *emc;
-	struct resource *res;
 	int irq, err;
 
 	/* driver has nothing to do in a case of memory timing absence */
@@ -689,8 +688,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	emc->regs = devm_ioremap_resource(&pdev->dev, res);
+	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
 		return PTR_ERR(emc->regs);
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 32/52] memory: tegra20-emc: Continue probing if timings are missing in device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

EMC driver will become mandatory after turning it into interconnect
provider because interconnect users, like display controller driver, will
fail to probe using newer device-trees that have interconnect properties.
Thus make EMC driver to probe even if timings are missing in device-tree.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra20-emc.c | 34 ++++++++++++++----------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index ce22ca7cfb77..34085e26dced 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -383,6 +383,11 @@ tegra_emc_find_node_by_ram_code(struct device *dev)
 	u32 value, ram_code;
 	int err;
 
+	if (of_get_child_count(dev->of_node) == 0) {
+		dev_info(dev, "device-tree doesn't have memory timings\n");
+		return NULL;
+	}
+
 	if (!of_property_read_bool(dev->of_node, "nvidia,use-ram-code"))
 		return of_node_get(dev->of_node);
 
@@ -451,6 +456,9 @@ static long emc_round_rate(unsigned long rate,
 	struct tegra_emc *emc = arg;
 	unsigned int i;
 
+	if (!emc->num_timings)
+		return clk_get_rate(emc->clk);
+
 	min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
 
 	for (i = 0; i < emc->num_timings; i++) {
@@ -656,13 +664,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	struct tegra_emc *emc;
 	int irq, err;
 
-	/* driver has nothing to do in a case of memory timing absence */
-	if (of_get_child_count(pdev->dev.of_node) == 0) {
-		dev_info(&pdev->dev,
-			 "EMC device tree node doesn't have memory timings\n");
-		return 0;
-	}
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		dev_err(&pdev->dev, "interrupt not specified\n");
@@ -670,23 +671,20 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return irq;
 	}
 
-	np = tegra_emc_find_node_by_ram_code(&pdev->dev);
-	if (!np)
-		return -EINVAL;
-
 	emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
-	if (!emc) {
-		of_node_put(np);
+	if (!emc)
 		return -ENOMEM;
-	}
 
 	emc->clk_nb.notifier_call = tegra_emc_clk_change_notify;
 	emc->dev = &pdev->dev;
 
-	err = tegra_emc_load_timings_from_dt(emc, np);
-	of_node_put(np);
-	if (err)
-		return err;
+	np = tegra_emc_find_node_by_ram_code(&pdev->dev);
+	if (np) {
+		err = tegra_emc_load_timings_from_dt(emc, np);
+		of_node_put(np);
+		if (err)
+			return err;
+	}
 
 	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 32/52] memory: tegra20-emc: Continue probing if timings are missing in device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

EMC driver will become mandatory after turning it into interconnect
provider because interconnect users, like display controller driver, will
fail to probe using newer device-trees that have interconnect properties.
Thus make EMC driver to probe even if timings are missing in device-tree.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra20-emc.c | 34 ++++++++++++++----------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index ce22ca7cfb77..34085e26dced 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -383,6 +383,11 @@ tegra_emc_find_node_by_ram_code(struct device *dev)
 	u32 value, ram_code;
 	int err;
 
+	if (of_get_child_count(dev->of_node) == 0) {
+		dev_info(dev, "device-tree doesn't have memory timings\n");
+		return NULL;
+	}
+
 	if (!of_property_read_bool(dev->of_node, "nvidia,use-ram-code"))
 		return of_node_get(dev->of_node);
 
@@ -451,6 +456,9 @@ static long emc_round_rate(unsigned long rate,
 	struct tegra_emc *emc = arg;
 	unsigned int i;
 
+	if (!emc->num_timings)
+		return clk_get_rate(emc->clk);
+
 	min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
 
 	for (i = 0; i < emc->num_timings; i++) {
@@ -656,13 +664,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	struct tegra_emc *emc;
 	int irq, err;
 
-	/* driver has nothing to do in a case of memory timing absence */
-	if (of_get_child_count(pdev->dev.of_node) == 0) {
-		dev_info(&pdev->dev,
-			 "EMC device tree node doesn't have memory timings\n");
-		return 0;
-	}
-
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
 		dev_err(&pdev->dev, "interrupt not specified\n");
@@ -670,23 +671,20 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return irq;
 	}
 
-	np = tegra_emc_find_node_by_ram_code(&pdev->dev);
-	if (!np)
-		return -EINVAL;
-
 	emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
-	if (!emc) {
-		of_node_put(np);
+	if (!emc)
 		return -ENOMEM;
-	}
 
 	emc->clk_nb.notifier_call = tegra_emc_clk_change_notify;
 	emc->dev = &pdev->dev;
 
-	err = tegra_emc_load_timings_from_dt(emc, np);
-	of_node_put(np);
-	if (err)
-		return err;
+	np = tegra_emc_find_node_by_ram_code(&pdev->dev);
+	if (np) {
+		err = tegra_emc_load_timings_from_dt(emc, np);
+		of_node_put(np);
+		if (err)
+			return err;
+	}
 
 	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 33/52] memory: tegra20: Support interconnect framework
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Now Internal and External Memory Controllers are memory interconnection
providers. This allows us to use interconnect API for tuning of memory
configuration. EMC driver now supports OPPs and DVFS.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |   3 +-
 drivers/memory/tegra/mc.h          |  12 ++
 drivers/memory/tegra/tegra20-emc.c | 176 +++++++++++++++++++++++++++++
 drivers/memory/tegra/tegra20.c     |  34 ++++++
 4 files changed, 224 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index ff426747cd7d..ac3dfe155505 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -11,7 +11,8 @@ config TEGRA_MC
 config TEGRA20_EMC
 	tristate "NVIDIA Tegra20 External Memory Controller driver"
 	default y
-	depends on ARCH_TEGRA_2x_SOC
+	depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
+	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra20 chips. The EMC controls the external DRAM on the board.
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index abeb6a2cc36a..531fb4fb7b17 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -78,6 +78,18 @@
 
 #define MC_TIMING_UPDATE				BIT(0)
 
+static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
+{
+	val = val * percents;
+	do_div(val, 100);
+
+	/*
+	 * High freq + high boosting percent + large polling interval are
+	 * resulting in integer overflow when watermarks are calculated.
+	 */
+	return min_t(u64, val, U32_MAX);
+}
+
 static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
 {
 	return readl_relaxed(mc->regs + offset);
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 34085e26dced..69ccb3fe5b0b 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -9,6 +9,7 @@
 #include <linux/clk/tegra.h>
 #include <linux/debugfs.h>
 #include <linux/err.h>
+#include <linux/interconnect-provider.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
@@ -16,11 +17,15 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include <linux/types.h>
 
 #include <soc/tegra/fuse.h>
 
+#include "mc.h"
+
 #define EMC_INTSTATUS				0x000
 #define EMC_INTMASK				0x004
 #define EMC_DBG					0x008
@@ -144,6 +149,9 @@ struct emc_timing {
 
 struct tegra_emc {
 	struct device *dev;
+	struct tegra_mc *mc;
+	struct opp_table *opp_table;
+	struct icc_provider provider;
 	struct notifier_block clk_nb;
 	struct clk *clk;
 	void __iomem *regs;
@@ -658,6 +666,166 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
 			    emc, &tegra_emc_debug_max_rate_fops);
 }
 
+static inline struct tegra_emc *
+to_tegra_emc_provider(struct icc_provider *provider)
+{
+	return container_of(provider, struct tegra_emc, provider);
+}
+
+static struct icc_node_data *
+emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	/* External Memory is the only possible ICC route */
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != TEGRA_ICC_EMEM)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		/*
+		 * SRC and DST nodes should have matching TAG in order to have
+		 * it set by default for a requested path.
+		 */
+		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+		ndata->node = node;
+
+		return ndata;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
+	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
+	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
+	unsigned long long rate = max(avg_bw, peak_bw);
+	unsigned int dram_data_bus_width_bytes = 4;
+	long rounded_rate;
+	int err;
+
+	/*
+	 * Tegra20 EMC runs on x2 clock rate of SDRAM bus because DDR data
+	 * is sampled on both clock edges. This means that EMC clock rate
+	 * equals to the peak data rate.
+	 */
+	do_div(rate, dram_data_bus_width_bytes);
+	rate = min_t(u64, rate, U32_MAX);
+
+	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
+	if (rounded_rate < 0)
+		return rounded_rate;
+
+	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra_emc_interconnect_init(struct tegra_emc *emc)
+{
+	const struct tegra_mc_soc *soc;
+	struct icc_node *node;
+	int err;
+
+	emc->mc = devm_tegra_get_memory_controller(emc->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
+
+	soc = emc->mc->soc;
+
+	emc->provider.dev = emc->dev;
+	emc->provider.set = emc_icc_set;
+	emc->provider.data = &emc->provider;
+	emc->provider.aggregate = soc->icc_ops->aggregate;
+	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&emc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create External Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_EMC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "External Memory Controller";
+	icc_node_add(node, &emc->provider);
+
+	/* link External Memory Controller to External Memory (DRAM) */
+	err = icc_link_create(node, TEGRA_ICC_EMEM);
+	if (err)
+		goto remove_nodes;
+
+	/* create External Memory node */
+	node = icc_node_create(TEGRA_ICC_EMEM);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto remove_nodes;
+
+	node->name = "External Memory (DRAM)";
+	icc_node_add(node, &emc->provider);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&emc->provider);
+del_provider:
+	icc_provider_del(&emc->provider);
+err_msg:
+	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
+static int tegra_emc_opp_table_init(struct tegra_emc *emc)
+{
+	const char *rname = "core";
+	int err;
+
+	/*
+	 * Legacy device-trees don't have OPP table and EMC driver isn't
+	 * useful in this case.
+	 */
+	if (!device_property_present(emc->dev, "operating-points-v2")) {
+		dev_err(emc->dev, "OPP table not found\n");
+		dev_err(emc->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
+	/* voltage scaling is optional */
+	if (device_property_present(emc->dev, "core-supply"))
+		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
+	else
+		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
+
+	if (IS_ERR(emc->opp_table))
+		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
+				     "failed to prepare OPP table\n");
+
+	err = dev_pm_opp_of_add_table(emc->dev);
+	if (err) {
+		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
+		goto put_table;
+	}
+
+	return 0;
+
+put_table:
+	dev_pm_opp_put_opp_table(emc->opp_table);
+
+	return err;
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
@@ -717,8 +885,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		goto unset_cb;
 	}
 
+	err = tegra_emc_opp_table_init(emc);
+	if (err)
+		goto unreg_notifier;
+
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
+	tegra_emc_interconnect_init(emc);
 
 	/*
 	 * Don't allow the kernel module to be unloaded. Unloading adds some
@@ -729,6 +902,8 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	return 0;
 
+unreg_notifier:
+	clk_notifier_unregister(emc->clk, &emc->clk_nb);
 unset_cb:
 	tegra20_clk_set_emc_round_callback(NULL, NULL);
 
@@ -747,6 +922,7 @@ static struct platform_driver tegra_emc_driver = {
 		.name = "tegra20-emc",
 		.of_match_table = tegra_emc_of_match,
 		.suppress_bind_attrs = true,
+		.sync_state = icc_sync_state,
 	},
 };
 module_platform_driver(tegra_emc_driver);
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
index a8098bff91d9..5127e8e8250f 100644
--- a/drivers/memory/tegra/tegra20.c
+++ b/drivers/memory/tegra/tegra20.c
@@ -280,6 +280,39 @@ static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
 	.reset_status = tegra20_mc_reset_status,
 };
 
+static int tegra20_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	/*
+	 * Technically, it should be possible to tune arbitration knobs here,
+	 * but the default values are known to work well on all devices.
+	 * Hence nothing to do here so far.
+	 */
+	return 0;
+}
+
+static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
+				   u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	/*
+	 * ISO clients need to reserve extra bandwidth up-front because
+	 * there could high bandwidth pressure during initial fulling-up
+	 * of the client's FIFO buffers. Secondly, we need to take into
+	 * account impurities of the memory subsystem.
+	 */
+	if (tag == TEGRA_MC_ICC_TAG_ISO)
+		peak_bw = tegra_mc_scale_percents(peak_bw, 300);
+
+	*agg_avg += avg_bw;
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
+static const struct tegra_mc_icc_ops tegra20_mc_icc_ops = {
+	.aggregate = tegra20_mc_icc_aggreate,
+	.set = tegra20_mc_icc_set,
+};
+
 const struct tegra_mc_soc tegra20_mc_soc = {
 	.clients = tegra20_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra20_mc_clients),
@@ -290,4 +323,5 @@ const struct tegra_mc_soc tegra20_mc_soc = {
 	.reset_ops = &tegra20_mc_reset_ops,
 	.resets = tegra20_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra20_mc_resets),
+	.icc_ops = &tegra20_mc_icc_ops,
 };
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 33/52] memory: tegra20: Support interconnect framework
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Now Internal and External Memory Controllers are memory interconnection
providers. This allows us to use interconnect API for tuning of memory
configuration. EMC driver now supports OPPs and DVFS.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |   3 +-
 drivers/memory/tegra/mc.h          |  12 ++
 drivers/memory/tegra/tegra20-emc.c | 176 +++++++++++++++++++++++++++++
 drivers/memory/tegra/tegra20.c     |  34 ++++++
 4 files changed, 224 insertions(+), 1 deletion(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index ff426747cd7d..ac3dfe155505 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -11,7 +11,8 @@ config TEGRA_MC
 config TEGRA20_EMC
 	tristate "NVIDIA Tegra20 External Memory Controller driver"
 	default y
-	depends on ARCH_TEGRA_2x_SOC
+	depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
+	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra20 chips. The EMC controls the external DRAM on the board.
diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
index abeb6a2cc36a..531fb4fb7b17 100644
--- a/drivers/memory/tegra/mc.h
+++ b/drivers/memory/tegra/mc.h
@@ -78,6 +78,18 @@
 
 #define MC_TIMING_UPDATE				BIT(0)
 
+static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
+{
+	val = val * percents;
+	do_div(val, 100);
+
+	/*
+	 * High freq + high boosting percent + large polling interval are
+	 * resulting in integer overflow when watermarks are calculated.
+	 */
+	return min_t(u64, val, U32_MAX);
+}
+
 static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
 {
 	return readl_relaxed(mc->regs + offset);
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 34085e26dced..69ccb3fe5b0b 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -9,6 +9,7 @@
 #include <linux/clk/tegra.h>
 #include <linux/debugfs.h>
 #include <linux/err.h>
+#include <linux/interconnect-provider.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
@@ -16,11 +17,15 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include <linux/types.h>
 
 #include <soc/tegra/fuse.h>
 
+#include "mc.h"
+
 #define EMC_INTSTATUS				0x000
 #define EMC_INTMASK				0x004
 #define EMC_DBG					0x008
@@ -144,6 +149,9 @@ struct emc_timing {
 
 struct tegra_emc {
 	struct device *dev;
+	struct tegra_mc *mc;
+	struct opp_table *opp_table;
+	struct icc_provider provider;
 	struct notifier_block clk_nb;
 	struct clk *clk;
 	void __iomem *regs;
@@ -658,6 +666,166 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
 			    emc, &tegra_emc_debug_max_rate_fops);
 }
 
+static inline struct tegra_emc *
+to_tegra_emc_provider(struct icc_provider *provider)
+{
+	return container_of(provider, struct tegra_emc, provider);
+}
+
+static struct icc_node_data *
+emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	/* External Memory is the only possible ICC route */
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != TEGRA_ICC_EMEM)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		/*
+		 * SRC and DST nodes should have matching TAG in order to have
+		 * it set by default for a requested path.
+		 */
+		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+		ndata->node = node;
+
+		return ndata;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
+	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
+	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
+	unsigned long long rate = max(avg_bw, peak_bw);
+	unsigned int dram_data_bus_width_bytes = 4;
+	long rounded_rate;
+	int err;
+
+	/*
+	 * Tegra20 EMC runs on x2 clock rate of SDRAM bus because DDR data
+	 * is sampled on both clock edges. This means that EMC clock rate
+	 * equals to the peak data rate.
+	 */
+	do_div(rate, dram_data_bus_width_bytes);
+	rate = min_t(u64, rate, U32_MAX);
+
+	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
+	if (rounded_rate < 0)
+		return rounded_rate;
+
+	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra_emc_interconnect_init(struct tegra_emc *emc)
+{
+	const struct tegra_mc_soc *soc;
+	struct icc_node *node;
+	int err;
+
+	emc->mc = devm_tegra_get_memory_controller(emc->dev);
+	if (IS_ERR(emc->mc))
+		return PTR_ERR(emc->mc);
+
+	soc = emc->mc->soc;
+
+	emc->provider.dev = emc->dev;
+	emc->provider.set = emc_icc_set;
+	emc->provider.data = &emc->provider;
+	emc->provider.aggregate = soc->icc_ops->aggregate;
+	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&emc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create External Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_EMC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "External Memory Controller";
+	icc_node_add(node, &emc->provider);
+
+	/* link External Memory Controller to External Memory (DRAM) */
+	err = icc_link_create(node, TEGRA_ICC_EMEM);
+	if (err)
+		goto remove_nodes;
+
+	/* create External Memory node */
+	node = icc_node_create(TEGRA_ICC_EMEM);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto remove_nodes;
+
+	node->name = "External Memory (DRAM)";
+	icc_node_add(node, &emc->provider);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&emc->provider);
+del_provider:
+	icc_provider_del(&emc->provider);
+err_msg:
+	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
+static int tegra_emc_opp_table_init(struct tegra_emc *emc)
+{
+	const char *rname = "core";
+	int err;
+
+	/*
+	 * Legacy device-trees don't have OPP table and EMC driver isn't
+	 * useful in this case.
+	 */
+	if (!device_property_present(emc->dev, "operating-points-v2")) {
+		dev_err(emc->dev, "OPP table not found\n");
+		dev_err(emc->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
+	/* voltage scaling is optional */
+	if (device_property_present(emc->dev, "core-supply"))
+		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
+	else
+		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
+
+	if (IS_ERR(emc->opp_table))
+		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
+				     "failed to prepare OPP table\n");
+
+	err = dev_pm_opp_of_add_table(emc->dev);
+	if (err) {
+		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
+		goto put_table;
+	}
+
+	return 0;
+
+put_table:
+	dev_pm_opp_put_opp_table(emc->opp_table);
+
+	return err;
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
@@ -717,8 +885,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		goto unset_cb;
 	}
 
+	err = tegra_emc_opp_table_init(emc);
+	if (err)
+		goto unreg_notifier;
+
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
+	tegra_emc_interconnect_init(emc);
 
 	/*
 	 * Don't allow the kernel module to be unloaded. Unloading adds some
@@ -729,6 +902,8 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	return 0;
 
+unreg_notifier:
+	clk_notifier_unregister(emc->clk, &emc->clk_nb);
 unset_cb:
 	tegra20_clk_set_emc_round_callback(NULL, NULL);
 
@@ -747,6 +922,7 @@ static struct platform_driver tegra_emc_driver = {
 		.name = "tegra20-emc",
 		.of_match_table = tegra_emc_of_match,
 		.suppress_bind_attrs = true,
+		.sync_state = icc_sync_state,
 	},
 };
 module_platform_driver(tegra_emc_driver);
diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
index a8098bff91d9..5127e8e8250f 100644
--- a/drivers/memory/tegra/tegra20.c
+++ b/drivers/memory/tegra/tegra20.c
@@ -280,6 +280,39 @@ static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
 	.reset_status = tegra20_mc_reset_status,
 };
 
+static int tegra20_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	/*
+	 * Technically, it should be possible to tune arbitration knobs here,
+	 * but the default values are known to work well on all devices.
+	 * Hence nothing to do here so far.
+	 */
+	return 0;
+}
+
+static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
+				   u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	/*
+	 * ISO clients need to reserve extra bandwidth up-front because
+	 * there could high bandwidth pressure during initial fulling-up
+	 * of the client's FIFO buffers. Secondly, we need to take into
+	 * account impurities of the memory subsystem.
+	 */
+	if (tag == TEGRA_MC_ICC_TAG_ISO)
+		peak_bw = tegra_mc_scale_percents(peak_bw, 300);
+
+	*agg_avg += avg_bw;
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
+static const struct tegra_mc_icc_ops tegra20_mc_icc_ops = {
+	.aggregate = tegra20_mc_icc_aggreate,
+	.set = tegra20_mc_icc_set,
+};
+
 const struct tegra_mc_soc tegra20_mc_soc = {
 	.clients = tegra20_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra20_mc_clients),
@@ -290,4 +323,5 @@ const struct tegra_mc_soc tegra20_mc_soc = {
 	.reset_ops = &tegra20_mc_reset_ops,
 	.resets = tegra20_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra20_mc_resets),
+	.icc_ops = &tegra20_mc_icc_ops,
 };
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 34/52] memory: tegra20-emc: Don't parse emc-stats node
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

EMC device-tree node now contains new emc-stats sub-node which needs to
be skipped when timing nodes are parsed by EMC driver, otherwise driver
will try to parse the emc-stats as a timing node and will error out.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra20-emc.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 69ccb3fe5b0b..27242659dfd6 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -349,7 +349,10 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
 	int child_count;
 	int err;
 
-	child_count = of_get_child_count(node);
+	child = of_find_node_by_name(node, "emc-stats");
+	of_node_put(child);
+
+	child_count = of_get_child_count(node) - (child ? 1 : 0);
 	if (!child_count) {
 		dev_err(emc->dev, "no memory timings in DT node: %pOF\n", node);
 		return -EINVAL;
@@ -364,6 +367,9 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
 	timing = emc->timings;
 
 	for_each_child_of_node(node, child) {
+		if (of_device_is_compatible(child, "nvidia,tegra20-emc-statistics"))
+			continue;
+
 		err = load_one_timing_from_dt(emc, timing++, child);
 		if (err) {
 			of_node_put(child);
@@ -391,7 +397,11 @@ tegra_emc_find_node_by_ram_code(struct device *dev)
 	u32 value, ram_code;
 	int err;
 
-	if (of_get_child_count(dev->of_node) == 0) {
+	/* old device-trees don't have emc-stats node */
+	np = of_find_node_by_name(dev->of_node, "emc-stats");
+	of_node_put(np);
+
+	if (of_get_child_count(dev->of_node) == (np ? 1 : 0)) {
 		dev_info(dev, "device-tree doesn't have memory timings\n");
 		return NULL;
 	}
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 34/52] memory: tegra20-emc: Don't parse emc-stats node
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

EMC device-tree node now contains new emc-stats sub-node which needs to
be skipped when timing nodes are parsed by EMC driver, otherwise driver
will try to parse the emc-stats as a timing node and will error out.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra20-emc.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 69ccb3fe5b0b..27242659dfd6 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -349,7 +349,10 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
 	int child_count;
 	int err;
 
-	child_count = of_get_child_count(node);
+	child = of_find_node_by_name(node, "emc-stats");
+	of_node_put(child);
+
+	child_count = of_get_child_count(node) - (child ? 1 : 0);
 	if (!child_count) {
 		dev_err(emc->dev, "no memory timings in DT node: %pOF\n", node);
 		return -EINVAL;
@@ -364,6 +367,9 @@ static int tegra_emc_load_timings_from_dt(struct tegra_emc *emc,
 	timing = emc->timings;
 
 	for_each_child_of_node(node, child) {
+		if (of_device_is_compatible(child, "nvidia,tegra20-emc-statistics"))
+			continue;
+
 		err = load_one_timing_from_dt(emc, timing++, child);
 		if (err) {
 			of_node_put(child);
@@ -391,7 +397,11 @@ tegra_emc_find_node_by_ram_code(struct device *dev)
 	u32 value, ram_code;
 	int err;
 
-	if (of_get_child_count(dev->of_node) == 0) {
+	/* old device-trees don't have emc-stats node */
+	np = of_find_node_by_name(dev->of_node, "emc-stats");
+	of_node_put(np);
+
+	if (of_get_child_count(dev->of_node) == (np ? 1 : 0)) {
 		dev_info(dev, "device-tree doesn't have memory timings\n");
 		return NULL;
 	}
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 35/52] memory: tegra: Add missing latency allowness entry for Page Table Cache
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

The PTC memory client misses the latency allowness entry and this patch
adds it.

This prevents erroneous clearing of MC_INTSTATUS 0x0 register during
of the LA programming in tegra_mc_setup_latency_allowance() due to the
missing entry. Note that this patch doesn't fix any known problems.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra114.c | 6 ++++++
 drivers/memory/tegra/tegra124.c | 6 ++++++
 drivers/memory/tegra/tegra30.c  | 6 ++++++
 3 files changed, 18 insertions(+)

diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index 48ef01c3ff90..ed376ba2d2fe 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra114_mc_clients[] = {
 		.id = 0x00,
 		.name = "ptcr",
 		.swgroup = TEGRA_SWGROUP_PTC,
+		.la = {
+			.reg = 0x34c,
+			.shift = 0,
+			.mask = 0xff,
+			.def = 0x0,
+		},
 	}, {
 		.id = 0x01,
 		.name = "display0a",
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 0cede24479bf..e2389573d3c0 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra124_mc_clients[] = {
 		.id = 0x00,
 		.name = "ptcr",
 		.swgroup = TEGRA_SWGROUP_PTC,
+		.la = {
+			.reg = 0x34c,
+			.shift = 0,
+			.mask = 0xff,
+			.def = 0x0,
+		},
 	}, {
 		.id = 0x01,
 		.name = "display0a",
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index fcdd812eed80..b1990b4133d8 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -36,6 +36,12 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 		.id = 0x00,
 		.name = "ptcr",
 		.swgroup = TEGRA_SWGROUP_PTC,
+		.la = {
+			.reg = 0x34c,
+			.shift = 0,
+			.mask = 0xff,
+			.def = 0x0,
+		},
 	}, {
 		.id = 0x01,
 		.name = "display0a",
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 35/52] memory: tegra: Add missing latency allowness entry for Page Table Cache
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

The PTC memory client misses the latency allowness entry and this patch
adds it.

This prevents erroneous clearing of MC_INTSTATUS 0x0 register during
of the LA programming in tegra_mc_setup_latency_allowance() due to the
missing entry. Note that this patch doesn't fix any known problems.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra114.c | 6 ++++++
 drivers/memory/tegra/tegra124.c | 6 ++++++
 drivers/memory/tegra/tegra30.c  | 6 ++++++
 3 files changed, 18 insertions(+)

diff --git a/drivers/memory/tegra/tegra114.c b/drivers/memory/tegra/tegra114.c
index 48ef01c3ff90..ed376ba2d2fe 100644
--- a/drivers/memory/tegra/tegra114.c
+++ b/drivers/memory/tegra/tegra114.c
@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra114_mc_clients[] = {
 		.id = 0x00,
 		.name = "ptcr",
 		.swgroup = TEGRA_SWGROUP_PTC,
+		.la = {
+			.reg = 0x34c,
+			.shift = 0,
+			.mask = 0xff,
+			.def = 0x0,
+		},
 	}, {
 		.id = 0x01,
 		.name = "display0a",
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index 0cede24479bf..e2389573d3c0 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -15,6 +15,12 @@ static const struct tegra_mc_client tegra124_mc_clients[] = {
 		.id = 0x00,
 		.name = "ptcr",
 		.swgroup = TEGRA_SWGROUP_PTC,
+		.la = {
+			.reg = 0x34c,
+			.shift = 0,
+			.mask = 0xff,
+			.def = 0x0,
+		},
 	}, {
 		.id = 0x01,
 		.name = "display0a",
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index fcdd812eed80..b1990b4133d8 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -36,6 +36,12 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 		.id = 0x00,
 		.name = "ptcr",
 		.swgroup = TEGRA_SWGROUP_PTC,
+		.la = {
+			.reg = 0x34c,
+			.shift = 0,
+			.mask = 0xff,
+			.def = 0x0,
+		},
 	}, {
 		.id = 0x01,
 		.name = "display0a",
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 36/52] memory: tegra: Add FIFO sizes to Tegra30 memory clients
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

The latency allowness is calculated based on buffering capabilities of
memory clients. This patch adds FIFO sizes to the Tegra30 memory clients.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra30.c | 66 ++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index b1990b4133d8..05780a0c6d39 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -42,6 +42,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x01,
 		.name = "display0a",
@@ -56,6 +57,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x02,
 		.name = "display0ab",
@@ -70,6 +72,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x03,
 		.name = "display0b",
@@ -84,6 +87,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x04,
 		.name = "display0bb",
@@ -98,6 +102,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x05,
 		.name = "display0c",
@@ -112,6 +117,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x06,
 		.name = "display0cb",
@@ -126,6 +132,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x07,
 		.name = "display1b",
@@ -140,6 +147,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x08,
 		.name = "display1bb",
@@ -154,6 +162,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x09,
 		.name = "eppup",
@@ -168,6 +177,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x17,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x0a,
 		.name = "g2pr",
@@ -182,6 +192,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x09,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x0b,
 		.name = "g2sr",
@@ -196,6 +207,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x09,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x0c,
 		.name = "mpeunifbr",
@@ -210,6 +222,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x50,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x0d,
 		.name = "viruv",
@@ -224,6 +237,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x2c,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x0e,
 		.name = "afir",
@@ -238,6 +252,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x0f,
 		.name = "avpcarm7r",
@@ -252,6 +267,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x04,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x10,
 		.name = "displayhc",
@@ -266,6 +282,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x11,
 		.name = "displayhcb",
@@ -280,6 +297,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x12,
 		.name = "fdcdrd",
@@ -294,6 +312,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x13,
 		.name = "fdcdrd2",
@@ -308,6 +327,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x14,
 		.name = "g2dr",
@@ -322,6 +342,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 48,
 	}, {
 		.id = 0x15,
 		.name = "hdar",
@@ -336,6 +357,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x16,
 		.name = "host1xdmar",
@@ -350,6 +372,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x05,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x17,
 		.name = "host1xr",
@@ -364,6 +387,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x50,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x18,
 		.name = "idxsrd",
@@ -378,6 +402,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x19,
 		.name = "idxsrd2",
@@ -392,6 +417,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x1a,
 		.name = "mpe_ipred",
@@ -406,6 +432,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x80,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x1b,
 		.name = "mpeamemrd",
@@ -420,6 +447,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x42,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x1c,
 		.name = "mpecsrd",
@@ -434,6 +462,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x1d,
 		.name = "ppcsahbdmar",
@@ -448,6 +477,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x1e,
 		.name = "ppcsahbslvr",
@@ -462,6 +492,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x12,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x1f,
 		.name = "satar",
@@ -476,6 +507,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x33,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x20,
 		.name = "texsrd",
@@ -490,6 +522,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x21,
 		.name = "texsrd2",
@@ -504,6 +537,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x22,
 		.name = "vdebsevr",
@@ -518,6 +552,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x23,
 		.name = "vdember",
@@ -532,6 +567,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xd0,
 		},
+		.fifo_size = 16 * 4,
 	}, {
 		.id = 0x24,
 		.name = "vdemcer",
@@ -546,6 +582,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x2a,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x25,
 		.name = "vdetper",
@@ -560,6 +597,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x74,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x26,
 		.name = "mpcorelpr",
@@ -570,6 +608,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x04,
 		},
+		.fifo_size = 16 * 14,
 	}, {
 		.id = 0x27,
 		.name = "mpcorer",
@@ -580,6 +619,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x04,
 		},
+		.fifo_size = 16 * 14,
 	}, {
 		.id = 0x28,
 		.name = "eppu",
@@ -594,6 +634,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x6c,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x29,
 		.name = "eppv",
@@ -608,6 +649,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x6c,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2a,
 		.name = "eppy",
@@ -622,6 +664,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x6c,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2b,
 		.name = "mpeunifbw",
@@ -636,6 +679,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x2c,
 		.name = "viwsb",
@@ -650,6 +694,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x12,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2d,
 		.name = "viwu",
@@ -664,6 +709,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xb2,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2e,
 		.name = "viwv",
@@ -678,6 +724,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xb2,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2f,
 		.name = "viwy",
@@ -692,6 +739,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x12,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x30,
 		.name = "g2dw",
@@ -706,6 +754,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x9,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x31,
 		.name = "afiw",
@@ -720,6 +769,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0c,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x32,
 		.name = "avpcarm7w",
@@ -734,6 +784,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0e,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x33,
 		.name = "fdcdwr",
@@ -748,6 +799,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x34,
 		.name = "fdcdwr2",
@@ -762,6 +814,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x35,
 		.name = "hdaw",
@@ -776,6 +829,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x36,
 		.name = "host1xw",
@@ -790,6 +844,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x37,
 		.name = "ispw",
@@ -804,6 +859,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x38,
 		.name = "mpcorelpw",
@@ -814,6 +870,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0e,
 		},
+		.fifo_size = 16 * 24,
 	}, {
 		.id = 0x39,
 		.name = "mpcorew",
@@ -824,6 +881,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0e,
 		},
+		.fifo_size = 16 * 24,
 	}, {
 		.id = 0x3a,
 		.name = "mpecswr",
@@ -838,6 +896,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x3b,
 		.name = "ppcsahbdmaw",
@@ -852,6 +911,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x3c,
 		.name = "ppcsahbslvw",
@@ -866,6 +926,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x06,
 		},
+		.fifo_size = 16 * 4,
 	}, {
 		.id = 0x3d,
 		.name = "sataw",
@@ -880,6 +941,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x33,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x3e,
 		.name = "vdebsevw",
@@ -894,6 +956,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 4,
 	}, {
 		.id = 0x3f,
 		.name = "vdedbgw",
@@ -908,6 +971,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x40,
 		.name = "vdembew",
@@ -922,6 +986,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x42,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x41,
 		.name = "vdetpmw",
@@ -936,6 +1001,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x2a,
 		},
+		.fifo_size = 16 * 16,
 	},
 };
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 36/52] memory: tegra: Add FIFO sizes to Tegra30 memory clients
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

The latency allowness is calculated based on buffering capabilities of
memory clients. This patch adds FIFO sizes to the Tegra30 memory clients.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra30.c | 66 ++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index b1990b4133d8..05780a0c6d39 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -42,6 +42,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x01,
 		.name = "display0a",
@@ -56,6 +57,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x02,
 		.name = "display0ab",
@@ -70,6 +72,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x03,
 		.name = "display0b",
@@ -84,6 +87,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x04,
 		.name = "display0bb",
@@ -98,6 +102,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x05,
 		.name = "display0c",
@@ -112,6 +117,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x06,
 		.name = "display0cb",
@@ -126,6 +132,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x07,
 		.name = "display1b",
@@ -140,6 +147,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x08,
 		.name = "display1bb",
@@ -154,6 +162,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x4e,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x09,
 		.name = "eppup",
@@ -168,6 +177,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x17,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x0a,
 		.name = "g2pr",
@@ -182,6 +192,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x09,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x0b,
 		.name = "g2sr",
@@ -196,6 +207,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x09,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x0c,
 		.name = "mpeunifbr",
@@ -210,6 +222,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x50,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x0d,
 		.name = "viruv",
@@ -224,6 +237,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x2c,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x0e,
 		.name = "afir",
@@ -238,6 +252,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x0f,
 		.name = "avpcarm7r",
@@ -252,6 +267,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x04,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x10,
 		.name = "displayhc",
@@ -266,6 +282,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x11,
 		.name = "displayhcb",
@@ -280,6 +297,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x12,
 		.name = "fdcdrd",
@@ -294,6 +312,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x13,
 		.name = "fdcdrd2",
@@ -308,6 +327,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x14,
 		.name = "g2dr",
@@ -322,6 +342,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 48,
 	}, {
 		.id = 0x15,
 		.name = "hdar",
@@ -336,6 +357,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x16,
 		.name = "host1xdmar",
@@ -350,6 +372,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x05,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x17,
 		.name = "host1xr",
@@ -364,6 +387,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x50,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x18,
 		.name = "idxsrd",
@@ -378,6 +402,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x19,
 		.name = "idxsrd2",
@@ -392,6 +417,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x1a,
 		.name = "mpe_ipred",
@@ -406,6 +432,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x80,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x1b,
 		.name = "mpeamemrd",
@@ -420,6 +447,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x42,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x1c,
 		.name = "mpecsrd",
@@ -434,6 +462,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x1d,
 		.name = "ppcsahbdmar",
@@ -448,6 +477,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x1e,
 		.name = "ppcsahbslvr",
@@ -462,6 +492,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x12,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x1f,
 		.name = "satar",
@@ -476,6 +507,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x33,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x20,
 		.name = "texsrd",
@@ -490,6 +522,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x21,
 		.name = "texsrd2",
@@ -504,6 +537,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x22,
 		.name = "vdebsevr",
@@ -518,6 +552,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x23,
 		.name = "vdember",
@@ -532,6 +567,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xd0,
 		},
+		.fifo_size = 16 * 4,
 	}, {
 		.id = 0x24,
 		.name = "vdemcer",
@@ -546,6 +582,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x2a,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x25,
 		.name = "vdetper",
@@ -560,6 +597,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x74,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x26,
 		.name = "mpcorelpr",
@@ -570,6 +608,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x04,
 		},
+		.fifo_size = 16 * 14,
 	}, {
 		.id = 0x27,
 		.name = "mpcorer",
@@ -580,6 +619,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x04,
 		},
+		.fifo_size = 16 * 14,
 	}, {
 		.id = 0x28,
 		.name = "eppu",
@@ -594,6 +634,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x6c,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x29,
 		.name = "eppv",
@@ -608,6 +649,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x6c,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2a,
 		.name = "eppy",
@@ -622,6 +664,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x6c,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2b,
 		.name = "mpeunifbw",
@@ -636,6 +679,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x13,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x2c,
 		.name = "viwsb",
@@ -650,6 +694,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x12,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2d,
 		.name = "viwu",
@@ -664,6 +709,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xb2,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2e,
 		.name = "viwv",
@@ -678,6 +724,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xb2,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x2f,
 		.name = "viwy",
@@ -692,6 +739,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x12,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x30,
 		.name = "g2dw",
@@ -706,6 +754,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x9,
 		},
+		.fifo_size = 16 * 128,
 	}, {
 		.id = 0x31,
 		.name = "afiw",
@@ -720,6 +769,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0c,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x32,
 		.name = "avpcarm7w",
@@ -734,6 +784,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0e,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x33,
 		.name = "fdcdwr",
@@ -748,6 +799,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x34,
 		.name = "fdcdwr2",
@@ -762,6 +814,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0a,
 		},
+		.fifo_size = 16 * 96,
 	}, {
 		.id = 0x35,
 		.name = "hdaw",
@@ -776,6 +829,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x36,
 		.name = "host1xw",
@@ -790,6 +844,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x37,
 		.name = "ispw",
@@ -804,6 +859,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 64,
 	}, {
 		.id = 0x38,
 		.name = "mpcorelpw",
@@ -814,6 +870,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0e,
 		},
+		.fifo_size = 16 * 24,
 	}, {
 		.id = 0x39,
 		.name = "mpcorew",
@@ -824,6 +881,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x0e,
 		},
+		.fifo_size = 16 * 24,
 	}, {
 		.id = 0x3a,
 		.name = "mpecswr",
@@ -838,6 +896,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 8,
 	}, {
 		.id = 0x3b,
 		.name = "ppcsahbdmaw",
@@ -852,6 +911,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x10,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x3c,
 		.name = "ppcsahbslvw",
@@ -866,6 +926,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x06,
 		},
+		.fifo_size = 16 * 4,
 	}, {
 		.id = 0x3d,
 		.name = "sataw",
@@ -880,6 +941,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x33,
 		},
+		.fifo_size = 16 * 32,
 	}, {
 		.id = 0x3e,
 		.name = "vdebsevw",
@@ -894,6 +956,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 4,
 	}, {
 		.id = 0x3f,
 		.name = "vdedbgw",
@@ -908,6 +971,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0xff,
 		},
+		.fifo_size = 16 * 16,
 	}, {
 		.id = 0x40,
 		.name = "vdembew",
@@ -922,6 +986,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x42,
 		},
+		.fifo_size = 16 * 2,
 	}, {
 		.id = 0x41,
 		.name = "vdetpmw",
@@ -936,6 +1001,7 @@ static const struct tegra_mc_client tegra30_mc_clients[] = {
 			.mask = 0xff,
 			.def = 0x2a,
 		},
+		.fifo_size = 16 * 16,
 	},
 };
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 37/52] memory: tegra30-emc: Make driver modular
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

This patch adds modularization support to the Tegra30 EMC driver. Driver
now can be compiled as a loadable kernel module.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |  2 +-
 drivers/memory/tegra/mc.c          |  3 +++
 drivers/memory/tegra/tegra30-emc.c | 17 ++++++++++++-----
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index ac3dfe155505..61cdb5c04b18 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -20,7 +20,7 @@ config TEGRA20_EMC
 	  external memory.
 
 config TEGRA30_EMC
-	bool "NVIDIA Tegra30 External Memory Controller driver"
+	tristate "NVIDIA Tegra30 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
 	help
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 53d61b05ebf8..15589bf8f5b6 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -346,6 +347,7 @@ int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(tegra_mc_write_emem_configuration);
 
 unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
 {
@@ -357,6 +359,7 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
 
 	return dram_count;
 }
+EXPORT_SYMBOL_GPL(tegra_mc_get_emem_device_count);
 
 static int load_one_timing(struct tegra_mc *mc,
 			   struct tegra_mc_timing *timing,
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 602dc4e08c61..b31e11f95462 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1331,6 +1331,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
 
+	/*
+	 * Don't allow the kernel module to be unloaded. Unloading adds some
+	 * extra complexity which doesn't really worth the effort in a case of
+	 * this driver.
+	 */
+	try_module_get(THIS_MODULE);
+
 	return 0;
 
 unset_cb:
@@ -1381,6 +1388,7 @@ static const struct of_device_id tegra_emc_of_match[] = {
 	{ .compatible = "nvidia,tegra30-emc", },
 	{},
 };
+MODULE_DEVICE_TABLE(of, tegra_emc_of_match);
 
 static struct platform_driver tegra_emc_driver = {
 	.probe = tegra_emc_probe,
@@ -1391,9 +1399,8 @@ static struct platform_driver tegra_emc_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
+module_platform_driver(tegra_emc_driver);
 
-static int __init tegra_emc_init(void)
-{
-	return platform_driver_register(&tegra_emc_driver);
-}
-subsys_initcall(tegra_emc_init);
+MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra30 EMC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 37/52] memory: tegra30-emc: Make driver modular
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

This patch adds modularization support to the Tegra30 EMC driver. Driver
now can be compiled as a loadable kernel module.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |  2 +-
 drivers/memory/tegra/mc.c          |  3 +++
 drivers/memory/tegra/tegra30-emc.c | 17 ++++++++++++-----
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index ac3dfe155505..61cdb5c04b18 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -20,7 +20,7 @@ config TEGRA20_EMC
 	  external memory.
 
 config TEGRA30_EMC
-	bool "NVIDIA Tegra30 External Memory Controller driver"
+	tristate "NVIDIA Tegra30 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
 	help
diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 53d61b05ebf8..15589bf8f5b6 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
+#include <linux/export.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -346,6 +347,7 @@ int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(tegra_mc_write_emem_configuration);
 
 unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
 {
@@ -357,6 +359,7 @@ unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc)
 
 	return dram_count;
 }
+EXPORT_SYMBOL_GPL(tegra_mc_get_emem_device_count);
 
 static int load_one_timing(struct tegra_mc *mc,
 			   struct tegra_mc_timing *timing,
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 602dc4e08c61..b31e11f95462 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1331,6 +1331,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
 
+	/*
+	 * Don't allow the kernel module to be unloaded. Unloading adds some
+	 * extra complexity which doesn't really worth the effort in a case of
+	 * this driver.
+	 */
+	try_module_get(THIS_MODULE);
+
 	return 0;
 
 unset_cb:
@@ -1381,6 +1388,7 @@ static const struct of_device_id tegra_emc_of_match[] = {
 	{ .compatible = "nvidia,tegra30-emc", },
 	{},
 };
+MODULE_DEVICE_TABLE(of, tegra_emc_of_match);
 
 static struct platform_driver tegra_emc_driver = {
 	.probe = tegra_emc_probe,
@@ -1391,9 +1399,8 @@ static struct platform_driver tegra_emc_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
+module_platform_driver(tegra_emc_driver);
 
-static int __init tegra_emc_init(void)
-{
-	return platform_driver_register(&tegra_emc_driver);
-}
-subsys_initcall(tegra_emc_init);
+MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra30 EMC driver");
+MODULE_LICENSE("GPL v2");
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 38/52] memory: tegra30-emc: Continue probing if timings are missing in device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

EMC driver will become mandatory after turning it into interconnect
provider because interconnect users, like display controller driver, will
fail to probe using newer device-trees that have interconnect properties.
Thus make EMC driver to probe even if timings are missing in device-tree.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra30-emc.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index b31e11f95462..78f770cf0d64 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -988,6 +988,11 @@ static struct device_node *emc_find_node_by_ram_code(struct device *dev)
 	u32 value, ram_code;
 	int err;
 
+	if (of_get_child_count(dev->of_node) == 0) {
+		dev_info(dev, "device-tree doesn't have memory timings\n");
+		return NULL;
+	}
+
 	ram_code = tegra_read_ram_code();
 
 	for_each_child_of_node(dev->of_node, np) {
@@ -1057,6 +1062,9 @@ static long emc_round_rate(unsigned long rate,
 	struct tegra_emc *emc = arg;
 	unsigned int i;
 
+	if (!emc->num_timings)
+		return clk_get_rate(emc->clk);
+
 	min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
 
 	for (i = 0; i < emc->num_timings; i++) {
@@ -1262,16 +1270,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	struct tegra_emc *emc;
 	int err;
 
-	if (of_get_child_count(pdev->dev.of_node) == 0) {
-		dev_info(&pdev->dev,
-			 "device-tree node doesn't have memory timings\n");
-		return -ENODEV;
-	}
-
-	np = emc_find_node_by_ram_code(&pdev->dev);
-	if (!np)
-		return -EINVAL;
-
 	emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
 	if (!emc) {
 		of_node_put(np);
@@ -1285,10 +1283,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	emc->clk_nb.notifier_call = emc_clk_change_notify;
 	emc->dev = &pdev->dev;
 
-	err = emc_load_timings_from_dt(emc, np);
-	of_node_put(np);
-	if (err)
-		return err;
+	np = emc_find_node_by_ram_code(&pdev->dev);
+	if (np) {
+		err = emc_load_timings_from_dt(emc, np);
+		of_node_put(np);
+		if (err)
+			return err;
+	}
 
 	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 38/52] memory: tegra30-emc: Continue probing if timings are missing in device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

EMC driver will become mandatory after turning it into interconnect
provider because interconnect users, like display controller driver, will
fail to probe using newer device-trees that have interconnect properties.
Thus make EMC driver to probe even if timings are missing in device-tree.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra30-emc.c | 29 +++++++++++++++--------------
 1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index b31e11f95462..78f770cf0d64 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -988,6 +988,11 @@ static struct device_node *emc_find_node_by_ram_code(struct device *dev)
 	u32 value, ram_code;
 	int err;
 
+	if (of_get_child_count(dev->of_node) == 0) {
+		dev_info(dev, "device-tree doesn't have memory timings\n");
+		return NULL;
+	}
+
 	ram_code = tegra_read_ram_code();
 
 	for_each_child_of_node(dev->of_node, np) {
@@ -1057,6 +1062,9 @@ static long emc_round_rate(unsigned long rate,
 	struct tegra_emc *emc = arg;
 	unsigned int i;
 
+	if (!emc->num_timings)
+		return clk_get_rate(emc->clk);
+
 	min_rate = min(min_rate, emc->timings[emc->num_timings - 1].rate);
 
 	for (i = 0; i < emc->num_timings; i++) {
@@ -1262,16 +1270,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	struct tegra_emc *emc;
 	int err;
 
-	if (of_get_child_count(pdev->dev.of_node) == 0) {
-		dev_info(&pdev->dev,
-			 "device-tree node doesn't have memory timings\n");
-		return -ENODEV;
-	}
-
-	np = emc_find_node_by_ram_code(&pdev->dev);
-	if (!np)
-		return -EINVAL;
-
 	emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
 	if (!emc) {
 		of_node_put(np);
@@ -1285,10 +1283,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	emc->clk_nb.notifier_call = emc_clk_change_notify;
 	emc->dev = &pdev->dev;
 
-	err = emc_load_timings_from_dt(emc, np);
-	of_node_put(np);
-	if (err)
-		return err;
+	np = emc_find_node_by_ram_code(&pdev->dev);
+	if (np) {
+		err = emc_load_timings_from_dt(emc, np);
+		of_node_put(np);
+		if (err)
+			return err;
+	}
 
 	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 39/52] memory: tegra30: Support interconnect framework
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Now Internal and External memory controllers are memory interconnection
providers. This allows us to use interconnect API for tuning of memory
configuration. EMC driver now supports OPPs and DVFS. MC driver now
supports tuning of memory arbitration latency, which needs to be done
for ISO memory clients, like a Display client for example.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |   1 +
 drivers/memory/tegra/tegra30-emc.c | 184 ++++++++++++++++++++++++++++-
 drivers/memory/tegra/tegra30.c     | 119 +++++++++++++++++++
 3 files changed, 302 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 61cdb5c04b18..73a5c5bca480 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -23,6 +23,7 @@ config TEGRA30_EMC
 	tristate "NVIDIA Tegra30 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
+	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra30 chips. The EMC controls the external DRAM on the board.
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 78f770cf0d64..66eae944ca6d 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -14,6 +14,7 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/interconnect-provider.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
@@ -21,6 +22,8 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include <linux/types.h>
 
@@ -326,6 +329,8 @@ struct emc_timing {
 struct tegra_emc {
 	struct device *dev;
 	struct tegra_mc *mc;
+	struct opp_table *opp_table;
+	struct icc_provider provider;
 	struct notifier_block clk_nb;
 	struct clk *clk;
 	void __iomem *regs;
@@ -973,11 +978,12 @@ static int emc_load_timings_from_dt(struct tegra_emc *emc,
 		return err;
 
 	dev_info(emc->dev,
-		 "got %u timings for RAM code %u (min %luMHz max %luMHz)\n",
+		 "got %u timings for RAM code %u (min %luMHz max %luMHz) OPP HW ver. 0x%lx\n",
 		 emc->num_timings,
 		 tegra_read_ram_code(),
 		 emc->timings[0].rate / 1000000,
-		 emc->timings[emc->num_timings - 1].rate / 1000000);
+		 emc->timings[emc->num_timings - 1].rate / 1000000,
+		 BIT(tegra_sku_info.soc_speedo_id));
 
 	return 0;
 }
@@ -1264,6 +1270,172 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
 			    emc, &tegra_emc_debug_max_rate_fops);
 }
 
+static inline struct tegra_emc *
+to_tegra_emc_provider(struct icc_provider *provider)
+{
+	return container_of(provider, struct tegra_emc, provider);
+}
+
+static struct icc_node_data *
+emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	/* External Memory is the only possible ICC route */
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != TEGRA_ICC_EMEM)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		/*
+		 * SRC and DST nodes should have matching TAG in order to have
+		 * it set by default for a requested path.
+		 */
+		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+		ndata->node = node;
+
+		return ndata;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
+	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
+	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
+	unsigned long long rate = max(avg_bw, peak_bw);
+	unsigned int dram_data_bus_width_bytes = 4;
+	unsigned int ddr = 2;
+	long rounded_rate;
+	int err;
+
+	/*
+	 * Tegra30 EMC runs on a clock rate of SDRAM bus. This means that
+	 * EMC clock rate is twice smaller than the peak data rate because
+	 * data is sample on both EMC clock edges.
+	 */
+	do_div(rate, ddr * dram_data_bus_width_bytes);
+	rate = min_t(u64, rate, U32_MAX);
+
+	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
+	if (rounded_rate < 0)
+		return rounded_rate;
+
+	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra_emc_interconnect_init(struct tegra_emc *emc)
+{
+	const struct tegra_mc_soc *soc = emc->mc->soc;
+	struct icc_node *node;
+	int err;
+
+	emc->provider.dev = emc->dev;
+	emc->provider.set = emc_icc_set;
+	emc->provider.data = &emc->provider;
+	emc->provider.aggregate = soc->icc_ops->aggregate;
+	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&emc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create External Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_EMC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "External Memory Controller";
+	icc_node_add(node, &emc->provider);
+
+	/* link External Memory Controller to External Memory (DRAM) */
+	err = icc_link_create(node, TEGRA_ICC_EMEM);
+	if (err)
+		goto remove_nodes;
+
+	/* create External Memory node */
+	node = icc_node_create(TEGRA_ICC_EMEM);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto remove_nodes;
+
+	node->name = "External Memory (DRAM)";
+	icc_node_add(node, &emc->provider);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&emc->provider);
+del_provider:
+	icc_provider_del(&emc->provider);
+err_msg:
+	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
+static int tegra_emc_opp_table_init(struct tegra_emc *emc)
+{
+	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
+	struct opp_table *opp_table;
+	const char *rname = "core";
+	int err;
+
+	/*
+	 * Legacy device-trees don't have OPP table and EMC driver isn't
+	 * useful in this case.
+	 */
+	if (!device_property_present(emc->dev, "operating-points-v2")) {
+		dev_err(emc->dev, "OPP table not found\n");
+		dev_err(emc->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
+	/* voltage scaling is optional */
+	if (device_property_present(emc->dev, "core-supply"))
+		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
+	else
+		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
+
+	if (IS_ERR(emc->opp_table))
+		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
+				     "failed to prepare OPP table\n");
+
+	opp_table = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
+	err = PTR_ERR_OR_ZERO(opp_table);
+	if (err) {
+		dev_err(emc->dev, "failed to set supported HW: %d\n", err);
+		goto put_table;
+	}
+
+	err = dev_pm_opp_of_add_table(emc->dev);
+	if (err) {
+		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
+		goto put_hw;
+	}
+
+	return 0;
+
+put_hw:
+	dev_pm_opp_put_supported_hw(emc->opp_table);
+put_table:
+	dev_pm_opp_put_opp_table(emc->opp_table);
+
+	return err;
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
@@ -1329,8 +1501,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		goto unset_cb;
 	}
 
+	err = tegra_emc_opp_table_init(emc);
+	if (err)
+		goto unreg_notifier;
+
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
+	tegra_emc_interconnect_init(emc);
 
 	/*
 	 * Don't allow the kernel module to be unloaded. Unloading adds some
@@ -1341,6 +1518,8 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	return 0;
 
+unreg_notifier:
+	clk_notifier_unregister(emc->clk, &emc->clk_nb);
 unset_cb:
 	tegra20_clk_set_emc_round_callback(NULL, NULL);
 
@@ -1398,6 +1577,7 @@ static struct platform_driver tegra_emc_driver = {
 		.of_match_table = tegra_emc_of_match,
 		.pm = &tegra_emc_pm_ops,
 		.suppress_bind_attrs = true,
+		.sync_state = icc_sync_state,
 	},
 };
 module_platform_driver(tegra_emc_driver);
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index 05780a0c6d39..f4ff967d7a10 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -1083,6 +1083,124 @@ static const struct tegra_mc_reset tegra30_mc_resets[] = {
 	TEGRA30_MC_RESET(VI,       0x200, 0x204, 17),
 };
 
+static void tegra30_mc_tune_client_latency(struct tegra_mc *mc,
+					   const struct tegra_mc_client *client,
+					   unsigned int bandwidth_mbytes_sec)
+{
+	u32 arb_tolerance_compensation_nsec, arb_tolerance_compensation_div;
+	const struct tegra_mc_la *la = &client->la;
+	unsigned int fifo_size = client->fifo_size;
+	u32 arb_nsec, la_ticks, value;
+
+	/* see 18.4.1 Client Configuration in Tegra3 TRM v03p */
+	if (bandwidth_mbytes_sec)
+		arb_nsec = fifo_size * NSEC_PER_USEC / bandwidth_mbytes_sec;
+	else
+		arb_nsec = U32_MAX;
+
+	/*
+	 * Latency allowness should be set with consideration for the module's
+	 * latency tolerance and internal buffering capabilities.
+	 *
+	 * Display memory clients use isochronous transfers and have very low
+	 * tolerance to a belated transfers. Hence we need to compensate the
+	 * memory arbitration imperfection for them in order to prevent FIFO
+	 * underflow condition when memory bus is busy.
+	 *
+	 * VI clients also need a stronger compensation.
+	 */
+	switch (client->swgroup) {
+	case TEGRA_SWGROUP_MPCORE:
+		/* we always want lower latency for CPU, hence don't touch it */
+		return;
+
+	case TEGRA_SWGROUP_DC:
+	case TEGRA_SWGROUP_DCB:
+		arb_tolerance_compensation_nsec = 1050;
+		arb_tolerance_compensation_div = 2;
+		break;
+
+	case TEGRA_SWGROUP_VI:
+		arb_tolerance_compensation_nsec = 1050;
+		arb_tolerance_compensation_div = 1;
+		break;
+
+	default:
+		arb_tolerance_compensation_nsec = 150;
+		arb_tolerance_compensation_div = 1;
+		break;
+	}
+
+	if (arb_nsec > arb_tolerance_compensation_nsec)
+		arb_nsec -= arb_tolerance_compensation_nsec;
+	else
+		arb_nsec = 0;
+
+	arb_nsec /= arb_tolerance_compensation_div;
+
+	/*
+	 * Latency allowance is a number of ticks a request from a particular
+	 * client may wait in the EMEM arbiter before it becomes a high-priority
+	 * request.
+	 */
+	la_ticks = arb_nsec / mc->tick;
+	la_ticks = min(la_ticks, la->mask);
+
+	value = mc_readl(mc, la->reg);
+	value &= ~(la->mask << la->shift);
+	value |= la_ticks << la->shift;
+	mc_writel(mc, value, la->reg);
+}
+
+static int tegra30_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct icc_provider *provider = src->provider;
+	struct tegra_mc *mc = container_of(provider, struct tegra_mc, provider);
+	const struct tegra_mc_client *client = &mc->soc->clients[src->id];
+	u64 peak_bandwidth = icc_units_to_bps(src->peak_bw);
+
+	/*
+	 * Skip pre-initialization that is done by icc_node_add(), which sets
+	 * bandwidth to maximum for all clients before drivers are loaded.
+	 *
+	 * This doesn't make sense for us because we don't have drivers for all
+	 * clients and it's okay to keep configuration left from bootloader
+	 * during boot, at least for today.
+	 */
+	if (src == dst)
+		return 0;
+
+	/* convert bytes/sec to megabytes/sec */
+	do_div(peak_bandwidth, 1000000);
+
+	tegra30_mc_tune_client_latency(mc, client, peak_bandwidth);
+
+	return 0;
+}
+
+static int tegra30_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
+				   u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	/*
+	 * ISO clients need to reserve extra bandwidth up-front because
+	 * there could high bandwidth pressure during initial fulling-up
+	 * of the client's FIFO buffers. Secondly, we need to take into
+	 * account impurities of the memory subsystem.
+	 */
+	if (tag == TEGRA_MC_ICC_TAG_ISO)
+		peak_bw = tegra_mc_scale_percents(peak_bw, 400);
+
+	*agg_avg += avg_bw;
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
+static const struct tegra_mc_icc_ops tegra30_mc_icc_ops = {
+	.aggregate = tegra30_mc_icc_aggreate,
+	.set = tegra30_mc_icc_set,
+};
+
 const struct tegra_mc_soc tegra30_mc_soc = {
 	.clients = tegra30_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra30_mc_clients),
@@ -1097,4 +1215,5 @@ const struct tegra_mc_soc tegra30_mc_soc = {
 	.reset_ops = &tegra_mc_reset_ops_common,
 	.resets = tegra30_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra30_mc_resets),
+	.icc_ops = &tegra30_mc_icc_ops,
 };
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 39/52] memory: tegra30: Support interconnect framework
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Now Internal and External memory controllers are memory interconnection
providers. This allows us to use interconnect API for tuning of memory
configuration. EMC driver now supports OPPs and DVFS. MC driver now
supports tuning of memory arbitration latency, which needs to be done
for ISO memory clients, like a Display client for example.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig       |   1 +
 drivers/memory/tegra/tegra30-emc.c | 184 ++++++++++++++++++++++++++++-
 drivers/memory/tegra/tegra30.c     | 119 +++++++++++++++++++
 3 files changed, 302 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 61cdb5c04b18..73a5c5bca480 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -23,6 +23,7 @@ config TEGRA30_EMC
 	tristate "NVIDIA Tegra30 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_3x_SOC
+	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra30 chips. The EMC controls the external DRAM on the board.
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 78f770cf0d64..66eae944ca6d 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -14,6 +14,7 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/err.h>
+#include <linux/interconnect-provider.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
@@ -21,6 +22,8 @@
 #include <linux/module.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
+#include <linux/slab.h>
 #include <linux/sort.h>
 #include <linux/types.h>
 
@@ -326,6 +329,8 @@ struct emc_timing {
 struct tegra_emc {
 	struct device *dev;
 	struct tegra_mc *mc;
+	struct opp_table *opp_table;
+	struct icc_provider provider;
 	struct notifier_block clk_nb;
 	struct clk *clk;
 	void __iomem *regs;
@@ -973,11 +978,12 @@ static int emc_load_timings_from_dt(struct tegra_emc *emc,
 		return err;
 
 	dev_info(emc->dev,
-		 "got %u timings for RAM code %u (min %luMHz max %luMHz)\n",
+		 "got %u timings for RAM code %u (min %luMHz max %luMHz) OPP HW ver. 0x%lx\n",
 		 emc->num_timings,
 		 tegra_read_ram_code(),
 		 emc->timings[0].rate / 1000000,
-		 emc->timings[emc->num_timings - 1].rate / 1000000);
+		 emc->timings[emc->num_timings - 1].rate / 1000000,
+		 BIT(tegra_sku_info.soc_speedo_id));
 
 	return 0;
 }
@@ -1264,6 +1270,172 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
 			    emc, &tegra_emc_debug_max_rate_fops);
 }
 
+static inline struct tegra_emc *
+to_tegra_emc_provider(struct icc_provider *provider)
+{
+	return container_of(provider, struct tegra_emc, provider);
+}
+
+static struct icc_node_data *
+emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	/* External Memory is the only possible ICC route */
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != TEGRA_ICC_EMEM)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		/*
+		 * SRC and DST nodes should have matching TAG in order to have
+		 * it set by default for a requested path.
+		 */
+		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+		ndata->node = node;
+
+		return ndata;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
+	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
+	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
+	unsigned long long rate = max(avg_bw, peak_bw);
+	unsigned int dram_data_bus_width_bytes = 4;
+	unsigned int ddr = 2;
+	long rounded_rate;
+	int err;
+
+	/*
+	 * Tegra30 EMC runs on a clock rate of SDRAM bus. This means that
+	 * EMC clock rate is twice smaller than the peak data rate because
+	 * data is sample on both EMC clock edges.
+	 */
+	do_div(rate, ddr * dram_data_bus_width_bytes);
+	rate = min_t(u64, rate, U32_MAX);
+
+	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
+	if (rounded_rate < 0)
+		return rounded_rate;
+
+	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra_emc_interconnect_init(struct tegra_emc *emc)
+{
+	const struct tegra_mc_soc *soc = emc->mc->soc;
+	struct icc_node *node;
+	int err;
+
+	emc->provider.dev = emc->dev;
+	emc->provider.set = emc_icc_set;
+	emc->provider.data = &emc->provider;
+	emc->provider.aggregate = soc->icc_ops->aggregate;
+	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&emc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create External Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_EMC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "External Memory Controller";
+	icc_node_add(node, &emc->provider);
+
+	/* link External Memory Controller to External Memory (DRAM) */
+	err = icc_link_create(node, TEGRA_ICC_EMEM);
+	if (err)
+		goto remove_nodes;
+
+	/* create External Memory node */
+	node = icc_node_create(TEGRA_ICC_EMEM);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto remove_nodes;
+
+	node->name = "External Memory (DRAM)";
+	icc_node_add(node, &emc->provider);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&emc->provider);
+del_provider:
+	icc_provider_del(&emc->provider);
+err_msg:
+	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
+static int tegra_emc_opp_table_init(struct tegra_emc *emc)
+{
+	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
+	struct opp_table *opp_table;
+	const char *rname = "core";
+	int err;
+
+	/*
+	 * Legacy device-trees don't have OPP table and EMC driver isn't
+	 * useful in this case.
+	 */
+	if (!device_property_present(emc->dev, "operating-points-v2")) {
+		dev_err(emc->dev, "OPP table not found\n");
+		dev_err(emc->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
+	/* voltage scaling is optional */
+	if (device_property_present(emc->dev, "core-supply"))
+		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
+	else
+		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
+
+	if (IS_ERR(emc->opp_table))
+		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
+				     "failed to prepare OPP table\n");
+
+	opp_table = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
+	err = PTR_ERR_OR_ZERO(opp_table);
+	if (err) {
+		dev_err(emc->dev, "failed to set supported HW: %d\n", err);
+		goto put_table;
+	}
+
+	err = dev_pm_opp_of_add_table(emc->dev);
+	if (err) {
+		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
+		goto put_hw;
+	}
+
+	return 0;
+
+put_hw:
+	dev_pm_opp_put_supported_hw(emc->opp_table);
+put_table:
+	dev_pm_opp_put_opp_table(emc->opp_table);
+
+	return err;
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
@@ -1329,8 +1501,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		goto unset_cb;
 	}
 
+	err = tegra_emc_opp_table_init(emc);
+	if (err)
+		goto unreg_notifier;
+
 	platform_set_drvdata(pdev, emc);
 	tegra_emc_debugfs_init(emc);
+	tegra_emc_interconnect_init(emc);
 
 	/*
 	 * Don't allow the kernel module to be unloaded. Unloading adds some
@@ -1341,6 +1518,8 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	return 0;
 
+unreg_notifier:
+	clk_notifier_unregister(emc->clk, &emc->clk_nb);
 unset_cb:
 	tegra20_clk_set_emc_round_callback(NULL, NULL);
 
@@ -1398,6 +1577,7 @@ static struct platform_driver tegra_emc_driver = {
 		.of_match_table = tegra_emc_of_match,
 		.pm = &tegra_emc_pm_ops,
 		.suppress_bind_attrs = true,
+		.sync_state = icc_sync_state,
 	},
 };
 module_platform_driver(tegra_emc_driver);
diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c
index 05780a0c6d39..f4ff967d7a10 100644
--- a/drivers/memory/tegra/tegra30.c
+++ b/drivers/memory/tegra/tegra30.c
@@ -1083,6 +1083,124 @@ static const struct tegra_mc_reset tegra30_mc_resets[] = {
 	TEGRA30_MC_RESET(VI,       0x200, 0x204, 17),
 };
 
+static void tegra30_mc_tune_client_latency(struct tegra_mc *mc,
+					   const struct tegra_mc_client *client,
+					   unsigned int bandwidth_mbytes_sec)
+{
+	u32 arb_tolerance_compensation_nsec, arb_tolerance_compensation_div;
+	const struct tegra_mc_la *la = &client->la;
+	unsigned int fifo_size = client->fifo_size;
+	u32 arb_nsec, la_ticks, value;
+
+	/* see 18.4.1 Client Configuration in Tegra3 TRM v03p */
+	if (bandwidth_mbytes_sec)
+		arb_nsec = fifo_size * NSEC_PER_USEC / bandwidth_mbytes_sec;
+	else
+		arb_nsec = U32_MAX;
+
+	/*
+	 * Latency allowness should be set with consideration for the module's
+	 * latency tolerance and internal buffering capabilities.
+	 *
+	 * Display memory clients use isochronous transfers and have very low
+	 * tolerance to a belated transfers. Hence we need to compensate the
+	 * memory arbitration imperfection for them in order to prevent FIFO
+	 * underflow condition when memory bus is busy.
+	 *
+	 * VI clients also need a stronger compensation.
+	 */
+	switch (client->swgroup) {
+	case TEGRA_SWGROUP_MPCORE:
+		/* we always want lower latency for CPU, hence don't touch it */
+		return;
+
+	case TEGRA_SWGROUP_DC:
+	case TEGRA_SWGROUP_DCB:
+		arb_tolerance_compensation_nsec = 1050;
+		arb_tolerance_compensation_div = 2;
+		break;
+
+	case TEGRA_SWGROUP_VI:
+		arb_tolerance_compensation_nsec = 1050;
+		arb_tolerance_compensation_div = 1;
+		break;
+
+	default:
+		arb_tolerance_compensation_nsec = 150;
+		arb_tolerance_compensation_div = 1;
+		break;
+	}
+
+	if (arb_nsec > arb_tolerance_compensation_nsec)
+		arb_nsec -= arb_tolerance_compensation_nsec;
+	else
+		arb_nsec = 0;
+
+	arb_nsec /= arb_tolerance_compensation_div;
+
+	/*
+	 * Latency allowance is a number of ticks a request from a particular
+	 * client may wait in the EMEM arbiter before it becomes a high-priority
+	 * request.
+	 */
+	la_ticks = arb_nsec / mc->tick;
+	la_ticks = min(la_ticks, la->mask);
+
+	value = mc_readl(mc, la->reg);
+	value &= ~(la->mask << la->shift);
+	value |= la_ticks << la->shift;
+	mc_writel(mc, value, la->reg);
+}
+
+static int tegra30_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct icc_provider *provider = src->provider;
+	struct tegra_mc *mc = container_of(provider, struct tegra_mc, provider);
+	const struct tegra_mc_client *client = &mc->soc->clients[src->id];
+	u64 peak_bandwidth = icc_units_to_bps(src->peak_bw);
+
+	/*
+	 * Skip pre-initialization that is done by icc_node_add(), which sets
+	 * bandwidth to maximum for all clients before drivers are loaded.
+	 *
+	 * This doesn't make sense for us because we don't have drivers for all
+	 * clients and it's okay to keep configuration left from bootloader
+	 * during boot, at least for today.
+	 */
+	if (src == dst)
+		return 0;
+
+	/* convert bytes/sec to megabytes/sec */
+	do_div(peak_bandwidth, 1000000);
+
+	tegra30_mc_tune_client_latency(mc, client, peak_bandwidth);
+
+	return 0;
+}
+
+static int tegra30_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
+				   u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	/*
+	 * ISO clients need to reserve extra bandwidth up-front because
+	 * there could high bandwidth pressure during initial fulling-up
+	 * of the client's FIFO buffers. Secondly, we need to take into
+	 * account impurities of the memory subsystem.
+	 */
+	if (tag == TEGRA_MC_ICC_TAG_ISO)
+		peak_bw = tegra_mc_scale_percents(peak_bw, 400);
+
+	*agg_avg += avg_bw;
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
+static const struct tegra_mc_icc_ops tegra30_mc_icc_ops = {
+	.aggregate = tegra30_mc_icc_aggreate,
+	.set = tegra30_mc_icc_set,
+};
+
 const struct tegra_mc_soc tegra30_mc_soc = {
 	.clients = tegra30_mc_clients,
 	.num_clients = ARRAY_SIZE(tegra30_mc_clients),
@@ -1097,4 +1215,5 @@ const struct tegra_mc_soc tegra30_mc_soc = {
 	.reset_ops = &tegra_mc_reset_ops_common,
 	.resets = tegra30_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra30_mc_resets),
+	.icc_ops = &tegra30_mc_icc_ops,
 };
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 40/52] memory: tegra124-emc: Make driver modular
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

This patch adds modularization support to the Tegra124 EMC driver. Driver
now can be compiled as a loadable kernel module. Note that EMC clock must
be registered at clk-init time, otherwise PLLM will be disabled as unused
clock at boot time if EMC driver is compiled as a module, hence this patch
adds prepare/complete callbacks, similar to what is done for Tegra20/30
EMC drivers.

Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/clk/tegra/Makefile           |  2 +-
 drivers/clk/tegra/clk-tegra124-emc.c | 41 ++++++++++++++++++++++++----
 drivers/clk/tegra/clk-tegra124.c     | 27 ++++++++++++++++--
 drivers/clk/tegra/clk.h              | 16 +++--------
 drivers/memory/tegra/Kconfig         |  2 +-
 drivers/memory/tegra/tegra124-emc.c  | 31 ++++++++++++++-------
 include/linux/clk/tegra.h            |  9 ++++++
 include/soc/tegra/emc.h              | 16 -----------
 8 files changed, 96 insertions(+), 48 deletions(-)
 delete mode 100644 include/soc/tegra/emc.h

diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index eec2313fd37e..c3f6549be069 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= clk-tegra20-emc.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= clk-tegra114.o
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= clk-tegra124.o
 obj-$(CONFIG_TEGRA_CLK_DFLL)		+= clk-tegra124-dfll-fcpu.o
-obj-$(CONFIG_TEGRA124_EMC)		+= clk-tegra124-emc.o
+obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= clk-tegra124-emc.o
 obj-$(CONFIG_ARCH_TEGRA_132_SOC)	+= clk-tegra124.o
 obj-y					+= cvb.o
 obj-$(CONFIG_ARCH_TEGRA_210_SOC)	+= clk-tegra210.o
diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c
index 745f9faa98d8..bdf6f4a51617 100644
--- a/drivers/clk/tegra/clk-tegra124-emc.c
+++ b/drivers/clk/tegra/clk-tegra124-emc.c
@@ -11,7 +11,9 @@
 #include <linux/clk-provider.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk/tegra.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
@@ -21,7 +23,6 @@
 #include <linux/string.h>
 
 #include <soc/tegra/fuse.h>
-#include <soc/tegra/emc.h>
 
 #include "clk.h"
 
@@ -80,6 +81,9 @@ struct tegra_clk_emc {
 	int num_timings;
 	struct emc_timing *timings;
 	spinlock_t *lock;
+
+	tegra124_emc_prepare_timing_change_cb *prepare_timing_change;
+	tegra124_emc_complete_timing_change_cb *complete_timing_change;
 };
 
 /* Common clock framework callback implementations */
@@ -176,6 +180,9 @@ static struct tegra_emc *emc_ensure_emc_driver(struct tegra_clk_emc *tegra)
 	if (tegra->emc)
 		return tegra->emc;
 
+	if (!tegra->prepare_timing_change || !tegra->complete_timing_change)
+		return NULL;
+
 	if (!tegra->emc_node)
 		return NULL;
 
@@ -241,7 +248,7 @@ static int emc_set_timing(struct tegra_clk_emc *tegra,
 
 	div = timing->parent_rate / (timing->rate / 2) - 2;
 
-	err = tegra_emc_prepare_timing_change(emc, timing->rate);
+	err = tegra->prepare_timing_change(emc, timing->rate);
 	if (err)
 		return err;
 
@@ -259,7 +266,7 @@ static int emc_set_timing(struct tegra_clk_emc *tegra,
 
 	spin_unlock_irqrestore(tegra->lock, flags);
 
-	tegra_emc_complete_timing_change(emc, timing->rate);
+	tegra->complete_timing_change(emc, timing->rate);
 
 	clk_hw_reparent(&tegra->hw, __clk_get_hw(timing->parent));
 	clk_disable_unprepare(tegra->prev_parent);
@@ -473,8 +480,8 @@ static const struct clk_ops tegra_clk_emc_ops = {
 	.get_parent = emc_get_parent,
 };
 
-struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
-				   spinlock_t *lock)
+struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np,
+				      spinlock_t *lock)
 {
 	struct tegra_clk_emc *tegra;
 	struct clk_init_data init;
@@ -538,3 +545,27 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
 
 	return clk;
 };
+
+void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
+				    tegra124_emc_complete_timing_change_cb *complete_cb)
+{
+	struct clk *clk = __clk_lookup("emc");
+	struct tegra_clk_emc *tegra;
+	struct clk_hw *hw;
+
+	if (clk) {
+		hw = __clk_get_hw(clk);
+		tegra = container_of(hw, struct tegra_clk_emc, hw);
+
+		tegra->prepare_timing_change = prep_cb;
+		tegra->complete_timing_change = complete_cb;
+	}
+}
+EXPORT_SYMBOL_GPL(tegra124_clk_set_emc_callbacks);
+
+bool tegra124_clk_emc_driver_available(struct clk_hw *hw)
+{
+	struct tegra_clk_emc *tegra = container_of(hw, struct tegra_clk_emc, hw);
+
+	return tegra->prepare_timing_change && tegra->complete_timing_change;
+}
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index e931319dcc9d..b4f2ae4066a6 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -929,6 +929,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true },
 	[tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true },
 	[tegra_clk_cec] = { .dt_id = TEGRA124_CLK_CEC, .present = true },
+	[tegra_clk_emc] = { .dt_id = TEGRA124_CLK_EMC, .present = false },
 };
 
 static struct tegra_devclk devclks[] __initdata = {
@@ -1500,6 +1501,26 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
 	writel(plld_base, clk_base + PLLD_BASE);
 }
 
+static struct clk *tegra124_clk_src_onecell_get(struct of_phandle_args *clkspec,
+						void *data)
+{
+	struct clk_hw *hw;
+	struct clk *clk;
+
+	clk = of_clk_src_onecell_get(clkspec, data);
+	if (IS_ERR(clk))
+		return clk;
+
+	hw = __clk_get_hw(clk);
+
+	if (clkspec->args[0] == TEGRA124_CLK_EMC) {
+		if (!tegra124_clk_emc_driver_available(hw))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return clk;
+}
+
 /**
  * tegra124_132_clock_init_post - clock initialization postamble for T124/T132
  * @np: struct device_node * of the DT node for the SoC CAR IP block
@@ -1516,10 +1537,10 @@ static void __init tegra124_132_clock_init_post(struct device_node *np)
 				  &pll_x_params);
 	tegra_init_special_resets(1, tegra124_reset_assert,
 				  tegra124_reset_deassert);
-	tegra_add_of_provider(np, of_clk_src_onecell_get);
+	tegra_add_of_provider(np, tegra124_clk_src_onecell_get);
 
-	clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np,
-							&emc_lock);
+	clks[TEGRA124_CLK_EMC] = tegra124_clk_register_emc(clk_base, np,
+							   &emc_lock);
 
 	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
 
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 6b565f6b5f66..2da7c93c1a6c 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -881,18 +881,6 @@ void tegra_super_clk_gen5_init(void __iomem *clk_base,
 			void __iomem *pmc_base, struct tegra_clk *tegra_clks,
 			struct tegra_clk_pll_params *pll_params);
 
-#ifdef CONFIG_TEGRA124_EMC
-struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
-				   spinlock_t *lock);
-#else
-static inline struct clk *tegra_clk_register_emc(void __iomem *base,
-						 struct device_node *np,
-						 spinlock_t *lock)
-{
-	return NULL;
-}
-#endif
-
 void tegra114_clock_tune_cpu_trimmers_high(void);
 void tegra114_clock_tune_cpu_trimmers_low(void);
 void tegra114_clock_tune_cpu_trimmers_init(void);
@@ -922,6 +910,10 @@ void tegra_clk_periph_resume(void);
 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw);
 struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter);
 
+struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np,
+				      spinlock_t *lock);
+bool tegra124_clk_emc_driver_available(struct clk_hw *emc_hw);
+
 struct clk *tegra210_clk_register_emc(struct device_node *np,
 				      void __iomem *regs);
 
diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 73a5c5bca480..94536dc4c495 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -31,7 +31,7 @@ config TEGRA30_EMC
 	  external memory.
 
 config TEGRA124_EMC
-	bool "NVIDIA Tegra124 External Memory Controller driver"
+	tristate "NVIDIA Tegra124 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_124_SOC
 	help
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index b92259d4fbd1..48e772ec544d 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -9,16 +9,17 @@
 #include <linux/clk-provider.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk/tegra.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/sort.h>
 #include <linux/string.h>
 
-#include <soc/tegra/emc.h>
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/mc.h>
 
@@ -562,8 +563,8 @@ static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc,
 	return timing;
 }
 
-int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
-				    unsigned long rate)
+static int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
+					   unsigned long rate)
 {
 	struct emc_timing *timing = tegra_emc_find_timing(emc, rate);
 	struct emc_timing *last = &emc->last_timing;
@@ -790,8 +791,8 @@ int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
 	return 0;
 }
 
-void tegra_emc_complete_timing_change(struct tegra_emc *emc,
-				      unsigned long rate)
+static void tegra_emc_complete_timing_change(struct tegra_emc *emc,
+					     unsigned long rate)
 {
 	struct emc_timing *timing = tegra_emc_find_timing(emc, rate);
 	struct emc_timing *last = &emc->last_timing;
@@ -987,6 +988,7 @@ static const struct of_device_id tegra_emc_of_match[] = {
 	{ .compatible = "nvidia,tegra132-emc" },
 	{}
 };
+MODULE_DEVICE_TABLE(of, tegra_emc_of_match);
 
 static struct device_node *
 tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code)
@@ -1228,9 +1230,19 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, emc);
 
+	tegra124_clk_set_emc_callbacks(tegra_emc_prepare_timing_change,
+				       tegra_emc_complete_timing_change);
+
 	if (IS_ENABLED(CONFIG_DEBUG_FS))
 		emc_debugfs_init(&pdev->dev, emc);
 
+	/*
+	 * Don't allow the kernel module to be unloaded. Unloading adds some
+	 * extra complexity which doesn't really worth the effort in a case of
+	 * this driver.
+	 */
+	try_module_get(THIS_MODULE);
+
 	return 0;
 };
 
@@ -1242,9 +1254,8 @@ static struct platform_driver tegra_emc_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
+module_platform_driver(tegra_emc_driver);
 
-static int tegra_emc_init(void)
-{
-	return platform_driver_register(&tegra_emc_driver);
-}
-subsys_initcall(tegra_emc_init);
+MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra124 EMC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index 3f01d43f0598..d4c5e607ef29 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -136,6 +136,8 @@ extern void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value);
 extern void tegra210_clk_emc_update_setting(u32 emc_src_value);
 
 struct clk;
+struct device_node;
+struct tegra_emc;
 
 typedef long (tegra20_clk_emc_round_cb)(unsigned long rate,
 					unsigned long min_rate,
@@ -146,6 +148,13 @@ void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
 					void *cb_arg);
 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same);
 
+typedef int (tegra124_emc_prepare_timing_change_cb)(struct tegra_emc *emc,
+						    unsigned long rate);
+typedef void (tegra124_emc_complete_timing_change_cb)(struct tegra_emc *emc,
+						      unsigned long rate);
+void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
+				    tegra124_emc_complete_timing_change_cb *complete_cb);
+
 struct tegra210_clk_emc_config {
 	unsigned long rate;
 	bool same_freq;
diff --git a/include/soc/tegra/emc.h b/include/soc/tegra/emc.h
deleted file mode 100644
index 05199a97ccf4..000000000000
--- a/include/soc/tegra/emc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2014 NVIDIA Corporation. All rights reserved.
- */
-
-#ifndef __SOC_TEGRA_EMC_H__
-#define __SOC_TEGRA_EMC_H__
-
-struct tegra_emc;
-
-int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
-				    unsigned long rate);
-void tegra_emc_complete_timing_change(struct tegra_emc *emc,
-				      unsigned long rate);
-
-#endif /* __SOC_TEGRA_EMC_H__ */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 40/52] memory: tegra124-emc: Make driver modular
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

This patch adds modularization support to the Tegra124 EMC driver. Driver
now can be compiled as a loadable kernel module. Note that EMC clock must
be registered at clk-init time, otherwise PLLM will be disabled as unused
clock at boot time if EMC driver is compiled as a module, hence this patch
adds prepare/complete callbacks, similar to what is done for Tegra20/30
EMC drivers.

Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/clk/tegra/Makefile           |  2 +-
 drivers/clk/tegra/clk-tegra124-emc.c | 41 ++++++++++++++++++++++++----
 drivers/clk/tegra/clk-tegra124.c     | 27 ++++++++++++++++--
 drivers/clk/tegra/clk.h              | 16 +++--------
 drivers/memory/tegra/Kconfig         |  2 +-
 drivers/memory/tegra/tegra124-emc.c  | 31 ++++++++++++++-------
 include/linux/clk/tegra.h            |  9 ++++++
 include/soc/tegra/emc.h              | 16 -----------
 8 files changed, 96 insertions(+), 48 deletions(-)
 delete mode 100644 include/soc/tegra/emc.h

diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index eec2313fd37e..c3f6549be069 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -22,7 +22,7 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= clk-tegra20-emc.o
 obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= clk-tegra114.o
 obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= clk-tegra124.o
 obj-$(CONFIG_TEGRA_CLK_DFLL)		+= clk-tegra124-dfll-fcpu.o
-obj-$(CONFIG_TEGRA124_EMC)		+= clk-tegra124-emc.o
+obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= clk-tegra124-emc.o
 obj-$(CONFIG_ARCH_TEGRA_132_SOC)	+= clk-tegra124.o
 obj-y					+= cvb.o
 obj-$(CONFIG_ARCH_TEGRA_210_SOC)	+= clk-tegra210.o
diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c
index 745f9faa98d8..bdf6f4a51617 100644
--- a/drivers/clk/tegra/clk-tegra124-emc.c
+++ b/drivers/clk/tegra/clk-tegra124-emc.c
@@ -11,7 +11,9 @@
 #include <linux/clk-provider.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk/tegra.h>
 #include <linux/delay.h>
+#include <linux/export.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
@@ -21,7 +23,6 @@
 #include <linux/string.h>
 
 #include <soc/tegra/fuse.h>
-#include <soc/tegra/emc.h>
 
 #include "clk.h"
 
@@ -80,6 +81,9 @@ struct tegra_clk_emc {
 	int num_timings;
 	struct emc_timing *timings;
 	spinlock_t *lock;
+
+	tegra124_emc_prepare_timing_change_cb *prepare_timing_change;
+	tegra124_emc_complete_timing_change_cb *complete_timing_change;
 };
 
 /* Common clock framework callback implementations */
@@ -176,6 +180,9 @@ static struct tegra_emc *emc_ensure_emc_driver(struct tegra_clk_emc *tegra)
 	if (tegra->emc)
 		return tegra->emc;
 
+	if (!tegra->prepare_timing_change || !tegra->complete_timing_change)
+		return NULL;
+
 	if (!tegra->emc_node)
 		return NULL;
 
@@ -241,7 +248,7 @@ static int emc_set_timing(struct tegra_clk_emc *tegra,
 
 	div = timing->parent_rate / (timing->rate / 2) - 2;
 
-	err = tegra_emc_prepare_timing_change(emc, timing->rate);
+	err = tegra->prepare_timing_change(emc, timing->rate);
 	if (err)
 		return err;
 
@@ -259,7 +266,7 @@ static int emc_set_timing(struct tegra_clk_emc *tegra,
 
 	spin_unlock_irqrestore(tegra->lock, flags);
 
-	tegra_emc_complete_timing_change(emc, timing->rate);
+	tegra->complete_timing_change(emc, timing->rate);
 
 	clk_hw_reparent(&tegra->hw, __clk_get_hw(timing->parent));
 	clk_disable_unprepare(tegra->prev_parent);
@@ -473,8 +480,8 @@ static const struct clk_ops tegra_clk_emc_ops = {
 	.get_parent = emc_get_parent,
 };
 
-struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
-				   spinlock_t *lock)
+struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np,
+				      spinlock_t *lock)
 {
 	struct tegra_clk_emc *tegra;
 	struct clk_init_data init;
@@ -538,3 +545,27 @@ struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
 
 	return clk;
 };
+
+void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
+				    tegra124_emc_complete_timing_change_cb *complete_cb)
+{
+	struct clk *clk = __clk_lookup("emc");
+	struct tegra_clk_emc *tegra;
+	struct clk_hw *hw;
+
+	if (clk) {
+		hw = __clk_get_hw(clk);
+		tegra = container_of(hw, struct tegra_clk_emc, hw);
+
+		tegra->prepare_timing_change = prep_cb;
+		tegra->complete_timing_change = complete_cb;
+	}
+}
+EXPORT_SYMBOL_GPL(tegra124_clk_set_emc_callbacks);
+
+bool tegra124_clk_emc_driver_available(struct clk_hw *hw)
+{
+	struct tegra_clk_emc *tegra = container_of(hw, struct tegra_clk_emc, hw);
+
+	return tegra->prepare_timing_change && tegra->complete_timing_change;
+}
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index e931319dcc9d..b4f2ae4066a6 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -929,6 +929,7 @@ static struct tegra_clk tegra124_clks[tegra_clk_max] __initdata = {
 	[tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true },
 	[tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true },
 	[tegra_clk_cec] = { .dt_id = TEGRA124_CLK_CEC, .present = true },
+	[tegra_clk_emc] = { .dt_id = TEGRA124_CLK_EMC, .present = false },
 };
 
 static struct tegra_devclk devclks[] __initdata = {
@@ -1500,6 +1501,26 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
 	writel(plld_base, clk_base + PLLD_BASE);
 }
 
+static struct clk *tegra124_clk_src_onecell_get(struct of_phandle_args *clkspec,
+						void *data)
+{
+	struct clk_hw *hw;
+	struct clk *clk;
+
+	clk = of_clk_src_onecell_get(clkspec, data);
+	if (IS_ERR(clk))
+		return clk;
+
+	hw = __clk_get_hw(clk);
+
+	if (clkspec->args[0] == TEGRA124_CLK_EMC) {
+		if (!tegra124_clk_emc_driver_available(hw))
+			return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	return clk;
+}
+
 /**
  * tegra124_132_clock_init_post - clock initialization postamble for T124/T132
  * @np: struct device_node * of the DT node for the SoC CAR IP block
@@ -1516,10 +1537,10 @@ static void __init tegra124_132_clock_init_post(struct device_node *np)
 				  &pll_x_params);
 	tegra_init_special_resets(1, tegra124_reset_assert,
 				  tegra124_reset_deassert);
-	tegra_add_of_provider(np, of_clk_src_onecell_get);
+	tegra_add_of_provider(np, tegra124_clk_src_onecell_get);
 
-	clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np,
-							&emc_lock);
+	clks[TEGRA124_CLK_EMC] = tegra124_clk_register_emc(clk_base, np,
+							   &emc_lock);
 
 	tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
 
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 6b565f6b5f66..2da7c93c1a6c 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -881,18 +881,6 @@ void tegra_super_clk_gen5_init(void __iomem *clk_base,
 			void __iomem *pmc_base, struct tegra_clk *tegra_clks,
 			struct tegra_clk_pll_params *pll_params);
 
-#ifdef CONFIG_TEGRA124_EMC
-struct clk *tegra_clk_register_emc(void __iomem *base, struct device_node *np,
-				   spinlock_t *lock);
-#else
-static inline struct clk *tegra_clk_register_emc(void __iomem *base,
-						 struct device_node *np,
-						 spinlock_t *lock)
-{
-	return NULL;
-}
-#endif
-
 void tegra114_clock_tune_cpu_trimmers_high(void);
 void tegra114_clock_tune_cpu_trimmers_low(void);
 void tegra114_clock_tune_cpu_trimmers_init(void);
@@ -922,6 +910,10 @@ void tegra_clk_periph_resume(void);
 bool tegra20_clk_emc_driver_available(struct clk_hw *emc_hw);
 struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter);
 
+struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np,
+				      spinlock_t *lock);
+bool tegra124_clk_emc_driver_available(struct clk_hw *emc_hw);
+
 struct clk *tegra210_clk_register_emc(struct device_node *np,
 				      void __iomem *regs);
 
diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 73a5c5bca480..94536dc4c495 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -31,7 +31,7 @@ config TEGRA30_EMC
 	  external memory.
 
 config TEGRA124_EMC
-	bool "NVIDIA Tegra124 External Memory Controller driver"
+	tristate "NVIDIA Tegra124 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_124_SOC
 	help
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index b92259d4fbd1..48e772ec544d 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -9,16 +9,17 @@
 #include <linux/clk-provider.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/clk/tegra.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/sort.h>
 #include <linux/string.h>
 
-#include <soc/tegra/emc.h>
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/mc.h>
 
@@ -562,8 +563,8 @@ static struct emc_timing *tegra_emc_find_timing(struct tegra_emc *emc,
 	return timing;
 }
 
-int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
-				    unsigned long rate)
+static int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
+					   unsigned long rate)
 {
 	struct emc_timing *timing = tegra_emc_find_timing(emc, rate);
 	struct emc_timing *last = &emc->last_timing;
@@ -790,8 +791,8 @@ int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
 	return 0;
 }
 
-void tegra_emc_complete_timing_change(struct tegra_emc *emc,
-				      unsigned long rate)
+static void tegra_emc_complete_timing_change(struct tegra_emc *emc,
+					     unsigned long rate)
 {
 	struct emc_timing *timing = tegra_emc_find_timing(emc, rate);
 	struct emc_timing *last = &emc->last_timing;
@@ -987,6 +988,7 @@ static const struct of_device_id tegra_emc_of_match[] = {
 	{ .compatible = "nvidia,tegra132-emc" },
 	{}
 };
+MODULE_DEVICE_TABLE(of, tegra_emc_of_match);
 
 static struct device_node *
 tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code)
@@ -1228,9 +1230,19 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, emc);
 
+	tegra124_clk_set_emc_callbacks(tegra_emc_prepare_timing_change,
+				       tegra_emc_complete_timing_change);
+
 	if (IS_ENABLED(CONFIG_DEBUG_FS))
 		emc_debugfs_init(&pdev->dev, emc);
 
+	/*
+	 * Don't allow the kernel module to be unloaded. Unloading adds some
+	 * extra complexity which doesn't really worth the effort in a case of
+	 * this driver.
+	 */
+	try_module_get(THIS_MODULE);
+
 	return 0;
 };
 
@@ -1242,9 +1254,8 @@ static struct platform_driver tegra_emc_driver = {
 		.suppress_bind_attrs = true,
 	},
 };
+module_platform_driver(tegra_emc_driver);
 
-static int tegra_emc_init(void)
-{
-	return platform_driver_register(&tegra_emc_driver);
-}
-subsys_initcall(tegra_emc_init);
+MODULE_AUTHOR("Mikko Perttunen <mperttunen@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra124 EMC driver");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/clk/tegra.h b/include/linux/clk/tegra.h
index 3f01d43f0598..d4c5e607ef29 100644
--- a/include/linux/clk/tegra.h
+++ b/include/linux/clk/tegra.h
@@ -136,6 +136,8 @@ extern void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value);
 extern void tegra210_clk_emc_update_setting(u32 emc_src_value);
 
 struct clk;
+struct device_node;
+struct tegra_emc;
 
 typedef long (tegra20_clk_emc_round_cb)(unsigned long rate,
 					unsigned long min_rate,
@@ -146,6 +148,13 @@ void tegra20_clk_set_emc_round_callback(tegra20_clk_emc_round_cb *round_cb,
 					void *cb_arg);
 int tegra20_clk_prepare_emc_mc_same_freq(struct clk *emc_clk, bool same);
 
+typedef int (tegra124_emc_prepare_timing_change_cb)(struct tegra_emc *emc,
+						    unsigned long rate);
+typedef void (tegra124_emc_complete_timing_change_cb)(struct tegra_emc *emc,
+						      unsigned long rate);
+void tegra124_clk_set_emc_callbacks(tegra124_emc_prepare_timing_change_cb *prep_cb,
+				    tegra124_emc_complete_timing_change_cb *complete_cb);
+
 struct tegra210_clk_emc_config {
 	unsigned long rate;
 	bool same_freq;
diff --git a/include/soc/tegra/emc.h b/include/soc/tegra/emc.h
deleted file mode 100644
index 05199a97ccf4..000000000000
--- a/include/soc/tegra/emc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2014 NVIDIA Corporation. All rights reserved.
- */
-
-#ifndef __SOC_TEGRA_EMC_H__
-#define __SOC_TEGRA_EMC_H__
-
-struct tegra_emc;
-
-int tegra_emc_prepare_timing_change(struct tegra_emc *emc,
-				    unsigned long rate);
-void tegra_emc_complete_timing_change(struct tegra_emc *emc,
-				      unsigned long rate);
-
-#endif /* __SOC_TEGRA_EMC_H__ */
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Use devm_platform_ioremap_resource() helper which makes code a bit
cleaner.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra124-emc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 48e772ec544d..2814b1b4a1d9 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1181,7 +1181,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
 	struct tegra_emc *emc;
-	struct resource *res;
 	u32 ram_code;
 	int err;
 
@@ -1191,8 +1190,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	emc->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	emc->regs = devm_ioremap_resource(&pdev->dev, res);
+	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
 		return PTR_ERR(emc->regs);
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Use devm_platform_ioremap_resource() helper which makes code a bit
cleaner.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/tegra124-emc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 48e772ec544d..2814b1b4a1d9 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -1181,7 +1181,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
 	struct tegra_emc *emc;
-	struct resource *res;
 	u32 ram_code;
 	int err;
 
@@ -1191,8 +1190,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	emc->dev = &pdev->dev;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	emc->regs = devm_ioremap_resource(&pdev->dev, res);
+	emc->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(emc->regs))
 		return PTR_ERR(emc->regs);
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 42/52] memory: tegra124: Support interconnect framework
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Now Internal and External memory controllers are memory interconnection
providers. This allows us to use interconnect API for tuning of memory
configuration. EMC driver now supports OPPs and DVFS.

Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig        |   1 +
 drivers/memory/tegra/tegra124-emc.c | 186 +++++++++++++++++++++++++++-
 drivers/memory/tegra/tegra124.c     |  31 +++++
 3 files changed, 216 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 94536dc4c495..3d1ef3ec1a2d 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -34,6 +34,7 @@ config TEGRA124_EMC
 	tristate "NVIDIA Tegra124 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_124_SOC
+	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra124 chips. The EMC controls the external DRAM on the board.
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 2814b1b4a1d9..bdce7bebe0ef 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -12,17 +12,21 @@
 #include <linux/clk/tegra.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
+#include <linux/interconnect-provider.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
 #include <linux/sort.h>
 #include <linux/string.h>
 
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/mc.h>
 
+#include "mc.h"
+
 #define EMC_FBIO_CFG5				0x104
 #define	EMC_FBIO_CFG5_DRAM_TYPE_MASK		0x3
 #define	EMC_FBIO_CFG5_DRAM_TYPE_SHIFT		0
@@ -482,6 +486,9 @@ struct tegra_emc {
 		unsigned long min_rate;
 		unsigned long max_rate;
 	} debugfs;
+
+	struct opp_table *opp_table;
+	struct icc_provider provider;
 };
 
 /* Timing change sequence functions */
@@ -1177,6 +1184,169 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc)
 			    emc, &tegra_emc_debug_max_rate_fops);
 }
 
+static inline struct tegra_emc *
+to_tegra_emc_provider(struct icc_provider *provider)
+{
+	return container_of(provider, struct tegra_emc, provider);
+}
+
+static struct icc_node_data *
+emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	/* External Memory is the only possible ICC route */
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != TEGRA_ICC_EMEM)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		/*
+		 * SRC and DST nodes should have matching TAG in order to have
+		 * it set by default for a requested path.
+		 */
+		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+		ndata->node = node;
+
+		return ndata;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
+	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
+	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
+	unsigned long long rate = max(avg_bw, peak_bw);
+	unsigned int dram_data_bus_width_bytes = 8;
+	unsigned int ddr = 2;
+	int err;
+
+	/*
+	 * Tegra124 EMC runs on a clock rate of SDRAM bus. This means that
+	 * EMC clock rate is twice smaller than the peak data rate because
+	 * data is sample on both EMC clock edges.
+	 */
+	do_div(rate, ddr * dram_data_bus_width_bytes);
+	rate = min_t(u64, rate, U32_MAX);
+
+	err = dev_pm_opp_set_rate(emc->dev, rate);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra_emc_interconnect_init(struct tegra_emc *emc)
+{
+	const struct tegra_mc_soc *soc = emc->mc->soc;
+	struct icc_node *node;
+	int err;
+
+	emc->provider.dev = emc->dev;
+	emc->provider.set = emc_icc_set;
+	emc->provider.data = &emc->provider;
+	emc->provider.aggregate = soc->icc_ops->aggregate;
+	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&emc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create External Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_EMC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "External Memory Controller";
+	icc_node_add(node, &emc->provider);
+
+	/* link External Memory Controller to External Memory (DRAM) */
+	err = icc_link_create(node, TEGRA_ICC_EMEM);
+	if (err)
+		goto remove_nodes;
+
+	/* create External Memory node */
+	node = icc_node_create(TEGRA_ICC_EMEM);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto remove_nodes;
+
+	node->name = "External Memory (DRAM)";
+	icc_node_add(node, &emc->provider);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&emc->provider);
+del_provider:
+	icc_provider_del(&emc->provider);
+err_msg:
+	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
+static int tegra_emc_opp_table_init(struct tegra_emc *emc)
+{
+	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
+	struct opp_table *opp_table;
+	const char *rname = "core";
+	int err;
+
+	/*
+	 * Legacy device-trees don't have OPP table and EMC driver isn't
+	 * useful in this case.
+	 */
+	if (!device_property_present(emc->dev, "operating-points-v2")) {
+		dev_err(emc->dev, "OPP table not found\n");
+		dev_err(emc->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
+	/* voltage scaling is optional */
+	if (device_property_present(emc->dev, "core-supply"))
+		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
+	else
+		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
+
+	if (IS_ERR(emc->opp_table))
+		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
+				     "failed to prepare OPP table\n");
+
+	opp_table = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
+	err = PTR_ERR_OR_ZERO(opp_table);
+	if (err) {
+		dev_err(emc->dev, "failed to set supported HW: %d\n", err);
+		goto put_table;
+	}
+
+	err = dev_pm_opp_of_add_table(emc->dev);
+	if (err) {
+		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
+		goto put_hw;
+	}
+
+	dev_info(emc->dev, "OPP HW ver. 0x%x\n", hw_version);
+
+	return 0;
+
+put_hw:
+	dev_pm_opp_put_supported_hw(emc->opp_table);
+put_table:
+	dev_pm_opp_put_opp_table(emc->opp_table);
+
+	return err;
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
@@ -1226,14 +1396,20 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	platform_set_drvdata(pdev, emc);
-
 	tegra124_clk_set_emc_callbacks(tegra_emc_prepare_timing_change,
 				       tegra_emc_complete_timing_change);
 
+	platform_set_drvdata(pdev, emc);
+
+	err = tegra_emc_opp_table_init(emc);
+	if (err)
+		goto unset_cb;
+
 	if (IS_ENABLED(CONFIG_DEBUG_FS))
 		emc_debugfs_init(&pdev->dev, emc);
 
+	tegra_emc_interconnect_init(emc);
+
 	/*
 	 * Don't allow the kernel module to be unloaded. Unloading adds some
 	 * extra complexity which doesn't really worth the effort in a case of
@@ -1242,6 +1418,11 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	try_module_get(THIS_MODULE);
 
 	return 0;
+
+unset_cb:
+	tegra124_clk_set_emc_callbacks(NULL, NULL);
+
+	return err;
 };
 
 static struct platform_driver tegra_emc_driver = {
@@ -1250,6 +1431,7 @@ static struct platform_driver tegra_emc_driver = {
 		.name = "tegra-emc",
 		.of_match_table = tegra_emc_of_match,
 		.suppress_bind_attrs = true,
+		.sync_state = icc_sync_state,
 	},
 };
 module_platform_driver(tegra_emc_driver);
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index e2389573d3c0..b69d76cd0411 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1010,6 +1010,35 @@ static const struct tegra_mc_reset tegra124_mc_resets[] = {
 	TEGRA124_MC_RESET(GPU,       0x970, 0x974,  2),
 };
 
+static int tegra124_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	/* TODO: program PTSA */
+	return 0;
+}
+
+static int tegra124_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
+				    u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	/*
+	 * ISO clients need to reserve extra bandwidth up-front because
+	 * there could high bandwidth pressure during initial fulling-up
+	 * of the client's FIFO buffers. Secondly, we need to take into
+	 * account impurities of the memory subsystem.
+	 */
+	if (tag == TEGRA_MC_ICC_TAG_ISO)
+		peak_bw = tegra_mc_scale_percents(peak_bw, 400);
+
+	*agg_avg += avg_bw;
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
+static const struct tegra_mc_icc_ops tegra124_mc_icc_ops = {
+	.aggregate = tegra124_mc_icc_aggreate,
+	.set = tegra124_mc_icc_set,
+};
+
 #ifdef CONFIG_ARCH_TEGRA_124_SOC
 static const unsigned long tegra124_mc_emem_regs[] = {
 	MC_EMEM_ARB_CFG,
@@ -1061,6 +1090,7 @@ const struct tegra_mc_soc tegra124_mc_soc = {
 	.reset_ops = &tegra_mc_reset_ops_common,
 	.resets = tegra124_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
+	.icc_ops = &tegra124_mc_icc_ops,
 };
 #endif /* CONFIG_ARCH_TEGRA_124_SOC */
 
@@ -1091,5 +1121,6 @@ const struct tegra_mc_soc tegra132_mc_soc = {
 	.reset_ops = &tegra_mc_reset_ops_common,
 	.resets = tegra124_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
+	.icc_ops = &tegra124_mc_icc_ops,
 };
 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 42/52] memory: tegra124: Support interconnect framework
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Now Internal and External memory controllers are memory interconnection
providers. This allows us to use interconnect API for tuning of memory
configuration. EMC driver now supports OPPs and DVFS.

Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/Kconfig        |   1 +
 drivers/memory/tegra/tegra124-emc.c | 186 +++++++++++++++++++++++++++-
 drivers/memory/tegra/tegra124.c     |  31 +++++
 3 files changed, 216 insertions(+), 2 deletions(-)

diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
index 94536dc4c495..3d1ef3ec1a2d 100644
--- a/drivers/memory/tegra/Kconfig
+++ b/drivers/memory/tegra/Kconfig
@@ -34,6 +34,7 @@ config TEGRA124_EMC
 	tristate "NVIDIA Tegra124 External Memory Controller driver"
 	default y
 	depends on TEGRA_MC && ARCH_TEGRA_124_SOC
+	select PM_OPP
 	help
 	  This driver is for the External Memory Controller (EMC) found on
 	  Tegra124 chips. The EMC controls the external DRAM on the board.
diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c
index 2814b1b4a1d9..bdce7bebe0ef 100644
--- a/drivers/memory/tegra/tegra124-emc.c
+++ b/drivers/memory/tegra/tegra124-emc.c
@@ -12,17 +12,21 @@
 #include <linux/clk/tegra.h>
 #include <linux/debugfs.h>
 #include <linux/delay.h>
+#include <linux/interconnect-provider.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/pm_opp.h>
 #include <linux/sort.h>
 #include <linux/string.h>
 
 #include <soc/tegra/fuse.h>
 #include <soc/tegra/mc.h>
 
+#include "mc.h"
+
 #define EMC_FBIO_CFG5				0x104
 #define	EMC_FBIO_CFG5_DRAM_TYPE_MASK		0x3
 #define	EMC_FBIO_CFG5_DRAM_TYPE_SHIFT		0
@@ -482,6 +486,9 @@ struct tegra_emc {
 		unsigned long min_rate;
 		unsigned long max_rate;
 	} debugfs;
+
+	struct opp_table *opp_table;
+	struct icc_provider provider;
 };
 
 /* Timing change sequence functions */
@@ -1177,6 +1184,169 @@ static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc)
 			    emc, &tegra_emc_debug_max_rate_fops);
 }
 
+static inline struct tegra_emc *
+to_tegra_emc_provider(struct icc_provider *provider)
+{
+	return container_of(provider, struct tegra_emc, provider);
+}
+
+static struct icc_node_data *
+emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
+{
+	struct icc_provider *provider = data;
+	struct icc_node_data *ndata;
+	struct icc_node *node;
+
+	/* External Memory is the only possible ICC route */
+	list_for_each_entry(node, &provider->nodes, node_list) {
+		if (node->id != TEGRA_ICC_EMEM)
+			continue;
+
+		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
+		if (!ndata)
+			return ERR_PTR(-ENOMEM);
+
+		/*
+		 * SRC and DST nodes should have matching TAG in order to have
+		 * it set by default for a requested path.
+		 */
+		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
+		ndata->node = node;
+
+		return ndata;
+	}
+
+	return ERR_PTR(-EINVAL);
+}
+
+static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
+	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
+	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
+	unsigned long long rate = max(avg_bw, peak_bw);
+	unsigned int dram_data_bus_width_bytes = 8;
+	unsigned int ddr = 2;
+	int err;
+
+	/*
+	 * Tegra124 EMC runs on a clock rate of SDRAM bus. This means that
+	 * EMC clock rate is twice smaller than the peak data rate because
+	 * data is sample on both EMC clock edges.
+	 */
+	do_div(rate, ddr * dram_data_bus_width_bytes);
+	rate = min_t(u64, rate, U32_MAX);
+
+	err = dev_pm_opp_set_rate(emc->dev, rate);
+	if (err)
+		return err;
+
+	return 0;
+}
+
+static int tegra_emc_interconnect_init(struct tegra_emc *emc)
+{
+	const struct tegra_mc_soc *soc = emc->mc->soc;
+	struct icc_node *node;
+	int err;
+
+	emc->provider.dev = emc->dev;
+	emc->provider.set = emc_icc_set;
+	emc->provider.data = &emc->provider;
+	emc->provider.aggregate = soc->icc_ops->aggregate;
+	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
+
+	err = icc_provider_add(&emc->provider);
+	if (err)
+		goto err_msg;
+
+	/* create External Memory Controller node */
+	node = icc_node_create(TEGRA_ICC_EMC);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto del_provider;
+
+	node->name = "External Memory Controller";
+	icc_node_add(node, &emc->provider);
+
+	/* link External Memory Controller to External Memory (DRAM) */
+	err = icc_link_create(node, TEGRA_ICC_EMEM);
+	if (err)
+		goto remove_nodes;
+
+	/* create External Memory node */
+	node = icc_node_create(TEGRA_ICC_EMEM);
+	err = PTR_ERR_OR_ZERO(node);
+	if (err)
+		goto remove_nodes;
+
+	node->name = "External Memory (DRAM)";
+	icc_node_add(node, &emc->provider);
+
+	return 0;
+
+remove_nodes:
+	icc_nodes_remove(&emc->provider);
+del_provider:
+	icc_provider_del(&emc->provider);
+err_msg:
+	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
+
+	return err;
+}
+
+static int tegra_emc_opp_table_init(struct tegra_emc *emc)
+{
+	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
+	struct opp_table *opp_table;
+	const char *rname = "core";
+	int err;
+
+	/*
+	 * Legacy device-trees don't have OPP table and EMC driver isn't
+	 * useful in this case.
+	 */
+	if (!device_property_present(emc->dev, "operating-points-v2")) {
+		dev_err(emc->dev, "OPP table not found\n");
+		dev_err(emc->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
+	/* voltage scaling is optional */
+	if (device_property_present(emc->dev, "core-supply"))
+		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
+	else
+		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
+
+	if (IS_ERR(emc->opp_table))
+		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
+				     "failed to prepare OPP table\n");
+
+	opp_table = dev_pm_opp_set_supported_hw(emc->dev, &hw_version, 1);
+	err = PTR_ERR_OR_ZERO(opp_table);
+	if (err) {
+		dev_err(emc->dev, "failed to set supported HW: %d\n", err);
+		goto put_table;
+	}
+
+	err = dev_pm_opp_of_add_table(emc->dev);
+	if (err) {
+		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
+		goto put_hw;
+	}
+
+	dev_info(emc->dev, "OPP HW ver. 0x%x\n", hw_version);
+
+	return 0;
+
+put_hw:
+	dev_pm_opp_put_supported_hw(emc->opp_table);
+put_table:
+	dev_pm_opp_put_opp_table(emc->opp_table);
+
+	return err;
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
 	struct device_node *np;
@@ -1226,14 +1396,20 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	platform_set_drvdata(pdev, emc);
-
 	tegra124_clk_set_emc_callbacks(tegra_emc_prepare_timing_change,
 				       tegra_emc_complete_timing_change);
 
+	platform_set_drvdata(pdev, emc);
+
+	err = tegra_emc_opp_table_init(emc);
+	if (err)
+		goto unset_cb;
+
 	if (IS_ENABLED(CONFIG_DEBUG_FS))
 		emc_debugfs_init(&pdev->dev, emc);
 
+	tegra_emc_interconnect_init(emc);
+
 	/*
 	 * Don't allow the kernel module to be unloaded. Unloading adds some
 	 * extra complexity which doesn't really worth the effort in a case of
@@ -1242,6 +1418,11 @@ static int tegra_emc_probe(struct platform_device *pdev)
 	try_module_get(THIS_MODULE);
 
 	return 0;
+
+unset_cb:
+	tegra124_clk_set_emc_callbacks(NULL, NULL);
+
+	return err;
 };
 
 static struct platform_driver tegra_emc_driver = {
@@ -1250,6 +1431,7 @@ static struct platform_driver tegra_emc_driver = {
 		.name = "tegra-emc",
 		.of_match_table = tegra_emc_of_match,
 		.suppress_bind_attrs = true,
+		.sync_state = icc_sync_state,
 	},
 };
 module_platform_driver(tegra_emc_driver);
diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c
index e2389573d3c0..b69d76cd0411 100644
--- a/drivers/memory/tegra/tegra124.c
+++ b/drivers/memory/tegra/tegra124.c
@@ -1010,6 +1010,35 @@ static const struct tegra_mc_reset tegra124_mc_resets[] = {
 	TEGRA124_MC_RESET(GPU,       0x970, 0x974,  2),
 };
 
+static int tegra124_mc_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+	/* TODO: program PTSA */
+	return 0;
+}
+
+static int tegra124_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
+				    u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+	/*
+	 * ISO clients need to reserve extra bandwidth up-front because
+	 * there could high bandwidth pressure during initial fulling-up
+	 * of the client's FIFO buffers. Secondly, we need to take into
+	 * account impurities of the memory subsystem.
+	 */
+	if (tag == TEGRA_MC_ICC_TAG_ISO)
+		peak_bw = tegra_mc_scale_percents(peak_bw, 400);
+
+	*agg_avg += avg_bw;
+	*agg_peak = max(*agg_peak, peak_bw);
+
+	return 0;
+}
+
+static const struct tegra_mc_icc_ops tegra124_mc_icc_ops = {
+	.aggregate = tegra124_mc_icc_aggreate,
+	.set = tegra124_mc_icc_set,
+};
+
 #ifdef CONFIG_ARCH_TEGRA_124_SOC
 static const unsigned long tegra124_mc_emem_regs[] = {
 	MC_EMEM_ARB_CFG,
@@ -1061,6 +1090,7 @@ const struct tegra_mc_soc tegra124_mc_soc = {
 	.reset_ops = &tegra_mc_reset_ops_common,
 	.resets = tegra124_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
+	.icc_ops = &tegra124_mc_icc_ops,
 };
 #endif /* CONFIG_ARCH_TEGRA_124_SOC */
 
@@ -1091,5 +1121,6 @@ const struct tegra_mc_soc tegra132_mc_soc = {
 	.reset_ops = &tegra_mc_reset_ops_common,
 	.resets = tegra124_mc_resets,
 	.num_resets = ARRAY_SIZE(tegra124_mc_resets),
+	.icc_ops = &tegra124_mc_icc_ops,
 };
 #endif /* CONFIG_ARCH_TEGRA_132_SOC */
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 43/52] memory: tegra: Remove superfluous error messages around platform_get_irq()
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

The platform_get_irq() prints error message telling that interrupt is
missing, hence there is no need to duplicated that message in the drivers.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c          | 4 +---
 drivers/memory/tegra/tegra20-emc.c | 1 -
 drivers/memory/tegra/tegra30-emc.c | 5 ++---
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 15589bf8f5b6..4a3bf08495c9 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -837,10 +837,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
 	}
 
 	mc->irq = platform_get_irq(pdev, 0);
-	if (mc->irq < 0) {
-		dev_err(&pdev->dev, "interrupt not specified\n");
+	if (mc->irq < 0)
 		return mc->irq;
-	}
 
 	WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n");
 
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 27242659dfd6..1519d6ce9b28 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -844,7 +844,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
-		dev_err(&pdev->dev, "interrupt not specified\n");
 		dev_err(&pdev->dev, "please update your device tree\n");
 		return irq;
 	}
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 66eae944ca6d..d2515d7f3c0b 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1472,10 +1472,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return err;
 
 	err = platform_get_irq(pdev, 0);
-	if (err < 0) {
-		dev_err(&pdev->dev, "interrupt not specified: %d\n", err);
+	if (err < 0)
 		return err;
-	}
+
 	emc->irq = err;
 
 	err = devm_request_irq(&pdev->dev, emc->irq, tegra_emc_isr, 0,
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 43/52] memory: tegra: Remove superfluous error messages around platform_get_irq()
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

The platform_get_irq() prints error message telling that interrupt is
missing, hence there is no need to duplicated that message in the drivers.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/memory/tegra/mc.c          | 4 +---
 drivers/memory/tegra/tegra20-emc.c | 1 -
 drivers/memory/tegra/tegra30-emc.c | 5 ++---
 3 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
index 15589bf8f5b6..4a3bf08495c9 100644
--- a/drivers/memory/tegra/mc.c
+++ b/drivers/memory/tegra/mc.c
@@ -837,10 +837,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
 	}
 
 	mc->irq = platform_get_irq(pdev, 0);
-	if (mc->irq < 0) {
-		dev_err(&pdev->dev, "interrupt not specified\n");
+	if (mc->irq < 0)
 		return mc->irq;
-	}
 
 	WARN(!mc->soc->client_id_mask, "missing client ID mask for this SoC\n");
 
diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
index 27242659dfd6..1519d6ce9b28 100644
--- a/drivers/memory/tegra/tegra20-emc.c
+++ b/drivers/memory/tegra/tegra20-emc.c
@@ -844,7 +844,6 @@ static int tegra_emc_probe(struct platform_device *pdev)
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
-		dev_err(&pdev->dev, "interrupt not specified\n");
 		dev_err(&pdev->dev, "please update your device tree\n");
 		return irq;
 	}
diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c
index 66eae944ca6d..d2515d7f3c0b 100644
--- a/drivers/memory/tegra/tegra30-emc.c
+++ b/drivers/memory/tegra/tegra30-emc.c
@@ -1472,10 +1472,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
 		return err;
 
 	err = platform_get_irq(pdev, 0);
-	if (err < 0) {
-		dev_err(&pdev->dev, "interrupt not specified: %d\n", err);
+	if (err < 0)
 		return err;
-	}
+
 	emc->irq = err;
 
 	err = devm_request_irq(&pdev->dev, emc->irq, tegra_emc_isr, 0,
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 44/52] drm/tegra: dc: Support memory bandwidth management
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Display controller (DC) performs isochronous memory transfers, and thus,
has a requirement for a minimum memory bandwidth that shall be fulfilled,
otherwise framebuffer data can't be fetched fast enough and this results
in a DC's data-FIFO underflow that follows by a visual corruption.

The Memory Controller drivers provide facility for memory bandwidth
management via interconnect API. This patch wires up the interconnect
API support to the DC driver and fixes distorted display output on
T30 Ouya, T124 TK1 and other Tegra devices.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/Kconfig |   1 +
 drivers/gpu/drm/tegra/dc.c    | 330 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/tegra/dc.h    |   6 +
 drivers/gpu/drm/tegra/drm.c   |  14 ++
 drivers/gpu/drm/tegra/hub.c   |   3 +
 drivers/gpu/drm/tegra/plane.c | 122 +++++++++++++
 drivers/gpu/drm/tegra/plane.h |  15 ++
 7 files changed, 491 insertions(+)

diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 5043dcaf1cf9..1650a448eabd 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -9,6 +9,7 @@ config DRM_TEGRA
 	select DRM_MIPI_DSI
 	select DRM_PANEL
 	select TEGRA_HOST1X
+	select INTERCONNECT
 	select IOMMU_IOVA
 	select CEC_CORE if CEC_NOTIFIER
 	help
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 424ad60b4f38..986e7a0dde2a 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -8,6 +8,7 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/iommu.h>
+#include <linux/interconnect.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
@@ -616,6 +617,9 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 	struct tegra_dc *dc = to_tegra_dc(state->crtc);
 	int err;
 
+	plane_state->peak_memory_bandwidth = 0;
+	plane_state->avg_memory_bandwidth = 0;
+
 	/* no need for further checks if the plane is being disabled */
 	if (!state->crtc)
 		return 0;
@@ -802,6 +806,12 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
 	formats = dc->soc->primary_formats;
 	modifiers = dc->soc->modifiers;
 
+	err = tegra_plane_interconnect_init(plane);
+	if (err) {
+		kfree(plane);
+		return ERR_PTR(err);
+	}
+
 	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
 				       &tegra_plane_funcs, formats,
 				       num_formats, modifiers, type, NULL);
@@ -833,9 +843,13 @@ static const u32 tegra_cursor_plane_formats[] = {
 static int tegra_cursor_atomic_check(struct drm_plane *plane,
 				     struct drm_plane_state *state)
 {
+	struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
 	struct tegra_plane *tegra = to_tegra_plane(plane);
 	int err;
 
+	plane_state->peak_memory_bandwidth = 0;
+	plane_state->avg_memory_bandwidth = 0;
+
 	/* no need for further checks if the plane is being disabled */
 	if (!state->crtc)
 		return 0;
@@ -973,6 +987,12 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
 	num_formats = ARRAY_SIZE(tegra_cursor_plane_formats);
 	formats = tegra_cursor_plane_formats;
 
+	err = tegra_plane_interconnect_init(plane);
+	if (err) {
+		kfree(plane);
+		return ERR_PTR(err);
+	}
+
 	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
 				       &tegra_plane_funcs, formats,
 				       num_formats, NULL,
@@ -1087,6 +1107,12 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
 	num_formats = dc->soc->num_overlay_formats;
 	formats = dc->soc->overlay_formats;
 
+	err = tegra_plane_interconnect_init(plane);
+	if (err) {
+		kfree(plane);
+		return ERR_PTR(err);
+	}
+
 	if (!cursor)
 		type = DRM_PLANE_TYPE_OVERLAY;
 	else
@@ -1204,6 +1230,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 {
 	struct tegra_dc_state *state = to_dc_state(crtc->state);
 	struct tegra_dc_state *copy;
+	unsigned int i;
 
 	copy = kmalloc(sizeof(*copy), GFP_KERNEL);
 	if (!copy)
@@ -1215,6 +1242,9 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 	copy->div = state->div;
 	copy->planes = state->planes;
 
+	for (i = 0; i < ARRAY_SIZE(state->plane_peak_bw); i++)
+		copy->plane_peak_bw[i] = state->plane_peak_bw[i];
+
 	return &copy->base;
 }
 
@@ -1741,6 +1771,104 @@ static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout)
 	return -ETIMEDOUT;
 }
 
+static void
+tegra_crtc_update_memory_bandwidth(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_crtc_state,
+				   bool prepare_bandwidth_transition)
+{
+	const struct tegra_plane_state *old_tegra_state, *new_tegra_state;
+	u32 i, new_avg_bw, old_avg_bw, new_peak_bw, old_peak_bw;
+	struct tegra_dc_state *old_dc_state, *new_dc_state;
+	const struct drm_plane_state *old_plane_state;
+	struct tegra_dc_window window, old_window;
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+	struct tegra_plane *tegra;
+	struct drm_plane *plane;
+
+	if (dc->soc->has_nvdisplay)
+		return;
+
+	if (!crtc->state->active) {
+		if (!old_crtc_state->active)
+			return;
+
+		/*
+		 * When CRTC is disabled on DPMS, the state of attached planes
+		 * is kept unchanged. Hence we need to enforce removal of the
+		 * bandwidths from the ICC paths.
+		 */
+		drm_atomic_crtc_for_each_plane(plane, crtc) {
+			tegra = to_tegra_plane(plane);
+
+			icc_set_bw(tegra->icc_mem, 0, 0);
+			icc_set_bw(tegra->icc_mem_vfilter, 0, 0);
+		}
+
+		return;
+	}
+
+	old_dc_state = to_dc_state(old_crtc_state);
+	new_dc_state = to_dc_state(crtc->state);
+
+	for_each_old_plane_in_state(old_crtc_state->state, plane,
+				    old_plane_state, i) {
+		old_tegra_state = to_const_tegra_plane_state(old_plane_state);
+		new_tegra_state = to_const_tegra_plane_state(plane->state);
+		tegra = to_tegra_plane(plane);
+
+		/*
+		 * We're iterating over the global atomic state and it contains
+		 * planes from another CRTC, hence we need to filter out the
+		 * planes unrelated to this CRTC.
+		 */
+		if (tegra->dc != dc)
+			continue;
+
+		new_avg_bw = new_tegra_state->avg_memory_bandwidth;
+		old_avg_bw = old_tegra_state->avg_memory_bandwidth;
+
+		new_peak_bw = new_dc_state->plane_peak_bw[tegra->index];
+		old_peak_bw = old_dc_state->plane_peak_bw[tegra->index];
+
+		/*
+		 * See the comment related to !crtc->state->active above,
+		 * which explains why bandwidths need to be updated when
+		 * CRTC is turning ON.
+		 */
+		if (new_avg_bw == old_avg_bw && new_peak_bw == old_peak_bw &&
+		    old_crtc_state->active)
+			continue;
+
+		window.src.h = drm_rect_height(&plane->state->src) >> 16;
+		window.dst.h = drm_rect_height(&plane->state->dst);
+
+		old_window.src.h = drm_rect_height(&old_plane_state->src) >> 16;
+		old_window.dst.h = drm_rect_height(&old_plane_state->dst);
+
+		/*
+		 * During the preparation phase (atomic_begin), the memory
+		 * freq should go high before the DC changes are committed
+		 * if bandwidth requirement goes up, otherwise memory freq
+		 * should to stay high if BW requirement goes down.  The
+		 * opposite applies to the completion phase (post_commit).
+		 */
+		if (prepare_bandwidth_transition) {
+			new_avg_bw = max(old_avg_bw, new_avg_bw);
+			new_peak_bw = max(old_peak_bw, new_peak_bw);
+
+			if (tegra_plane_use_vertical_filtering(tegra, &old_window))
+				window = old_window;
+		}
+
+		icc_set_bw(tegra->icc_mem, new_avg_bw, new_peak_bw);
+
+		if (tegra_plane_use_vertical_filtering(tegra, &window))
+			icc_set_bw(tegra->icc_mem_vfilter, new_avg_bw, new_peak_bw);
+		else
+			icc_set_bw(tegra->icc_mem_vfilter, 0, 0);
+	}
+}
+
 static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
 				      struct drm_crtc_state *old_state)
 {
@@ -1922,6 +2050,8 @@ static void tegra_crtc_atomic_begin(struct drm_crtc *crtc,
 {
 	unsigned long flags;
 
+	tegra_crtc_update_memory_bandwidth(crtc, old_crtc_state, true);
+
 	if (crtc->state->event) {
 		spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
@@ -1952,7 +2082,195 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,
 	value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
 }
 
+static bool tegra_plane_is_cursor(const struct drm_plane_state *state)
+{
+	const struct tegra_dc_soc_info *soc = to_tegra_dc(state->crtc)->soc;
+	const struct drm_format_info *fmt = state->fb->format;
+	unsigned int src_w = drm_rect_width(&state->src) >> 16;
+	unsigned int dst_w = drm_rect_width(&state->dst);
+
+	if (state->plane->type != DRM_PLANE_TYPE_CURSOR)
+		return false;
+
+	if (soc->supports_cursor)
+		return true;
+
+	if (src_w != dst_w || fmt->num_planes != 1 || src_w * fmt->cpp[0] > 256)
+		return false;
+
+	return true;
+}
+
+static unsigned int
+tegra_plane_overlap_mask(struct drm_crtc_state *state,
+			 const struct drm_plane_state *plane_state)
+{
+	const struct drm_plane_state *other_state;
+	const struct tegra_plane *tegra;
+	unsigned int overlap_mask = 0;
+	struct drm_plane *plane;
+	struct drm_rect rect;
+
+	if (!plane_state->visible || !plane_state->fb)
+		return 0;
+
+	drm_atomic_crtc_state_for_each_plane_state(plane, other_state, state) {
+		rect = plane_state->dst;
+
+		tegra = to_tegra_plane(other_state->plane);
+
+		if (!other_state->visible || !other_state->fb)
+			continue;
+
+		/*
+		 * Ignore cursor plane overlaps because it's not practical to
+		 * assume that it contributes to the bandwidth in overlapping
+		 * area if window width is small.
+		 */
+		if (tegra_plane_is_cursor(other_state))
+			continue;
+
+		if (drm_rect_intersect(&rect, &other_state->dst))
+			overlap_mask |= BIT(tegra->index);
+	}
+
+	/*
+	 * Data prefetch FIFO will easily help to overcome temporal memory
+	 * pressure if other plane overlaps with the cursor plane.
+	 */
+	if (tegra_plane_is_cursor(plane_state) && overlap_mask)
+		return 0;
+
+	return overlap_mask;
+}
+
+static struct drm_plane *
+tegra_crtc_get_plane_by_index(struct drm_crtc *crtc, unsigned int index)
+{
+	struct drm_plane *plane;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		if (to_tegra_plane(plane)->index == index)
+			return plane;
+	}
+
+	return NULL;
+}
+
+static int tegra_crtc_atomic_check(struct drm_crtc *crtc,
+				   struct drm_crtc_state *state)
+{
+	struct tegra_dc_state *old_dc_state, *dc_state = to_dc_state(state);
+	ulong overlap_mask[ARRAY_SIZE(dc_state->plane_peak_bw)] = {}, mask;
+	u32 plane_peak_bw[ARRAY_SIZE(dc_state->plane_peak_bw)] = {};
+	bool all_planes_overlap_simultaneously = true;
+	const struct tegra_plane_state *tegra_state;
+	const struct drm_plane_state *plane_state;
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+	struct drm_crtc_state *old_state;
+	struct tegra_plane *tegra;
+	struct drm_plane *plane;
+	u32 i, k, overlap_bw;
+
+	/*
+	 * The nv-display uses shared planes.  The algorithm below assumes
+	 * maximum 3 planes per-CRTC, this assumption isn't applicable to
+	 * the nv-display.  Note that T124 support has additional windows,
+	 * but currently they aren't supported by the driver.
+	 */
+	if (dc->soc->has_nvdisplay)
+		return 0;
+
+	/*
+	 * For overlapping planes pixel's data is fetched for each plane at
+	 * the same time, hence bandwidths are accumulated in this case.
+	 * This needs to be taken into account for calculating total bandwidth
+	 * consumed by all planes.
+	 *
+	 * Here we get the overlapping state of each plane, which is a
+	 * bitmask of plane indices telling with what planes there is an
+	 * overlap. Note that bitmask[plane] includes BIT(plane) in order
+	 * to make further code nicer and simpler.
+	 */
+	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state) {
+		tegra_state = to_const_tegra_plane_state(plane_state);
+		tegra = to_tegra_plane(plane);
+
+		plane_peak_bw[tegra->index] = tegra_state->peak_memory_bandwidth;
+		mask = tegra_plane_overlap_mask(state, plane_state);
+		overlap_mask[tegra->index] = mask;
+
+		if (hweight_long(mask) != 3)
+			all_planes_overlap_simultaneously = false;
+	}
+
+	old_state = drm_atomic_get_old_crtc_state(state->state, crtc);
+	old_dc_state = to_dc_state(old_state);
+
+	/*
+	 * Then we calculate maximum bandwidth of each plane state.
+	 * The bandwidth includes the plane BW + BW of the "simultaneously"
+	 * overlapping planes, where "simultaneously" means areas where DC
+	 * fetches from the planes simultaneously during of scan-out process.
+	 *
+	 * For example, if plane A overlaps with planes B and C, but B and C
+	 * don't overlap, then the peak bandwidth will be either in area where
+	 * A-and-B or A-and-C planes overlap.
+	 *
+	 * The plane_peak_bw[] contains peak memory bandwidth values of
+	 * each plane, this information is needed by interconnect provider
+	 * in order to set up latency allowness based on the peak BW, see
+	 * tegra_crtc_update_memory_bandwidth().
+	 */
+	for (i = 0; i < ARRAY_SIZE(dc_state->plane_peak_bw); i++) {
+		overlap_bw = 0;
+
+		for_each_set_bit(k, &overlap_mask[i], 3) {
+			if (k == i)
+				continue;
+
+			if (all_planes_overlap_simultaneously)
+				overlap_bw += plane_peak_bw[k];
+			else
+				overlap_bw = max(overlap_bw, plane_peak_bw[k]);
+		}
+
+		dc_state->plane_peak_bw[i] = plane_peak_bw[i] + overlap_bw;
+
+		/*
+		 * If plane's peak bandwidth changed (for example plane isn't
+		 * overlapped anymore) and plane isn't in the atomic state,
+		 * then add plane to the state in order to have the bandwidth
+		 * updated.
+		 */
+		if (old_dc_state->plane_peak_bw[i] != dc_state->plane_peak_bw[i]) {
+			plane = tegra_crtc_get_plane_by_index(crtc, i);
+			if (!plane)
+				continue;
+
+			plane_state = drm_atomic_get_plane_state(state->state,
+								 plane);
+			if (IS_ERR(plane_state))
+				return PTR_ERR(plane_state);
+		}
+	}
+
+	return 0;
+}
+
+void tegra_crtc_atomic_post_commit(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_crtc_state)
+{
+	/*
+	 * Display bandwidth is allowed to go down only once hardware state
+	 * is known to be armed, i.e. state was committed and VBLANK event
+	 * was received.
+	 */
+	tegra_crtc_update_memory_bandwidth(crtc, old_crtc_state, false);
+}
+
 static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
+	.atomic_check = tegra_crtc_atomic_check,
 	.atomic_begin = tegra_crtc_atomic_begin,
 	.atomic_flush = tegra_crtc_atomic_flush,
 	.atomic_enable = tegra_crtc_atomic_enable,
@@ -2243,7 +2561,9 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
 	.overlay_formats = tegra20_overlay_formats,
 	.modifiers = tegra20_modifiers,
 	.has_win_a_without_filters = true,
+	.has_win_b_vfilter_mem_client = true,
 	.has_win_c_without_vert_filter = true,
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
@@ -2262,7 +2582,9 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
 	.overlay_formats = tegra20_overlay_formats,
 	.modifiers = tegra20_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = true,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = true,
 };
 
 static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
@@ -2281,7 +2603,9 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
 	.overlay_formats = tegra114_overlay_formats,
 	.modifiers = tegra20_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = false,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = true,
 };
 
 static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
@@ -2300,7 +2624,9 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
 	.overlay_formats = tegra124_overlay_formats,
 	.modifiers = tegra124_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = false,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -2319,7 +2645,9 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
 	.overlay_formats = tegra114_overlay_formats,
 	.modifiers = tegra124_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = false,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = {
@@ -2368,6 +2696,7 @@ static const struct tegra_dc_soc_info tegra186_dc_soc_info = {
 	.has_nvdisplay = true,
 	.wgrps = tegra186_dc_wgrps,
 	.num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps),
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_windowgroup_soc tegra194_dc_wgrps[] = {
@@ -2416,6 +2745,7 @@ static const struct tegra_dc_soc_info tegra194_dc_soc_info = {
 	.has_nvdisplay = true,
 	.wgrps = tegra194_dc_wgrps,
 	.num_wgrps = ARRAY_SIZE(tegra194_dc_wgrps),
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct of_device_id tegra_dc_of_match[] = {
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 051d03dcb9b0..8fade75caef9 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -23,6 +23,8 @@ struct tegra_dc_state {
 	unsigned int div;
 
 	u32 planes;
+
+	unsigned long plane_peak_bw[6];
 };
 
 static inline struct tegra_dc_state *to_dc_state(struct drm_crtc_state *state)
@@ -65,7 +67,9 @@ struct tegra_dc_soc_info {
 	unsigned int num_overlay_formats;
 	const u64 *modifiers;
 	bool has_win_a_without_filters;
+	bool has_win_b_vfilter_mem_client;
 	bool has_win_c_without_vert_filter;
+	unsigned int plane_tiled_memory_bandwidth_x2;
 };
 
 struct tegra_dc {
@@ -151,6 +155,8 @@ int tegra_dc_state_setup_clock(struct tegra_dc *dc,
 			       struct drm_crtc_state *crtc_state,
 			       struct clk *clk, unsigned long pclk,
 			       unsigned int div);
+void tegra_crtc_atomic_post_commit(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_crtc_state);
 
 /* from rgb.c */
 int tegra_dc_rgb_probe(struct tegra_dc *dc);
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index ba9d1c3e7cac..455a1ae639ba 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -20,6 +20,7 @@
 #include <drm/drm_prime.h>
 #include <drm/drm_vblank.h>
 
+#include "dc.h"
 #include "drm.h"
 #include "gem.h"
 
@@ -59,6 +60,17 @@ static const struct drm_mode_config_funcs tegra_drm_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
+static void tegra_atomic_post_commit(struct drm_device *drm,
+				     struct drm_atomic_state *old_state)
+{
+	struct drm_crtc_state *old_crtc_state;
+	struct drm_crtc *crtc;
+	unsigned int i;
+
+	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i)
+		tegra_crtc_atomic_post_commit(crtc, old_crtc_state);
+}
+
 static void tegra_atomic_commit_tail(struct drm_atomic_state *old_state)
 {
 	struct drm_device *drm = old_state->dev;
@@ -75,6 +87,8 @@ static void tegra_atomic_commit_tail(struct drm_atomic_state *old_state)
 	} else {
 		drm_atomic_helper_commit_tail_rpm(old_state);
 	}
+
+	tegra_atomic_post_commit(drm, old_state);
 }
 
 static const struct drm_mode_config_helper_funcs
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index 22a03f7ffdc1..4fa338dc7eb2 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -344,6 +344,9 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane,
 	struct tegra_dc *dc = to_tegra_dc(state->crtc);
 	int err;
 
+	plane_state->peak_memory_bandwidth = 0;
+	plane_state->avg_memory_bandwidth = 0;
+
 	/* no need for further checks if the plane is being disabled */
 	if (!state->crtc || !state->fb)
 		return 0;
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 539d14935728..f525994fba70 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/iommu.h>
+#include <linux/interconnect.h>
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -64,6 +65,8 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
 	copy->reflect_x = state->reflect_x;
 	copy->reflect_y = state->reflect_y;
 	copy->opaque = state->opaque;
+	copy->peak_memory_bandwidth = state->peak_memory_bandwidth;
+	copy->avg_memory_bandwidth = state->avg_memory_bandwidth;
 
 	for (i = 0; i < 2; i++)
 		copy->blending[i] = state->blending[i];
@@ -212,6 +215,88 @@ void tegra_plane_cleanup_fb(struct drm_plane *plane,
 		tegra_dc_unpin(dc, to_tegra_plane_state(state));
 }
 
+static int tegra_plane_check_memory_bandwidth(struct drm_plane_state *state)
+{
+	struct tegra_plane_state *tegra_state = to_tegra_plane_state(state);
+	unsigned int i, bpp, bpp_plane, dst_w, dst_h, src_w, src_h, mul;
+	u32 avg_bandwidth = 0, peak_bandwidth;
+	const struct tegra_dc_soc_info *soc;
+	const struct drm_format_info *fmt;
+	struct drm_crtc_state *crtc_state;
+
+	if (!state->visible)
+		return 0;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
+	if (!crtc_state)
+		return -EINVAL;
+
+	src_w = drm_rect_width(&state->src) >> 16;
+	src_h = drm_rect_height(&state->src) >> 16;
+	dst_w = drm_rect_width(&state->dst);
+	dst_h = drm_rect_height(&state->dst);
+
+	fmt = state->fb->format;
+	soc = to_tegra_dc(state->crtc)->soc;
+
+	/*
+	 * Note that real memory bandwidth vary depending on format and
+	 * memory layout, we are not taking that into account because small
+	 * estimation error isn't important since bandwidth is rounded up
+	 * anyway.
+	 */
+	for (i = 0, bpp = 0; i < fmt->num_planes; i++) {
+		bpp_plane = fmt->cpp[i] * 8;
+
+		/*
+		 * Sub-sampling is relevant for chroma planes only and vertical
+		 * readouts are not cached, hence only horizontal sub-sampling
+		 * matters.
+		 */
+		if (i > 0)
+			bpp_plane /= fmt->hsub;
+
+		bpp += bpp_plane;
+	}
+
+	/*
+	 * Horizontal downscale takes extra bandwidth which roughly depends
+	 * on the scaled width.
+	 */
+	if (src_w > dst_w)
+		mul = (src_w - dst_w) * bpp / 2048 + 1;
+	else
+		mul = 1;
+
+	/* average bandwidth in bytes/s */
+	avg_bandwidth  = src_w * src_h * bpp / 8 * mul;
+	avg_bandwidth *= drm_mode_vrefresh(&crtc_state->mode);
+
+	/* mode.clock in kHz, peak bandwidth in kbit/s */
+	peak_bandwidth = crtc_state->mode.clock * bpp * mul;
+
+	/* ICC bandwidth in kbyte/s */
+	peak_bandwidth = kbps_to_icc(peak_bandwidth);
+	avg_bandwidth  = Bps_to_icc(avg_bandwidth);
+
+	/*
+	 * Tegra30/114 Memory Controller can't interleave DC memory requests
+	 * and DC uses 16-bytes atom for the tiled windows, while DDR3 uses 32
+	 * bytes atom. Hence there is x2 memory overfetch for tiled framebuffer
+	 * and DDR3 on older SoCs.
+	 */
+	if (soc->plane_tiled_memory_bandwidth_x2 &&
+	    tegra_state->tiling.mode == TEGRA_BO_TILING_MODE_TILED) {
+		peak_bandwidth *= 2;
+		avg_bandwidth *= 2;
+	}
+
+	tegra_state->peak_memory_bandwidth = peak_bandwidth;
+	tegra_state->avg_memory_bandwidth = avg_bandwidth;
+
+	return 0;
+}
+
 int tegra_plane_state_add(struct tegra_plane *plane,
 			  struct drm_plane_state *state)
 {
@@ -230,6 +315,10 @@ int tegra_plane_state_add(struct tegra_plane *plane,
 	if (err < 0)
 		return err;
 
+	err = tegra_plane_check_memory_bandwidth(state);
+	if (err < 0)
+		return err;
+
 	tegra = to_dc_state(crtc_state);
 
 	tegra->planes |= WIN_A_ACT_REQ << plane->index;
@@ -595,3 +684,36 @@ int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
 
 	return 0;
 }
+
+static const char * const tegra_plane_icc_names[] = {
+	"wina", "winb", "winc", "", "", "", "cursor",
+};
+
+int tegra_plane_interconnect_init(struct tegra_plane *plane)
+{
+	const char *icc_name = tegra_plane_icc_names[plane->index];
+	struct device *dev = plane->dc->dev;
+	struct tegra_dc *dc = plane->dc;
+	int err;
+
+	plane->icc_mem = devm_of_icc_get(dev, icc_name);
+	err = PTR_ERR_OR_ZERO(plane->icc_mem);
+	if (err) {
+		dev_err_probe(dev, err, "failed to get %s interconnect\n",
+			      icc_name);
+		return err;
+	}
+
+	/* plane B on T20/30 has a dedicated memory client for a 6-tap vertical filter */
+	if (plane->index == 1 && dc->soc->has_win_b_vfilter_mem_client) {
+		plane->icc_mem_vfilter = devm_of_icc_get(dev, "winb-vfilter");
+		err = PTR_ERR_OR_ZERO(plane->icc_mem_vfilter);
+		if (err) {
+			dev_err_probe(dev, err, "failed to get %s interconnect\n",
+				      "winb-vfilter");
+			return err;
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index c691dd79b27b..f2731aae7d01 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -8,6 +8,7 @@
 
 #include <drm/drm_plane.h>
 
+struct icc_path;
 struct tegra_bo;
 struct tegra_dc;
 
@@ -16,6 +17,9 @@ struct tegra_plane {
 	struct tegra_dc *dc;
 	unsigned int offset;
 	unsigned int index;
+
+	struct icc_path *icc_mem;
+	struct icc_path *icc_mem_vfilter;
 };
 
 struct tegra_cursor {
@@ -52,6 +56,10 @@ struct tegra_plane_state {
 	/* used for legacy blending support only */
 	struct tegra_plane_legacy_blending_state blending[2];
 	bool opaque;
+
+	/* bandwidths are in ICC units, i.e. kbytes/sec */
+	u32 peak_memory_bandwidth;
+	u32 avg_memory_bandwidth;
 };
 
 static inline struct tegra_plane_state *
@@ -63,6 +71,12 @@ to_tegra_plane_state(struct drm_plane_state *state)
 	return NULL;
 }
 
+static inline const struct tegra_plane_state *
+to_const_tegra_plane_state(const struct drm_plane_state *state)
+{
+	return to_tegra_plane_state((struct drm_plane_state *)state);
+}
+
 extern const struct drm_plane_funcs tegra_plane_funcs;
 
 int tegra_plane_prepare_fb(struct drm_plane *plane,
@@ -77,5 +91,6 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap);
 bool tegra_plane_format_is_yuv(unsigned int format, bool *planar);
 int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
 				   struct tegra_plane_state *state);
+int tegra_plane_interconnect_init(struct tegra_plane *plane);
 
 #endif /* TEGRA_PLANE_H */
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 44/52] drm/tegra: dc: Support memory bandwidth management
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Display controller (DC) performs isochronous memory transfers, and thus,
has a requirement for a minimum memory bandwidth that shall be fulfilled,
otherwise framebuffer data can't be fetched fast enough and this results
in a DC's data-FIFO underflow that follows by a visual corruption.

The Memory Controller drivers provide facility for memory bandwidth
management via interconnect API. This patch wires up the interconnect
API support to the DC driver and fixes distorted display output on
T30 Ouya, T124 TK1 and other Tegra devices.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/Kconfig |   1 +
 drivers/gpu/drm/tegra/dc.c    | 330 ++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/tegra/dc.h    |   6 +
 drivers/gpu/drm/tegra/drm.c   |  14 ++
 drivers/gpu/drm/tegra/hub.c   |   3 +
 drivers/gpu/drm/tegra/plane.c | 122 +++++++++++++
 drivers/gpu/drm/tegra/plane.h |  15 ++
 7 files changed, 491 insertions(+)

diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 5043dcaf1cf9..1650a448eabd 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -9,6 +9,7 @@ config DRM_TEGRA
 	select DRM_MIPI_DSI
 	select DRM_PANEL
 	select TEGRA_HOST1X
+	select INTERCONNECT
 	select IOMMU_IOVA
 	select CEC_CORE if CEC_NOTIFIER
 	help
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 424ad60b4f38..986e7a0dde2a 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -8,6 +8,7 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/iommu.h>
+#include <linux/interconnect.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/pm_runtime.h>
@@ -616,6 +617,9 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
 	struct tegra_dc *dc = to_tegra_dc(state->crtc);
 	int err;
 
+	plane_state->peak_memory_bandwidth = 0;
+	plane_state->avg_memory_bandwidth = 0;
+
 	/* no need for further checks if the plane is being disabled */
 	if (!state->crtc)
 		return 0;
@@ -802,6 +806,12 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
 	formats = dc->soc->primary_formats;
 	modifiers = dc->soc->modifiers;
 
+	err = tegra_plane_interconnect_init(plane);
+	if (err) {
+		kfree(plane);
+		return ERR_PTR(err);
+	}
+
 	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
 				       &tegra_plane_funcs, formats,
 				       num_formats, modifiers, type, NULL);
@@ -833,9 +843,13 @@ static const u32 tegra_cursor_plane_formats[] = {
 static int tegra_cursor_atomic_check(struct drm_plane *plane,
 				     struct drm_plane_state *state)
 {
+	struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
 	struct tegra_plane *tegra = to_tegra_plane(plane);
 	int err;
 
+	plane_state->peak_memory_bandwidth = 0;
+	plane_state->avg_memory_bandwidth = 0;
+
 	/* no need for further checks if the plane is being disabled */
 	if (!state->crtc)
 		return 0;
@@ -973,6 +987,12 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm,
 	num_formats = ARRAY_SIZE(tegra_cursor_plane_formats);
 	formats = tegra_cursor_plane_formats;
 
+	err = tegra_plane_interconnect_init(plane);
+	if (err) {
+		kfree(plane);
+		return ERR_PTR(err);
+	}
+
 	err = drm_universal_plane_init(drm, &plane->base, possible_crtcs,
 				       &tegra_plane_funcs, formats,
 				       num_formats, NULL,
@@ -1087,6 +1107,12 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
 	num_formats = dc->soc->num_overlay_formats;
 	formats = dc->soc->overlay_formats;
 
+	err = tegra_plane_interconnect_init(plane);
+	if (err) {
+		kfree(plane);
+		return ERR_PTR(err);
+	}
+
 	if (!cursor)
 		type = DRM_PLANE_TYPE_OVERLAY;
 	else
@@ -1204,6 +1230,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 {
 	struct tegra_dc_state *state = to_dc_state(crtc->state);
 	struct tegra_dc_state *copy;
+	unsigned int i;
 
 	copy = kmalloc(sizeof(*copy), GFP_KERNEL);
 	if (!copy)
@@ -1215,6 +1242,9 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
 	copy->div = state->div;
 	copy->planes = state->planes;
 
+	for (i = 0; i < ARRAY_SIZE(state->plane_peak_bw); i++)
+		copy->plane_peak_bw[i] = state->plane_peak_bw[i];
+
 	return &copy->base;
 }
 
@@ -1741,6 +1771,104 @@ static int tegra_dc_wait_idle(struct tegra_dc *dc, unsigned long timeout)
 	return -ETIMEDOUT;
 }
 
+static void
+tegra_crtc_update_memory_bandwidth(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_crtc_state,
+				   bool prepare_bandwidth_transition)
+{
+	const struct tegra_plane_state *old_tegra_state, *new_tegra_state;
+	u32 i, new_avg_bw, old_avg_bw, new_peak_bw, old_peak_bw;
+	struct tegra_dc_state *old_dc_state, *new_dc_state;
+	const struct drm_plane_state *old_plane_state;
+	struct tegra_dc_window window, old_window;
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+	struct tegra_plane *tegra;
+	struct drm_plane *plane;
+
+	if (dc->soc->has_nvdisplay)
+		return;
+
+	if (!crtc->state->active) {
+		if (!old_crtc_state->active)
+			return;
+
+		/*
+		 * When CRTC is disabled on DPMS, the state of attached planes
+		 * is kept unchanged. Hence we need to enforce removal of the
+		 * bandwidths from the ICC paths.
+		 */
+		drm_atomic_crtc_for_each_plane(plane, crtc) {
+			tegra = to_tegra_plane(plane);
+
+			icc_set_bw(tegra->icc_mem, 0, 0);
+			icc_set_bw(tegra->icc_mem_vfilter, 0, 0);
+		}
+
+		return;
+	}
+
+	old_dc_state = to_dc_state(old_crtc_state);
+	new_dc_state = to_dc_state(crtc->state);
+
+	for_each_old_plane_in_state(old_crtc_state->state, plane,
+				    old_plane_state, i) {
+		old_tegra_state = to_const_tegra_plane_state(old_plane_state);
+		new_tegra_state = to_const_tegra_plane_state(plane->state);
+		tegra = to_tegra_plane(plane);
+
+		/*
+		 * We're iterating over the global atomic state and it contains
+		 * planes from another CRTC, hence we need to filter out the
+		 * planes unrelated to this CRTC.
+		 */
+		if (tegra->dc != dc)
+			continue;
+
+		new_avg_bw = new_tegra_state->avg_memory_bandwidth;
+		old_avg_bw = old_tegra_state->avg_memory_bandwidth;
+
+		new_peak_bw = new_dc_state->plane_peak_bw[tegra->index];
+		old_peak_bw = old_dc_state->plane_peak_bw[tegra->index];
+
+		/*
+		 * See the comment related to !crtc->state->active above,
+		 * which explains why bandwidths need to be updated when
+		 * CRTC is turning ON.
+		 */
+		if (new_avg_bw == old_avg_bw && new_peak_bw == old_peak_bw &&
+		    old_crtc_state->active)
+			continue;
+
+		window.src.h = drm_rect_height(&plane->state->src) >> 16;
+		window.dst.h = drm_rect_height(&plane->state->dst);
+
+		old_window.src.h = drm_rect_height(&old_plane_state->src) >> 16;
+		old_window.dst.h = drm_rect_height(&old_plane_state->dst);
+
+		/*
+		 * During the preparation phase (atomic_begin), the memory
+		 * freq should go high before the DC changes are committed
+		 * if bandwidth requirement goes up, otherwise memory freq
+		 * should to stay high if BW requirement goes down.  The
+		 * opposite applies to the completion phase (post_commit).
+		 */
+		if (prepare_bandwidth_transition) {
+			new_avg_bw = max(old_avg_bw, new_avg_bw);
+			new_peak_bw = max(old_peak_bw, new_peak_bw);
+
+			if (tegra_plane_use_vertical_filtering(tegra, &old_window))
+				window = old_window;
+		}
+
+		icc_set_bw(tegra->icc_mem, new_avg_bw, new_peak_bw);
+
+		if (tegra_plane_use_vertical_filtering(tegra, &window))
+			icc_set_bw(tegra->icc_mem_vfilter, new_avg_bw, new_peak_bw);
+		else
+			icc_set_bw(tegra->icc_mem_vfilter, 0, 0);
+	}
+}
+
 static void tegra_crtc_atomic_disable(struct drm_crtc *crtc,
 				      struct drm_crtc_state *old_state)
 {
@@ -1922,6 +2050,8 @@ static void tegra_crtc_atomic_begin(struct drm_crtc *crtc,
 {
 	unsigned long flags;
 
+	tegra_crtc_update_memory_bandwidth(crtc, old_crtc_state, true);
+
 	if (crtc->state->event) {
 		spin_lock_irqsave(&crtc->dev->event_lock, flags);
 
@@ -1952,7 +2082,195 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,
 	value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
 }
 
+static bool tegra_plane_is_cursor(const struct drm_plane_state *state)
+{
+	const struct tegra_dc_soc_info *soc = to_tegra_dc(state->crtc)->soc;
+	const struct drm_format_info *fmt = state->fb->format;
+	unsigned int src_w = drm_rect_width(&state->src) >> 16;
+	unsigned int dst_w = drm_rect_width(&state->dst);
+
+	if (state->plane->type != DRM_PLANE_TYPE_CURSOR)
+		return false;
+
+	if (soc->supports_cursor)
+		return true;
+
+	if (src_w != dst_w || fmt->num_planes != 1 || src_w * fmt->cpp[0] > 256)
+		return false;
+
+	return true;
+}
+
+static unsigned int
+tegra_plane_overlap_mask(struct drm_crtc_state *state,
+			 const struct drm_plane_state *plane_state)
+{
+	const struct drm_plane_state *other_state;
+	const struct tegra_plane *tegra;
+	unsigned int overlap_mask = 0;
+	struct drm_plane *plane;
+	struct drm_rect rect;
+
+	if (!plane_state->visible || !plane_state->fb)
+		return 0;
+
+	drm_atomic_crtc_state_for_each_plane_state(plane, other_state, state) {
+		rect = plane_state->dst;
+
+		tegra = to_tegra_plane(other_state->plane);
+
+		if (!other_state->visible || !other_state->fb)
+			continue;
+
+		/*
+		 * Ignore cursor plane overlaps because it's not practical to
+		 * assume that it contributes to the bandwidth in overlapping
+		 * area if window width is small.
+		 */
+		if (tegra_plane_is_cursor(other_state))
+			continue;
+
+		if (drm_rect_intersect(&rect, &other_state->dst))
+			overlap_mask |= BIT(tegra->index);
+	}
+
+	/*
+	 * Data prefetch FIFO will easily help to overcome temporal memory
+	 * pressure if other plane overlaps with the cursor plane.
+	 */
+	if (tegra_plane_is_cursor(plane_state) && overlap_mask)
+		return 0;
+
+	return overlap_mask;
+}
+
+static struct drm_plane *
+tegra_crtc_get_plane_by_index(struct drm_crtc *crtc, unsigned int index)
+{
+	struct drm_plane *plane;
+
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		if (to_tegra_plane(plane)->index == index)
+			return plane;
+	}
+
+	return NULL;
+}
+
+static int tegra_crtc_atomic_check(struct drm_crtc *crtc,
+				   struct drm_crtc_state *state)
+{
+	struct tegra_dc_state *old_dc_state, *dc_state = to_dc_state(state);
+	ulong overlap_mask[ARRAY_SIZE(dc_state->plane_peak_bw)] = {}, mask;
+	u32 plane_peak_bw[ARRAY_SIZE(dc_state->plane_peak_bw)] = {};
+	bool all_planes_overlap_simultaneously = true;
+	const struct tegra_plane_state *tegra_state;
+	const struct drm_plane_state *plane_state;
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+	struct drm_crtc_state *old_state;
+	struct tegra_plane *tegra;
+	struct drm_plane *plane;
+	u32 i, k, overlap_bw;
+
+	/*
+	 * The nv-display uses shared planes.  The algorithm below assumes
+	 * maximum 3 planes per-CRTC, this assumption isn't applicable to
+	 * the nv-display.  Note that T124 support has additional windows,
+	 * but currently they aren't supported by the driver.
+	 */
+	if (dc->soc->has_nvdisplay)
+		return 0;
+
+	/*
+	 * For overlapping planes pixel's data is fetched for each plane at
+	 * the same time, hence bandwidths are accumulated in this case.
+	 * This needs to be taken into account for calculating total bandwidth
+	 * consumed by all planes.
+	 *
+	 * Here we get the overlapping state of each plane, which is a
+	 * bitmask of plane indices telling with what planes there is an
+	 * overlap. Note that bitmask[plane] includes BIT(plane) in order
+	 * to make further code nicer and simpler.
+	 */
+	drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state) {
+		tegra_state = to_const_tegra_plane_state(plane_state);
+		tegra = to_tegra_plane(plane);
+
+		plane_peak_bw[tegra->index] = tegra_state->peak_memory_bandwidth;
+		mask = tegra_plane_overlap_mask(state, plane_state);
+		overlap_mask[tegra->index] = mask;
+
+		if (hweight_long(mask) != 3)
+			all_planes_overlap_simultaneously = false;
+	}
+
+	old_state = drm_atomic_get_old_crtc_state(state->state, crtc);
+	old_dc_state = to_dc_state(old_state);
+
+	/*
+	 * Then we calculate maximum bandwidth of each plane state.
+	 * The bandwidth includes the plane BW + BW of the "simultaneously"
+	 * overlapping planes, where "simultaneously" means areas where DC
+	 * fetches from the planes simultaneously during of scan-out process.
+	 *
+	 * For example, if plane A overlaps with planes B and C, but B and C
+	 * don't overlap, then the peak bandwidth will be either in area where
+	 * A-and-B or A-and-C planes overlap.
+	 *
+	 * The plane_peak_bw[] contains peak memory bandwidth values of
+	 * each plane, this information is needed by interconnect provider
+	 * in order to set up latency allowness based on the peak BW, see
+	 * tegra_crtc_update_memory_bandwidth().
+	 */
+	for (i = 0; i < ARRAY_SIZE(dc_state->plane_peak_bw); i++) {
+		overlap_bw = 0;
+
+		for_each_set_bit(k, &overlap_mask[i], 3) {
+			if (k == i)
+				continue;
+
+			if (all_planes_overlap_simultaneously)
+				overlap_bw += plane_peak_bw[k];
+			else
+				overlap_bw = max(overlap_bw, plane_peak_bw[k]);
+		}
+
+		dc_state->plane_peak_bw[i] = plane_peak_bw[i] + overlap_bw;
+
+		/*
+		 * If plane's peak bandwidth changed (for example plane isn't
+		 * overlapped anymore) and plane isn't in the atomic state,
+		 * then add plane to the state in order to have the bandwidth
+		 * updated.
+		 */
+		if (old_dc_state->plane_peak_bw[i] != dc_state->plane_peak_bw[i]) {
+			plane = tegra_crtc_get_plane_by_index(crtc, i);
+			if (!plane)
+				continue;
+
+			plane_state = drm_atomic_get_plane_state(state->state,
+								 plane);
+			if (IS_ERR(plane_state))
+				return PTR_ERR(plane_state);
+		}
+	}
+
+	return 0;
+}
+
+void tegra_crtc_atomic_post_commit(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_crtc_state)
+{
+	/*
+	 * Display bandwidth is allowed to go down only once hardware state
+	 * is known to be armed, i.e. state was committed and VBLANK event
+	 * was received.
+	 */
+	tegra_crtc_update_memory_bandwidth(crtc, old_crtc_state, false);
+}
+
 static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
+	.atomic_check = tegra_crtc_atomic_check,
 	.atomic_begin = tegra_crtc_atomic_begin,
 	.atomic_flush = tegra_crtc_atomic_flush,
 	.atomic_enable = tegra_crtc_atomic_enable,
@@ -2243,7 +2561,9 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
 	.overlay_formats = tegra20_overlay_formats,
 	.modifiers = tegra20_modifiers,
 	.has_win_a_without_filters = true,
+	.has_win_b_vfilter_mem_client = true,
 	.has_win_c_without_vert_filter = true,
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
@@ -2262,7 +2582,9 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
 	.overlay_formats = tegra20_overlay_formats,
 	.modifiers = tegra20_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = true,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = true,
 };
 
 static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
@@ -2281,7 +2603,9 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
 	.overlay_formats = tegra114_overlay_formats,
 	.modifiers = tegra20_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = false,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = true,
 };
 
 static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
@@ -2300,7 +2624,9 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
 	.overlay_formats = tegra124_overlay_formats,
 	.modifiers = tegra124_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = false,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
@@ -2319,7 +2645,9 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
 	.overlay_formats = tegra114_overlay_formats,
 	.modifiers = tegra124_modifiers,
 	.has_win_a_without_filters = false,
+	.has_win_b_vfilter_mem_client = false,
 	.has_win_c_without_vert_filter = false,
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_windowgroup_soc tegra186_dc_wgrps[] = {
@@ -2368,6 +2696,7 @@ static const struct tegra_dc_soc_info tegra186_dc_soc_info = {
 	.has_nvdisplay = true,
 	.wgrps = tegra186_dc_wgrps,
 	.num_wgrps = ARRAY_SIZE(tegra186_dc_wgrps),
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct tegra_windowgroup_soc tegra194_dc_wgrps[] = {
@@ -2416,6 +2745,7 @@ static const struct tegra_dc_soc_info tegra194_dc_soc_info = {
 	.has_nvdisplay = true,
 	.wgrps = tegra194_dc_wgrps,
 	.num_wgrps = ARRAY_SIZE(tegra194_dc_wgrps),
+	.plane_tiled_memory_bandwidth_x2 = false,
 };
 
 static const struct of_device_id tegra_dc_of_match[] = {
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 051d03dcb9b0..8fade75caef9 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -23,6 +23,8 @@ struct tegra_dc_state {
 	unsigned int div;
 
 	u32 planes;
+
+	unsigned long plane_peak_bw[6];
 };
 
 static inline struct tegra_dc_state *to_dc_state(struct drm_crtc_state *state)
@@ -65,7 +67,9 @@ struct tegra_dc_soc_info {
 	unsigned int num_overlay_formats;
 	const u64 *modifiers;
 	bool has_win_a_without_filters;
+	bool has_win_b_vfilter_mem_client;
 	bool has_win_c_without_vert_filter;
+	unsigned int plane_tiled_memory_bandwidth_x2;
 };
 
 struct tegra_dc {
@@ -151,6 +155,8 @@ int tegra_dc_state_setup_clock(struct tegra_dc *dc,
 			       struct drm_crtc_state *crtc_state,
 			       struct clk *clk, unsigned long pclk,
 			       unsigned int div);
+void tegra_crtc_atomic_post_commit(struct drm_crtc *crtc,
+				   struct drm_crtc_state *old_crtc_state);
 
 /* from rgb.c */
 int tegra_dc_rgb_probe(struct tegra_dc *dc);
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index ba9d1c3e7cac..455a1ae639ba 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -20,6 +20,7 @@
 #include <drm/drm_prime.h>
 #include <drm/drm_vblank.h>
 
+#include "dc.h"
 #include "drm.h"
 #include "gem.h"
 
@@ -59,6 +60,17 @@ static const struct drm_mode_config_funcs tegra_drm_mode_config_funcs = {
 	.atomic_commit = drm_atomic_helper_commit,
 };
 
+static void tegra_atomic_post_commit(struct drm_device *drm,
+				     struct drm_atomic_state *old_state)
+{
+	struct drm_crtc_state *old_crtc_state;
+	struct drm_crtc *crtc;
+	unsigned int i;
+
+	for_each_old_crtc_in_state(old_state, crtc, old_crtc_state, i)
+		tegra_crtc_atomic_post_commit(crtc, old_crtc_state);
+}
+
 static void tegra_atomic_commit_tail(struct drm_atomic_state *old_state)
 {
 	struct drm_device *drm = old_state->dev;
@@ -75,6 +87,8 @@ static void tegra_atomic_commit_tail(struct drm_atomic_state *old_state)
 	} else {
 		drm_atomic_helper_commit_tail_rpm(old_state);
 	}
+
+	tegra_atomic_post_commit(drm, old_state);
 }
 
 static const struct drm_mode_config_helper_funcs
diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c
index 22a03f7ffdc1..4fa338dc7eb2 100644
--- a/drivers/gpu/drm/tegra/hub.c
+++ b/drivers/gpu/drm/tegra/hub.c
@@ -344,6 +344,9 @@ static int tegra_shared_plane_atomic_check(struct drm_plane *plane,
 	struct tegra_dc *dc = to_tegra_dc(state->crtc);
 	int err;
 
+	plane_state->peak_memory_bandwidth = 0;
+	plane_state->avg_memory_bandwidth = 0;
+
 	/* no need for further checks if the plane is being disabled */
 	if (!state->crtc || !state->fb)
 		return 0;
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index 539d14935728..f525994fba70 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/iommu.h>
+#include <linux/interconnect.h>
 
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
@@ -64,6 +65,8 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane)
 	copy->reflect_x = state->reflect_x;
 	copy->reflect_y = state->reflect_y;
 	copy->opaque = state->opaque;
+	copy->peak_memory_bandwidth = state->peak_memory_bandwidth;
+	copy->avg_memory_bandwidth = state->avg_memory_bandwidth;
 
 	for (i = 0; i < 2; i++)
 		copy->blending[i] = state->blending[i];
@@ -212,6 +215,88 @@ void tegra_plane_cleanup_fb(struct drm_plane *plane,
 		tegra_dc_unpin(dc, to_tegra_plane_state(state));
 }
 
+static int tegra_plane_check_memory_bandwidth(struct drm_plane_state *state)
+{
+	struct tegra_plane_state *tegra_state = to_tegra_plane_state(state);
+	unsigned int i, bpp, bpp_plane, dst_w, dst_h, src_w, src_h, mul;
+	u32 avg_bandwidth = 0, peak_bandwidth;
+	const struct tegra_dc_soc_info *soc;
+	const struct drm_format_info *fmt;
+	struct drm_crtc_state *crtc_state;
+
+	if (!state->visible)
+		return 0;
+
+	crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
+	if (!crtc_state)
+		return -EINVAL;
+
+	src_w = drm_rect_width(&state->src) >> 16;
+	src_h = drm_rect_height(&state->src) >> 16;
+	dst_w = drm_rect_width(&state->dst);
+	dst_h = drm_rect_height(&state->dst);
+
+	fmt = state->fb->format;
+	soc = to_tegra_dc(state->crtc)->soc;
+
+	/*
+	 * Note that real memory bandwidth vary depending on format and
+	 * memory layout, we are not taking that into account because small
+	 * estimation error isn't important since bandwidth is rounded up
+	 * anyway.
+	 */
+	for (i = 0, bpp = 0; i < fmt->num_planes; i++) {
+		bpp_plane = fmt->cpp[i] * 8;
+
+		/*
+		 * Sub-sampling is relevant for chroma planes only and vertical
+		 * readouts are not cached, hence only horizontal sub-sampling
+		 * matters.
+		 */
+		if (i > 0)
+			bpp_plane /= fmt->hsub;
+
+		bpp += bpp_plane;
+	}
+
+	/*
+	 * Horizontal downscale takes extra bandwidth which roughly depends
+	 * on the scaled width.
+	 */
+	if (src_w > dst_w)
+		mul = (src_w - dst_w) * bpp / 2048 + 1;
+	else
+		mul = 1;
+
+	/* average bandwidth in bytes/s */
+	avg_bandwidth  = src_w * src_h * bpp / 8 * mul;
+	avg_bandwidth *= drm_mode_vrefresh(&crtc_state->mode);
+
+	/* mode.clock in kHz, peak bandwidth in kbit/s */
+	peak_bandwidth = crtc_state->mode.clock * bpp * mul;
+
+	/* ICC bandwidth in kbyte/s */
+	peak_bandwidth = kbps_to_icc(peak_bandwidth);
+	avg_bandwidth  = Bps_to_icc(avg_bandwidth);
+
+	/*
+	 * Tegra30/114 Memory Controller can't interleave DC memory requests
+	 * and DC uses 16-bytes atom for the tiled windows, while DDR3 uses 32
+	 * bytes atom. Hence there is x2 memory overfetch for tiled framebuffer
+	 * and DDR3 on older SoCs.
+	 */
+	if (soc->plane_tiled_memory_bandwidth_x2 &&
+	    tegra_state->tiling.mode == TEGRA_BO_TILING_MODE_TILED) {
+		peak_bandwidth *= 2;
+		avg_bandwidth *= 2;
+	}
+
+	tegra_state->peak_memory_bandwidth = peak_bandwidth;
+	tegra_state->avg_memory_bandwidth = avg_bandwidth;
+
+	return 0;
+}
+
 int tegra_plane_state_add(struct tegra_plane *plane,
 			  struct drm_plane_state *state)
 {
@@ -230,6 +315,10 @@ int tegra_plane_state_add(struct tegra_plane *plane,
 	if (err < 0)
 		return err;
 
+	err = tegra_plane_check_memory_bandwidth(state);
+	if (err < 0)
+		return err;
+
 	tegra = to_dc_state(crtc_state);
 
 	tegra->planes |= WIN_A_ACT_REQ << plane->index;
@@ -595,3 +684,36 @@ int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
 
 	return 0;
 }
+
+static const char * const tegra_plane_icc_names[] = {
+	"wina", "winb", "winc", "", "", "", "cursor",
+};
+
+int tegra_plane_interconnect_init(struct tegra_plane *plane)
+{
+	const char *icc_name = tegra_plane_icc_names[plane->index];
+	struct device *dev = plane->dc->dev;
+	struct tegra_dc *dc = plane->dc;
+	int err;
+
+	plane->icc_mem = devm_of_icc_get(dev, icc_name);
+	err = PTR_ERR_OR_ZERO(plane->icc_mem);
+	if (err) {
+		dev_err_probe(dev, err, "failed to get %s interconnect\n",
+			      icc_name);
+		return err;
+	}
+
+	/* plane B on T20/30 has a dedicated memory client for a 6-tap vertical filter */
+	if (plane->index == 1 && dc->soc->has_win_b_vfilter_mem_client) {
+		plane->icc_mem_vfilter = devm_of_icc_get(dev, "winb-vfilter");
+		err = PTR_ERR_OR_ZERO(plane->icc_mem_vfilter);
+		if (err) {
+			dev_err_probe(dev, err, "failed to get %s interconnect\n",
+				      "winb-vfilter");
+			return err;
+		}
+	}
+
+	return 0;
+}
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h
index c691dd79b27b..f2731aae7d01 100644
--- a/drivers/gpu/drm/tegra/plane.h
+++ b/drivers/gpu/drm/tegra/plane.h
@@ -8,6 +8,7 @@
 
 #include <drm/drm_plane.h>
 
+struct icc_path;
 struct tegra_bo;
 struct tegra_dc;
 
@@ -16,6 +17,9 @@ struct tegra_plane {
 	struct tegra_dc *dc;
 	unsigned int offset;
 	unsigned int index;
+
+	struct icc_path *icc_mem;
+	struct icc_path *icc_mem_vfilter;
 };
 
 struct tegra_cursor {
@@ -52,6 +56,10 @@ struct tegra_plane_state {
 	/* used for legacy blending support only */
 	struct tegra_plane_legacy_blending_state blending[2];
 	bool opaque;
+
+	/* bandwidths are in ICC units, i.e. kbytes/sec */
+	u32 peak_memory_bandwidth;
+	u32 avg_memory_bandwidth;
 };
 
 static inline struct tegra_plane_state *
@@ -63,6 +71,12 @@ to_tegra_plane_state(struct drm_plane_state *state)
 	return NULL;
 }
 
+static inline const struct tegra_plane_state *
+to_const_tegra_plane_state(const struct drm_plane_state *state)
+{
+	return to_tegra_plane_state((struct drm_plane_state *)state);
+}
+
 extern const struct drm_plane_funcs tegra_plane_funcs;
 
 int tegra_plane_prepare_fb(struct drm_plane *plane,
@@ -77,5 +91,6 @@ int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap);
 bool tegra_plane_format_is_yuv(unsigned int format, bool *planar);
 int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
 				   struct tegra_plane_state *state);
+int tegra_plane_interconnect_init(struct tegra_plane *plane);
 
 #endif /* TEGRA_PLANE_H */
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 45/52] drm/tegra: dc: Extend debug stats with total number of events
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

It's useful to know the total number of underflow events and currently
the debug stats are getting reset each time CRTC is being disabled. Let's
account the overall number of events that doesn't get a reset.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/dc.c | 10 ++++++++++
 drivers/gpu/drm/tegra/dc.h |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 986e7a0dde2a..f50a42170977 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1539,6 +1539,11 @@ static int tegra_dc_show_stats(struct seq_file *s, void *data)
 	seq_printf(s, "underflow: %lu\n", dc->stats.underflow);
 	seq_printf(s, "overflow: %lu\n", dc->stats.overflow);
 
+	seq_printf(s, "frames total: %lu\n", dc->stats.frames_total);
+	seq_printf(s, "vblank total: %lu\n", dc->stats.vblank_total);
+	seq_printf(s, "underflow total: %lu\n", dc->stats.underflow_total);
+	seq_printf(s, "overflow total: %lu\n", dc->stats.overflow_total);
+
 	return 0;
 }
 
@@ -2289,6 +2294,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		/*
 		dev_dbg(dc->dev, "%s(): frame end\n", __func__);
 		*/
+		dc->stats.frames_total++;
 		dc->stats.frames++;
 	}
 
@@ -2297,6 +2303,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
 		*/
 		drm_crtc_handle_vblank(&dc->base);
+		dc->stats.vblank_total++;
 		dc->stats.vblank++;
 	}
 
@@ -2304,6 +2311,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		/*
 		dev_dbg(dc->dev, "%s(): underflow\n", __func__);
 		*/
+		dc->stats.underflow_total++;
 		dc->stats.underflow++;
 	}
 
@@ -2311,11 +2319,13 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		/*
 		dev_dbg(dc->dev, "%s(): overflow\n", __func__);
 		*/
+		dc->stats.overflow_total++;
 		dc->stats.overflow++;
 	}
 
 	if (status & HEAD_UF_INT) {
 		dev_dbg_ratelimited(dc->dev, "%s(): head underflow\n", __func__);
+		dc->stats.underflow_total++;
 		dc->stats.underflow++;
 	}
 
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 8fade75caef9..e3fc48f8154a 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -40,6 +40,11 @@ struct tegra_dc_stats {
 	unsigned long vblank;
 	unsigned long underflow;
 	unsigned long overflow;
+
+	unsigned long frames_total;
+	unsigned long vblank_total;
+	unsigned long underflow_total;
+	unsigned long overflow_total;
 };
 
 struct tegra_windowgroup_soc {
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 45/52] drm/tegra: dc: Extend debug stats with total number of events
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

It's useful to know the total number of underflow events and currently
the debug stats are getting reset each time CRTC is being disabled. Let's
account the overall number of events that doesn't get a reset.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/gpu/drm/tegra/dc.c | 10 ++++++++++
 drivers/gpu/drm/tegra/dc.h |  5 +++++
 2 files changed, 15 insertions(+)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 986e7a0dde2a..f50a42170977 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1539,6 +1539,11 @@ static int tegra_dc_show_stats(struct seq_file *s, void *data)
 	seq_printf(s, "underflow: %lu\n", dc->stats.underflow);
 	seq_printf(s, "overflow: %lu\n", dc->stats.overflow);
 
+	seq_printf(s, "frames total: %lu\n", dc->stats.frames_total);
+	seq_printf(s, "vblank total: %lu\n", dc->stats.vblank_total);
+	seq_printf(s, "underflow total: %lu\n", dc->stats.underflow_total);
+	seq_printf(s, "overflow total: %lu\n", dc->stats.overflow_total);
+
 	return 0;
 }
 
@@ -2289,6 +2294,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		/*
 		dev_dbg(dc->dev, "%s(): frame end\n", __func__);
 		*/
+		dc->stats.frames_total++;
 		dc->stats.frames++;
 	}
 
@@ -2297,6 +2303,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
 		*/
 		drm_crtc_handle_vblank(&dc->base);
+		dc->stats.vblank_total++;
 		dc->stats.vblank++;
 	}
 
@@ -2304,6 +2311,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		/*
 		dev_dbg(dc->dev, "%s(): underflow\n", __func__);
 		*/
+		dc->stats.underflow_total++;
 		dc->stats.underflow++;
 	}
 
@@ -2311,11 +2319,13 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 		/*
 		dev_dbg(dc->dev, "%s(): overflow\n", __func__);
 		*/
+		dc->stats.overflow_total++;
 		dc->stats.overflow++;
 	}
 
 	if (status & HEAD_UF_INT) {
 		dev_dbg_ratelimited(dc->dev, "%s(): head underflow\n", __func__);
+		dc->stats.underflow_total++;
 		dc->stats.underflow++;
 	}
 
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 8fade75caef9..e3fc48f8154a 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -40,6 +40,11 @@ struct tegra_dc_stats {
 	unsigned long vblank;
 	unsigned long underflow;
 	unsigned long overflow;
+
+	unsigned long frames_total;
+	unsigned long vblank_total;
+	unsigned long underflow_total;
+	unsigned long overflow_total;
 };
 
 struct tegra_windowgroup_soc {
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

This patch fixes lockup which happens when OPP table is released if
interconnect provider uses OPP in the icc_provider->set() callback
and bandwidth of the ICC path is set to 0 by the ICC core when path
is released. The icc_put() doesn't need the opp_table_lock protection,
hence let's move it outside of the lock in order to resolve the problem.

In particular this fixes tegra-devfreq driver lockup on trying to unload
the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
provider also uses OPP for DVFS, hence they both take same opp_table_lock
when OPP table of the devfreq is released.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/opp/core.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 2483e765318a..1134df360fe0 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1187,12 +1187,6 @@ static void _opp_table_kref_release(struct kref *kref)
 	if (!IS_ERR(opp_table->clk))
 		clk_put(opp_table->clk);
 
-	if (opp_table->paths) {
-		for (i = 0; i < opp_table->path_count; i++)
-			icc_put(opp_table->paths[i]);
-		kfree(opp_table->paths);
-	}
-
 	WARN_ON(!list_empty(&opp_table->opp_list));
 
 	list_for_each_entry_safe(opp_dev, temp, &opp_table->dev_list, node) {
@@ -1209,9 +1203,22 @@ static void _opp_table_kref_release(struct kref *kref)
 	mutex_destroy(&opp_table->genpd_virt_dev_lock);
 	mutex_destroy(&opp_table->lock);
 	list_del(&opp_table->node);
-	kfree(opp_table);
 
 	mutex_unlock(&opp_table_lock);
+
+	/*
+	 * Interconnect provider may use OPP too, hence icc_put() needs to be
+	 * invoked outside of the opp_table_lock in order to prevent nested
+	 * locking which happens when bandwidth of the ICC path is set to 0
+	 * by ICC core on release of the path.
+	 */
+	if (opp_table->paths) {
+		for (i = 0; i < opp_table->path_count; i++)
+			icc_put(opp_table->paths[i]);
+		kfree(opp_table->paths);
+	}
+
+	kfree(opp_table);
 }
 
 void dev_pm_opp_put_opp_table(struct opp_table *opp_table)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

This patch fixes lockup which happens when OPP table is released if
interconnect provider uses OPP in the icc_provider->set() callback
and bandwidth of the ICC path is set to 0 by the ICC core when path
is released. The icc_put() doesn't need the opp_table_lock protection,
hence let's move it outside of the lock in order to resolve the problem.

In particular this fixes tegra-devfreq driver lockup on trying to unload
the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
provider also uses OPP for DVFS, hence they both take same opp_table_lock
when OPP table of the devfreq is released.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/opp/core.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 2483e765318a..1134df360fe0 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1187,12 +1187,6 @@ static void _opp_table_kref_release(struct kref *kref)
 	if (!IS_ERR(opp_table->clk))
 		clk_put(opp_table->clk);
 
-	if (opp_table->paths) {
-		for (i = 0; i < opp_table->path_count; i++)
-			icc_put(opp_table->paths[i]);
-		kfree(opp_table->paths);
-	}
-
 	WARN_ON(!list_empty(&opp_table->opp_list));
 
 	list_for_each_entry_safe(opp_dev, temp, &opp_table->dev_list, node) {
@@ -1209,9 +1203,22 @@ static void _opp_table_kref_release(struct kref *kref)
 	mutex_destroy(&opp_table->genpd_virt_dev_lock);
 	mutex_destroy(&opp_table->lock);
 	list_del(&opp_table->node);
-	kfree(opp_table);
 
 	mutex_unlock(&opp_table_lock);
+
+	/*
+	 * Interconnect provider may use OPP too, hence icc_put() needs to be
+	 * invoked outside of the opp_table_lock in order to prevent nested
+	 * locking which happens when bandwidth of the ICC path is set to 0
+	 * by ICC core on release of the path.
+	 */
+	if (opp_table->paths) {
+		for (i = 0; i < opp_table->path_count; i++)
+			icc_put(opp_table->paths[i]);
+		kfree(opp_table->paths);
+	}
+
+	kfree(opp_table);
 }
 
 void dev_pm_opp_put_opp_table(struct opp_table *opp_table)
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 47/52] PM / devfreq: tegra20: Silence deferred probe error
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Tegra EMC driver was turned into a regular kernel driver, meaning that it
could be compiled as a loadable kernel module now. Hence EMC clock isn't
guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
Let's silence the deferred probe error.

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra20-devfreq.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
index ff82bac9ee4e..fd801534771d 100644
--- a/drivers/devfreq/tegra20-devfreq.c
+++ b/drivers/devfreq/tegra20-devfreq.c
@@ -141,11 +141,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 
 	/* EMC is a system-critical clock that is always enabled */
 	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
-	if (IS_ERR(tegra->emc_clock)) {
-		err = PTR_ERR(tegra->emc_clock);
-		dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
-		return err;
-	}
+	if (IS_ERR(tegra->emc_clock))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
+				     "failed to get emc clock\n");
 
 	tegra->regs = mc->regs;
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 47/52] PM / devfreq: tegra20: Silence deferred probe error
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Tegra EMC driver was turned into a regular kernel driver, meaning that it
could be compiled as a loadable kernel module now. Hence EMC clock isn't
guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
Let's silence the deferred probe error.

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra20-devfreq.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
index ff82bac9ee4e..fd801534771d 100644
--- a/drivers/devfreq/tegra20-devfreq.c
+++ b/drivers/devfreq/tegra20-devfreq.c
@@ -141,11 +141,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 
 	/* EMC is a system-critical clock that is always enabled */
 	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
-	if (IS_ERR(tegra->emc_clock)) {
-		err = PTR_ERR(tegra->emc_clock);
-		dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
-		return err;
-	}
+	if (IS_ERR(tegra->emc_clock))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
+				     "failed to get emc clock\n");
 
 	tegra->regs = mc->regs;
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 48/52] PM / devfreq: tegra20: Relax Kconfig dependency
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

The Tegra EMC driver now could be compiled as a loadable kernel module.
Currently devfreq driver depends on the EMC/MC drivers in Kconfig, and
thus, devfreq is forced to be a kernel module if EMC is compiled as a
module. This build dependency could be relaxed since devfreq driver
checks MC/EMC presence on probe, allowing kernel configuration where
devfreq is a built-in driver and EMC driver is a loadable module.
This change puts Tegra20 devfreq Kconfig entry on a par with the Tegra30
devfreq entry.

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 37dc40d1fcfb..0ee36ae2fa79 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -123,7 +123,7 @@ config ARM_TEGRA_DEVFREQ
 
 config ARM_TEGRA20_DEVFREQ
 	tristate "NVIDIA Tegra20 DEVFREQ Driver"
-	depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST
+	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
 	depends on COMMON_CLK
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
 	help
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 48/52] PM / devfreq: tegra20: Relax Kconfig dependency
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

The Tegra EMC driver now could be compiled as a loadable kernel module.
Currently devfreq driver depends on the EMC/MC drivers in Kconfig, and
thus, devfreq is forced to be a kernel module if EMC is compiled as a
module. This build dependency could be relaxed since devfreq driver
checks MC/EMC presence on probe, allowing kernel configuration where
devfreq is a built-in driver and EMC driver is a loadable module.
This change puts Tegra20 devfreq Kconfig entry on a par with the Tegra30
devfreq entry.

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 37dc40d1fcfb..0ee36ae2fa79 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -123,7 +123,7 @@ config ARM_TEGRA_DEVFREQ
 
 config ARM_TEGRA20_DEVFREQ
 	tristate "NVIDIA Tegra20 DEVFREQ Driver"
-	depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST
+	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
 	depends on COMMON_CLK
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
 	help
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

External (EMC) and Internal Memory Controllers (IMC) have a nearly
identical statistics gathering module. This patch switches driver to use
EMC_STAT instead of IMC_STAT and adds device-tree support which brings ICC
support and makes driver to use bandwidth OPPs defined in device-tree.

The previous tegra20-devfreq variant was depending on presence of both
EMC and IMC drivers simultaneously because it wasn't apparent how to use
EMC_STAT properly back in the day. Dependency on the IMC driver is gone
after this patch.

The older variant of the devfreq driver also isn't suitable anymore
because EMC got support for interconnect framework and DVFS, hence
tegra20-devfreq shouldn't drive the EMC clock directly, but use OPP
API for issuing memory bandwidth requests.

The polling interval is changed from 500ms to 30ms in order to improve
responsiveness of the system in general and because EMC clock is now
allowed to go lower than before since display driver supports ICC now
as well.

The parent EMC device is an MFD device now and tegra20-devfreq its
sub-device. Devfreq driver uses SYSCON API for retrieving regmap of the
EMC registers from the parent device.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/Kconfig           |   1 +
 drivers/devfreq/tegra20-devfreq.c | 174 +++++++++++++-----------------
 2 files changed, 75 insertions(+), 100 deletions(-)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 0ee36ae2fa79..1bd225e571df 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -126,6 +126,7 @@ config ARM_TEGRA20_DEVFREQ
 	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
 	depends on COMMON_CLK
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	select MFD_SYSCON
 	help
 	  This adds the DEVFREQ driver for the Tegra20 family of SoCs.
 	  It reads Memory Controller counters and adjusts the operating
diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
index fd801534771d..0a36b085d32a 100644
--- a/drivers/devfreq/tegra20-devfreq.c
+++ b/drivers/devfreq/tegra20-devfreq.c
@@ -7,180 +7,148 @@
 
 #include <linux/clk.h>
 #include <linux/devfreq.h>
-#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_opp.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 
-#include <soc/tegra/mc.h>
-
 #include "governor.h"
 
-#define MC_STAT_CONTROL				0x90
-#define MC_STAT_EMC_CLOCK_LIMIT			0xa0
-#define MC_STAT_EMC_CLOCKS			0xa4
-#define MC_STAT_EMC_CONTROL			0xa8
-#define MC_STAT_EMC_COUNT			0xb8
+#define EMC_STAT_CONTROL			0x160
+#define EMC_STAT_LLMC_CONTROL			0x178
+#define EMC_STAT_PWR_CLOCK_LIMIT		0x198
+#define EMC_STAT_PWR_CLOCKS			0x19c
+#define EMC_STAT_PWR_COUNT			0x1a0
 
-#define EMC_GATHER_CLEAR			(1 << 8)
-#define EMC_GATHER_ENABLE			(3 << 8)
+#define EMC_PWR_GATHER_CLEAR			(1 << 8)
+#define EMC_PWR_GATHER_DISABLE			(2 << 8)
+#define EMC_PWR_GATHER_ENABLE			(3 << 8)
 
 struct tegra_devfreq {
+	struct devfreq_simple_ondemand_data ondemand_data;
+	struct opp_table *opp_table;
 	struct devfreq *devfreq;
 	struct clk *emc_clock;
-	void __iomem *regs;
+	struct regmap *rmap;
 };
 
 static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
 				u32 flags)
 {
-	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
-	struct devfreq *devfreq = tegra->devfreq;
 	struct dev_pm_opp *opp;
-	unsigned long rate;
-	int err;
+	int ret;
 
 	opp = devfreq_recommended_opp(dev, freq, flags);
-	if (IS_ERR(opp))
+	if (IS_ERR(opp)) {
+		dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
 		return PTR_ERR(opp);
+	}
 
-	rate = dev_pm_opp_get_freq(opp);
+	ret = dev_pm_opp_set_bw(dev, opp);
 	dev_pm_opp_put(opp);
 
-	err = clk_set_min_rate(tegra->emc_clock, rate);
-	if (err)
-		return err;
-
-	err = clk_set_rate(tegra->emc_clock, 0);
-	if (err)
-		goto restore_min_rate;
-
-	return 0;
-
-restore_min_rate:
-	clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
-
-	return err;
+	return ret;
 }
 
 static int tegra_devfreq_get_dev_status(struct device *dev,
 					struct devfreq_dev_status *stat)
 {
 	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
+	u32 count, clocks;
 
-	/*
-	 * EMC_COUNT returns number of memory events, that number is lower
-	 * than the number of clocks. Conversion ratio of 1/8 results in a
-	 * bit higher bandwidth than actually needed, it is good enough for
-	 * the time being because drivers don't support requesting minimum
-	 * needed memory bandwidth yet.
-	 *
-	 * TODO: adjust the ratio value once relevant drivers will support
-	 * memory bandwidth management.
-	 */
-	stat->busy_time = readl_relaxed(tegra->regs + MC_STAT_EMC_COUNT);
-	stat->total_time = readl_relaxed(tegra->regs + MC_STAT_EMC_CLOCKS) / 8;
-	stat->current_frequency = clk_get_rate(tegra->emc_clock);
+	/* freeze counters */
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_DISABLE);
+
+	/* number of clocks when EMC request was accepted */
+	regmap_read(tegra->rmap, EMC_STAT_PWR_COUNT, &count);
+	/* total number of clocks while PWR_GATHER control was set to ENABLE */
+	regmap_read(tegra->rmap, EMC_STAT_PWR_CLOCKS, &clocks);
 
-	writel_relaxed(EMC_GATHER_CLEAR, tegra->regs + MC_STAT_CONTROL);
-	writel_relaxed(EMC_GATHER_ENABLE, tegra->regs + MC_STAT_CONTROL);
+	/* clear counters and restart */
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_CLEAR);
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_ENABLE);
+
+	stat->busy_time = count;
+	stat->total_time = clocks;
+	stat->current_frequency = clk_get_rate(tegra->emc_clock);
 
 	return 0;
 }
 
 static struct devfreq_dev_profile tegra_devfreq_profile = {
-	.polling_ms	= 500,
+	.polling_ms	= 30,
 	.target		= tegra_devfreq_target,
 	.get_dev_status	= tegra_devfreq_get_dev_status,
 };
 
-static struct tegra_mc *tegra_get_memory_controller(void)
-{
-	struct platform_device *pdev;
-	struct device_node *np;
-	struct tegra_mc *mc;
-
-	np = of_find_compatible_node(NULL, NULL, "nvidia,tegra20-mc-gart");
-	if (!np)
-		return ERR_PTR(-ENOENT);
-
-	pdev = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!pdev)
-		return ERR_PTR(-ENODEV);
-
-	mc = platform_get_drvdata(pdev);
-	if (!mc)
-		return ERR_PTR(-EPROBE_DEFER);
-
-	return mc;
-}
-
 static int tegra_devfreq_probe(struct platform_device *pdev)
 {
+	struct device_node *emc_np = pdev->dev.parent->of_node;
 	struct tegra_devfreq *tegra;
-	struct tegra_mc *mc;
-	unsigned long max_rate;
-	unsigned long rate;
 	int err;
 
-	mc = tegra_get_memory_controller();
-	if (IS_ERR(mc)) {
-		err = PTR_ERR(mc);
-		dev_err(&pdev->dev, "failed to get memory controller: %d\n",
-			err);
-		return err;
-	}
-
 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
 	if (!tegra)
 		return -ENOMEM;
 
 	/* EMC is a system-critical clock that is always enabled */
-	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
+	tegra->emc_clock = devm_get_clk_from_child(&pdev->dev, emc_np, NULL);
 	if (IS_ERR(tegra->emc_clock))
 		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
 				     "failed to get emc clock\n");
 
-	tegra->regs = mc->regs;
-
-	max_rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
+	tegra->rmap = device_node_to_regmap(emc_np);
+	if (IS_ERR(tegra->rmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->rmap),
+				     "failed to get emc regmap\n");
 
-	for (rate = 0; rate <= max_rate; rate++) {
-		rate = clk_round_rate(tegra->emc_clock, rate);
+	tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
+	if (IS_ERR(tegra->opp_table))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
+				     "failed to prepare opp table\n");
 
-		err = dev_pm_opp_add(&pdev->dev, rate, 0);
-		if (err) {
-			dev_err(&pdev->dev, "failed to add opp: %d\n", err);
-			goto remove_opps;
-		}
+	err = dev_pm_opp_of_add_table(&pdev->dev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to add opp table: %d\n", err);
+		goto put_table;
 	}
 
+	/*
+	 * PWR_COUNT is 1/2 of PWR_CLOCKS at max, and thus, the up-threshold
+	 * should be less than 50.  Secondly, multiple active memory clients
+	 * may cause over 20 of lost clock cycles due to stalls caused by
+	 * competing memory accesses.  This means that threshold should be
+	 * set to a less than 30 in order to have a properly working governor.
+	 */
+	tegra->ondemand_data.upthreshold = 20;
+
 	/*
 	 * Reset statistic gathers state, select global bandwidth for the
 	 * statistics collection mode and set clocks counter saturation
 	 * limit to maximum.
 	 */
-	writel_relaxed(0x00000000, tegra->regs + MC_STAT_CONTROL);
-	writel_relaxed(0x00000000, tegra->regs + MC_STAT_EMC_CONTROL);
-	writel_relaxed(0xffffffff, tegra->regs + MC_STAT_EMC_CLOCK_LIMIT);
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, 0x00000000);
+	regmap_write(tegra->rmap, EMC_STAT_LLMC_CONTROL, 0x00000000);
+	regmap_write(tegra->rmap, EMC_STAT_PWR_CLOCK_LIMIT, 0xffffffff);
 
 	platform_set_drvdata(pdev, tegra);
 
 	tegra->devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
-					    DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
+					    DEVFREQ_GOV_SIMPLE_ONDEMAND,
+					    &tegra->ondemand_data);
 	if (IS_ERR(tegra->devfreq)) {
 		err = PTR_ERR(tegra->devfreq);
-		goto remove_opps;
+		goto put_table;
 	}
 
 	return 0;
 
-remove_opps:
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
+put_table:
+	dev_pm_opp_put_opp_table(tegra->opp_table);
 
 	return err;
 }
@@ -190,21 +158,27 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
 	struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
 
 	devfreq_remove_device(tegra->devfreq);
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
+	dev_pm_opp_of_remove_table(&pdev->dev);
+	dev_pm_opp_put_opp_table(tegra->opp_table);
 
 	return 0;
 }
 
+static const struct of_device_id tegra_devfreq_of_match[] = {
+	{ .compatible = "nvidia,tegra20-emc-statistics" },
+	{ },
+};
+
 static struct platform_driver tegra_devfreq_driver = {
 	.probe		= tegra_devfreq_probe,
 	.remove		= tegra_devfreq_remove,
 	.driver		= {
 		.name	= "tegra20-devfreq",
+		.of_match_table = tegra_devfreq_of_match,
 	},
 };
 module_platform_driver(tegra_devfreq_driver);
 
-MODULE_ALIAS("platform:tegra20-devfreq");
 MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
 MODULE_DESCRIPTION("NVIDIA Tegra20 devfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

External (EMC) and Internal Memory Controllers (IMC) have a nearly
identical statistics gathering module. This patch switches driver to use
EMC_STAT instead of IMC_STAT and adds device-tree support which brings ICC
support and makes driver to use bandwidth OPPs defined in device-tree.

The previous tegra20-devfreq variant was depending on presence of both
EMC and IMC drivers simultaneously because it wasn't apparent how to use
EMC_STAT properly back in the day. Dependency on the IMC driver is gone
after this patch.

The older variant of the devfreq driver also isn't suitable anymore
because EMC got support for interconnect framework and DVFS, hence
tegra20-devfreq shouldn't drive the EMC clock directly, but use OPP
API for issuing memory bandwidth requests.

The polling interval is changed from 500ms to 30ms in order to improve
responsiveness of the system in general and because EMC clock is now
allowed to go lower than before since display driver supports ICC now
as well.

The parent EMC device is an MFD device now and tegra20-devfreq its
sub-device. Devfreq driver uses SYSCON API for retrieving regmap of the
EMC registers from the parent device.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/Kconfig           |   1 +
 drivers/devfreq/tegra20-devfreq.c | 174 +++++++++++++-----------------
 2 files changed, 75 insertions(+), 100 deletions(-)

diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 0ee36ae2fa79..1bd225e571df 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -126,6 +126,7 @@ config ARM_TEGRA20_DEVFREQ
 	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
 	depends on COMMON_CLK
 	select DEVFREQ_GOV_SIMPLE_ONDEMAND
+	select MFD_SYSCON
 	help
 	  This adds the DEVFREQ driver for the Tegra20 family of SoCs.
 	  It reads Memory Controller counters and adjusts the operating
diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
index fd801534771d..0a36b085d32a 100644
--- a/drivers/devfreq/tegra20-devfreq.c
+++ b/drivers/devfreq/tegra20-devfreq.c
@@ -7,180 +7,148 @@
 
 #include <linux/clk.h>
 #include <linux/devfreq.h>
-#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mfd/syscon.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pm_opp.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 
-#include <soc/tegra/mc.h>
-
 #include "governor.h"
 
-#define MC_STAT_CONTROL				0x90
-#define MC_STAT_EMC_CLOCK_LIMIT			0xa0
-#define MC_STAT_EMC_CLOCKS			0xa4
-#define MC_STAT_EMC_CONTROL			0xa8
-#define MC_STAT_EMC_COUNT			0xb8
+#define EMC_STAT_CONTROL			0x160
+#define EMC_STAT_LLMC_CONTROL			0x178
+#define EMC_STAT_PWR_CLOCK_LIMIT		0x198
+#define EMC_STAT_PWR_CLOCKS			0x19c
+#define EMC_STAT_PWR_COUNT			0x1a0
 
-#define EMC_GATHER_CLEAR			(1 << 8)
-#define EMC_GATHER_ENABLE			(3 << 8)
+#define EMC_PWR_GATHER_CLEAR			(1 << 8)
+#define EMC_PWR_GATHER_DISABLE			(2 << 8)
+#define EMC_PWR_GATHER_ENABLE			(3 << 8)
 
 struct tegra_devfreq {
+	struct devfreq_simple_ondemand_data ondemand_data;
+	struct opp_table *opp_table;
 	struct devfreq *devfreq;
 	struct clk *emc_clock;
-	void __iomem *regs;
+	struct regmap *rmap;
 };
 
 static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
 				u32 flags)
 {
-	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
-	struct devfreq *devfreq = tegra->devfreq;
 	struct dev_pm_opp *opp;
-	unsigned long rate;
-	int err;
+	int ret;
 
 	opp = devfreq_recommended_opp(dev, freq, flags);
-	if (IS_ERR(opp))
+	if (IS_ERR(opp)) {
+		dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
 		return PTR_ERR(opp);
+	}
 
-	rate = dev_pm_opp_get_freq(opp);
+	ret = dev_pm_opp_set_bw(dev, opp);
 	dev_pm_opp_put(opp);
 
-	err = clk_set_min_rate(tegra->emc_clock, rate);
-	if (err)
-		return err;
-
-	err = clk_set_rate(tegra->emc_clock, 0);
-	if (err)
-		goto restore_min_rate;
-
-	return 0;
-
-restore_min_rate:
-	clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
-
-	return err;
+	return ret;
 }
 
 static int tegra_devfreq_get_dev_status(struct device *dev,
 					struct devfreq_dev_status *stat)
 {
 	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
+	u32 count, clocks;
 
-	/*
-	 * EMC_COUNT returns number of memory events, that number is lower
-	 * than the number of clocks. Conversion ratio of 1/8 results in a
-	 * bit higher bandwidth than actually needed, it is good enough for
-	 * the time being because drivers don't support requesting minimum
-	 * needed memory bandwidth yet.
-	 *
-	 * TODO: adjust the ratio value once relevant drivers will support
-	 * memory bandwidth management.
-	 */
-	stat->busy_time = readl_relaxed(tegra->regs + MC_STAT_EMC_COUNT);
-	stat->total_time = readl_relaxed(tegra->regs + MC_STAT_EMC_CLOCKS) / 8;
-	stat->current_frequency = clk_get_rate(tegra->emc_clock);
+	/* freeze counters */
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_DISABLE);
+
+	/* number of clocks when EMC request was accepted */
+	regmap_read(tegra->rmap, EMC_STAT_PWR_COUNT, &count);
+	/* total number of clocks while PWR_GATHER control was set to ENABLE */
+	regmap_read(tegra->rmap, EMC_STAT_PWR_CLOCKS, &clocks);
 
-	writel_relaxed(EMC_GATHER_CLEAR, tegra->regs + MC_STAT_CONTROL);
-	writel_relaxed(EMC_GATHER_ENABLE, tegra->regs + MC_STAT_CONTROL);
+	/* clear counters and restart */
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_CLEAR);
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_ENABLE);
+
+	stat->busy_time = count;
+	stat->total_time = clocks;
+	stat->current_frequency = clk_get_rate(tegra->emc_clock);
 
 	return 0;
 }
 
 static struct devfreq_dev_profile tegra_devfreq_profile = {
-	.polling_ms	= 500,
+	.polling_ms	= 30,
 	.target		= tegra_devfreq_target,
 	.get_dev_status	= tegra_devfreq_get_dev_status,
 };
 
-static struct tegra_mc *tegra_get_memory_controller(void)
-{
-	struct platform_device *pdev;
-	struct device_node *np;
-	struct tegra_mc *mc;
-
-	np = of_find_compatible_node(NULL, NULL, "nvidia,tegra20-mc-gart");
-	if (!np)
-		return ERR_PTR(-ENOENT);
-
-	pdev = of_find_device_by_node(np);
-	of_node_put(np);
-	if (!pdev)
-		return ERR_PTR(-ENODEV);
-
-	mc = platform_get_drvdata(pdev);
-	if (!mc)
-		return ERR_PTR(-EPROBE_DEFER);
-
-	return mc;
-}
-
 static int tegra_devfreq_probe(struct platform_device *pdev)
 {
+	struct device_node *emc_np = pdev->dev.parent->of_node;
 	struct tegra_devfreq *tegra;
-	struct tegra_mc *mc;
-	unsigned long max_rate;
-	unsigned long rate;
 	int err;
 
-	mc = tegra_get_memory_controller();
-	if (IS_ERR(mc)) {
-		err = PTR_ERR(mc);
-		dev_err(&pdev->dev, "failed to get memory controller: %d\n",
-			err);
-		return err;
-	}
-
 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
 	if (!tegra)
 		return -ENOMEM;
 
 	/* EMC is a system-critical clock that is always enabled */
-	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
+	tegra->emc_clock = devm_get_clk_from_child(&pdev->dev, emc_np, NULL);
 	if (IS_ERR(tegra->emc_clock))
 		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
 				     "failed to get emc clock\n");
 
-	tegra->regs = mc->regs;
-
-	max_rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
+	tegra->rmap = device_node_to_regmap(emc_np);
+	if (IS_ERR(tegra->rmap))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->rmap),
+				     "failed to get emc regmap\n");
 
-	for (rate = 0; rate <= max_rate; rate++) {
-		rate = clk_round_rate(tegra->emc_clock, rate);
+	tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
+	if (IS_ERR(tegra->opp_table))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
+				     "failed to prepare opp table\n");
 
-		err = dev_pm_opp_add(&pdev->dev, rate, 0);
-		if (err) {
-			dev_err(&pdev->dev, "failed to add opp: %d\n", err);
-			goto remove_opps;
-		}
+	err = dev_pm_opp_of_add_table(&pdev->dev);
+	if (err) {
+		dev_err(&pdev->dev, "failed to add opp table: %d\n", err);
+		goto put_table;
 	}
 
+	/*
+	 * PWR_COUNT is 1/2 of PWR_CLOCKS at max, and thus, the up-threshold
+	 * should be less than 50.  Secondly, multiple active memory clients
+	 * may cause over 20 of lost clock cycles due to stalls caused by
+	 * competing memory accesses.  This means that threshold should be
+	 * set to a less than 30 in order to have a properly working governor.
+	 */
+	tegra->ondemand_data.upthreshold = 20;
+
 	/*
 	 * Reset statistic gathers state, select global bandwidth for the
 	 * statistics collection mode and set clocks counter saturation
 	 * limit to maximum.
 	 */
-	writel_relaxed(0x00000000, tegra->regs + MC_STAT_CONTROL);
-	writel_relaxed(0x00000000, tegra->regs + MC_STAT_EMC_CONTROL);
-	writel_relaxed(0xffffffff, tegra->regs + MC_STAT_EMC_CLOCK_LIMIT);
+	regmap_write(tegra->rmap, EMC_STAT_CONTROL, 0x00000000);
+	regmap_write(tegra->rmap, EMC_STAT_LLMC_CONTROL, 0x00000000);
+	regmap_write(tegra->rmap, EMC_STAT_PWR_CLOCK_LIMIT, 0xffffffff);
 
 	platform_set_drvdata(pdev, tegra);
 
 	tegra->devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
-					    DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
+					    DEVFREQ_GOV_SIMPLE_ONDEMAND,
+					    &tegra->ondemand_data);
 	if (IS_ERR(tegra->devfreq)) {
 		err = PTR_ERR(tegra->devfreq);
-		goto remove_opps;
+		goto put_table;
 	}
 
 	return 0;
 
-remove_opps:
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
+put_table:
+	dev_pm_opp_put_opp_table(tegra->opp_table);
 
 	return err;
 }
@@ -190,21 +158,27 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
 	struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
 
 	devfreq_remove_device(tegra->devfreq);
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
+	dev_pm_opp_of_remove_table(&pdev->dev);
+	dev_pm_opp_put_opp_table(tegra->opp_table);
 
 	return 0;
 }
 
+static const struct of_device_id tegra_devfreq_of_match[] = {
+	{ .compatible = "nvidia,tegra20-emc-statistics" },
+	{ },
+};
+
 static struct platform_driver tegra_devfreq_driver = {
 	.probe		= tegra_devfreq_probe,
 	.remove		= tegra_devfreq_remove,
 	.driver		= {
 		.name	= "tegra20-devfreq",
+		.of_match_table = tegra_devfreq_of_match,
 	},
 };
 module_platform_driver(tegra_devfreq_driver);
 
-MODULE_ALIAS("platform:tegra20-devfreq");
 MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
 MODULE_DESCRIPTION("NVIDIA Tegra20 devfreq driver");
 MODULE_LICENSE("GPL v2");
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 50/52] PM / devfreq: tegra30: Silence deferred probe error
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Tegra EMC driver was turned into a regular kernel driver, meaning that it
could be compiled as a loadable kernel module now. Hence EMC clock isn't
guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
Let's silence the deferred probe error.

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra30-devfreq.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index f5e74c2ede85..3f732ab53573 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -801,10 +801,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	}
 
 	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
-	if (IS_ERR(tegra->emc_clock)) {
-		dev_err(&pdev->dev, "Failed to get emc clock\n");
-		return PTR_ERR(tegra->emc_clock);
-	}
+	if (IS_ERR(tegra->emc_clock))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
+				     "Failed to get emc clock\n");
 
 	err = platform_get_irq(pdev, 0);
 	if (err < 0)
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 50/52] PM / devfreq: tegra30: Silence deferred probe error
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Tegra EMC driver was turned into a regular kernel driver, meaning that it
could be compiled as a loadable kernel module now. Hence EMC clock isn't
guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
Let's silence the deferred probe error.

Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra30-devfreq.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index f5e74c2ede85..3f732ab53573 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -801,10 +801,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	}
 
 	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
-	if (IS_ERR(tegra->emc_clock)) {
-		dev_err(&pdev->dev, "Failed to get emc clock\n");
-		return PTR_ERR(tegra->emc_clock);
-	}
+	if (IS_ERR(tegra->emc_clock))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
+				     "Failed to get emc clock\n");
 
 	err = platform_get_irq(pdev, 0);
 	if (err < 0)
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

This patch moves ACTMON driver away from generating OPP table by itself,
transitioning it to use the table which comes from device-tree. This
change breaks compatibility with older device-trees in order to bring
support for the interconnect framework to the driver. This is a mandatory
change which needs to be done in order to implement interconnect-based
memory DVFS. Users of legacy device-trees will get a message telling that
theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
 1 file changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index 3f732ab53573..1b0b91a71886 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -19,6 +19,8 @@
 #include <linux/reset.h>
 #include <linux/workqueue.h>
 
+#include <soc/tegra/fuse.h>
+
 #include "governor.h"
 
 #define ACTMON_GLB_STATUS					0x0
@@ -155,6 +157,7 @@ struct tegra_devfreq_device {
 
 struct tegra_devfreq {
 	struct devfreq		*devfreq;
+	struct opp_table	*opp_table;
 
 	struct reset_control	*reset;
 	struct clk		*clock;
@@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
 static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
 				u32 flags)
 {
-	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
-	struct devfreq *devfreq = tegra->devfreq;
 	struct dev_pm_opp *opp;
-	unsigned long rate;
-	int err;
+	int ret;
 
 	opp = devfreq_recommended_opp(dev, freq, flags);
 	if (IS_ERR(opp)) {
-		dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
+		dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
 		return PTR_ERR(opp);
 	}
-	rate = dev_pm_opp_get_freq(opp);
-	dev_pm_opp_put(opp);
-
-	err = clk_set_min_rate(tegra->emc_clock, rate * KHZ);
-	if (err)
-		return err;
-
-	err = clk_set_rate(tegra->emc_clock, 0);
-	if (err)
-		goto restore_min_rate;
 
-	return 0;
-
-restore_min_rate:
-	clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
+	ret = dev_pm_opp_set_bw(dev, opp);
+	dev_pm_opp_put(opp);
 
-	return err;
+	return ret;
 }
 
 static int tegra_devfreq_get_dev_status(struct device *dev,
@@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
 	stat->private_data = tegra;
 
 	/* The below are to be used by the other governors */
-	stat->current_frequency = cur_freq;
+	stat->current_frequency = cur_freq * KHZ;
 
 	actmon_dev = &tegra->devices[MCALL];
 
@@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
 		target_freq = max(target_freq, dev->target_freq);
 	}
 
-	*freq = target_freq;
+	*freq = target_freq * KHZ;
 
 	return 0;
 }
@@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
 
 static int tegra_devfreq_probe(struct platform_device *pdev)
 {
+	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
 	struct tegra_devfreq_device *dev;
 	struct tegra_devfreq *tegra;
+	struct opp_table *opp_table;
 	struct devfreq *devfreq;
 	unsigned int i;
 	long rate;
 	int err;
 
+	/* legacy device-trees don't have OPP table and must be updated */
+	if (!device_property_present(&pdev->dev, "operating-points-v2")) {
+		dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
+		dev_err(&pdev->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
 	if (!tegra)
 		return -ENOMEM;
@@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
+	if (IS_ERR(tegra->opp_table))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
+				     "Failed to prepare OPP table\n");
+
+	opp_table = dev_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
+	err = PTR_ERR_OR_ZERO(opp_table);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
+		goto put_table;
+	}
+
+	err = dev_pm_opp_of_add_table(&pdev->dev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
+		goto put_hw;
+	}
+
 	err = clk_prepare_enable(tegra->clock);
 	if (err) {
 		dev_err(&pdev->dev,
 			"Failed to prepare and enable ACTMON clock\n");
-		return err;
+		goto remove_table;
 	}
 
 	err = reset_control_reset(tegra->reset);
@@ -849,23 +864,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 		dev->regs = tegra->regs + dev->config->offset;
 	}
 
-	for (rate = 0; rate <= tegra->max_freq * KHZ; rate++) {
-		rate = clk_round_rate(tegra->emc_clock, rate);
-
-		if (rate < 0) {
-			dev_err(&pdev->dev,
-				"Failed to round clock rate: %ld\n", rate);
-			err = rate;
-			goto remove_opps;
-		}
-
-		err = dev_pm_opp_add(&pdev->dev, rate / KHZ, 0);
-		if (err) {
-			dev_err(&pdev->dev, "Failed to add OPP: %d\n", err);
-			goto remove_opps;
-		}
-	}
-
 	platform_set_drvdata(pdev, tegra);
 
 	tegra->clk_rate_change_nb.notifier_call = tegra_actmon_clk_notify_cb;
@@ -881,7 +879,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	}
 
 	tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
-	tegra_devfreq_profile.initial_freq /= KHZ;
 
 	devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
 				     "tegra_actmon", NULL);
@@ -901,6 +898,12 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	reset_control_reset(tegra->reset);
 disable_clk:
 	clk_disable_unprepare(tegra->clock);
+remove_table:
+	dev_pm_opp_of_remove_table(&pdev->dev);
+put_hw:
+	dev_pm_opp_put_supported_hw(tegra->opp_table);
+put_table:
+	dev_pm_opp_put_opp_table(tegra->opp_table);
 
 	return err;
 }
@@ -912,11 +915,13 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
 	devfreq_remove_device(tegra->devfreq);
 	devfreq_remove_governor(&tegra_devfreq_governor);
 
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
-
 	reset_control_reset(tegra->reset);
 	clk_disable_unprepare(tegra->clock);
 
+	dev_pm_opp_of_remove_table(&pdev->dev);
+	dev_pm_opp_put_supported_hw(tegra->opp_table);
+	dev_pm_opp_put_opp_table(tegra->opp_table);
+
 	return 0;
 }
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

This patch moves ACTMON driver away from generating OPP table by itself,
transitioning it to use the table which comes from device-tree. This
change breaks compatibility with older device-trees in order to bring
support for the interconnect framework to the driver. This is a mandatory
change which needs to be done in order to implement interconnect-based
memory DVFS. Users of legacy device-trees will get a message telling that
theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
 1 file changed, 48 insertions(+), 43 deletions(-)

diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index 3f732ab53573..1b0b91a71886 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -19,6 +19,8 @@
 #include <linux/reset.h>
 #include <linux/workqueue.h>
 
+#include <soc/tegra/fuse.h>
+
 #include "governor.h"
 
 #define ACTMON_GLB_STATUS					0x0
@@ -155,6 +157,7 @@ struct tegra_devfreq_device {
 
 struct tegra_devfreq {
 	struct devfreq		*devfreq;
+	struct opp_table	*opp_table;
 
 	struct reset_control	*reset;
 	struct clk		*clock;
@@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
 static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
 				u32 flags)
 {
-	struct tegra_devfreq *tegra = dev_get_drvdata(dev);
-	struct devfreq *devfreq = tegra->devfreq;
 	struct dev_pm_opp *opp;
-	unsigned long rate;
-	int err;
+	int ret;
 
 	opp = devfreq_recommended_opp(dev, freq, flags);
 	if (IS_ERR(opp)) {
-		dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
+		dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
 		return PTR_ERR(opp);
 	}
-	rate = dev_pm_opp_get_freq(opp);
-	dev_pm_opp_put(opp);
-
-	err = clk_set_min_rate(tegra->emc_clock, rate * KHZ);
-	if (err)
-		return err;
-
-	err = clk_set_rate(tegra->emc_clock, 0);
-	if (err)
-		goto restore_min_rate;
 
-	return 0;
-
-restore_min_rate:
-	clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
+	ret = dev_pm_opp_set_bw(dev, opp);
+	dev_pm_opp_put(opp);
 
-	return err;
+	return ret;
 }
 
 static int tegra_devfreq_get_dev_status(struct device *dev,
@@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
 	stat->private_data = tegra;
 
 	/* The below are to be used by the other governors */
-	stat->current_frequency = cur_freq;
+	stat->current_frequency = cur_freq * KHZ;
 
 	actmon_dev = &tegra->devices[MCALL];
 
@@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
 		target_freq = max(target_freq, dev->target_freq);
 	}
 
-	*freq = target_freq;
+	*freq = target_freq * KHZ;
 
 	return 0;
 }
@@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
 
 static int tegra_devfreq_probe(struct platform_device *pdev)
 {
+	u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
 	struct tegra_devfreq_device *dev;
 	struct tegra_devfreq *tegra;
+	struct opp_table *opp_table;
 	struct devfreq *devfreq;
 	unsigned int i;
 	long rate;
 	int err;
 
+	/* legacy device-trees don't have OPP table and must be updated */
+	if (!device_property_present(&pdev->dev, "operating-points-v2")) {
+		dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
+		dev_err(&pdev->dev, "please update your device tree\n");
+		return -ENODEV;
+	}
+
 	tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
 	if (!tegra)
 		return -ENOMEM;
@@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
+	if (IS_ERR(tegra->opp_table))
+		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
+				     "Failed to prepare OPP table\n");
+
+	opp_table = dev_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
+	err = PTR_ERR_OR_ZERO(opp_table);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
+		goto put_table;
+	}
+
+	err = dev_pm_opp_of_add_table(&pdev->dev);
+	if (err) {
+		dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
+		goto put_hw;
+	}
+
 	err = clk_prepare_enable(tegra->clock);
 	if (err) {
 		dev_err(&pdev->dev,
 			"Failed to prepare and enable ACTMON clock\n");
-		return err;
+		goto remove_table;
 	}
 
 	err = reset_control_reset(tegra->reset);
@@ -849,23 +864,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 		dev->regs = tegra->regs + dev->config->offset;
 	}
 
-	for (rate = 0; rate <= tegra->max_freq * KHZ; rate++) {
-		rate = clk_round_rate(tegra->emc_clock, rate);
-
-		if (rate < 0) {
-			dev_err(&pdev->dev,
-				"Failed to round clock rate: %ld\n", rate);
-			err = rate;
-			goto remove_opps;
-		}
-
-		err = dev_pm_opp_add(&pdev->dev, rate / KHZ, 0);
-		if (err) {
-			dev_err(&pdev->dev, "Failed to add OPP: %d\n", err);
-			goto remove_opps;
-		}
-	}
-
 	platform_set_drvdata(pdev, tegra);
 
 	tegra->clk_rate_change_nb.notifier_call = tegra_actmon_clk_notify_cb;
@@ -881,7 +879,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	}
 
 	tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
-	tegra_devfreq_profile.initial_freq /= KHZ;
 
 	devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
 				     "tegra_actmon", NULL);
@@ -901,6 +898,12 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	reset_control_reset(tegra->reset);
 disable_clk:
 	clk_disable_unprepare(tegra->clock);
+remove_table:
+	dev_pm_opp_of_remove_table(&pdev->dev);
+put_hw:
+	dev_pm_opp_put_supported_hw(tegra->opp_table);
+put_table:
+	dev_pm_opp_put_opp_table(tegra->opp_table);
 
 	return err;
 }
@@ -912,11 +915,13 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
 	devfreq_remove_device(tegra->devfreq);
 	devfreq_remove_governor(&tegra_devfreq_governor);
 
-	dev_pm_opp_remove_all_dynamic(&pdev->dev);
-
 	reset_control_reset(tegra->reset);
 	clk_disable_unprepare(tegra->clock);
 
+	dev_pm_opp_of_remove_table(&pdev->dev);
+	dev_pm_opp_put_supported_hw(tegra->opp_table);
+	dev_pm_opp_put_opp_table(tegra->opp_table);
+
 	return 0;
 }
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 52/52] PM / devfreq: tegra30: Separate configurations per-SoC generation
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-25 22:17   ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

Previously we were using count-weight of the T124 for T30 in order to
get EMC clock rate that was reasonable for T30. In fact the count-weight
should be x2 times smaller on T30, but then devfreq was producing a bit
too low EMC clock rate for ISO memory clients, like display controller
for example.

Now both Tegra ACTMON and Tegra DRM display drivers support interconnect
framework and display driver tells to ICC what a minimum memory bandwidth
is needed, preventing FIFO underflows. Thus, now we can use a proper
count-weight value for Tegra30 and MC_ALL device config needs a bit more
aggressive boosting.

This patch adds a separate ACTMON driver configuration that is specific
to Tegra30.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra30-devfreq.c | 68 ++++++++++++++++++++++++-------
 1 file changed, 54 insertions(+), 14 deletions(-)

diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index 1b0b91a71886..95aba89eae88 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -57,13 +57,6 @@
 #define ACTMON_BELOW_WMARK_WINDOW				3
 #define ACTMON_BOOST_FREQ_STEP					16000
 
-/*
- * Activity counter is incremented every 256 memory transactions, and each
- * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is
- * 4 * 256 = 1024.
- */
-#define ACTMON_COUNT_WEIGHT					0x400
-
 /*
  * ACTMON_AVERAGE_WINDOW_LOG2: default value for @DEV_CTRL_K_VAL, which
  * translates to 2 ^ (K_VAL + 1). ex: 2 ^ (6 + 1) = 128
@@ -111,7 +104,7 @@ enum tegra_actmon_device {
 	MCCPU,
 };
 
-static const struct tegra_devfreq_device_config actmon_device_configs[] = {
+static const struct tegra_devfreq_device_config tegra124_device_configs[] = {
 	{
 		/* MCALL: All memory accesses (including from the CPUs) */
 		.offset = 0x1c0,
@@ -133,6 +126,28 @@ static const struct tegra_devfreq_device_config actmon_device_configs[] = {
 	},
 };
 
+static const struct tegra_devfreq_device_config tegra30_device_configs[] = {
+	{
+		/* MCALL: All memory accesses (including from the CPUs) */
+		.offset = 0x1c0,
+		.irq_mask = 1 << 26,
+		.boost_up_coeff = 200,
+		.boost_down_coeff = 50,
+		.boost_up_threshold = 20,
+		.boost_down_threshold = 10,
+	},
+	{
+		/* MCCPU: memory accesses from the CPUs */
+		.offset = 0x200,
+		.irq_mask = 1 << 25,
+		.boost_up_coeff = 800,
+		.boost_down_coeff = 40,
+		.boost_up_threshold = 27,
+		.boost_down_threshold = 10,
+		.avg_dependency_threshold = 16000, /* 16MHz in kHz units */
+	},
+};
+
 /**
  * struct tegra_devfreq_device - state specific to an ACTMON device
  *
@@ -155,6 +170,12 @@ struct tegra_devfreq_device {
 	unsigned long target_freq;
 };
 
+struct tegra_devfreq_soc_data {
+	const struct tegra_devfreq_device_config *configs;
+	/* Weight value for count measurements */
+	unsigned int count_weight;
+};
+
 struct tegra_devfreq {
 	struct devfreq		*devfreq;
 	struct opp_table	*opp_table;
@@ -171,11 +192,13 @@ struct tegra_devfreq {
 	struct delayed_work	cpufreq_update_work;
 	struct notifier_block	cpu_rate_change_nb;
 
-	struct tegra_devfreq_device devices[ARRAY_SIZE(actmon_device_configs)];
+	struct tegra_devfreq_device devices[ARRAY_SIZE(tegra124_device_configs)];
 
 	unsigned int		irq;
 
 	bool			started;
+
+	const struct tegra_devfreq_soc_data *soc;
 };
 
 struct tegra_actmon_emc_ratio {
@@ -488,7 +511,7 @@ static void tegra_actmon_configure_device(struct tegra_devfreq *tegra,
 	tegra_devfreq_update_avg_wmark(tegra, dev);
 	tegra_devfreq_update_wmark(tegra, dev);
 
-	device_writel(dev, ACTMON_COUNT_WEIGHT, ACTMON_DEV_COUNT_WEIGHT);
+	device_writel(dev, tegra->soc->count_weight, ACTMON_DEV_COUNT_WEIGHT);
 	device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS);
 
 	val |= ACTMON_DEV_CTRL_ENB_PERIODIC;
@@ -781,6 +804,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	if (!tegra)
 		return -ENOMEM;
 
+	tegra->soc = of_device_get_match_data(&pdev->dev);
+
 	tegra->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(tegra->regs))
 		return PTR_ERR(tegra->regs);
@@ -858,9 +883,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 
 	tegra->max_freq = rate / KHZ;
 
-	for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) {
+	for (i = 0; i < ARRAY_SIZE(tegra124_device_configs); i++) {
 		dev = tegra->devices + i;
-		dev->config = actmon_device_configs + i;
+		dev->config = tegra->soc->configs + i;
 		dev->regs = tegra->regs + dev->config->offset;
 	}
 
@@ -925,9 +950,24 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct tegra_devfreq_soc_data tegra124_soc = {
+	.configs = tegra124_device_configs,
+
+	/*
+	 * Activity counter is incremented every 256 memory transactions,
+	 * and each transaction takes 4 EMC clocks.
+	 */
+	.count_weight = 4 * 256,
+};
+
+static const struct tegra_devfreq_soc_data tegra30_soc = {
+	.configs = tegra30_device_configs,
+	.count_weight = 2 * 256,
+};
+
 static const struct of_device_id tegra_devfreq_of_match[] = {
-	{ .compatible = "nvidia,tegra30-actmon" },
-	{ .compatible = "nvidia,tegra124-actmon" },
+	{ .compatible = "nvidia,tegra30-actmon",  .data = &tegra30_soc, },
+	{ .compatible = "nvidia,tegra124-actmon", .data = &tegra124_soc, },
 	{ },
 };
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 290+ messages in thread

* [PATCH v6 52/52] PM / devfreq: tegra30: Separate configurations per-SoC generation
@ 2020-10-25 22:17   ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-25 22:17 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

Previously we were using count-weight of the T124 for T30 in order to
get EMC clock rate that was reasonable for T30. In fact the count-weight
should be x2 times smaller on T30, but then devfreq was producing a bit
too low EMC clock rate for ISO memory clients, like display controller
for example.

Now both Tegra ACTMON and Tegra DRM display drivers support interconnect
framework and display driver tells to ICC what a minimum memory bandwidth
is needed, preventing FIFO underflows. Thus, now we can use a proper
count-weight value for Tegra30 and MC_ALL device config needs a bit more
aggressive boosting.

This patch adds a separate ACTMON driver configuration that is specific
to Tegra30.

Tested-by: Peter Geis <pgwipeout@gmail.com>
Tested-by: Nicolas Chauvet <kwizart@gmail.com>
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
 drivers/devfreq/tegra30-devfreq.c | 68 ++++++++++++++++++++++++-------
 1 file changed, 54 insertions(+), 14 deletions(-)

diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
index 1b0b91a71886..95aba89eae88 100644
--- a/drivers/devfreq/tegra30-devfreq.c
+++ b/drivers/devfreq/tegra30-devfreq.c
@@ -57,13 +57,6 @@
 #define ACTMON_BELOW_WMARK_WINDOW				3
 #define ACTMON_BOOST_FREQ_STEP					16000
 
-/*
- * Activity counter is incremented every 256 memory transactions, and each
- * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is
- * 4 * 256 = 1024.
- */
-#define ACTMON_COUNT_WEIGHT					0x400
-
 /*
  * ACTMON_AVERAGE_WINDOW_LOG2: default value for @DEV_CTRL_K_VAL, which
  * translates to 2 ^ (K_VAL + 1). ex: 2 ^ (6 + 1) = 128
@@ -111,7 +104,7 @@ enum tegra_actmon_device {
 	MCCPU,
 };
 
-static const struct tegra_devfreq_device_config actmon_device_configs[] = {
+static const struct tegra_devfreq_device_config tegra124_device_configs[] = {
 	{
 		/* MCALL: All memory accesses (including from the CPUs) */
 		.offset = 0x1c0,
@@ -133,6 +126,28 @@ static const struct tegra_devfreq_device_config actmon_device_configs[] = {
 	},
 };
 
+static const struct tegra_devfreq_device_config tegra30_device_configs[] = {
+	{
+		/* MCALL: All memory accesses (including from the CPUs) */
+		.offset = 0x1c0,
+		.irq_mask = 1 << 26,
+		.boost_up_coeff = 200,
+		.boost_down_coeff = 50,
+		.boost_up_threshold = 20,
+		.boost_down_threshold = 10,
+	},
+	{
+		/* MCCPU: memory accesses from the CPUs */
+		.offset = 0x200,
+		.irq_mask = 1 << 25,
+		.boost_up_coeff = 800,
+		.boost_down_coeff = 40,
+		.boost_up_threshold = 27,
+		.boost_down_threshold = 10,
+		.avg_dependency_threshold = 16000, /* 16MHz in kHz units */
+	},
+};
+
 /**
  * struct tegra_devfreq_device - state specific to an ACTMON device
  *
@@ -155,6 +170,12 @@ struct tegra_devfreq_device {
 	unsigned long target_freq;
 };
 
+struct tegra_devfreq_soc_data {
+	const struct tegra_devfreq_device_config *configs;
+	/* Weight value for count measurements */
+	unsigned int count_weight;
+};
+
 struct tegra_devfreq {
 	struct devfreq		*devfreq;
 	struct opp_table	*opp_table;
@@ -171,11 +192,13 @@ struct tegra_devfreq {
 	struct delayed_work	cpufreq_update_work;
 	struct notifier_block	cpu_rate_change_nb;
 
-	struct tegra_devfreq_device devices[ARRAY_SIZE(actmon_device_configs)];
+	struct tegra_devfreq_device devices[ARRAY_SIZE(tegra124_device_configs)];
 
 	unsigned int		irq;
 
 	bool			started;
+
+	const struct tegra_devfreq_soc_data *soc;
 };
 
 struct tegra_actmon_emc_ratio {
@@ -488,7 +511,7 @@ static void tegra_actmon_configure_device(struct tegra_devfreq *tegra,
 	tegra_devfreq_update_avg_wmark(tegra, dev);
 	tegra_devfreq_update_wmark(tegra, dev);
 
-	device_writel(dev, ACTMON_COUNT_WEIGHT, ACTMON_DEV_COUNT_WEIGHT);
+	device_writel(dev, tegra->soc->count_weight, ACTMON_DEV_COUNT_WEIGHT);
 	device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS);
 
 	val |= ACTMON_DEV_CTRL_ENB_PERIODIC;
@@ -781,6 +804,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 	if (!tegra)
 		return -ENOMEM;
 
+	tegra->soc = of_device_get_match_data(&pdev->dev);
+
 	tegra->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(tegra->regs))
 		return PTR_ERR(tegra->regs);
@@ -858,9 +883,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
 
 	tegra->max_freq = rate / KHZ;
 
-	for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) {
+	for (i = 0; i < ARRAY_SIZE(tegra124_device_configs); i++) {
 		dev = tegra->devices + i;
-		dev->config = actmon_device_configs + i;
+		dev->config = tegra->soc->configs + i;
 		dev->regs = tegra->regs + dev->config->offset;
 	}
 
@@ -925,9 +950,24 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct tegra_devfreq_soc_data tegra124_soc = {
+	.configs = tegra124_device_configs,
+
+	/*
+	 * Activity counter is incremented every 256 memory transactions,
+	 * and each transaction takes 4 EMC clocks.
+	 */
+	.count_weight = 4 * 256,
+};
+
+static const struct tegra_devfreq_soc_data tegra30_soc = {
+	.configs = tegra30_device_configs,
+	.count_weight = 2 * 256,
+};
+
 static const struct of_device_id tegra_devfreq_of_match[] = {
-	{ .compatible = "nvidia,tegra30-actmon" },
-	{ .compatible = "nvidia,tegra124-actmon" },
+	{ .compatible = "nvidia,tegra30-actmon",  .data = &tegra30_soc, },
+	{ .compatible = "nvidia,tegra124-actmon", .data = &tegra124_soc, },
 	{ },
 };
 
-- 
2.27.0

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 44/52] drm/tegra: dc: Support memory bandwidth management
  2020-10-25 22:17   ` Dmitry Osipenko
  (?)
@ 2020-10-26  1:50   ` kernel test robot
  -1 siblings, 0 replies; 290+ messages in thread
From: kernel test robot @ 2020-10-26  1:50 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 5120 bytes --]

Hi Dmitry,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.10-rc1 next-20201023]
[cannot apply to tegra/for-next robh/for-next tegra-drm/drm/tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3650b228f83adda7e5ee532e2b90429c03f7b9ec
config: arm-defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/7ceea541a585d7d6be0fa35c90a735f69820005f
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
        git checkout 7ceea541a585d7d6be0fa35c90a735f69820005f
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All warnings (new ones prefixed by >>):

   drivers/gpu/drm/tegra/plane.c: In function 'tegra_plane_check_memory_bandwidth':
>> drivers/gpu/drm/tegra/plane.c:221:41: warning: variable 'dst_h' set but not used [-Wunused-but-set-variable]
     221 |  unsigned int i, bpp, bpp_plane, dst_w, dst_h, src_w, src_h, mul;
         |                                         ^~~~~

vim +/dst_h +221 drivers/gpu/drm/tegra/plane.c

   217	
   218	static int tegra_plane_check_memory_bandwidth(struct drm_plane_state *state)
   219	{
   220		struct tegra_plane_state *tegra_state = to_tegra_plane_state(state);
 > 221		unsigned int i, bpp, bpp_plane, dst_w, dst_h, src_w, src_h, mul;
   222		u32 avg_bandwidth = 0, peak_bandwidth;
   223		const struct tegra_dc_soc_info *soc;
   224		const struct drm_format_info *fmt;
   225		struct drm_crtc_state *crtc_state;
   226	
   227		if (!state->visible)
   228			return 0;
   229	
   230		crtc_state = drm_atomic_get_new_crtc_state(state->state, state->crtc);
   231		if (!crtc_state)
   232			return -EINVAL;
   233	
   234		src_w = drm_rect_width(&state->src) >> 16;
   235		src_h = drm_rect_height(&state->src) >> 16;
   236		dst_w = drm_rect_width(&state->dst);
   237		dst_h = drm_rect_height(&state->dst);
   238	
   239		fmt = state->fb->format;
   240		soc = to_tegra_dc(state->crtc)->soc;
   241	
   242		/*
   243		 * Note that real memory bandwidth vary depending on format and
   244		 * memory layout, we are not taking that into account because small
   245		 * estimation error isn't important since bandwidth is rounded up
   246		 * anyway.
   247		 */
   248		for (i = 0, bpp = 0; i < fmt->num_planes; i++) {
   249			bpp_plane = fmt->cpp[i] * 8;
   250	
   251			/*
   252			 * Sub-sampling is relevant for chroma planes only and vertical
   253			 * readouts are not cached, hence only horizontal sub-sampling
   254			 * matters.
   255			 */
   256			if (i > 0)
   257				bpp_plane /= fmt->hsub;
   258	
   259			bpp += bpp_plane;
   260		}
   261	
   262		/*
   263		 * Horizontal downscale takes extra bandwidth which roughly depends
   264		 * on the scaled width.
   265		 */
   266		if (src_w > dst_w)
   267			mul = (src_w - dst_w) * bpp / 2048 + 1;
   268		else
   269			mul = 1;
   270	
   271		/* average bandwidth in bytes/s */
   272		avg_bandwidth  = src_w * src_h * bpp / 8 * mul;
   273		avg_bandwidth *= drm_mode_vrefresh(&crtc_state->mode);
   274	
   275		/* mode.clock in kHz, peak bandwidth in kbit/s */
   276		peak_bandwidth = crtc_state->mode.clock * bpp * mul;
   277	
   278		/* ICC bandwidth in kbyte/s */
   279		peak_bandwidth = kbps_to_icc(peak_bandwidth);
   280		avg_bandwidth  = Bps_to_icc(avg_bandwidth);
   281	
   282		/*
   283		 * Tegra30/114 Memory Controller can't interleave DC memory requests
   284		 * and DC uses 16-bytes atom for the tiled windows, while DDR3 uses 32
   285		 * bytes atom. Hence there is x2 memory overfetch for tiled framebuffer
   286		 * and DDR3 on older SoCs.
   287		 */
   288		if (soc->plane_tiled_memory_bandwidth_x2 &&
   289		    tegra_state->tiling.mode == TEGRA_BO_TILING_MODE_TILED) {
   290			peak_bandwidth *= 2;
   291			avg_bandwidth *= 2;
   292		}
   293	
   294		tegra_state->peak_memory_bandwidth = peak_bandwidth;
   295		tegra_state->avg_memory_bandwidth = avg_bandwidth;
   296	
   297		return 0;
   298	}
   299	

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 53723 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
  (?)
@ 2020-10-26  2:50   ` kernel test robot
  -1 siblings, 0 replies; 290+ messages in thread
From: kernel test robot @ 2020-10-26  2:50 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 11658 bytes --]

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.10-rc1 next-20201026]
[cannot apply to tegra/for-next robh/for-next tegra-drm/drm/tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3650b228f83adda7e5ee532e2b90429c03f7b9ec
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/15b275421ab8d79907837dabd50b1372c4731f9a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
        git checkout 15b275421ab8d79907837dabd50b1372c4731f9a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   `.exit.text' referenced in section `__jump_table' of fs/cifs/cifsfs.o: defined in discarded section `.exit.text' of fs/cifs/cifsfs.o
   `.exit.text' referenced in section `__jump_table' of fs/cifs/cifsfs.o: defined in discarded section `.exit.text' of fs/cifs/cifsfs.o
   `.exit.text' referenced in section `__jump_table' of fs/fuse/inode.o: defined in discarded section `.exit.text' of fs/fuse/inode.o
   `.exit.text' referenced in section `__jump_table' of fs/fuse/inode.o: defined in discarded section `.exit.text' of fs/fuse/inode.o
   `.exit.text' referenced in section `__jump_table' of fs/ceph/super.o: defined in discarded section `.exit.text' of fs/ceph/super.o
   `.exit.text' referenced in section `__jump_table' of fs/ceph/super.o: defined in discarded section `.exit.text' of fs/ceph/super.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/rio_cm.o: defined in discarded section `.exit.text' of drivers/rapidio/rio_cm.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/rio_cm.o: defined in discarded section `.exit.text' of drivers/rapidio/rio_cm.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen2.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen2.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/rapidio/switches/idt_gen3.o: defined in discarded section `.exit.text' of drivers/rapidio/switches/idt_gen3.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/vt8623fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/vt8623fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/vt8623fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/vt8623fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/s3fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/s3fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/s3fb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/s3fb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/arkfb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/arkfb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/arkfb.o: defined in discarded section `.exit.text' of drivers/video/fbdev/arkfb.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.o: defined in discarded section `.exit.text' of drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.o
   `.exit.text' referenced in section `__jump_table' of drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.o: defined in discarded section `.exit.text' of drivers/video/fbdev/omap2/omapfb/displays/panel-dsi-cm.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/phantom.o: defined in discarded section `.exit.text' of drivers/misc/phantom.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/phantom.o: defined in discarded section `.exit.text' of drivers/misc/phantom.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/habanalabs/common/habanalabs_drv.o: defined in discarded section `.exit.text' of drivers/misc/habanalabs/common/habanalabs_drv.o
   `.exit.text' referenced in section `__jump_table' of drivers/misc/habanalabs/common/habanalabs_drv.o: defined in discarded section `.exit.text' of drivers/misc/habanalabs/common/habanalabs_drv.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/fcoe/fcoe.o: defined in discarded section `.exit.text' of drivers/scsi/fcoe/fcoe.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/fcoe/fcoe.o: defined in discarded section `.exit.text' of drivers/scsi/fcoe/fcoe.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/cxgbi/libcxgbi.o: defined in discarded section `.exit.text' of drivers/scsi/cxgbi/libcxgbi.o
   `.exit.text' referenced in section `__jump_table' of drivers/scsi/cxgbi/libcxgbi.o: defined in discarded section `.exit.text' of drivers/scsi/cxgbi/libcxgbi.o
   `.exit.text' referenced in section `__jump_table' of drivers/target/target_core_configfs.o: defined in discarded section `.exit.text' of drivers/target/target_core_configfs.o
   `.exit.text' referenced in section `__jump_table' of drivers/target/target_core_configfs.o: defined in discarded section `.exit.text' of drivers/target/target_core_configfs.o
   `.exit.text' referenced in section `__jump_table' of drivers/mtd/maps/pcmciamtd.o: defined in discarded section `.exit.text' of drivers/mtd/maps/pcmciamtd.o
   `.exit.text' referenced in section `__jump_table' of drivers/mtd/maps/pcmciamtd.o: defined in discarded section `.exit.text' of drivers/mtd/maps/pcmciamtd.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o: defined in discarded section `.exit.text' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o: defined in discarded section `.exit.text' of drivers/net/wireless/zydas/zd1211rw/zd_usb.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/ray_cs.o: defined in discarded section `.exit.text' of drivers/net/wireless/ray_cs.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/ray_cs.o: defined in discarded section `.exit.text' of drivers/net/wireless/ray_cs.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/mac80211_hwsim.o: defined in discarded section `.exit.text' of drivers/net/wireless/mac80211_hwsim.o
   `.exit.text' referenced in section `__jump_table' of drivers/net/wireless/mac80211_hwsim.o: defined in discarded section `.exit.text' of drivers/net/wireless/mac80211_hwsim.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/inode.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/inode.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/inode.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/inode.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/g_ffs.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/g_ffs.o
   `.exit.text' referenced in section `__jump_table' of drivers/usb/gadget/legacy/g_ffs.o: defined in discarded section `.exit.text' of drivers/usb/gadget/legacy/g_ffs.o
   `.exit.text' referenced in section `__jump_table' of drivers/media/common/siano/smscoreapi.o: defined in discarded section `.exit.text' of drivers/media/common/siano/smscoreapi.o
   `.exit.text' referenced in section `__jump_table' of drivers/media/common/siano/smscoreapi.o: defined in discarded section `.exit.text' of drivers/media/common/siano/smscoreapi.o
   xtensa-linux-ld: drivers/devfreq/tegra30-devfreq.o: in function `tegra_actmon_delayed_update':
   tegra30-devfreq.c:(.text+0x2e4): undefined reference to `tegra_sku_info'
>> xtensa-linux-ld: tegra30-devfreq.c:(.text+0x2e0): undefined reference to `tegra_sku_info'
   `.exit.text' referenced in section `__jump_table' of drivers/vme/bridges/vme_fake.o: defined in discarded section `.exit.text' of drivers/vme/bridges/vme_fake.o
   `.exit.text' referenced in section `__jump_table' of drivers/vme/bridges/vme_fake.o: defined in discarded section `.exit.text' of drivers/vme/bridges/vme_fake.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/nf_conntrack_h323_main.o: defined in discarded section `.exit.text' of net/netfilter/nf_conntrack_h323_main.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/nf_conntrack_h323_main.o: defined in discarded section `.exit.text' of net/netfilter/nf_conntrack_h323_main.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/ipset/ip_set_core.o: defined in discarded section `.exit.text' of net/netfilter/ipset/ip_set_core.o
   `.exit.text' referenced in section `__jump_table' of net/netfilter/ipset/ip_set_core.o: defined in discarded section `.exit.text' of net/netfilter/ipset/ip_set_core.o
   `.exit.text' referenced in section `__jump_table' of net/bluetooth/6lowpan.o: defined in discarded section `.exit.text' of net/bluetooth/6lowpan.o
   `.exit.text' referenced in section `__jump_table' of net/bluetooth/6lowpan.o: defined in discarded section `.exit.text' of net/bluetooth/6lowpan.o
   `.exit.text' referenced in section `__jump_table' of net/ceph/ceph_common.o: defined in discarded section `.exit.text' of net/ceph/ceph_common.o
   `.exit.text' referenced in section `__jump_table' of net/ceph/ceph_common.o: defined in discarded section `.exit.text' of net/ceph/ceph_common.o

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 66174 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 47/52] PM / devfreq: tegra20: Silence deferred probe error
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-26  3:16     ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-10-26  3:16 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

On 10/26/20 7:17 AM, Dmitry Osipenko wrote:
> Tegra EMC driver was turned into a regular kernel driver, meaning that it
> could be compiled as a loadable kernel module now. Hence EMC clock isn't
> guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
> Let's silence the deferred probe error.
> 
> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra20-devfreq.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
> index ff82bac9ee4e..fd801534771d 100644
> --- a/drivers/devfreq/tegra20-devfreq.c
> +++ b/drivers/devfreq/tegra20-devfreq.c
> @@ -141,11 +141,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>  
>  	/* EMC is a system-critical clock that is always enabled */
>  	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
> -	if (IS_ERR(tegra->emc_clock)) {
> -		err = PTR_ERR(tegra->emc_clock);
> -		dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
> -		return err;
> -	}
> +	if (IS_ERR(tegra->emc_clock))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
> +				     "failed to get emc clock\n");
>  
>  	tegra->regs = mc->regs;
>  
> 

Applied it. Thanks.

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics
 

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 47/52] PM / devfreq: tegra20: Silence deferred probe error
@ 2020-10-26  3:16     ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-10-26  3:16 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

On 10/26/20 7:17 AM, Dmitry Osipenko wrote:
> Tegra EMC driver was turned into a regular kernel driver, meaning that it
> could be compiled as a loadable kernel module now. Hence EMC clock isn't
> guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
> Let's silence the deferred probe error.
> 
> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra20-devfreq.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
> index ff82bac9ee4e..fd801534771d 100644
> --- a/drivers/devfreq/tegra20-devfreq.c
> +++ b/drivers/devfreq/tegra20-devfreq.c
> @@ -141,11 +141,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>  
>  	/* EMC is a system-critical clock that is always enabled */
>  	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
> -	if (IS_ERR(tegra->emc_clock)) {
> -		err = PTR_ERR(tegra->emc_clock);
> -		dev_err(&pdev->dev, "failed to get emc clock: %d\n", err);
> -		return err;
> -	}
> +	if (IS_ERR(tegra->emc_clock))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
> +				     "failed to get emc clock\n");
>  
>  	tegra->regs = mc->regs;
>  
> 

Applied it. Thanks.

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics
 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 50/52] PM / devfreq: tegra30: Silence deferred probe error
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-26  3:17     ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-10-26  3:17 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

On 10/26/20 7:17 AM, Dmitry Osipenko wrote:
> Tegra EMC driver was turned into a regular kernel driver, meaning that it
> could be compiled as a loadable kernel module now. Hence EMC clock isn't
> guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
> Let's silence the deferred probe error.
> 
> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index f5e74c2ede85..3f732ab53573 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -801,10 +801,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>  	}
>  
>  	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
> -	if (IS_ERR(tegra->emc_clock)) {
> -		dev_err(&pdev->dev, "Failed to get emc clock\n");
> -		return PTR_ERR(tegra->emc_clock);
> -	}
> +	if (IS_ERR(tegra->emc_clock))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
> +				     "Failed to get emc clock\n");
>  
>  	err = platform_get_irq(pdev, 0);
>  	if (err < 0)
> 

Applied it. Thanks.

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 50/52] PM / devfreq: tegra30: Silence deferred probe error
@ 2020-10-26  3:17     ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-10-26  3:17 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

On 10/26/20 7:17 AM, Dmitry Osipenko wrote:
> Tegra EMC driver was turned into a regular kernel driver, meaning that it
> could be compiled as a loadable kernel module now. Hence EMC clock isn't
> guaranteed to be available and clk_get("emc") may return -EPROBE_DEFER.
> Let's silence the deferred probe error.
> 
> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index f5e74c2ede85..3f732ab53573 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -801,10 +801,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>  	}
>  
>  	tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
> -	if (IS_ERR(tegra->emc_clock)) {
> -		dev_err(&pdev->dev, "Failed to get emc clock\n");
> -		return PTR_ERR(tegra->emc_clock);
> -	}
> +	if (IS_ERR(tegra->emc_clock))
> +		return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
> +				     "Failed to get emc clock\n");
>  
>  	err = platform_get_irq(pdev, 0);
>  	if (err < 0)
> 

Applied it. Thanks.

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 48/52] PM / devfreq: tegra20: Relax Kconfig dependency
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-26  3:18     ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-10-26  3:18 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

On 10/26/20 7:17 AM, Dmitry Osipenko wrote:
> The Tegra EMC driver now could be compiled as a loadable kernel module.
> Currently devfreq driver depends on the EMC/MC drivers in Kconfig, and
> thus, devfreq is forced to be a kernel module if EMC is compiled as a
> module. This build dependency could be relaxed since devfreq driver
> checks MC/EMC presence on probe, allowing kernel configuration where
> devfreq is a built-in driver and EMC driver is a loadable module.
> This change puts Tegra20 devfreq Kconfig entry on a par with the Tegra30
> devfreq entry.
> 
> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> index 37dc40d1fcfb..0ee36ae2fa79 100644
> --- a/drivers/devfreq/Kconfig
> +++ b/drivers/devfreq/Kconfig
> @@ -123,7 +123,7 @@ config ARM_TEGRA_DEVFREQ
>  
>  config ARM_TEGRA20_DEVFREQ
>  	tristate "NVIDIA Tegra20 DEVFREQ Driver"
> -	depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST
> +	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
>  	depends on COMMON_CLK
>  	select DEVFREQ_GOV_SIMPLE_ONDEMAND
>  	help
> 

Applied it.

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 48/52] PM / devfreq: tegra20: Relax Kconfig dependency
@ 2020-10-26  3:18     ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-10-26  3:18 UTC (permalink / raw)
  To: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski
  Cc: linux-tegra, devicetree, linux-kernel, dri-devel, linux-pm

On 10/26/20 7:17 AM, Dmitry Osipenko wrote:
> The Tegra EMC driver now could be compiled as a loadable kernel module.
> Currently devfreq driver depends on the EMC/MC drivers in Kconfig, and
> thus, devfreq is forced to be a kernel module if EMC is compiled as a
> module. This build dependency could be relaxed since devfreq driver
> checks MC/EMC presence on probe, allowing kernel configuration where
> devfreq is a built-in driver and EMC driver is a loadable module.
> This change puts Tegra20 devfreq Kconfig entry on a par with the Tegra30
> devfreq entry.
> 
> Acked-by: Chanwoo Choi <cw00.choi@samsung.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> index 37dc40d1fcfb..0ee36ae2fa79 100644
> --- a/drivers/devfreq/Kconfig
> +++ b/drivers/devfreq/Kconfig
> @@ -123,7 +123,7 @@ config ARM_TEGRA_DEVFREQ
>  
>  config ARM_TEGRA20_DEVFREQ
>  	tristate "NVIDIA Tegra20 DEVFREQ Driver"
> -	depends on (TEGRA_MC && TEGRA20_EMC) || COMPILE_TEST
> +	depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
>  	depends on COMMON_CLK
>  	select DEVFREQ_GOV_SIMPLE_ONDEMAND
>  	help
> 

Applied it.

-- 
Best Regards,
Chanwoo Choi
Samsung Electronics
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
  (?)
  (?)
@ 2020-10-26  3:45   ` kernel test robot
  -1 siblings, 0 replies; 290+ messages in thread
From: kernel test robot @ 2020-10-26  3:45 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 1814 bytes --]

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.10-rc1 next-20201026]
[cannot apply to tegra/for-next robh/for-next tegra-drm/drm/tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3650b228f83adda7e5ee532e2b90429c03f7b9ec
config: m68k-allmodconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/15b275421ab8d79907837dabd50b1372c4731f9a
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
        git checkout 15b275421ab8d79907837dabd50b1372c4731f9a
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=m68k 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>, old ones prefixed by <<):

>> ERROR: modpost: "tegra_sku_info" [drivers/devfreq/tegra30-devfreq.ko] undefined!

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 58851 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 40/52] memory: tegra124-emc: Make driver modular
  2020-10-25 22:17   ` Dmitry Osipenko
  (?)
@ 2020-10-26  4:04   ` kernel test robot
  -1 siblings, 0 replies; 290+ messages in thread
From: kernel test robot @ 2020-10-26  4:04 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 2223 bytes --]

Hi Dmitry,

I love your patch! Yet something to improve:

[auto build test ERROR on linus/master]
[also build test ERROR on v5.10-rc1 next-20201026]
[cannot apply to tegra/for-next robh/for-next tegra-drm/drm/tegra/for-next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url:    https://github.com/0day-ci/linux/commits/Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
base:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 3650b228f83adda7e5ee532e2b90429c03f7b9ec
config: arm64-allyesconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # https://github.com/0day-ci/linux/commit/d100fc4bb3b3013d94cb745fd040c36b18947f82
        git remote add linux-review https://github.com/0day-ci/linux
        git fetch --no-tags linux-review Dmitry-Osipenko/Introduce-memory-interconnect-for-NVIDIA-Tegra-SoCs/20201026-062401
        git checkout d100fc4bb3b3013d94cb745fd040c36b18947f82
        # save the attached .config to linux build tree
        COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   aarch64-linux-ld: Unexpected GOT/PLT entries detected!
   aarch64-linux-ld: Unexpected run-time procedure linkages detected!
   aarch64-linux-ld: drivers/clk/tegra/clk-tegra124.o: in function `tegra124_clk_src_onecell_get':
>> clk-tegra124.c:(.text+0x3a4): undefined reference to `tegra124_clk_emc_driver_available'
   aarch64-linux-ld: drivers/clk/tegra/clk-tegra124.o: in function `tegra124_132_clock_init_post':
>> clk-tegra124.c:(.init.text+0x1014): undefined reference to `tegra124_clk_register_emc'

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 75378 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 12/52] dt-bindings: memory: tegra124: mc: Document new interconnect property
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-26 12:49     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-26 12:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Krzysztof Kozlowski, Jonathan Hunter, Michael Turquette,
	dri-devel, Mikko Perttunen, devicetree, Thierry Reding,
	linux-tegra, Peter De Schrijver, Stephen Boyd, Georgi Djakov,
	linux-kernel, linux-pm, Nicolas Chauvet, Viresh Kumar,
	Peter Geis, Rob Herring, MyungJoo Ham, Chanwoo Choi,
	Kyungmin Park

On Mon, 26 Oct 2020 01:16:55 +0300, Dmitry Osipenko wrote:
> Memory controller is interconnected with memory clients and with the
> External Memory Controller. Document new interconnect property which
> turns memory controller into interconnect provider.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra124-mc.yaml      | 5 +++++
>  1 file changed, 5 insertions(+)
> 


My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.example.dt.yaml: memory-controller@70019000: '#interconnect-cells' is a required property
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml


See https://patchwork.ozlabs.org/patch/1387321

The base for the patch is generally the last rc1. Any dependencies
should be noted.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 12/52] dt-bindings: memory: tegra124: mc: Document new interconnect property
@ 2020-10-26 12:49     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-26 12:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, Rob Herring, linux-pm, Stephen Boyd,
	Viresh Kumar, Michael Turquette, Chanwoo Choi, linux-kernel,
	dri-devel, Jonathan Hunter, Nicolas Chauvet, MyungJoo Ham,
	Thierry Reding, Krzysztof Kozlowski, Peter Geis, linux-tegra,
	Kyungmin Park, Peter De Schrijver, Georgi Djakov

On Mon, 26 Oct 2020 01:16:55 +0300, Dmitry Osipenko wrote:
> Memory controller is interconnected with memory clients and with the
> External Memory Controller. Document new interconnect property which
> turns memory controller into interconnect provider.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra124-mc.yaml      | 5 +++++
>  1 file changed, 5 insertions(+)
> 


My bot found errors running 'make dt_binding_check' on your patch:

yamllint warnings/errors:

dtschema/dtc warnings/errors:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.example.dt.yaml: memory-controller@70019000: '#interconnect-cells' is a required property
	From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml


See https://patchwork.ozlabs.org/patch/1387321

The base for the patch is generally the last rc1. Any dependencies
should be noted.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit.

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-26 12:51     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-26 12:51 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: MyungJoo Ham, Stephen Boyd, Thierry Reding, Peter De Schrijver,
	Mikko Perttunen, linux-tegra, dri-devel, Viresh Kumar,
	Georgi Djakov, Michael Turquette, Peter Geis, Kyungmin Park,
	Rob Herring, Nicolas Chauvet, Jonathan Hunter, devicetree,
	linux-pm, Krzysztof Kozlowski, Chanwoo Choi, linux-kernel

On Mon, 26 Oct 2020 01:16:56 +0300, Dmitry Osipenko wrote:
> External memory controller is interconnected with memory controller and
> with external memory. Document new interconnect property which turns
> External Memory Controller into interconnect provider.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
@ 2020-10-26 12:51     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-26 12:51 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, Rob Herring, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	Chanwoo Choi, linux-kernel, dri-devel, Jonathan Hunter,
	Michael Turquette, Kyungmin Park, MyungJoo Ham, Thierry Reding,
	Krzysztof Kozlowski, Peter Geis, linux-tegra, Georgi Djakov

On Mon, 26 Oct 2020 01:16:56 +0300, Dmitry Osipenko wrote:
> External memory controller is interconnected with memory controller and
> with external memory. Document new interconnect property which turns
> External Memory Controller into interconnect provider.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>  1 file changed, 7 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
  2020-10-25 22:16 ` Dmitry Osipenko
@ 2020-10-26 15:08   ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-26 15:08 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
> Hello,
> 
> This series brings initial support for memory interconnect to Tegra20,
> Tegra30 and Tegra124 SoCs.
> 
> For the starter only display controllers and devfreq devices are getting
> interconnect API support, others could be supported later on. The display
> controllers have the biggest demand for interconnect API right now because
> dynamic memory frequency scaling can't be done safely without taking into
> account bandwidth requirement from the displays. In particular this series
> fixes distorted display output on T30 Ouya and T124 TK1 devices.

Hi,

You introduced in v6 multiple new patches. Could you describe the
dependencies, if any?

Best regards,
Krzysztof

> Changelog:
> 
> v6: - This series was massively reworked in comparison to v5, most of the
>       patches that previously got r-b need a new round of a review (!).
> 
>     - Added missed clk-rounding to the set() callback of EMC ICC providers.
>       Now clk_set_min_rate() doesn't error out on rate overflow.
> 
>     - Now peak bandwidth is properly taken into account by the set() callback
>       of EMC ICC providers.
> 
>     - EMC runs at 2x of the DRAM bus only on Tegra20, this now taken in account
>       properly by the EMC ICC set() callbacks.
> 
>     - ICC drivers use new icc_sync_state() and xlate_extended().
> 
>     - ICC drivers support new TEGRA_MC_ICC_TAG_ISO for ICC paths, which
>       conveys to ICC driver that memory path uses isochronous transfers.
> 
>     - Added support for memory latency scaling to Tegra30 ICC provider.
>       It's required for fixing display FIFO underflows on T30.
> 
>     - Added basic interconnect support to Tegra124 drivers.
> 
>     - Tegra20/30/124 EMC drivers now support voltage scaling using generic
>       OPP API.
> 
>     - The display bandwidth management is reworked and improved. It now
>       supports both bandwidth and latency allocations. The nv-display is
>       now also taken into account properly, i.e. it's kept untouched.
>       The extra bandwidth reservation required for ISO clients is moved
>       from DC driver to the ICC drivers.
> 
>     - Dropped patch that tuned T20 display controller memory client because
>       turned out that it kills ~30% of memory bandwidth. It should be possible
>       to support client tuning, but it's too complicated for now.
> 
>     - Corrected display's cursor and winb-vfilter ICC clients.
>       The winb-vfilter was erroneously used in place of cursor's client
>       in device-trees.
> 
>     - Added devm_tegra_get_memory_controller() and switched drivers to
>       use it.
> 
>     - Device-tree OPP tables are now supported by memory and devfreq
>       drivers.
> 
>     - Tegra20-devfeq driver is reworked and now uses EMC-stats instead
>       of IMC-stats (which are nearly identical modules) because previously
>       I failed to understand how EMC-stats work and succeeded this time,
>       thinking that it simply doesn't work. This removes a bit icky dependency
>       on using both EMC and MC drivers simultaneously by the devfreq driver.
> 
>     - Tegra20-devfeq driver now is a sub-device of the EMC, it also now uses
>       interconnect API for driving memory bandwidth.
> 
>     - Tegra30-devfreq got interconnect support.
> 
>     - Devfreq patches now use dev_err_probe(), which was suggested by
>       Chanwoo Choi.
> 
>     - Added acks from Chanwoo Choi and Rob Herring to the reviewed and
>       unchanged patches.
> 
>     - Added tested-by from Peter Geis and Nicolas Chauvet, who tested this
>       series on Ouya and TK1 devices, reporting that it fixes display
>       corruption on these devices which happened due to insufficient memory
>       bandwidth.
> 
>     - Added patches to fix T20 EMC registers size.
> 
>     - Fixed missing LA entry for PTC in the Tegra MC drivers.
> 
>     - New and updated patches in v6:
> 
>         dt-bindings: memory: tegra20: emc: Correct registers range in example
>         dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
>         dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
>         dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
>         dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
>         dt-bindings: memory: tegra124: mc: Document new interconnect property
>         dt-bindings: memory: tegra124: emc: Document new interconnect property
>         dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
>         dt-bindings: tegra30-actmon: Document OPP and interconnect properties
>         dt-bindings: memory: tegra124: Add memory client IDs
>         ARM: tegra: Correct EMC registers size in Tegra20 device-tree
>         ARM: tegra: Add interconnect properties to Tegra124 device-tree
>         ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC device-tree
>         ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
>         ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes
>         ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes
>         memory: tegra: Add and use devm_tegra_get_memory_controller()
>         memory: tegra-mc: Add interconnect framework
>         memory: tegra20: Support interconnect framework
>         memory: tegra20-emc: Skip parsing of emc-stats DT sub-node
>         memory: tegra: Add missing latency allowness entry for Page Table Cache
>         memory: tegra: Add FIFO sizes to Tegra30 memory clients
>         memory: tegra30: Support interconnect framework
>         memory: tegra124-emc: Make driver modular
>         memory: tegra124: Support interconnect framework
>         memory: tegra: Remove superfluous error messages around platform_get_irq()
>         drm/tegra: dc: Support memory bandwidth management
>         drm/tegra: dc: Extend debug stats with total number of events
>         PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
>         PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
>         PM / devfreq: tegra30: Separate configurations per-SoC generation
>         opp: Put interconnect paths outside of opp_table_lock

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
@ 2020-10-26 15:08   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-26 15:08 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
> Hello,
> 
> This series brings initial support for memory interconnect to Tegra20,
> Tegra30 and Tegra124 SoCs.
> 
> For the starter only display controllers and devfreq devices are getting
> interconnect API support, others could be supported later on. The display
> controllers have the biggest demand for interconnect API right now because
> dynamic memory frequency scaling can't be done safely without taking into
> account bandwidth requirement from the displays. In particular this series
> fixes distorted display output on T30 Ouya and T124 TK1 devices.

Hi,

You introduced in v6 multiple new patches. Could you describe the
dependencies, if any?

Best regards,
Krzysztof

> Changelog:
> 
> v6: - This series was massively reworked in comparison to v5, most of the
>       patches that previously got r-b need a new round of a review (!).
> 
>     - Added missed clk-rounding to the set() callback of EMC ICC providers.
>       Now clk_set_min_rate() doesn't error out on rate overflow.
> 
>     - Now peak bandwidth is properly taken into account by the set() callback
>       of EMC ICC providers.
> 
>     - EMC runs at 2x of the DRAM bus only on Tegra20, this now taken in account
>       properly by the EMC ICC set() callbacks.
> 
>     - ICC drivers use new icc_sync_state() and xlate_extended().
> 
>     - ICC drivers support new TEGRA_MC_ICC_TAG_ISO for ICC paths, which
>       conveys to ICC driver that memory path uses isochronous transfers.
> 
>     - Added support for memory latency scaling to Tegra30 ICC provider.
>       It's required for fixing display FIFO underflows on T30.
> 
>     - Added basic interconnect support to Tegra124 drivers.
> 
>     - Tegra20/30/124 EMC drivers now support voltage scaling using generic
>       OPP API.
> 
>     - The display bandwidth management is reworked and improved. It now
>       supports both bandwidth and latency allocations. The nv-display is
>       now also taken into account properly, i.e. it's kept untouched.
>       The extra bandwidth reservation required for ISO clients is moved
>       from DC driver to the ICC drivers.
> 
>     - Dropped patch that tuned T20 display controller memory client because
>       turned out that it kills ~30% of memory bandwidth. It should be possible
>       to support client tuning, but it's too complicated for now.
> 
>     - Corrected display's cursor and winb-vfilter ICC clients.
>       The winb-vfilter was erroneously used in place of cursor's client
>       in device-trees.
> 
>     - Added devm_tegra_get_memory_controller() and switched drivers to
>       use it.
> 
>     - Device-tree OPP tables are now supported by memory and devfreq
>       drivers.
> 
>     - Tegra20-devfeq driver is reworked and now uses EMC-stats instead
>       of IMC-stats (which are nearly identical modules) because previously
>       I failed to understand how EMC-stats work and succeeded this time,
>       thinking that it simply doesn't work. This removes a bit icky dependency
>       on using both EMC and MC drivers simultaneously by the devfreq driver.
> 
>     - Tegra20-devfeq driver now is a sub-device of the EMC, it also now uses
>       interconnect API for driving memory bandwidth.
> 
>     - Tegra30-devfreq got interconnect support.
> 
>     - Devfreq patches now use dev_err_probe(), which was suggested by
>       Chanwoo Choi.
> 
>     - Added acks from Chanwoo Choi and Rob Herring to the reviewed and
>       unchanged patches.
> 
>     - Added tested-by from Peter Geis and Nicolas Chauvet, who tested this
>       series on Ouya and TK1 devices, reporting that it fixes display
>       corruption on these devices which happened due to insufficient memory
>       bandwidth.
> 
>     - Added patches to fix T20 EMC registers size.
> 
>     - Fixed missing LA entry for PTC in the Tegra MC drivers.
> 
>     - New and updated patches in v6:
> 
>         dt-bindings: memory: tegra20: emc: Correct registers range in example
>         dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
>         dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
>         dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
>         dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
>         dt-bindings: memory: tegra124: mc: Document new interconnect property
>         dt-bindings: memory: tegra124: emc: Document new interconnect property
>         dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
>         dt-bindings: tegra30-actmon: Document OPP and interconnect properties
>         dt-bindings: memory: tegra124: Add memory client IDs
>         ARM: tegra: Correct EMC registers size in Tegra20 device-tree
>         ARM: tegra: Add interconnect properties to Tegra124 device-tree
>         ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC device-tree
>         ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
>         ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes
>         ARM: tegra: Add DVFS properties to Tegra124 EMC and ACTMON device-tree nodes
>         memory: tegra: Add and use devm_tegra_get_memory_controller()
>         memory: tegra-mc: Add interconnect framework
>         memory: tegra20: Support interconnect framework
>         memory: tegra20-emc: Skip parsing of emc-stats DT sub-node
>         memory: tegra: Add missing latency allowness entry for Page Table Cache
>         memory: tegra: Add FIFO sizes to Tegra30 memory clients
>         memory: tegra30: Support interconnect framework
>         memory: tegra124-emc: Make driver modular
>         memory: tegra124: Support interconnect framework
>         memory: tegra: Remove superfluous error messages around platform_get_irq()
>         drm/tegra: dc: Support memory bandwidth management
>         drm/tegra: dc: Extend debug stats with total number of events
>         PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
>         PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
>         PM / devfreq: tegra30: Separate configurations per-SoC generation
>         opp: Put interconnect paths outside of opp_table_lock
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
  2020-10-26 15:08   ` Krzysztof Kozlowski
@ 2020-10-26 19:14     ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-26 19:14 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Chanwoo Choi
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm, linux-kernel,
	dri-devel, devicetree

26.10.2020 18:08, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
>> Hello,
>>
>> This series brings initial support for memory interconnect to Tegra20,
>> Tegra30 and Tegra124 SoCs.
>>
>> For the starter only display controllers and devfreq devices are getting
>> interconnect API support, others could be supported later on. The display
>> controllers have the biggest demand for interconnect API right now because
>> dynamic memory frequency scaling can't be done safely without taking into
>> account bandwidth requirement from the displays. In particular this series
>> fixes distorted display output on T30 Ouya and T124 TK1 devices.
> 
> Hi,
> 
> You introduced in v6 multiple new patches. Could you describe the
> dependencies, if any?

Hello,

The v6 dropped some older patches and replaced them with the new
patches. Previously I wanted to postpone the more complex changes for
later times, like supporting OPP tables and DVFS, but then the review
started to take more time than was expected and there was enough time to
complete those features.

There are five basic sets of patches:

	1. DT bindings
	2. DT changes
	3. SoC, clk and memory
	4. devfreq
	5. DRM

Each set could be applied separately.

Memory patches have a build dependency on the SoC and clk patches.

The "tegra-mc: Add interconnect framework" and "Add and use
devm_tegra_get_memory_controller()" are the root build dependencies for
all memory/ patches. Other patches are grouped per SoC generation
(Tegra20/30/124), patches within a SoC-gen group are interdependent.

I suppose the best variant would be to merge the whole series via
tegra-tree in order to preserve logical order of the patches. Although,
merging each set of patches separately also should be okay to do.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
@ 2020-10-26 19:14     ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-26 19:14 UTC (permalink / raw)
  To: Krzysztof Kozlowski, Chanwoo Choi
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, linux-pm,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-kernel,
	Rob Herring, Jonathan Hunter, Nicolas Chauvet, Kyungmin Park,
	Thierry Reding, MyungJoo Ham, Peter Geis, linux-tegra,
	Georgi Djakov, devicetree

26.10.2020 18:08, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
>> Hello,
>>
>> This series brings initial support for memory interconnect to Tegra20,
>> Tegra30 and Tegra124 SoCs.
>>
>> For the starter only display controllers and devfreq devices are getting
>> interconnect API support, others could be supported later on. The display
>> controllers have the biggest demand for interconnect API right now because
>> dynamic memory frequency scaling can't be done safely without taking into
>> account bandwidth requirement from the displays. In particular this series
>> fixes distorted display output on T30 Ouya and T124 TK1 devices.
> 
> Hi,
> 
> You introduced in v6 multiple new patches. Could you describe the
> dependencies, if any?

Hello,

The v6 dropped some older patches and replaced them with the new
patches. Previously I wanted to postpone the more complex changes for
later times, like supporting OPP tables and DVFS, but then the review
started to take more time than was expected and there was enough time to
complete those features.

There are five basic sets of patches:

	1. DT bindings
	2. DT changes
	3. SoC, clk and memory
	4. devfreq
	5. DRM

Each set could be applied separately.

Memory patches have a build dependency on the SoC and clk patches.

The "tegra-mc: Add interconnect framework" and "Add and use
devm_tegra_get_memory_controller()" are the root build dependencies for
all memory/ patches. Other patches are grouped per SoC generation
(Tegra20/30/124), patches within a SoC-gen group are interdependent.

I suppose the best variant would be to merge the whole series via
tegra-tree in order to preserve logical order of the patches. Although,
merging each set of patches separately also should be okay to do.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27  5:10     ` Viresh Kumar
  -1 siblings, 0 replies; 290+ messages in thread
From: Viresh Kumar @ 2020-10-27  5:10 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

On 26-10-20, 01:17, Dmitry Osipenko wrote:
> This patch fixes lockup which happens when OPP table is released if
> interconnect provider uses OPP in the icc_provider->set() callback
> and bandwidth of the ICC path is set to 0 by the ICC core when path
> is released. The icc_put() doesn't need the opp_table_lock protection,
> hence let's move it outside of the lock in order to resolve the problem.
> 
> In particular this fixes tegra-devfreq driver lockup on trying to unload
> the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
> provider also uses OPP for DVFS, hence they both take same opp_table_lock
> when OPP table of the devfreq is released.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/opp/core.c | 21 ++++++++++++++-------
>  1 file changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/opp/core.c b/drivers/opp/core.c
> index 2483e765318a..1134df360fe0 100644
> --- a/drivers/opp/core.c
> +++ b/drivers/opp/core.c
> @@ -1187,12 +1187,6 @@ static void _opp_table_kref_release(struct kref *kref)
>  	if (!IS_ERR(opp_table->clk))
>  		clk_put(opp_table->clk);
>  
> -	if (opp_table->paths) {
> -		for (i = 0; i < opp_table->path_count; i++)
> -			icc_put(opp_table->paths[i]);
> -		kfree(opp_table->paths);
> -	}
> -
>  	WARN_ON(!list_empty(&opp_table->opp_list));
>  
>  	list_for_each_entry_safe(opp_dev, temp, &opp_table->dev_list, node) {
> @@ -1209,9 +1203,22 @@ static void _opp_table_kref_release(struct kref *kref)
>  	mutex_destroy(&opp_table->genpd_virt_dev_lock);
>  	mutex_destroy(&opp_table->lock);
>  	list_del(&opp_table->node);
> -	kfree(opp_table);
>  
>  	mutex_unlock(&opp_table_lock);
> +
> +	/*
> +	 * Interconnect provider may use OPP too, hence icc_put() needs to be
> +	 * invoked outside of the opp_table_lock in order to prevent nested
> +	 * locking which happens when bandwidth of the ICC path is set to 0
> +	 * by ICC core on release of the path.
> +	 */
> +	if (opp_table->paths) {
> +		for (i = 0; i < opp_table->path_count; i++)
> +			icc_put(opp_table->paths[i]);
> +		kfree(opp_table->paths);
> +	}
> +
> +	kfree(opp_table);
>  }

Never make such _fixes_ part of such a big patchset. Always send them
separately.

Having said that, I already have a patch with me which shall fix it for you as
well:

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 4ac4e7ce6b8b..0e0a5269dc82 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1181,6 +1181,10 @@ static void _opp_table_kref_release(struct kref *kref)
        struct opp_device *opp_dev, *temp;
        int i;
 
+       /* Drop the lock as soon as we can */
+       list_del(&opp_table->node);
+       mutex_unlock(&opp_table_lock);
+
        _of_clear_opp_table(opp_table);
 
        /* Release clk */
@@ -1208,10 +1212,7 @@ static void _opp_table_kref_release(struct kref *kref)
 
        mutex_destroy(&opp_table->genpd_virt_dev_lock);
        mutex_destroy(&opp_table->lock);
-       list_del(&opp_table->node);
        kfree(opp_table);
-
-       mutex_unlock(&opp_table_lock);
 }
 
 void dev_pm_opp_put_opp_table(struct opp_table *opp_table)


-- 
viresh

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
@ 2020-10-27  5:10     ` Viresh Kumar
  0 siblings, 0 replies; 290+ messages in thread
From: Viresh Kumar @ 2020-10-27  5:10 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, linux-pm, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

On 26-10-20, 01:17, Dmitry Osipenko wrote:
> This patch fixes lockup which happens when OPP table is released if
> interconnect provider uses OPP in the icc_provider->set() callback
> and bandwidth of the ICC path is set to 0 by the ICC core when path
> is released. The icc_put() doesn't need the opp_table_lock protection,
> hence let's move it outside of the lock in order to resolve the problem.
> 
> In particular this fixes tegra-devfreq driver lockup on trying to unload
> the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
> provider also uses OPP for DVFS, hence they both take same opp_table_lock
> when OPP table of the devfreq is released.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/opp/core.c | 21 ++++++++++++++-------
>  1 file changed, 14 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/opp/core.c b/drivers/opp/core.c
> index 2483e765318a..1134df360fe0 100644
> --- a/drivers/opp/core.c
> +++ b/drivers/opp/core.c
> @@ -1187,12 +1187,6 @@ static void _opp_table_kref_release(struct kref *kref)
>  	if (!IS_ERR(opp_table->clk))
>  		clk_put(opp_table->clk);
>  
> -	if (opp_table->paths) {
> -		for (i = 0; i < opp_table->path_count; i++)
> -			icc_put(opp_table->paths[i]);
> -		kfree(opp_table->paths);
> -	}
> -
>  	WARN_ON(!list_empty(&opp_table->opp_list));
>  
>  	list_for_each_entry_safe(opp_dev, temp, &opp_table->dev_list, node) {
> @@ -1209,9 +1203,22 @@ static void _opp_table_kref_release(struct kref *kref)
>  	mutex_destroy(&opp_table->genpd_virt_dev_lock);
>  	mutex_destroy(&opp_table->lock);
>  	list_del(&opp_table->node);
> -	kfree(opp_table);
>  
>  	mutex_unlock(&opp_table_lock);
> +
> +	/*
> +	 * Interconnect provider may use OPP too, hence icc_put() needs to be
> +	 * invoked outside of the opp_table_lock in order to prevent nested
> +	 * locking which happens when bandwidth of the ICC path is set to 0
> +	 * by ICC core on release of the path.
> +	 */
> +	if (opp_table->paths) {
> +		for (i = 0; i < opp_table->path_count; i++)
> +			icc_put(opp_table->paths[i]);
> +		kfree(opp_table->paths);
> +	}
> +
> +	kfree(opp_table);
>  }

Never make such _fixes_ part of such a big patchset. Always send them
separately.

Having said that, I already have a patch with me which shall fix it for you as
well:

diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 4ac4e7ce6b8b..0e0a5269dc82 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1181,6 +1181,10 @@ static void _opp_table_kref_release(struct kref *kref)
        struct opp_device *opp_dev, *temp;
        int i;
 
+       /* Drop the lock as soon as we can */
+       list_del(&opp_table->node);
+       mutex_unlock(&opp_table_lock);
+
        _of_clear_opp_table(opp_table);
 
        /* Release clk */
@@ -1208,10 +1212,7 @@ static void _opp_table_kref_release(struct kref *kref)
 
        mutex_destroy(&opp_table->genpd_virt_dev_lock);
        mutex_destroy(&opp_table->lock);
-       list_del(&opp_table->node);
        kfree(opp_table);
-
-       mutex_unlock(&opp_table_lock);
 }
 
 void dev_pm_opp_put_opp_table(struct opp_table *opp_table)


-- 
viresh
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
  2020-10-26 19:14     ` Dmitry Osipenko
@ 2020-10-27  8:52       ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:52 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Chanwoo Choi, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm, linux-kernel,
	dri-devel, devicetree

On Mon, Oct 26, 2020 at 10:14:10PM +0300, Dmitry Osipenko wrote:
> 26.10.2020 18:08, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
> >> Hello,
> >>
> >> This series brings initial support for memory interconnect to Tegra20,
> >> Tegra30 and Tegra124 SoCs.
> >>
> >> For the starter only display controllers and devfreq devices are getting
> >> interconnect API support, others could be supported later on. The display
> >> controllers have the biggest demand for interconnect API right now because
> >> dynamic memory frequency scaling can't be done safely without taking into
> >> account bandwidth requirement from the displays. In particular this series
> >> fixes distorted display output on T30 Ouya and T124 TK1 devices.
> > 
> > Hi,
> > 
> > You introduced in v6 multiple new patches. Could you describe the
> > dependencies, if any?
> 
> Hello,
> 
> The v6 dropped some older patches and replaced them with the new
> patches. Previously I wanted to postpone the more complex changes for
> later times, like supporting OPP tables and DVFS, but then the review
> started to take more time than was expected and there was enough time to
> complete those features.
> 
> There are five basic sets of patches:
> 
> 	1. DT bindings
> 	2. DT changes
> 	3. SoC, clk and memory
> 	4. devfreq
> 	5. DRM
> 
> Each set could be applied separately.
> 
> Memory patches have a build dependency on the SoC and clk patches.
> 
> The "tegra-mc: Add interconnect framework" and "Add and use
> devm_tegra_get_memory_controller()" are the root build dependencies for
> all memory/ patches. Other patches are grouped per SoC generation
> (Tegra20/30/124), patches within a SoC-gen group are interdependent.
> 
> I suppose the best variant would be to merge the whole series via
> tegra-tree in order to preserve logical order of the patches. Although,
> merging each set of patches separately also should be okay to do.

Thanks for explanation. I already have three patches for Tegra MC (and
probably two more will be respun) so this might be conflict-prone. The
easiest in such case is to provide me soc and clk patches on the branch,
so I could keep all Tegra MC together.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
@ 2020-10-27  8:52       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:52 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 10:14:10PM +0300, Dmitry Osipenko wrote:
> 26.10.2020 18:08, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
> >> Hello,
> >>
> >> This series brings initial support for memory interconnect to Tegra20,
> >> Tegra30 and Tegra124 SoCs.
> >>
> >> For the starter only display controllers and devfreq devices are getting
> >> interconnect API support, others could be supported later on. The display
> >> controllers have the biggest demand for interconnect API right now because
> >> dynamic memory frequency scaling can't be done safely without taking into
> >> account bandwidth requirement from the displays. In particular this series
> >> fixes distorted display output on T30 Ouya and T124 TK1 devices.
> > 
> > Hi,
> > 
> > You introduced in v6 multiple new patches. Could you describe the
> > dependencies, if any?
> 
> Hello,
> 
> The v6 dropped some older patches and replaced them with the new
> patches. Previously I wanted to postpone the more complex changes for
> later times, like supporting OPP tables and DVFS, but then the review
> started to take more time than was expected and there was enough time to
> complete those features.
> 
> There are five basic sets of patches:
> 
> 	1. DT bindings
> 	2. DT changes
> 	3. SoC, clk and memory
> 	4. devfreq
> 	5. DRM
> 
> Each set could be applied separately.
> 
> Memory patches have a build dependency on the SoC and clk patches.
> 
> The "tegra-mc: Add interconnect framework" and "Add and use
> devm_tegra_get_memory_controller()" are the root build dependencies for
> all memory/ patches. Other patches are grouped per SoC generation
> (Tegra20/30/124), patches within a SoC-gen group are interdependent.
> 
> I suppose the best variant would be to merge the whole series via
> tegra-tree in order to preserve logical order of the patches. Although,
> merging each set of patches separately also should be okay to do.

Thanks for explanation. I already have three patches for Tegra MC (and
probably two more will be respun) so this might be conflict-prone. The
easiest in such case is to provide me soc and clk patches on the branch,
so I could keep all Tegra MC together.

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
  2020-10-25 22:16   ` [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia, memory-controller property Dmitry Osipenko
@ 2020-10-27  8:54     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:54 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> behind EMC and these controllers are tightly coupled. This patch adds the
> new phandle property which allows to properly express connection of EMC
> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> par with Tegra30+ EMC bindings, which is handy to have.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 567cffd37f3f..1b0d4417aad8 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -12,6 +12,7 @@ Properties:
>    irrespective of ram-code configuration.
>  - interrupts : Should contain EMC General interrupt.
>  - clocks : Should contain EMC clock.
> +- nvidia,memory-controller : Phandle of the Memory Controller node.

It looks like you adding a required property which is an ABI break.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
@ 2020-10-27  8:54     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:54 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> behind EMC and these controllers are tightly coupled. This patch adds the
> new phandle property which allows to properly express connection of EMC
> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> par with Tegra30+ EMC bindings, which is handy to have.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 567cffd37f3f..1b0d4417aad8 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -12,6 +12,7 @@ Properties:
>    irrespective of ram-code configuration.
>  - interrupts : Should contain EMC General interrupt.
>  - clocks : Should contain EMC clock.
> +- nvidia,memory-controller : Phandle of the Memory Controller node.

It looks like you adding a required property which is an ABI break.

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27  8:55     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:55 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:48AM +0300, Dmitry Osipenko wrote:
> Memory controller is interconnected with memory clients and with the
> External Memory Controller. Document new interconnect property which
> turns memory controller into interconnect provider.
> 
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> index e55328237df4..739b7c6f2e26 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> @@ -16,6 +16,8 @@ Required properties:
>    IOMMU specifier needed to encode an address. GART supports only a single
>    address space that is shared by all devices, therefore no additional
>    information needed for the address encoding.
> +- #interconnect-cells : Should be 1. This cell represents memory client.
> +  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.

This is a list of required properties so you break the ABI. All existing
DTBs will be affected.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
@ 2020-10-27  8:55     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:55 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:48AM +0300, Dmitry Osipenko wrote:
> Memory controller is interconnected with memory clients and with the
> External Memory Controller. Document new interconnect property which
> turns memory controller into interconnect provider.
> 
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> index e55328237df4..739b7c6f2e26 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> @@ -16,6 +16,8 @@ Required properties:
>    IOMMU specifier needed to encode an address. GART supports only a single
>    address space that is shared by all devices, therefore no additional
>    information needed for the address encoding.
> +- #interconnect-cells : Should be 1. This cell represents memory client.
> +  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.

This is a list of required properties so you break the ABI. All existing
DTBs will be affected.

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 07/52] dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27  8:57     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:57 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:50AM +0300, Dmitry Osipenko wrote:
> The SoC core voltage can't be changed without taking into account the
> clock rate of External Memory Controller. Document OPP table that will
> be used for dynamic voltage frequency scaling, taking into account EMC
> voltage requirement. Document optional core voltage regulator, which is
> optional because some boards may have a fixed core regulator and still
> frequency scaling may be desired to have.

You need to document that property is optional in the binding.

Best regards,
Krzysztof

> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt      | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 0a53adc6ccba..8d09b228ac42 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -14,11 +14,23 @@ Properties:
>  - clocks : Should contain EMC clock.
>  - nvidia,memory-controller : Phandle of the Memory Controller node.
>  - #interconnect-cells : Should be 0.
> +- core-supply: Phandle of voltage regulator of the SoC "core" power domain.
> +- operating-points-v2: See ../bindings/opp/opp.txt for details.
>  
>  Child device nodes describe the memory settings for different configurations and clock rates.
>  
>  Example:
>  
> +	emc_icc_dvfs_opp_table: emc_opp_table0 {
> +		compatible = "operating-points-v2";
> +
> +		opp@36000000 {
> +			opp-microvolt = <950000 950000 1300000>;
> +			opp-hz = /bits/ 64 <36000000>;
> +		};
> +		...
> +	};
> +
>  	memory-controller@7000f400 {
>  		#address-cells = < 1 >;
>  		#size-cells = < 0 >;
> @@ -28,6 +40,8 @@ Example:
>  		interrupts = <0 78 0x04>;
>  		clocks = <&tegra_car TEGRA20_CLK_EMC>;
>  		nvidia,memory-controller = <&mc>;
> +		core-supply = <&core_vdd_reg>;
> +		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
>  	}
>  
>  
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 07/52] dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator
@ 2020-10-27  8:57     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  8:57 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:50AM +0300, Dmitry Osipenko wrote:
> The SoC core voltage can't be changed without taking into account the
> clock rate of External Memory Controller. Document OPP table that will
> be used for dynamic voltage frequency scaling, taking into account EMC
> voltage requirement. Document optional core voltage regulator, which is
> optional because some boards may have a fixed core regulator and still
> frequency scaling may be desired to have.

You need to document that property is optional in the binding.

Best regards,
Krzysztof

> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt      | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 0a53adc6ccba..8d09b228ac42 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -14,11 +14,23 @@ Properties:
>  - clocks : Should contain EMC clock.
>  - nvidia,memory-controller : Phandle of the Memory Controller node.
>  - #interconnect-cells : Should be 0.
> +- core-supply: Phandle of voltage regulator of the SoC "core" power domain.
> +- operating-points-v2: See ../bindings/opp/opp.txt for details.
>  
>  Child device nodes describe the memory settings for different configurations and clock rates.
>  
>  Example:
>  
> +	emc_icc_dvfs_opp_table: emc_opp_table0 {
> +		compatible = "operating-points-v2";
> +
> +		opp@36000000 {
> +			opp-microvolt = <950000 950000 1300000>;
> +			opp-hz = /bits/ 64 <36000000>;
> +		};
> +		...
> +	};
> +
>  	memory-controller@7000f400 {
>  		#address-cells = < 1 >;
>  		#size-cells = < 0 >;
> @@ -28,6 +40,8 @@ Example:
>  		interrupts = <0 78 0x04>;
>  		clocks = <&tegra_car TEGRA20_CLK_EMC>;
>  		nvidia,memory-controller = <&mc>;
> +		core-supply = <&core_vdd_reg>;
> +		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
>  	}
>  
>  
> -- 
> 2.27.0
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27  9:02     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:02 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
> External Memory Controller can gather various hardware statistics that
> are intended to be used for debugging purposes and for dynamic frequency
> scaling of memory bus.
> 
> Document the new mfd-simple compatible and EMC statistics sub-device.
> The subdev contains EMC DFS OPP table and interconnect paths to be used
> for dynamic scaling of system's memory bandwidth based on EMC utilization
> statistics.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 8d09b228ac42..382aabcd6952 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -4,7 +4,7 @@ Properties:
>  - name : Should be emc
>  - #address-cells : Should be 1
>  - #size-cells : Should be 0
> -- compatible : Should contain "nvidia,tegra20-emc".
> +- compatible : Should contain "nvidia,tegra20-emc" and "simple-mfd".

Changing a compatible match is another break of ABI, unless it is not
really required. It's unclear to me from the contents of the patch.

>  - reg : Offset and length of the register set for the device
>  - nvidia,use-ram-code : If present, the sub-nodes will be addressed
>    and chosen using the ramcode board selector. If omitted, only one
> @@ -17,7 +17,8 @@ Properties:
>  - core-supply: Phandle of voltage regulator of the SoC "core" power domain.
>  - operating-points-v2: See ../bindings/opp/opp.txt for details.
>  
> -Child device nodes describe the memory settings for different configurations and clock rates.
> +Child device nodes describe the memory settings for different configurations and clock rates,
> +as well as EMC activity statistics collection sub-device.
>  
>  Example:
>  
> @@ -31,17 +32,34 @@ Example:
>  		...
>  	};
>  
> +	emc_bw_dfs_opp_table: emc_opp_table1 {

Hyphens for node name.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-27  9:02     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:02 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
> External Memory Controller can gather various hardware statistics that
> are intended to be used for debugging purposes and for dynamic frequency
> scaling of memory bus.
> 
> Document the new mfd-simple compatible and EMC statistics sub-device.
> The subdev contains EMC DFS OPP table and interconnect paths to be used
> for dynamic scaling of system's memory bandwidth based on EMC utilization
> statistics.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 8d09b228ac42..382aabcd6952 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -4,7 +4,7 @@ Properties:
>  - name : Should be emc
>  - #address-cells : Should be 1
>  - #size-cells : Should be 0
> -- compatible : Should contain "nvidia,tegra20-emc".
> +- compatible : Should contain "nvidia,tegra20-emc" and "simple-mfd".

Changing a compatible match is another break of ABI, unless it is not
really required. It's unclear to me from the contents of the patch.

>  - reg : Offset and length of the register set for the device
>  - nvidia,use-ram-code : If present, the sub-nodes will be addressed
>    and chosen using the ramcode board selector. If omitted, only one
> @@ -17,7 +17,8 @@ Properties:
>  - core-supply: Phandle of voltage regulator of the SoC "core" power domain.
>  - operating-points-v2: See ../bindings/opp/opp.txt for details.
>  
> -Child device nodes describe the memory settings for different configurations and clock rates.
> +Child device nodes describe the memory settings for different configurations and clock rates,
> +as well as EMC activity statistics collection sub-device.
>  
>  Example:
>  
> @@ -31,17 +32,34 @@ Example:
>  		...
>  	};
>  
> +	emc_bw_dfs_opp_table: emc_opp_table1 {

Hyphens for node name.

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 06/52] dt-bindings: memory: tegra20: emc: Document new interconnect property
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27  9:03     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:03 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:49AM +0300, Dmitry Osipenko wrote:
> External Memory Controller is interconnected with memory controller and
> with external memory. Document new interconnect property which turns EMC
> into interconnect provider.
> 
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 1b0d4417aad8..0a53adc6ccba 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -13,6 +13,7 @@ Properties:
>  - interrupts : Should contain EMC General interrupt.
>  - clocks : Should contain EMC clock.
>  - nvidia,memory-controller : Phandle of the Memory Controller node.
> +- #interconnect-cells : Should be 0.
>  
>  Child device nodes describe the memory settings for different configurations and clock rates.
>  
> @@ -21,6 +22,7 @@ Example:
>  	memory-controller@7000f400 {
>  		#address-cells = < 1 >;
>  		#size-cells = < 0 >;
> +		#interconnect-cells = < 0 >;

No spaces within <>. I see existing example, but bad pattern should not
be continued just because it is already there.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 06/52] dt-bindings: memory: tegra20: emc: Document new interconnect property
@ 2020-10-27  9:03     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:03 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:49AM +0300, Dmitry Osipenko wrote:
> External Memory Controller is interconnected with memory controller and
> with external memory. Document new interconnect property which turns EMC
> into interconnect provider.
> 
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 1b0d4417aad8..0a53adc6ccba 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -13,6 +13,7 @@ Properties:
>  - interrupts : Should contain EMC General interrupt.
>  - clocks : Should contain EMC clock.
>  - nvidia,memory-controller : Phandle of the Memory Controller node.
> +- #interconnect-cells : Should be 0.
>  
>  Child device nodes describe the memory settings for different configurations and clock rates.
>  
> @@ -21,6 +22,7 @@ Example:
>  	memory-controller@7000f400 {
>  		#address-cells = < 1 >;
>  		#size-cells = < 0 >;
> +		#interconnect-cells = < 0 >;

No spaces within <>. I see existing example, but bad pattern should not
be continued just because it is already there.

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27  9:05     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:05 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:52AM +0300, Dmitry Osipenko wrote:
> Memory controller is interconnected with memory clients and with the
> External Memory Controller. Document new interconnect property which
> turns memory controller into interconnect provider.
> 
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> index 84fd57bcf0dc..5436e6d420bc 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> @@ -57,6 +57,9 @@ properties:
>    "#iommu-cells":
>      const: 1
>  
> +  "#interconnect-cells":
> +    const: 1
> +
>  patternProperties:
>    "^emc-timings-[0-9]+$":
>      type: object
> @@ -120,6 +123,7 @@ required:
>    - clock-names
>    - "#reset-cells"
>    - "#iommu-cells"
> +  - "#interconnect-cells"

Rob,

You were fine with adding a new required property which breaks all
existing DTBs?

Were these bindings marked as unstable? The patchset does not even
say/scream that it breaks the ABI, so this might be quite a surprise for
someone...

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
@ 2020-10-27  9:05     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:05 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:52AM +0300, Dmitry Osipenko wrote:
> Memory controller is interconnected with memory clients and with the
> External Memory Controller. Document new interconnect property which
> turns memory controller into interconnect provider.
> 
> Acked-by: Rob Herring <robh@kernel.org>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> index 84fd57bcf0dc..5436e6d420bc 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> @@ -57,6 +57,9 @@ properties:
>    "#iommu-cells":
>      const: 1
>  
> +  "#interconnect-cells":
> +    const: 1
> +
>  patternProperties:
>    "^emc-timings-[0-9]+$":
>      type: object
> @@ -120,6 +123,7 @@ required:
>    - clock-names
>    - "#reset-cells"
>    - "#iommu-cells"
> +  - "#interconnect-cells"

Rob,

You were fine with adding a new required property which breaks all
existing DTBs?

Were these bindings marked as unstable? The patchset does not even
say/scream that it breaks the ABI, so this might be quite a surprise for
someone...

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 20/52] ARM: tegra: Correct EMC registers size in Tegra20 device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27  9:10     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:10 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:03AM +0300, Dmitry Osipenko wrote:
> The Tegra20 EMC registers size should be twice bigger. This patch fixes
> the size.

Don't use "This patch" (this appears here). Better to use:
"Fix the size of ..." or just "The size should be twice bigger" as it is
obvious that you fix it.

https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L151

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 20/52] ARM: tegra: Correct EMC registers size in Tegra20 device-tree
@ 2020-10-27  9:10     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:10 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:03AM +0300, Dmitry Osipenko wrote:
> The Tegra20 EMC registers size should be twice bigger. This patch fixes
> the size.

Don't use "This patch" (this appears here). Better to use:
"Fix the size of ..." or just "The size should be twice bigger" as it is
obvious that you fix it.

https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L151

Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 21/52] ARM: tegra: Add interconnect properties to Tegra20 device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27  9:12     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:12 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:04AM +0300, Dmitry Osipenko wrote:
> Add interconnect properties to the Memory Controller, External Memory
> Controller and the Display Controller nodes in order to describe hardware
> interconnection.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/boot/dts/tegra20.dtsi | 26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> index 9347f7789245..2e1304493f7d 100644
> --- a/arch/arm/boot/dts/tegra20.dtsi
> +++ b/arch/arm/boot/dts/tegra20.dtsi
> @@ -111,6 +111,17 @@ dc@54200000 {
>  
>  			nvidia,head = <0>;
>  
> +			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,

I think you just added the defines and did not include them here, so
this should not even build. Did you test it?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 21/52] ARM: tegra: Add interconnect properties to Tegra20 device-tree
@ 2020-10-27  9:12     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:12 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:04AM +0300, Dmitry Osipenko wrote:
> Add interconnect properties to the Memory Controller, External Memory
> Controller and the Display Controller nodes in order to describe hardware
> interconnection.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/boot/dts/tegra20.dtsi | 26 +++++++++++++++++++++++++-
>  1 file changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> index 9347f7789245..2e1304493f7d 100644
> --- a/arch/arm/boot/dts/tegra20.dtsi
> +++ b/arch/arm/boot/dts/tegra20.dtsi
> @@ -111,6 +111,17 @@ dc@54200000 {
>  
>  			nvidia,head = <0>;
>  
> +			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,

I think you just added the defines and did not include them here, so
this should not even build. Did you test it?

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 22/52] ARM: tegra: Add interconnect properties to Tegra30 device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27  9:15     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:15 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:05AM +0300, Dmitry Osipenko wrote:
> Add interconnect properties to the Memory Controller, External Memory
> Controller and the Display Controller nodes in order to describe hardware
> interconnection.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/boot/dts/tegra30.dtsi | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
> index aeae8c092d41..2caf6cc6f4b1 100644
> --- a/arch/arm/boot/dts/tegra30.dtsi
> +++ b/arch/arm/boot/dts/tegra30.dtsi
> @@ -210,6 +210,17 @@ dc@54200000 {
>  
>  			nvidia,head = <0>;
>  
> +			interconnects = <&mc TEGRA30_MC_DISPLAY0A &emc>,

Does not compile.

> +					<&mc TEGRA30_MC_DISPLAY0B &emc>,
> +					<&mc TEGRA30_MC_DISPLAY1B &emc>,
> +					<&mc TEGRA30_MC_DISPLAY0C &emc>,
> +					<&mc TEGRA30_MC_DISPLAYHC &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winb-vfilter",
> +					     "winc",
> +					     "cursor";
> +
>  			rgb {
>  				status = "disabled";
>  			};
> @@ -229,6 +240,17 @@ dc@54240000 {
>  
>  			nvidia,head = <1>;
>  
> +			interconnects = <&mc TEGRA30_MC_DISPLAY0AB &emc>,
> +					<&mc TEGRA30_MC_DISPLAY0BB &emc>,
> +					<&mc TEGRA30_MC_DISPLAY1BB &emc>,
> +					<&mc TEGRA30_MC_DISPLAY0CB &emc>,
> +					<&mc TEGRA30_MC_DISPLAYHCB &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winb-vfilter",
> +					     "winc",
> +					     "cursor";
> +
>  			rgb {
>  				status = "disabled";
>  			};
> @@ -748,15 +770,18 @@ mc: memory-controller@7000f000 {
>  
>  		#iommu-cells = <1>;
>  		#reset-cells = <1>;
> +		#interconnect-cells = <1>;
>  	};
>  
> -	memory-controller@7000f400 {
> +	emc: memory-controller@7000f400 {
>  		compatible = "nvidia,tegra30-emc";
>  		reg = <0x7000f400 0x400>;
>  		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
>  		clocks = <&tegra_car TEGRA30_CLK_EMC>;
>  
>  		nvidia,memory-controller = <&mc>;
> +

No need for blank line.

Best regards,
Krzysztof

> +		#interconnect-cells = <0>;
>  	};
>  
>  	fuse@7000f800 {
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 22/52] ARM: tegra: Add interconnect properties to Tegra30 device-tree
@ 2020-10-27  9:15     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:15 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:05AM +0300, Dmitry Osipenko wrote:
> Add interconnect properties to the Memory Controller, External Memory
> Controller and the Display Controller nodes in order to describe hardware
> interconnection.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/boot/dts/tegra30.dtsi | 27 ++++++++++++++++++++++++++-
>  1 file changed, 26 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
> index aeae8c092d41..2caf6cc6f4b1 100644
> --- a/arch/arm/boot/dts/tegra30.dtsi
> +++ b/arch/arm/boot/dts/tegra30.dtsi
> @@ -210,6 +210,17 @@ dc@54200000 {
>  
>  			nvidia,head = <0>;
>  
> +			interconnects = <&mc TEGRA30_MC_DISPLAY0A &emc>,

Does not compile.

> +					<&mc TEGRA30_MC_DISPLAY0B &emc>,
> +					<&mc TEGRA30_MC_DISPLAY1B &emc>,
> +					<&mc TEGRA30_MC_DISPLAY0C &emc>,
> +					<&mc TEGRA30_MC_DISPLAYHC &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winb-vfilter",
> +					     "winc",
> +					     "cursor";
> +
>  			rgb {
>  				status = "disabled";
>  			};
> @@ -229,6 +240,17 @@ dc@54240000 {
>  
>  			nvidia,head = <1>;
>  
> +			interconnects = <&mc TEGRA30_MC_DISPLAY0AB &emc>,
> +					<&mc TEGRA30_MC_DISPLAY0BB &emc>,
> +					<&mc TEGRA30_MC_DISPLAY1BB &emc>,
> +					<&mc TEGRA30_MC_DISPLAY0CB &emc>,
> +					<&mc TEGRA30_MC_DISPLAYHCB &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winb-vfilter",
> +					     "winc",
> +					     "cursor";
> +
>  			rgb {
>  				status = "disabled";
>  			};
> @@ -748,15 +770,18 @@ mc: memory-controller@7000f000 {
>  
>  		#iommu-cells = <1>;
>  		#reset-cells = <1>;
> +		#interconnect-cells = <1>;
>  	};
>  
> -	memory-controller@7000f400 {
> +	emc: memory-controller@7000f400 {
>  		compatible = "nvidia,tegra30-emc";
>  		reg = <0x7000f400 0x400>;
>  		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
>  		clocks = <&tegra_car TEGRA30_CLK_EMC>;
>  
>  		nvidia,memory-controller = <&mc>;
> +

No need for blank line.

Best regards,
Krzysztof

> +		#interconnect-cells = <0>;
>  	};
>  
>  	fuse@7000f800 {
> -- 
> 2.27.0
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 23/52] ARM: tegra: Add interconnect properties to Tegra124 device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27  9:16     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:16 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:06AM +0300, Dmitry Osipenko wrote:
> Add interconnect properties to the Memory Controller, External Memory
> Controller and the Display Controller nodes in order to describe hardware
> interconnection.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/boot/dts/tegra124.dtsi | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
> index 64f488ba1e72..1801e30b1d3a 100644
> --- a/arch/arm/boot/dts/tegra124.dtsi
> +++ b/arch/arm/boot/dts/tegra124.dtsi
> @@ -113,6 +113,19 @@ dc@54200000 {
>  			iommus = <&mc TEGRA_SWGROUP_DC>;
>  
>  			nvidia,head = <0>;
> +
> +			interconnects = <&mc TEGRA124_MC_DISPLAY0A &emc>,

This does not compile.

> +					<&mc TEGRA124_MC_DISPLAY0B &emc>,
> +					<&mc TEGRA124_MC_DISPLAY0C &emc>,
> +					<&mc TEGRA124_MC_DISPLAYHC &emc>,
> +					<&mc TEGRA124_MC_DISPLAYD &emc>,
> +					<&mc TEGRA124_MC_DISPLAYT &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winc",
> +					     "cursor",
> +					     "wind",
> +					     "wint";
>  		};
>  
>  		dc@54240000 {
> @@ -127,6 +140,15 @@ dc@54240000 {
>  			iommus = <&mc TEGRA_SWGROUP_DCB>;
>  
>  			nvidia,head = <1>;
> +
> +			interconnects = <&mc TEGRA124_MC_DISPLAY0AB &emc>,
> +					<&mc TEGRA124_MC_DISPLAY0BB &emc>,
> +					<&mc TEGRA124_MC_DISPLAY0CB &emc>,
> +					<&mc TEGRA124_MC_DISPLAYHCB &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winc",
> +					     "cursor";
>  		};
>  
>  		hdmi: hdmi@54280000 {
> @@ -628,6 +650,7 @@ mc: memory-controller@70019000 {
>  
>  		#iommu-cells = <1>;
>  		#reset-cells = <1>;
> +		#interconnect-cells = <1>;
>  	};
>  
>  	emc: external-memory-controller@7001b000 {
> @@ -637,6 +660,8 @@ emc: external-memory-controller@7001b000 {
>  		clock-names = "emc";
>  
>  		nvidia,memory-controller = <&mc>;
> +

No need for blank line.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 23/52] ARM: tegra: Add interconnect properties to Tegra124 device-tree
@ 2020-10-27  9:16     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:16 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:06AM +0300, Dmitry Osipenko wrote:
> Add interconnect properties to the Memory Controller, External Memory
> Controller and the Display Controller nodes in order to describe hardware
> interconnection.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  arch/arm/boot/dts/tegra124.dtsi | 25 +++++++++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/tegra124.dtsi b/arch/arm/boot/dts/tegra124.dtsi
> index 64f488ba1e72..1801e30b1d3a 100644
> --- a/arch/arm/boot/dts/tegra124.dtsi
> +++ b/arch/arm/boot/dts/tegra124.dtsi
> @@ -113,6 +113,19 @@ dc@54200000 {
>  			iommus = <&mc TEGRA_SWGROUP_DC>;
>  
>  			nvidia,head = <0>;
> +
> +			interconnects = <&mc TEGRA124_MC_DISPLAY0A &emc>,

This does not compile.

> +					<&mc TEGRA124_MC_DISPLAY0B &emc>,
> +					<&mc TEGRA124_MC_DISPLAY0C &emc>,
> +					<&mc TEGRA124_MC_DISPLAYHC &emc>,
> +					<&mc TEGRA124_MC_DISPLAYD &emc>,
> +					<&mc TEGRA124_MC_DISPLAYT &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winc",
> +					     "cursor",
> +					     "wind",
> +					     "wint";
>  		};
>  
>  		dc@54240000 {
> @@ -127,6 +140,15 @@ dc@54240000 {
>  			iommus = <&mc TEGRA_SWGROUP_DCB>;
>  
>  			nvidia,head = <1>;
> +
> +			interconnects = <&mc TEGRA124_MC_DISPLAY0AB &emc>,
> +					<&mc TEGRA124_MC_DISPLAY0BB &emc>,
> +					<&mc TEGRA124_MC_DISPLAY0CB &emc>,
> +					<&mc TEGRA124_MC_DISPLAYHCB &emc>;
> +			interconnect-names = "wina",
> +					     "winb",
> +					     "winc",
> +					     "cursor";
>  		};
>  
>  		hdmi: hdmi@54280000 {
> @@ -628,6 +650,7 @@ mc: memory-controller@70019000 {
>  
>  		#iommu-cells = <1>;
>  		#reset-cells = <1>;
> +		#interconnect-cells = <1>;
>  	};
>  
>  	emc: external-memory-controller@7001b000 {
> @@ -637,6 +660,8 @@ emc: external-memory-controller@7001b000 {
>  		clock-names = "emc";
>  
>  		nvidia,memory-controller = <&mc>;
> +

No need for blank line.

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 25/52] ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27  9:18     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:08AM +0300, Dmitry Osipenko wrote:
> Add EMC OPP DVFS/DFS tables and emc-stats subdev that will be used for
> dynamic memory bandwidth scaling, while EMC itself will perform voltage
> scaling. Update board device-trees with optional EMC core supply and
> remove unsupported OPPs.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../boot/dts/tegra20-acer-a500-picasso.dts    |  12 ++
>  arch/arm/boot/dts/tegra20-colibri.dtsi        |   8 +
>  arch/arm/boot/dts/tegra20-paz00.dts           |  10 +
>  .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 181 ++++++++++++++++++
>  arch/arm/boot/dts/tegra20.dtsi                |  12 +-
>  5 files changed, 222 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
> 
> diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
> index a0b829738e8f..f5c1591c8ea8 100644
> --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
> +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
> @@ -1058,9 +1058,21 @@ map0 {
>  		};
>  	};
>  
> +	emc_opp_table0 {

All node names with hyphens -. Not underscores.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 25/52] ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node
@ 2020-10-27  9:18     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:08AM +0300, Dmitry Osipenko wrote:
> Add EMC OPP DVFS/DFS tables and emc-stats subdev that will be used for
> dynamic memory bandwidth scaling, while EMC itself will perform voltage
> scaling. Update board device-trees with optional EMC core supply and
> remove unsupported OPPs.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../boot/dts/tegra20-acer-a500-picasso.dts    |  12 ++
>  arch/arm/boot/dts/tegra20-colibri.dtsi        |   8 +
>  arch/arm/boot/dts/tegra20-paz00.dts           |  10 +
>  .../arm/boot/dts/tegra20-peripherals-opp.dtsi | 181 ++++++++++++++++++
>  arch/arm/boot/dts/tegra20.dtsi                |  12 +-
>  5 files changed, 222 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/boot/dts/tegra20-peripherals-opp.dtsi
> 
> diff --git a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
> index a0b829738e8f..f5c1591c8ea8 100644
> --- a/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
> +++ b/arch/arm/boot/dts/tegra20-acer-a500-picasso.dts
> @@ -1058,9 +1058,21 @@ map0 {
>  		};
>  	};
>  
> +	emc_opp_table0 {

All node names with hyphens -. Not underscores.

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27  9:42     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:42 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:11AM +0300, Dmitry Osipenko wrote:
> Multiple Tegra drivers need to retrieve Memory Controller and there is
> duplication of the retrieval code among the drivers. This patch removes
> the duplication and fixes put_device() which was missed in the duplicated
> code.
> 
> EMC drivers now use new common devm_tegra_get_memory_controller() helper
> instead of opencoding the MC retrieval.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
>  drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
>  drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
>  drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
>  include/soc/tegra/mc.h                   | 10 +++++
>  5 files changed, 74 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
> index ec8403557ed4..12ea2c79205a 100644
> --- a/drivers/memory/tegra/mc.c
> +++ b/drivers/memory/tegra/mc.c
> @@ -42,6 +42,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
>  
> +static void tegra_mc_devm_action_put_device(void *data)
> +{
> +	struct tegra_mc *mc = data;
> +
> +	put_device(mc->dev);
> +}
> +
> +/**
> + * devm_tegra_get_memory_controller() - get Tegra Memory Controller handle
> + * @dev: device pointer for the consumer device
> + *
> + * This function will search for the Memory Controller node in a device-tree
> + * and retrieve the Memory Controller handle.
> + *
> + * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
> + */
> +struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev)

Usually 'get' is a suffix (for example in clk, gpiod, iio, led), so:
devm_tegra_memory_controller_get()

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
@ 2020-10-27  9:42     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27  9:42 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:11AM +0300, Dmitry Osipenko wrote:
> Multiple Tegra drivers need to retrieve Memory Controller and there is
> duplication of the retrieval code among the drivers. This patch removes
> the duplication and fixes put_device() which was missed in the duplicated
> code.
> 
> EMC drivers now use new common devm_tegra_get_memory_controller() helper
> instead of opencoding the MC retrieval.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
>  drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
>  drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
>  drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
>  include/soc/tegra/mc.h                   | 10 +++++
>  5 files changed, 74 insertions(+), 59 deletions(-)
> 
> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
> index ec8403557ed4..12ea2c79205a 100644
> --- a/drivers/memory/tegra/mc.c
> +++ b/drivers/memory/tegra/mc.c
> @@ -42,6 +42,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
>  
> +static void tegra_mc_devm_action_put_device(void *data)
> +{
> +	struct tegra_mc *mc = data;
> +
> +	put_device(mc->dev);
> +}
> +
> +/**
> + * devm_tegra_get_memory_controller() - get Tegra Memory Controller handle
> + * @dev: device pointer for the consumer device
> + *
> + * This function will search for the Memory Controller node in a device-tree
> + * and retrieve the Memory Controller handle.
> + *
> + * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
> + */
> +struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev)

Usually 'get' is a suffix (for example in clk, gpiod, iio, led), so:
devm_tegra_memory_controller_get()

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 10:09     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 10:09 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:16AM +0300, Dmitry Osipenko wrote:
> Now Internal and External Memory Controllers are memory interconnection
> providers. This allows us to use interconnect API for tuning of memory
> configuration. EMC driver now supports OPPs and DVFS.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig       |   3 +-
>  drivers/memory/tegra/mc.h          |  12 ++
>  drivers/memory/tegra/tegra20-emc.c | 176 +++++++++++++++++++++++++++++
>  drivers/memory/tegra/tegra20.c     |  34 ++++++
>  4 files changed, 224 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> index ff426747cd7d..ac3dfe155505 100644
> --- a/drivers/memory/tegra/Kconfig
> +++ b/drivers/memory/tegra/Kconfig
> @@ -11,7 +11,8 @@ config TEGRA_MC
>  config TEGRA20_EMC
>  	tristate "NVIDIA Tegra20 External Memory Controller driver"
>  	default y
> -	depends on ARCH_TEGRA_2x_SOC
> +	depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
> +	select PM_OPP
>  	help
>  	  This driver is for the External Memory Controller (EMC) found on
>  	  Tegra20 chips. The EMC controls the external DRAM on the board.
> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> index abeb6a2cc36a..531fb4fb7b17 100644
> --- a/drivers/memory/tegra/mc.h
> +++ b/drivers/memory/tegra/mc.h
> @@ -78,6 +78,18 @@
>  
>  #define MC_TIMING_UPDATE				BIT(0)
>  
> +static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
> +{
> +	val = val * percents;
> +	do_div(val, 100);
> +
> +	/*
> +	 * High freq + high boosting percent + large polling interval are
> +	 * resulting in integer overflow when watermarks are calculated.
> +	 */
> +	return min_t(u64, val, U32_MAX);
> +}
> +
>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
>  {
>  	return readl_relaxed(mc->regs + offset);
> diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
> index 34085e26dced..69ccb3fe5b0b 100644
> --- a/drivers/memory/tegra/tegra20-emc.c
> +++ b/drivers/memory/tegra/tegra20-emc.c
> @@ -9,6 +9,7 @@
>  #include <linux/clk/tegra.h>
>  #include <linux/debugfs.h>
>  #include <linux/err.h>
> +#include <linux/interconnect-provider.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
> @@ -16,11 +17,15 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/slab.h>
>  #include <linux/sort.h>
>  #include <linux/types.h>
>  
>  #include <soc/tegra/fuse.h>
>  
> +#include "mc.h"
> +
>  #define EMC_INTSTATUS				0x000
>  #define EMC_INTMASK				0x004
>  #define EMC_DBG					0x008
> @@ -144,6 +149,9 @@ struct emc_timing {
>  
>  struct tegra_emc {
>  	struct device *dev;
> +	struct tegra_mc *mc;
> +	struct opp_table *opp_table;
> +	struct icc_provider provider;
>  	struct notifier_block clk_nb;
>  	struct clk *clk;
>  	void __iomem *regs;
> @@ -658,6 +666,166 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
>  			    emc, &tegra_emc_debug_max_rate_fops);
>  }
>  
> +static inline struct tegra_emc *
> +to_tegra_emc_provider(struct icc_provider *provider)
> +{
> +	return container_of(provider, struct tegra_emc, provider);
> +}
> +
> +static struct icc_node_data *
> +emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
> +{
> +	struct icc_provider *provider = data;
> +	struct icc_node_data *ndata;
> +	struct icc_node *node;
> +
> +	/* External Memory is the only possible ICC route */
> +	list_for_each_entry(node, &provider->nodes, node_list) {
> +		if (node->id != TEGRA_ICC_EMEM)
> +			continue;
> +
> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> +		if (!ndata)
> +			return ERR_PTR(-ENOMEM);
> +
> +		/*
> +		 * SRC and DST nodes should have matching TAG in order to have
> +		 * it set by default for a requested path.
> +		 */
> +		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> +		ndata->node = node;
> +
> +		return ndata;
> +	}
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
> +	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
> +	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
> +	unsigned long long rate = max(avg_bw, peak_bw);
> +	unsigned int dram_data_bus_width_bytes = 4;
> +	long rounded_rate;
> +	int err;
> +
> +	/*
> +	 * Tegra20 EMC runs on x2 clock rate of SDRAM bus because DDR data
> +	 * is sampled on both clock edges. This means that EMC clock rate
> +	 * equals to the peak data rate.
> +	 */
> +	do_div(rate, dram_data_bus_width_bytes);
> +	rate = min_t(u64, rate, U32_MAX);
> +
> +	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
> +	if (rounded_rate < 0)
> +		return rounded_rate;
> +
> +	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
> +	if (err)
> +		return err;
> +
> +	return 0;
> +}
> +
> +static int tegra_emc_interconnect_init(struct tegra_emc *emc)
> +{
> +	const struct tegra_mc_soc *soc;
> +	struct icc_node *node;
> +	int err;
> +
> +	emc->mc = devm_tegra_get_memory_controller(emc->dev);
> +	if (IS_ERR(emc->mc))
> +		return PTR_ERR(emc->mc);
> +
> +	soc = emc->mc->soc;
> +
> +	emc->provider.dev = emc->dev;
> +	emc->provider.set = emc_icc_set;
> +	emc->provider.data = &emc->provider;
> +	emc->provider.aggregate = soc->icc_ops->aggregate;
> +	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
> +
> +	err = icc_provider_add(&emc->provider);
> +	if (err)
> +		goto err_msg;
> +
> +	/* create External Memory Controller node */
> +	node = icc_node_create(TEGRA_ICC_EMC);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto del_provider;
> +
> +	node->name = "External Memory Controller";
> +	icc_node_add(node, &emc->provider);
> +
> +	/* link External Memory Controller to External Memory (DRAM) */
> +	err = icc_link_create(node, TEGRA_ICC_EMEM);
> +	if (err)
> +		goto remove_nodes;
> +
> +	/* create External Memory node */
> +	node = icc_node_create(TEGRA_ICC_EMEM);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto remove_nodes;
> +
> +	node->name = "External Memory (DRAM)";
> +	icc_node_add(node, &emc->provider);
> +
> +	return 0;
> +
> +remove_nodes:
> +	icc_nodes_remove(&emc->provider);
> +del_provider:
> +	icc_provider_del(&emc->provider);
> +err_msg:
> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);

You will print such errors on all existing DTBs. Since it is not a
failure of probe (it is actually quite expected, normal situation when
booting with older DTB), let's change it to warning (here and in all
other places and drivers).

> +
> +	return err;
> +}
> +
> +static int tegra_emc_opp_table_init(struct tegra_emc *emc)
> +{
> +	const char *rname = "core";
> +	int err;
> +
> +	/*
> +	 * Legacy device-trees don't have OPP table and EMC driver isn't
> +	 * useful in this case.
> +	 */
> +	if (!device_property_present(emc->dev, "operating-points-v2")) {
> +		dev_err(emc->dev, "OPP table not found\n");
> +		dev_err(emc->dev, "please update your device tree\n");
> +		return -ENODEV;
> +	}
> +
> +	/* voltage scaling is optional */
> +	if (device_property_present(emc->dev, "core-supply"))
> +		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
> +	else
> +		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
> +
> +	if (IS_ERR(emc->opp_table))
> +		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
> +				     "failed to prepare OPP table\n");
> +
> +	err = dev_pm_opp_of_add_table(emc->dev);
> +	if (err) {
> +		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
> +		goto put_table;
> +	}
> +
> +	return 0;
> +
> +put_table:
> +	dev_pm_opp_put_opp_table(emc->opp_table);
> +
> +	return err;
> +}
> +
>  static int tegra_emc_probe(struct platform_device *pdev)
>  {
>  	struct device_node *np;
> @@ -717,8 +885,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
>  		goto unset_cb;
>  	}
>  
> +	err = tegra_emc_opp_table_init(emc);
> +	if (err)
> +		goto unreg_notifier;

This looks like the ABI break I mentioned around DT bindings. Are the
bindings marked as unstable?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
@ 2020-10-27 10:09     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 10:09 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:16AM +0300, Dmitry Osipenko wrote:
> Now Internal and External Memory Controllers are memory interconnection
> providers. This allows us to use interconnect API for tuning of memory
> configuration. EMC driver now supports OPPs and DVFS.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig       |   3 +-
>  drivers/memory/tegra/mc.h          |  12 ++
>  drivers/memory/tegra/tegra20-emc.c | 176 +++++++++++++++++++++++++++++
>  drivers/memory/tegra/tegra20.c     |  34 ++++++
>  4 files changed, 224 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> index ff426747cd7d..ac3dfe155505 100644
> --- a/drivers/memory/tegra/Kconfig
> +++ b/drivers/memory/tegra/Kconfig
> @@ -11,7 +11,8 @@ config TEGRA_MC
>  config TEGRA20_EMC
>  	tristate "NVIDIA Tegra20 External Memory Controller driver"
>  	default y
> -	depends on ARCH_TEGRA_2x_SOC
> +	depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
> +	select PM_OPP
>  	help
>  	  This driver is for the External Memory Controller (EMC) found on
>  	  Tegra20 chips. The EMC controls the external DRAM on the board.
> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> index abeb6a2cc36a..531fb4fb7b17 100644
> --- a/drivers/memory/tegra/mc.h
> +++ b/drivers/memory/tegra/mc.h
> @@ -78,6 +78,18 @@
>  
>  #define MC_TIMING_UPDATE				BIT(0)
>  
> +static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
> +{
> +	val = val * percents;
> +	do_div(val, 100);
> +
> +	/*
> +	 * High freq + high boosting percent + large polling interval are
> +	 * resulting in integer overflow when watermarks are calculated.
> +	 */
> +	return min_t(u64, val, U32_MAX);
> +}
> +
>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
>  {
>  	return readl_relaxed(mc->regs + offset);
> diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
> index 34085e26dced..69ccb3fe5b0b 100644
> --- a/drivers/memory/tegra/tegra20-emc.c
> +++ b/drivers/memory/tegra/tegra20-emc.c
> @@ -9,6 +9,7 @@
>  #include <linux/clk/tegra.h>
>  #include <linux/debugfs.h>
>  #include <linux/err.h>
> +#include <linux/interconnect-provider.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
> @@ -16,11 +17,15 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/slab.h>
>  #include <linux/sort.h>
>  #include <linux/types.h>
>  
>  #include <soc/tegra/fuse.h>
>  
> +#include "mc.h"
> +
>  #define EMC_INTSTATUS				0x000
>  #define EMC_INTMASK				0x004
>  #define EMC_DBG					0x008
> @@ -144,6 +149,9 @@ struct emc_timing {
>  
>  struct tegra_emc {
>  	struct device *dev;
> +	struct tegra_mc *mc;
> +	struct opp_table *opp_table;
> +	struct icc_provider provider;
>  	struct notifier_block clk_nb;
>  	struct clk *clk;
>  	void __iomem *regs;
> @@ -658,6 +666,166 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
>  			    emc, &tegra_emc_debug_max_rate_fops);
>  }
>  
> +static inline struct tegra_emc *
> +to_tegra_emc_provider(struct icc_provider *provider)
> +{
> +	return container_of(provider, struct tegra_emc, provider);
> +}
> +
> +static struct icc_node_data *
> +emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
> +{
> +	struct icc_provider *provider = data;
> +	struct icc_node_data *ndata;
> +	struct icc_node *node;
> +
> +	/* External Memory is the only possible ICC route */
> +	list_for_each_entry(node, &provider->nodes, node_list) {
> +		if (node->id != TEGRA_ICC_EMEM)
> +			continue;
> +
> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> +		if (!ndata)
> +			return ERR_PTR(-ENOMEM);
> +
> +		/*
> +		 * SRC and DST nodes should have matching TAG in order to have
> +		 * it set by default for a requested path.
> +		 */
> +		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> +		ndata->node = node;
> +
> +		return ndata;
> +	}
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
> +	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
> +	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
> +	unsigned long long rate = max(avg_bw, peak_bw);
> +	unsigned int dram_data_bus_width_bytes = 4;
> +	long rounded_rate;
> +	int err;
> +
> +	/*
> +	 * Tegra20 EMC runs on x2 clock rate of SDRAM bus because DDR data
> +	 * is sampled on both clock edges. This means that EMC clock rate
> +	 * equals to the peak data rate.
> +	 */
> +	do_div(rate, dram_data_bus_width_bytes);
> +	rate = min_t(u64, rate, U32_MAX);
> +
> +	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
> +	if (rounded_rate < 0)
> +		return rounded_rate;
> +
> +	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
> +	if (err)
> +		return err;
> +
> +	return 0;
> +}
> +
> +static int tegra_emc_interconnect_init(struct tegra_emc *emc)
> +{
> +	const struct tegra_mc_soc *soc;
> +	struct icc_node *node;
> +	int err;
> +
> +	emc->mc = devm_tegra_get_memory_controller(emc->dev);
> +	if (IS_ERR(emc->mc))
> +		return PTR_ERR(emc->mc);
> +
> +	soc = emc->mc->soc;
> +
> +	emc->provider.dev = emc->dev;
> +	emc->provider.set = emc_icc_set;
> +	emc->provider.data = &emc->provider;
> +	emc->provider.aggregate = soc->icc_ops->aggregate;
> +	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
> +
> +	err = icc_provider_add(&emc->provider);
> +	if (err)
> +		goto err_msg;
> +
> +	/* create External Memory Controller node */
> +	node = icc_node_create(TEGRA_ICC_EMC);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto del_provider;
> +
> +	node->name = "External Memory Controller";
> +	icc_node_add(node, &emc->provider);
> +
> +	/* link External Memory Controller to External Memory (DRAM) */
> +	err = icc_link_create(node, TEGRA_ICC_EMEM);
> +	if (err)
> +		goto remove_nodes;
> +
> +	/* create External Memory node */
> +	node = icc_node_create(TEGRA_ICC_EMEM);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto remove_nodes;
> +
> +	node->name = "External Memory (DRAM)";
> +	icc_node_add(node, &emc->provider);
> +
> +	return 0;
> +
> +remove_nodes:
> +	icc_nodes_remove(&emc->provider);
> +del_provider:
> +	icc_provider_del(&emc->provider);
> +err_msg:
> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);

You will print such errors on all existing DTBs. Since it is not a
failure of probe (it is actually quite expected, normal situation when
booting with older DTB), let's change it to warning (here and in all
other places and drivers).

> +
> +	return err;
> +}
> +
> +static int tegra_emc_opp_table_init(struct tegra_emc *emc)
> +{
> +	const char *rname = "core";
> +	int err;
> +
> +	/*
> +	 * Legacy device-trees don't have OPP table and EMC driver isn't
> +	 * useful in this case.
> +	 */
> +	if (!device_property_present(emc->dev, "operating-points-v2")) {
> +		dev_err(emc->dev, "OPP table not found\n");
> +		dev_err(emc->dev, "please update your device tree\n");
> +		return -ENODEV;
> +	}
> +
> +	/* voltage scaling is optional */
> +	if (device_property_present(emc->dev, "core-supply"))
> +		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
> +	else
> +		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
> +
> +	if (IS_ERR(emc->opp_table))
> +		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
> +				     "failed to prepare OPP table\n");
> +
> +	err = dev_pm_opp_of_add_table(emc->dev);
> +	if (err) {
> +		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
> +		goto put_table;
> +	}
> +
> +	return 0;
> +
> +put_table:
> +	dev_pm_opp_put_opp_table(emc->opp_table);
> +
> +	return err;
> +}
> +
>  static int tegra_emc_probe(struct platform_device *pdev)
>  {
>  	struct device_node *np;
> @@ -717,8 +885,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
>  		goto unset_cb;
>  	}
>  
> +	err = tegra_emc_opp_table_init(emc);
> +	if (err)
> +		goto unreg_notifier;

This looks like the ABI break I mentioned around DT bindings. Are the
bindings marked as unstable?

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27 10:25     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 10:25 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
> External memory controller is interconnected with memory controller and
> with external memory. Document new interconnect property which turns
> External Memory Controller into interconnect provider.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> index 278549f9e051..ac00832ceac1 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> @@ -29,6 +29,9 @@ properties:
>      items:
>        - const: emc
>  
> +  "#interconnect-cells":
> +    const: 0
> +
>    nvidia,memory-controller:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description:
> @@ -327,6 +330,7 @@ required:
>    - clocks
>    - clock-names
>    - nvidia,memory-controller
> +  - "#interconnect-cells"

Another required property, what about all existing users of this binding?

>  
>  additionalProperties: false
>  
> @@ -345,6 +349,7 @@ examples:
>  
>          #iommu-cells = <1>;
>          #reset-cells = <1>;
> +        #interconnect-cells = <1>;

You meant '0'?

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
@ 2020-10-27 10:25     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 10:25 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
> External memory controller is interconnected with memory controller and
> with external memory. Document new interconnect property which turns
> External Memory Controller into interconnect provider.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> index 278549f9e051..ac00832ceac1 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> @@ -29,6 +29,9 @@ properties:
>      items:
>        - const: emc
>  
> +  "#interconnect-cells":
> +    const: 0
> +
>    nvidia,memory-controller:
>      $ref: /schemas/types.yaml#/definitions/phandle
>      description:
> @@ -327,6 +330,7 @@ required:
>    - clocks
>    - clock-names
>    - nvidia,memory-controller
> +  - "#interconnect-cells"

Another required property, what about all existing users of this binding?

>  
>  additionalProperties: false
>  
> @@ -345,6 +349,7 @@ examples:
>  
>          #iommu-cells = <1>;
>          #reset-cells = <1>;
> +        #interconnect-cells = <1>;

You meant '0'?

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 10:27     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 10:27 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:17:24AM +0300, Dmitry Osipenko wrote:
> Use devm_platform_ioremap_resource() helper which makes code a bit
> cleaner.

Such cleanups (and few other in this patchset) should be at beginning of
patchset or even as part of a separate one.  I think there is not much
stopping anyone from applying these... except that you put them in the
middle of big dependency.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
@ 2020-10-27 10:27     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 10:27 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Mon, Oct 26, 2020 at 01:17:24AM +0300, Dmitry Osipenko wrote:
> Use devm_platform_ioremap_resource() helper which makes code a bit
> cleaner.

Such cleanups (and few other in this patchset) should be at beginning of
patchset or even as part of a separate one.  I think there is not much
stopping anyone from applying these... except that you put them in the
middle of big dependency.

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 01/52] clk: tegra: Export Tegra20 EMC kernel symbols
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27 13:04     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:04 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 392 bytes --]

On Mon, Oct 26, 2020 at 01:16:44AM +0300, Dmitry Osipenko wrote:
> We're going to modularize Tegra EMC drivers and some of the EMC clk driver
> symbols need to be exported, let's export them.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/clk/tegra/clk-tegra20-emc.c | 3 +++
>  1 file changed, 3 insertions(+)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 01/52] clk: tegra: Export Tegra20 EMC kernel symbols
@ 2020-10-27 13:04     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:04 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 392 bytes --]

On Mon, Oct 26, 2020 at 01:16:44AM +0300, Dmitry Osipenko wrote:
> We're going to modularize Tegra EMC drivers and some of the EMC clk driver
> symbols need to be exported, let's export them.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/clk/tegra/clk-tegra20-emc.c | 3 +++
>  1 file changed, 3 insertions(+)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 02/52] soc/tegra: fuse: Export tegra_read_ram_code()
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27 13:17     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:17 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 517 bytes --]

On Mon, Oct 26, 2020 at 01:16:45AM +0300, Dmitry Osipenko wrote:
> The tegra_read_ram_code() is used by EMC drivers and we're going to make
> these driver modular, hence this function needs to be exported.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/soc/tegra/fuse/tegra-apbmisc.c | 2 ++
>  1 file changed, 2 insertions(+)

I'm not a big fan of exporting yet another of these tiny helpers, but I
don't have any better ideas, so:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 02/52] soc/tegra: fuse: Export tegra_read_ram_code()
@ 2020-10-27 13:17     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:17 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 517 bytes --]

On Mon, Oct 26, 2020 at 01:16:45AM +0300, Dmitry Osipenko wrote:
> The tegra_read_ram_code() is used by EMC drivers and we're going to make
> these driver modular, hence this function needs to be exported.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/soc/tegra/fuse/tegra-apbmisc.c | 2 ++
>  1 file changed, 2 insertions(+)

I'm not a big fan of exporting yet another of these tiny helpers, but I
don't have any better ideas, so:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 03/52] dt-bindings: memory: tegra20: emc: Correct registers range in example
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27 13:18     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 409 bytes --]

On Mon, Oct 26, 2020 at 01:16:46AM +0300, Dmitry Osipenko wrote:
> There is superfluous zero in the registers base address and registers
> size should be twice bigger.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 03/52] dt-bindings: memory: tegra20: emc: Correct registers range in example
@ 2020-10-27 13:18     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:18 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 409 bytes --]

On Mon, Oct 26, 2020 at 01:16:46AM +0300, Dmitry Osipenko wrote:
> There is superfluous zero in the registers base address and registers
> size should be twice bigger.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-27 13:22     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:22 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 997 bytes --]

On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
> External Memory Controller can gather various hardware statistics that
> are intended to be used for debugging purposes and for dynamic frequency
> scaling of memory bus.
> 
> Document the new mfd-simple compatible and EMC statistics sub-device.
> The subdev contains EMC DFS OPP table and interconnect paths to be used
> for dynamic scaling of system's memory bandwidth based on EMC utilization
> statistics.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>  1 file changed, 40 insertions(+), 3 deletions(-)

Why does this have to be modelled as a separate device? Isn't this just
using a couple of registers out of the EMC register range? If so, this
would better just be integrated into the parent node and implemented as
part of the EMC driver. No need to further complicate things by adding
a dummy child.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-27 13:22     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:22 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 997 bytes --]

On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
> External Memory Controller can gather various hardware statistics that
> are intended to be used for debugging purposes and for dynamic frequency
> scaling of memory bus.
> 
> Document the new mfd-simple compatible and EMC statistics sub-device.
> The subdev contains EMC DFS OPP table and interconnect paths to be used
> for dynamic scaling of system's memory bandwidth based on EMC utilization
> statistics.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>  1 file changed, 40 insertions(+), 3 deletions(-)

Why does this have to be modelled as a separate device? Isn't this just
using a couple of registers out of the EMC register range? If so, this
would better just be integrated into the parent node and implemented as
part of the EMC driver. No need to further complicate things by adding
a dummy child.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 21/52] ARM: tegra: Add interconnect properties to Tegra20 device-tree
  2020-10-27  9:12     ` Krzysztof Kozlowski
@ 2020-10-27 13:30       ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:30 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Dmitry Osipenko, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 1137 bytes --]

On Tue, Oct 27, 2020 at 10:12:47AM +0100, Krzysztof Kozlowski wrote:
> On Mon, Oct 26, 2020 at 01:17:04AM +0300, Dmitry Osipenko wrote:
> > Add interconnect properties to the Memory Controller, External Memory
> > Controller and the Display Controller nodes in order to describe hardware
> > interconnection.
> > 
> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > ---
> >  arch/arm/boot/dts/tegra20.dtsi | 26 +++++++++++++++++++++++++-
> >  1 file changed, 25 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> > index 9347f7789245..2e1304493f7d 100644
> > --- a/arch/arm/boot/dts/tegra20.dtsi
> > +++ b/arch/arm/boot/dts/tegra20.dtsi
> > @@ -111,6 +111,17 @@ dc@54200000 {
> >  
> >  			nvidia,head = <0>;
> >  
> > +			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
> 
> I think you just added the defines and did not include them here, so
> this should not even build. Did you test it?

The dt-bindings/memory/tegra20-mc.h header is already included in
existing DTS files for MC hot flush resets, so this should be fine.

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 21/52] ARM: tegra: Add interconnect properties to Tegra20 device-tree
@ 2020-10-27 13:30       ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:30 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, dri-devel, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Dmitry Osipenko, Georgi Djakov, devicetree


[-- Attachment #1.1: Type: text/plain, Size: 1137 bytes --]

On Tue, Oct 27, 2020 at 10:12:47AM +0100, Krzysztof Kozlowski wrote:
> On Mon, Oct 26, 2020 at 01:17:04AM +0300, Dmitry Osipenko wrote:
> > Add interconnect properties to the Memory Controller, External Memory
> > Controller and the Display Controller nodes in order to describe hardware
> > interconnection.
> > 
> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > ---
> >  arch/arm/boot/dts/tegra20.dtsi | 26 +++++++++++++++++++++++++-
> >  1 file changed, 25 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
> > index 9347f7789245..2e1304493f7d 100644
> > --- a/arch/arm/boot/dts/tegra20.dtsi
> > +++ b/arch/arm/boot/dts/tegra20.dtsi
> > @@ -111,6 +111,17 @@ dc@54200000 {
> >  
> >  			nvidia,head = <0>;
> >  
> > +			interconnects = <&mc TEGRA20_MC_DISPLAY0A &emc>,
> 
> I think you just added the defines and did not include them here, so
> this should not even build. Did you test it?

The dt-bindings/memory/tegra20-mc.h header is already included in
existing DTS files for MC hot flush resets, so this should be fine.

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 13:35     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 913 bytes --]

On Mon, Oct 26, 2020 at 01:17:11AM +0300, Dmitry Osipenko wrote:
> Multiple Tegra drivers need to retrieve Memory Controller and there is
> duplication of the retrieval code among the drivers. This patch removes
> the duplication and fixes put_device() which was missed in the duplicated
> code.
> 
> EMC drivers now use new common devm_tegra_get_memory_controller() helper
> instead of opencoding the MC retrieval.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
>  drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
>  drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
>  drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
>  include/soc/tegra/mc.h                   | 10 +++++
>  5 files changed, 74 insertions(+), 59 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
@ 2020-10-27 13:35     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:35 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 913 bytes --]

On Mon, Oct 26, 2020 at 01:17:11AM +0300, Dmitry Osipenko wrote:
> Multiple Tegra drivers need to retrieve Memory Controller and there is
> duplication of the retrieval code among the drivers. This patch removes
> the duplication and fixes put_device() which was missed in the duplicated
> code.
> 
> EMC drivers now use new common devm_tegra_get_memory_controller() helper
> instead of opencoding the MC retrieval.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
>  drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
>  drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
>  drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
>  include/soc/tegra/mc.h                   | 10 +++++
>  5 files changed, 74 insertions(+), 59 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 29/52] memory: tegra-mc: Add interconnect framework
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 13:48     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:48 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 7304 bytes --]

On Mon, Oct 26, 2020 at 01:17:12AM +0300, Dmitry Osipenko wrote:
> Now Memory Controller is a memory interconnection provider. This allows
> us to use interconnect API for tuning of memory configuration. This patch
> adds common ICC core and adds hooks which should be implemented by the SoC
> drivers.
> 
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig |   1 +
>  drivers/memory/tegra/mc.c    | 129 +++++++++++++++++++++++++++++++++++
>  drivers/memory/tegra/mc.h    |   8 +++
>  include/soc/tegra/mc.h       |  16 +++++
>  4 files changed, 154 insertions(+)
> 
> diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> index 9f0a96bf9ccc..b38e5255effe 100644
> --- a/drivers/memory/tegra/Kconfig
> +++ b/drivers/memory/tegra/Kconfig
> @@ -3,6 +3,7 @@ config TEGRA_MC
>  	bool "NVIDIA Tegra Memory Controller support"
>  	default y
>  	depends on ARCH_TEGRA
> +	select INTERCONNECT
>  	help
>  	  This driver supports the Memory Controller (MC) hardware found on
>  	  NVIDIA Tegra SoCs.
> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
> index 12ea2c79205a..53d61b05ebf8 100644
> --- a/drivers/memory/tegra/mc.c
> +++ b/drivers/memory/tegra/mc.c
> @@ -639,6 +639,133 @@ static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
>  	return IRQ_HANDLED;
>  }
>  
> +static struct icc_node_data *
> +tegra_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
> +{
> +	struct icc_provider *provider = data;
> +	unsigned int idx = spec->args[0];
> +	struct icc_node_data *ndata;
> +	struct icc_node *node;
> +
> +	list_for_each_entry(node, &provider->nodes, node_list) {
> +		if (node->id != idx)
> +			continue;
> +
> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> +		if (!ndata)
> +			return ERR_PTR(-ENOMEM);
> +
> +		ndata->node = node;
> +
> +		/* these clients are isochronous by default on all SoCs */
> +		if (strstarts(node->name, "display") ||
> +		    strstarts(node->name, "ptc") ||
> +		    strstarts(node->name, "vi"))
> +			ndata->tag = TEGRA_MC_ICC_TAG_ISO;

This looks like something that might be better left to the drivers to
decide. Doing this here seems okay for now, but I suspect that this will
get fairly complicated to keep accurate as we add more clients later on.

> +
> +		return ndata;
> +	}
> +
> +	pr_err("%s: invalid client index %u\n", __func__, idx);

Perhaps use "dev_err(provider->dev, ...);"?

> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +/*
> + * Memory Controller (MC) has few Memory Clients that are issuing memory
> + * bandwidth allocation requests to the MC interconnect provider. The MC
> + * provider aggregates the requests and then sends the aggregated request
> + * up to the External Memory Controller (EMC) interconnect provider which
> + * re-configures hardware interface to External Memory (EMEM) in accordance
> + * to the required bandwidth. Each MC interconnect node represents an
> + * individual Memory Client.
> + *
> + * Memory interconnect topology:
> + *
> + *               +----+
> + * +--------+    |    |
> + * | TEXSRD +--->+    |
> + * +--------+    |    |
> + *               |    |    +-----+    +------+
> + *    ...        | MC +--->+ EMC +--->+ EMEM |
> + *               |    |    +-----+    +------+
> + * +--------+    |    |
> + * | DISP.. +--->+    |
> + * +--------+    |    |
> + *               +----+
> + */
> +static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
> +{
> +	struct icc_node *node;
> +	unsigned int i;
> +	int err;
> +
> +	/* older device-trees don't have interconnect properties */
> +	if (!of_find_property(mc->dev->of_node, "#interconnect-cells", NULL) ||
> +	    !mc->soc->icc_ops)
> +		return 0;

This indicates that this property is indeed optional, so the bindings
should reflect that.

> +
> +	mc->provider.dev = mc->dev;
> +	mc->provider.data = &mc->provider;
> +	mc->provider.set = mc->soc->icc_ops->set;
> +	mc->provider.aggregate = mc->soc->icc_ops->aggregate;
> +	mc->provider.xlate_extended = tegra_mc_of_icc_xlate_extended;
> +
> +	err = icc_provider_add(&mc->provider);
> +	if (err)
> +		goto err_msg;
> +
> +	/* create Memory Controller node */
> +	node = icc_node_create(TEGRA_ICC_MC);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto del_provider;
> +
> +	node->name = "Memory Controller";
> +	icc_node_add(node, &mc->provider);
> +
> +	/* link Memory Controller to External Memory Controller */
> +	err = icc_link_create(node, TEGRA_ICC_EMC);
> +	if (err)
> +		goto remove_nodes;
> +
> +	for (i = 0; i < mc->soc->num_clients; i++) {
> +		/* create MC client node */
> +		node = icc_node_create(mc->soc->clients[i].id);
> +		err = PTR_ERR_OR_ZERO(node);
> +		if (err)
> +			goto remove_nodes;
> +
> +		node->name = mc->soc->clients[i].name;
> +		icc_node_add(node, &mc->provider);

I'm not fully familiar with how these nodes are set up, but would it be
possible to set the isochronous tag here already? I'd still prefer this
to be up to the drivers because I think that nicely localizes the
device-specific information in the driver, but if that's not an option,
then doing it here, based on lookup data from the MC clients table
sounds like the next best thing.

> +		/* link Memory Client to Memory Controller */
> +		err = icc_link_create(node, TEGRA_ICC_MC);
> +		if (err)
> +			goto remove_nodes;
> +	}
> +
> +	/*
> +	 * MC driver is registered too early, so early that generic driver
> +	 * syncing doesn't work for the MC. But it doesn't really matter
> +	 * since syncing works for the EMC drivers, hence the we can sync
> +	 * the MC driver by ourselves and then EMC will complete syncing of
> +	 * the whole ICC state.
> +	 */
> +	icc_sync_state(mc->dev);
> +
> +	return 0;
> +
> +remove_nodes:
> +	icc_nodes_remove(&mc->provider);
> +del_provider:
> +	icc_provider_del(&mc->provider);
> +err_msg:
> +	dev_err(mc->dev, "failed to initialize ICC: %d\n", err);
> +
> +	return err;
> +}
> +
>  static int tegra_mc_probe(struct platform_device *pdev)
>  {
>  	struct resource *res;
> @@ -747,6 +874,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> +	tegra_mc_interconnect_setup(mc);

Do you want to check the return value here for errors? If not, might as
well make the function return void.

> +
>  	return 0;
>  }
>  
> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> index afa3ba45c9e6..abeb6a2cc36a 100644
> --- a/drivers/memory/tegra/mc.h
> +++ b/drivers/memory/tegra/mc.h
> @@ -115,4 +115,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
>  extern const struct tegra_mc_soc tegra210_mc_soc;
>  #endif
>  
> +/*
> + * These IDs are for internal use of Tegra's ICC, the values are chosen
> + * such that they don't conflict with the device-tree ICC node IDs.
> + */
> +#define TEGRA_ICC_EMC		1000
> +#define TEGRA_ICC_EMEM		2000
> +#define TEGRA_ICC_MC		3000

Sounds to me like these could equally well be 1000, 1001 and 1002. Why
leave these large holes in the number space?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 29/52] memory: tegra-mc: Add interconnect framework
@ 2020-10-27 13:48     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:48 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 7304 bytes --]

On Mon, Oct 26, 2020 at 01:17:12AM +0300, Dmitry Osipenko wrote:
> Now Memory Controller is a memory interconnection provider. This allows
> us to use interconnect API for tuning of memory configuration. This patch
> adds common ICC core and adds hooks which should be implemented by the SoC
> drivers.
> 
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig |   1 +
>  drivers/memory/tegra/mc.c    | 129 +++++++++++++++++++++++++++++++++++
>  drivers/memory/tegra/mc.h    |   8 +++
>  include/soc/tegra/mc.h       |  16 +++++
>  4 files changed, 154 insertions(+)
> 
> diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> index 9f0a96bf9ccc..b38e5255effe 100644
> --- a/drivers/memory/tegra/Kconfig
> +++ b/drivers/memory/tegra/Kconfig
> @@ -3,6 +3,7 @@ config TEGRA_MC
>  	bool "NVIDIA Tegra Memory Controller support"
>  	default y
>  	depends on ARCH_TEGRA
> +	select INTERCONNECT
>  	help
>  	  This driver supports the Memory Controller (MC) hardware found on
>  	  NVIDIA Tegra SoCs.
> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
> index 12ea2c79205a..53d61b05ebf8 100644
> --- a/drivers/memory/tegra/mc.c
> +++ b/drivers/memory/tegra/mc.c
> @@ -639,6 +639,133 @@ static __maybe_unused irqreturn_t tegra20_mc_irq(int irq, void *data)
>  	return IRQ_HANDLED;
>  }
>  
> +static struct icc_node_data *
> +tegra_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
> +{
> +	struct icc_provider *provider = data;
> +	unsigned int idx = spec->args[0];
> +	struct icc_node_data *ndata;
> +	struct icc_node *node;
> +
> +	list_for_each_entry(node, &provider->nodes, node_list) {
> +		if (node->id != idx)
> +			continue;
> +
> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> +		if (!ndata)
> +			return ERR_PTR(-ENOMEM);
> +
> +		ndata->node = node;
> +
> +		/* these clients are isochronous by default on all SoCs */
> +		if (strstarts(node->name, "display") ||
> +		    strstarts(node->name, "ptc") ||
> +		    strstarts(node->name, "vi"))
> +			ndata->tag = TEGRA_MC_ICC_TAG_ISO;

This looks like something that might be better left to the drivers to
decide. Doing this here seems okay for now, but I suspect that this will
get fairly complicated to keep accurate as we add more clients later on.

> +
> +		return ndata;
> +	}
> +
> +	pr_err("%s: invalid client index %u\n", __func__, idx);

Perhaps use "dev_err(provider->dev, ...);"?

> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +/*
> + * Memory Controller (MC) has few Memory Clients that are issuing memory
> + * bandwidth allocation requests to the MC interconnect provider. The MC
> + * provider aggregates the requests and then sends the aggregated request
> + * up to the External Memory Controller (EMC) interconnect provider which
> + * re-configures hardware interface to External Memory (EMEM) in accordance
> + * to the required bandwidth. Each MC interconnect node represents an
> + * individual Memory Client.
> + *
> + * Memory interconnect topology:
> + *
> + *               +----+
> + * +--------+    |    |
> + * | TEXSRD +--->+    |
> + * +--------+    |    |
> + *               |    |    +-----+    +------+
> + *    ...        | MC +--->+ EMC +--->+ EMEM |
> + *               |    |    +-----+    +------+
> + * +--------+    |    |
> + * | DISP.. +--->+    |
> + * +--------+    |    |
> + *               +----+
> + */
> +static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
> +{
> +	struct icc_node *node;
> +	unsigned int i;
> +	int err;
> +
> +	/* older device-trees don't have interconnect properties */
> +	if (!of_find_property(mc->dev->of_node, "#interconnect-cells", NULL) ||
> +	    !mc->soc->icc_ops)
> +		return 0;

This indicates that this property is indeed optional, so the bindings
should reflect that.

> +
> +	mc->provider.dev = mc->dev;
> +	mc->provider.data = &mc->provider;
> +	mc->provider.set = mc->soc->icc_ops->set;
> +	mc->provider.aggregate = mc->soc->icc_ops->aggregate;
> +	mc->provider.xlate_extended = tegra_mc_of_icc_xlate_extended;
> +
> +	err = icc_provider_add(&mc->provider);
> +	if (err)
> +		goto err_msg;
> +
> +	/* create Memory Controller node */
> +	node = icc_node_create(TEGRA_ICC_MC);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto del_provider;
> +
> +	node->name = "Memory Controller";
> +	icc_node_add(node, &mc->provider);
> +
> +	/* link Memory Controller to External Memory Controller */
> +	err = icc_link_create(node, TEGRA_ICC_EMC);
> +	if (err)
> +		goto remove_nodes;
> +
> +	for (i = 0; i < mc->soc->num_clients; i++) {
> +		/* create MC client node */
> +		node = icc_node_create(mc->soc->clients[i].id);
> +		err = PTR_ERR_OR_ZERO(node);
> +		if (err)
> +			goto remove_nodes;
> +
> +		node->name = mc->soc->clients[i].name;
> +		icc_node_add(node, &mc->provider);

I'm not fully familiar with how these nodes are set up, but would it be
possible to set the isochronous tag here already? I'd still prefer this
to be up to the drivers because I think that nicely localizes the
device-specific information in the driver, but if that's not an option,
then doing it here, based on lookup data from the MC clients table
sounds like the next best thing.

> +		/* link Memory Client to Memory Controller */
> +		err = icc_link_create(node, TEGRA_ICC_MC);
> +		if (err)
> +			goto remove_nodes;
> +	}
> +
> +	/*
> +	 * MC driver is registered too early, so early that generic driver
> +	 * syncing doesn't work for the MC. But it doesn't really matter
> +	 * since syncing works for the EMC drivers, hence the we can sync
> +	 * the MC driver by ourselves and then EMC will complete syncing of
> +	 * the whole ICC state.
> +	 */
> +	icc_sync_state(mc->dev);
> +
> +	return 0;
> +
> +remove_nodes:
> +	icc_nodes_remove(&mc->provider);
> +del_provider:
> +	icc_provider_del(&mc->provider);
> +err_msg:
> +	dev_err(mc->dev, "failed to initialize ICC: %d\n", err);
> +
> +	return err;
> +}
> +
>  static int tegra_mc_probe(struct platform_device *pdev)
>  {
>  	struct resource *res;
> @@ -747,6 +874,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> +	tegra_mc_interconnect_setup(mc);

Do you want to check the return value here for errors? If not, might as
well make the function return void.

> +
>  	return 0;
>  }
>  
> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> index afa3ba45c9e6..abeb6a2cc36a 100644
> --- a/drivers/memory/tegra/mc.h
> +++ b/drivers/memory/tegra/mc.h
> @@ -115,4 +115,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
>  extern const struct tegra_mc_soc tegra210_mc_soc;
>  #endif
>  
> +/*
> + * These IDs are for internal use of Tegra's ICC, the values are chosen
> + * such that they don't conflict with the device-tree ICC node IDs.
> + */
> +#define TEGRA_ICC_EMC		1000
> +#define TEGRA_ICC_EMEM		2000
> +#define TEGRA_ICC_MC		3000

Sounds to me like these could equally well be 1000, 1001 and 1002. Why
leave these large holes in the number space?

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 30/52] memory: tegra20-emc: Make driver modular
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 13:49     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 470 bytes --]

On Mon, Oct 26, 2020 at 01:17:13AM +0300, Dmitry Osipenko wrote:
> This patch adds modularization support to the Tegra20 EMC driver. Driver
> now can be compiled as a loadable kernel module.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig       |  2 +-
>  drivers/memory/tegra/tegra20-emc.c | 17 ++++++++++++-----
>  2 files changed, 13 insertions(+), 6 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 30/52] memory: tegra20-emc: Make driver modular
@ 2020-10-27 13:49     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:49 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 470 bytes --]

On Mon, Oct 26, 2020 at 01:17:13AM +0300, Dmitry Osipenko wrote:
> This patch adds modularization support to the Tegra20 EMC driver. Driver
> now can be compiled as a loadable kernel module.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig       |  2 +-
>  drivers/memory/tegra/tegra20-emc.c | 17 ++++++++++++-----
>  2 files changed, 13 insertions(+), 6 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 31/52] memory: tegra20-emc: Use devm_platform_ioremap_resource()
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 13:50     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:50 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 607 bytes --]

On Mon, Oct 26, 2020 at 01:17:14AM +0300, Dmitry Osipenko wrote:
> Use devm_platform_ioremap_resource() helper which makes code a bit
> cleaner.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/tegra20-emc.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)

I'm not a fan of this helper, to be honest, because I think all the
churn that we've seen with the conversions isn't really worth the 1 or 2
lines that it saves, but hey, looks like this is pretty broadly
accepted, so if Krzysztof likes it:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 31/52] memory: tegra20-emc: Use devm_platform_ioremap_resource()
@ 2020-10-27 13:50     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:50 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 607 bytes --]

On Mon, Oct 26, 2020 at 01:17:14AM +0300, Dmitry Osipenko wrote:
> Use devm_platform_ioremap_resource() helper which makes code a bit
> cleaner.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/tegra20-emc.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)

I'm not a fan of this helper, to be honest, because I think all the
churn that we've seen with the conversions isn't really worth the 1 or 2
lines that it saves, but hey, looks like this is pretty broadly
accepted, so if Krzysztof likes it:

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 32/52] memory: tegra20-emc: Continue probing if timings are missing in device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 13:52     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:52 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 571 bytes --]

On Mon, Oct 26, 2020 at 01:17:15AM +0300, Dmitry Osipenko wrote:
> EMC driver will become mandatory after turning it into interconnect
> provider because interconnect users, like display controller driver, will
> fail to probe using newer device-trees that have interconnect properties.
> Thus make EMC driver to probe even if timings are missing in device-tree.

Does it really have to be mandatory? Sounds like that's going to make it
unnecessarily complicated to merge all of this. Is it complicated to
make interconnect support optional in consumer drivers?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 32/52] memory: tegra20-emc: Continue probing if timings are missing in device-tree
@ 2020-10-27 13:52     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 13:52 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 571 bytes --]

On Mon, Oct 26, 2020 at 01:17:15AM +0300, Dmitry Osipenko wrote:
> EMC driver will become mandatory after turning it into interconnect
> provider because interconnect users, like display controller driver, will
> fail to probe using newer device-trees that have interconnect properties.
> Thus make EMC driver to probe even if timings are missing in device-tree.

Does it really have to be mandatory? Sounds like that's going to make it
unnecessarily complicated to merge all of this. Is it complicated to
make interconnect support optional in consumer drivers?

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 31/52] memory: tegra20-emc: Use devm_platform_ioremap_resource()
  2020-10-27 13:50     ` Thierry Reding
@ 2020-10-27 13:57       ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 13:57 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Dmitry Osipenko, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, 27 Oct 2020 at 14:50, Thierry Reding <thierry.reding@gmail.com> wrote:
>
> On Mon, Oct 26, 2020 at 01:17:14AM +0300, Dmitry Osipenko wrote:
> > Use devm_platform_ioremap_resource() helper which makes code a bit
> > cleaner.
> >
> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > ---
> >  drivers/memory/tegra/tegra20-emc.c | 4 +---
> >  1 file changed, 1 insertion(+), 3 deletions(-)
>
> I'm not a fan of this helper, to be honest, because I think all the
> churn that we've seen with the conversions isn't really worth the 1 or 2
> lines that it saves, but hey, looks like this is pretty broadly
> accepted, so if Krzysztof likes it:
>
> Acked-by: Thierry Reding <treding@nvidia.com>

Such changes indeed do not bring much but still less local variables
and -1 line. I am fine with them. They also save one error msg from
devm_ioremap_resource() in case of platform_get_resource() failure.

Best regards,
Krzysztof

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 31/52] memory: tegra20-emc: Use devm_platform_ioremap_resource()
@ 2020-10-27 13:57       ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 13:57 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Peter De Schrijver, Mikko Perttunen, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, dri-devel, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Dmitry Osipenko, Georgi Djakov, devicetree

On Tue, 27 Oct 2020 at 14:50, Thierry Reding <thierry.reding@gmail.com> wrote:
>
> On Mon, Oct 26, 2020 at 01:17:14AM +0300, Dmitry Osipenko wrote:
> > Use devm_platform_ioremap_resource() helper which makes code a bit
> > cleaner.
> >
> > Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > ---
> >  drivers/memory/tegra/tegra20-emc.c | 4 +---
> >  1 file changed, 1 insertion(+), 3 deletions(-)
>
> I'm not a fan of this helper, to be honest, because I think all the
> churn that we've seen with the conversions isn't really worth the 1 or 2
> lines that it saves, but hey, looks like this is pretty broadly
> accepted, so if Krzysztof likes it:
>
> Acked-by: Thierry Reding <treding@nvidia.com>

Such changes indeed do not bring much but still less local variables
and -1 line. I am fine with them. They also save one error msg from
devm_ioremap_resource() in case of platform_get_resource() failure.

Best regards,
Krzysztof
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-27 14:11     ` Thierry Reding
  -1 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 14:11 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

[-- Attachment #1: Type: text/plain, Size: 11362 bytes --]

On Mon, Oct 26, 2020 at 01:17:16AM +0300, Dmitry Osipenko wrote:
> Now Internal and External Memory Controllers are memory interconnection
> providers. This allows us to use interconnect API for tuning of memory
> configuration. EMC driver now supports OPPs and DVFS.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig       |   3 +-
>  drivers/memory/tegra/mc.h          |  12 ++
>  drivers/memory/tegra/tegra20-emc.c | 176 +++++++++++++++++++++++++++++
>  drivers/memory/tegra/tegra20.c     |  34 ++++++
>  4 files changed, 224 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> index ff426747cd7d..ac3dfe155505 100644
> --- a/drivers/memory/tegra/Kconfig
> +++ b/drivers/memory/tegra/Kconfig
> @@ -11,7 +11,8 @@ config TEGRA_MC
>  config TEGRA20_EMC
>  	tristate "NVIDIA Tegra20 External Memory Controller driver"
>  	default y
> -	depends on ARCH_TEGRA_2x_SOC
> +	depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
> +	select PM_OPP
>  	help
>  	  This driver is for the External Memory Controller (EMC) found on
>  	  Tegra20 chips. The EMC controls the external DRAM on the board.
> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> index abeb6a2cc36a..531fb4fb7b17 100644
> --- a/drivers/memory/tegra/mc.h
> +++ b/drivers/memory/tegra/mc.h
> @@ -78,6 +78,18 @@
>  
>  #define MC_TIMING_UPDATE				BIT(0)
>  
> +static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
> +{
> +	val = val * percents;
> +	do_div(val, 100);
> +
> +	/*
> +	 * High freq + high boosting percent + large polling interval are
> +	 * resulting in integer overflow when watermarks are calculated.
> +	 */
> +	return min_t(u64, val, U32_MAX);
> +}
> +
>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
>  {
>  	return readl_relaxed(mc->regs + offset);
> diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
> index 34085e26dced..69ccb3fe5b0b 100644
> --- a/drivers/memory/tegra/tegra20-emc.c
> +++ b/drivers/memory/tegra/tegra20-emc.c
> @@ -9,6 +9,7 @@
>  #include <linux/clk/tegra.h>
>  #include <linux/debugfs.h>
>  #include <linux/err.h>
> +#include <linux/interconnect-provider.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
> @@ -16,11 +17,15 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/slab.h>
>  #include <linux/sort.h>
>  #include <linux/types.h>
>  
>  #include <soc/tegra/fuse.h>
>  
> +#include "mc.h"
> +
>  #define EMC_INTSTATUS				0x000
>  #define EMC_INTMASK				0x004
>  #define EMC_DBG					0x008
> @@ -144,6 +149,9 @@ struct emc_timing {
>  
>  struct tegra_emc {
>  	struct device *dev;
> +	struct tegra_mc *mc;
> +	struct opp_table *opp_table;
> +	struct icc_provider provider;
>  	struct notifier_block clk_nb;
>  	struct clk *clk;
>  	void __iomem *regs;
> @@ -658,6 +666,166 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
>  			    emc, &tegra_emc_debug_max_rate_fops);
>  }
>  
> +static inline struct tegra_emc *
> +to_tegra_emc_provider(struct icc_provider *provider)
> +{
> +	return container_of(provider, struct tegra_emc, provider);
> +}
> +
> +static struct icc_node_data *
> +emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
> +{
> +	struct icc_provider *provider = data;
> +	struct icc_node_data *ndata;
> +	struct icc_node *node;
> +
> +	/* External Memory is the only possible ICC route */
> +	list_for_each_entry(node, &provider->nodes, node_list) {
> +		if (node->id != TEGRA_ICC_EMEM)
> +			continue;
> +
> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> +		if (!ndata)
> +			return ERR_PTR(-ENOMEM);
> +
> +		/*
> +		 * SRC and DST nodes should have matching TAG in order to have
> +		 * it set by default for a requested path.
> +		 */
> +		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> +		ndata->node = node;
> +
> +		return ndata;
> +	}
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
> +	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
> +	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
> +	unsigned long long rate = max(avg_bw, peak_bw);
> +	unsigned int dram_data_bus_width_bytes = 4;

Perhaps use something shorter for this variable (like dram_bus_width)? Also,
since it's never modified, perhaps make it const? Or a #define?

> +	long rounded_rate;
> +	int err;
> +
> +	/*
> +	 * Tegra20 EMC runs on x2 clock rate of SDRAM bus because DDR data
> +	 * is sampled on both clock edges. This means that EMC clock rate
> +	 * equals to the peak data rate.
> +	 */
> +	do_div(rate, dram_data_bus_width_bytes);
> +	rate = min_t(u64, rate, U32_MAX);
> +
> +	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
> +	if (rounded_rate < 0)
> +		return rounded_rate;
> +
> +	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
> +	if (err)
> +		return err;
> +
> +	return 0;
> +}
> +
> +static int tegra_emc_interconnect_init(struct tegra_emc *emc)
> +{
> +	const struct tegra_mc_soc *soc;
> +	struct icc_node *node;
> +	int err;
> +
> +	emc->mc = devm_tegra_get_memory_controller(emc->dev);
> +	if (IS_ERR(emc->mc))
> +		return PTR_ERR(emc->mc);
> +
> +	soc = emc->mc->soc;
> +
> +	emc->provider.dev = emc->dev;
> +	emc->provider.set = emc_icc_set;
> +	emc->provider.data = &emc->provider;
> +	emc->provider.aggregate = soc->icc_ops->aggregate;
> +	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
> +
> +	err = icc_provider_add(&emc->provider);
> +	if (err)
> +		goto err_msg;
> +
> +	/* create External Memory Controller node */
> +	node = icc_node_create(TEGRA_ICC_EMC);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto del_provider;

As far as I can tell, icc_node_create() always returns either a valid
pointer or an ERR_PTR-encoded negative error-code. So I think the more
idiomatic way to write this would be:

	node = icc_node_create(TEGRA_ICC_EMC);
	if (IS_ERR(node)) {
		err = PTR_ERR(node);
		goto del_provider;
	}

> +
> +	node->name = "External Memory Controller";
> +	icc_node_add(node, &emc->provider);
> +
> +	/* link External Memory Controller to External Memory (DRAM) */
> +	err = icc_link_create(node, TEGRA_ICC_EMEM);
> +	if (err)
> +		goto remove_nodes;
> +
> +	/* create External Memory node */
> +	node = icc_node_create(TEGRA_ICC_EMEM);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto remove_nodes;

Same here.

> +
> +	node->name = "External Memory (DRAM)";
> +	icc_node_add(node, &emc->provider);
> +
> +	return 0;
> +
> +remove_nodes:
> +	icc_nodes_remove(&emc->provider);
> +del_provider:
> +	icc_provider_del(&emc->provider);
> +err_msg:
> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);

It might be worth duplicating this error message to the failure
locations so that the exact failure can be identified.

> +
> +	return err;
> +}
> +
> +static int tegra_emc_opp_table_init(struct tegra_emc *emc)
> +{
> +	const char *rname = "core";
> +	int err;
> +
> +	/*
> +	 * Legacy device-trees don't have OPP table and EMC driver isn't
> +	 * useful in this case.
> +	 */
> +	if (!device_property_present(emc->dev, "operating-points-v2")) {
> +		dev_err(emc->dev, "OPP table not found\n");
> +		dev_err(emc->dev, "please update your device tree\n");

This should be a single error message. These messages end up in kmsg
records and having this split into two dev_err() calls makes them into
two separate records and that in turn makes it more difficult to
determine whether they belong together or not.

> +		return -ENODEV;
> +	}
> +
> +	/* voltage scaling is optional */
> +	if (device_property_present(emc->dev, "core-supply"))
> +		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
> +	else
> +		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
> +
> +	if (IS_ERR(emc->opp_table))
> +		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
> +				     "failed to prepare OPP table\n");
> +
> +	err = dev_pm_opp_of_add_table(emc->dev);
> +	if (err) {
> +		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
> +		goto put_table;
> +	}
> +
> +	return 0;
> +
> +put_table:
> +	dev_pm_opp_put_opp_table(emc->opp_table);
> +
> +	return err;
> +}
> +
>  static int tegra_emc_probe(struct platform_device *pdev)
>  {
>  	struct device_node *np;
> @@ -717,8 +885,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
>  		goto unset_cb;
>  	}
>  
> +	err = tegra_emc_opp_table_init(emc);
> +	if (err)
> +		goto unreg_notifier;
> +
>  	platform_set_drvdata(pdev, emc);
>  	tegra_emc_debugfs_init(emc);
> +	tegra_emc_interconnect_init(emc);
>  
>  	/*
>  	 * Don't allow the kernel module to be unloaded. Unloading adds some
> @@ -729,6 +902,8 @@ static int tegra_emc_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> +unreg_notifier:
> +	clk_notifier_unregister(emc->clk, &emc->clk_nb);
>  unset_cb:
>  	tegra20_clk_set_emc_round_callback(NULL, NULL);
>  
> @@ -747,6 +922,7 @@ static struct platform_driver tegra_emc_driver = {
>  		.name = "tegra20-emc",
>  		.of_match_table = tegra_emc_of_match,
>  		.suppress_bind_attrs = true,
> +		.sync_state = icc_sync_state,
>  	},
>  };
>  module_platform_driver(tegra_emc_driver);
> diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
> index a8098bff91d9..5127e8e8250f 100644
> --- a/drivers/memory/tegra/tegra20.c
> +++ b/drivers/memory/tegra/tegra20.c
> @@ -280,6 +280,39 @@ static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
>  	.reset_status = tegra20_mc_reset_status,
>  };
>  
> +static int tegra20_mc_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	/*
> +	 * Technically, it should be possible to tune arbitration knobs here,
> +	 * but the default values are known to work well on all devices.
> +	 * Hence nothing to do here so far.
> +	 */
> +	return 0;
> +}
> +
> +static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
> +				   u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> +{
> +	/*
> +	 * ISO clients need to reserve extra bandwidth up-front because
> +	 * there could high bandwidth pressure during initial fulling-up

"filling of the client's FIFO buffers"

> +	 * of the client's FIFO buffers. Secondly, we need to take into
> +	 * account impurities of the memory subsystem.
> +	 */
> +	if (tag == TEGRA_MC_ICC_TAG_ISO)
> +		peak_bw = tegra_mc_scale_percents(peak_bw, 300);

300% sounds a bit excessive. Do we really need that much?

> +
> +	*agg_avg += avg_bw;
> +	*agg_peak = max(*agg_peak, peak_bw);

I'm not very familiar with ICC, but shouldn't the aggregated peak value
be the sum of the current aggregated peak and the new peak bandwidth?
Currently you're selecting the maximum peak bandwidth across all
clients, so isn't that going to be too small if for whatever reason
multiple clients need peak bandwidth at the same time?

Thierry

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
@ 2020-10-27 14:11     ` Thierry Reding
  0 siblings, 0 replies; 290+ messages in thread
From: Thierry Reding @ 2020-10-27 14:11 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette


[-- Attachment #1.1: Type: text/plain, Size: 11362 bytes --]

On Mon, Oct 26, 2020 at 01:17:16AM +0300, Dmitry Osipenko wrote:
> Now Internal and External Memory Controllers are memory interconnection
> providers. This allows us to use interconnect API for tuning of memory
> configuration. EMC driver now supports OPPs and DVFS.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/memory/tegra/Kconfig       |   3 +-
>  drivers/memory/tegra/mc.h          |  12 ++
>  drivers/memory/tegra/tegra20-emc.c | 176 +++++++++++++++++++++++++++++
>  drivers/memory/tegra/tegra20.c     |  34 ++++++
>  4 files changed, 224 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/memory/tegra/Kconfig b/drivers/memory/tegra/Kconfig
> index ff426747cd7d..ac3dfe155505 100644
> --- a/drivers/memory/tegra/Kconfig
> +++ b/drivers/memory/tegra/Kconfig
> @@ -11,7 +11,8 @@ config TEGRA_MC
>  config TEGRA20_EMC
>  	tristate "NVIDIA Tegra20 External Memory Controller driver"
>  	default y
> -	depends on ARCH_TEGRA_2x_SOC
> +	depends on TEGRA_MC && ARCH_TEGRA_2x_SOC
> +	select PM_OPP
>  	help
>  	  This driver is for the External Memory Controller (EMC) found on
>  	  Tegra20 chips. The EMC controls the external DRAM on the board.
> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
> index abeb6a2cc36a..531fb4fb7b17 100644
> --- a/drivers/memory/tegra/mc.h
> +++ b/drivers/memory/tegra/mc.h
> @@ -78,6 +78,18 @@
>  
>  #define MC_TIMING_UPDATE				BIT(0)
>  
> +static inline u32 tegra_mc_scale_percents(u64 val, unsigned int percents)
> +{
> +	val = val * percents;
> +	do_div(val, 100);
> +
> +	/*
> +	 * High freq + high boosting percent + large polling interval are
> +	 * resulting in integer overflow when watermarks are calculated.
> +	 */
> +	return min_t(u64, val, U32_MAX);
> +}
> +
>  static inline u32 mc_readl(struct tegra_mc *mc, unsigned long offset)
>  {
>  	return readl_relaxed(mc->regs + offset);
> diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c
> index 34085e26dced..69ccb3fe5b0b 100644
> --- a/drivers/memory/tegra/tegra20-emc.c
> +++ b/drivers/memory/tegra/tegra20-emc.c
> @@ -9,6 +9,7 @@
>  #include <linux/clk/tegra.h>
>  #include <linux/debugfs.h>
>  #include <linux/err.h>
> +#include <linux/interconnect-provider.h>
>  #include <linux/interrupt.h>
>  #include <linux/io.h>
>  #include <linux/iopoll.h>
> @@ -16,11 +17,15 @@
>  #include <linux/module.h>
>  #include <linux/of.h>
>  #include <linux/platform_device.h>
> +#include <linux/pm_opp.h>
> +#include <linux/slab.h>
>  #include <linux/sort.h>
>  #include <linux/types.h>
>  
>  #include <soc/tegra/fuse.h>
>  
> +#include "mc.h"
> +
>  #define EMC_INTSTATUS				0x000
>  #define EMC_INTMASK				0x004
>  #define EMC_DBG					0x008
> @@ -144,6 +149,9 @@ struct emc_timing {
>  
>  struct tegra_emc {
>  	struct device *dev;
> +	struct tegra_mc *mc;
> +	struct opp_table *opp_table;
> +	struct icc_provider provider;
>  	struct notifier_block clk_nb;
>  	struct clk *clk;
>  	void __iomem *regs;
> @@ -658,6 +666,166 @@ static void tegra_emc_debugfs_init(struct tegra_emc *emc)
>  			    emc, &tegra_emc_debug_max_rate_fops);
>  }
>  
> +static inline struct tegra_emc *
> +to_tegra_emc_provider(struct icc_provider *provider)
> +{
> +	return container_of(provider, struct tegra_emc, provider);
> +}
> +
> +static struct icc_node_data *
> +emc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
> +{
> +	struct icc_provider *provider = data;
> +	struct icc_node_data *ndata;
> +	struct icc_node *node;
> +
> +	/* External Memory is the only possible ICC route */
> +	list_for_each_entry(node, &provider->nodes, node_list) {
> +		if (node->id != TEGRA_ICC_EMEM)
> +			continue;
> +
> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
> +		if (!ndata)
> +			return ERR_PTR(-ENOMEM);
> +
> +		/*
> +		 * SRC and DST nodes should have matching TAG in order to have
> +		 * it set by default for a requested path.
> +		 */
> +		ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> +		ndata->node = node;
> +
> +		return ndata;
> +	}
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +
> +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
> +	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
> +	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
> +	unsigned long long rate = max(avg_bw, peak_bw);
> +	unsigned int dram_data_bus_width_bytes = 4;

Perhaps use something shorter for this variable (like dram_bus_width)? Also,
since it's never modified, perhaps make it const? Or a #define?

> +	long rounded_rate;
> +	int err;
> +
> +	/*
> +	 * Tegra20 EMC runs on x2 clock rate of SDRAM bus because DDR data
> +	 * is sampled on both clock edges. This means that EMC clock rate
> +	 * equals to the peak data rate.
> +	 */
> +	do_div(rate, dram_data_bus_width_bytes);
> +	rate = min_t(u64, rate, U32_MAX);
> +
> +	rounded_rate = emc_round_rate(rate, 0, U32_MAX, emc);
> +	if (rounded_rate < 0)
> +		return rounded_rate;
> +
> +	err = dev_pm_opp_set_rate(emc->dev, rounded_rate);
> +	if (err)
> +		return err;
> +
> +	return 0;
> +}
> +
> +static int tegra_emc_interconnect_init(struct tegra_emc *emc)
> +{
> +	const struct tegra_mc_soc *soc;
> +	struct icc_node *node;
> +	int err;
> +
> +	emc->mc = devm_tegra_get_memory_controller(emc->dev);
> +	if (IS_ERR(emc->mc))
> +		return PTR_ERR(emc->mc);
> +
> +	soc = emc->mc->soc;
> +
> +	emc->provider.dev = emc->dev;
> +	emc->provider.set = emc_icc_set;
> +	emc->provider.data = &emc->provider;
> +	emc->provider.aggregate = soc->icc_ops->aggregate;
> +	emc->provider.xlate_extended = emc_of_icc_xlate_extended;
> +
> +	err = icc_provider_add(&emc->provider);
> +	if (err)
> +		goto err_msg;
> +
> +	/* create External Memory Controller node */
> +	node = icc_node_create(TEGRA_ICC_EMC);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto del_provider;

As far as I can tell, icc_node_create() always returns either a valid
pointer or an ERR_PTR-encoded negative error-code. So I think the more
idiomatic way to write this would be:

	node = icc_node_create(TEGRA_ICC_EMC);
	if (IS_ERR(node)) {
		err = PTR_ERR(node);
		goto del_provider;
	}

> +
> +	node->name = "External Memory Controller";
> +	icc_node_add(node, &emc->provider);
> +
> +	/* link External Memory Controller to External Memory (DRAM) */
> +	err = icc_link_create(node, TEGRA_ICC_EMEM);
> +	if (err)
> +		goto remove_nodes;
> +
> +	/* create External Memory node */
> +	node = icc_node_create(TEGRA_ICC_EMEM);
> +	err = PTR_ERR_OR_ZERO(node);
> +	if (err)
> +		goto remove_nodes;

Same here.

> +
> +	node->name = "External Memory (DRAM)";
> +	icc_node_add(node, &emc->provider);
> +
> +	return 0;
> +
> +remove_nodes:
> +	icc_nodes_remove(&emc->provider);
> +del_provider:
> +	icc_provider_del(&emc->provider);
> +err_msg:
> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);

It might be worth duplicating this error message to the failure
locations so that the exact failure can be identified.

> +
> +	return err;
> +}
> +
> +static int tegra_emc_opp_table_init(struct tegra_emc *emc)
> +{
> +	const char *rname = "core";
> +	int err;
> +
> +	/*
> +	 * Legacy device-trees don't have OPP table and EMC driver isn't
> +	 * useful in this case.
> +	 */
> +	if (!device_property_present(emc->dev, "operating-points-v2")) {
> +		dev_err(emc->dev, "OPP table not found\n");
> +		dev_err(emc->dev, "please update your device tree\n");

This should be a single error message. These messages end up in kmsg
records and having this split into two dev_err() calls makes them into
two separate records and that in turn makes it more difficult to
determine whether they belong together or not.

> +		return -ENODEV;
> +	}
> +
> +	/* voltage scaling is optional */
> +	if (device_property_present(emc->dev, "core-supply"))
> +		emc->opp_table = dev_pm_opp_set_regulators(emc->dev, &rname, 1);
> +	else
> +		emc->opp_table = dev_pm_opp_get_opp_table(emc->dev);
> +
> +	if (IS_ERR(emc->opp_table))
> +		return dev_err_probe(emc->dev, PTR_ERR(emc->opp_table),
> +				     "failed to prepare OPP table\n");
> +
> +	err = dev_pm_opp_of_add_table(emc->dev);
> +	if (err) {
> +		dev_err(emc->dev, "failed to add OPP table: %d\n", err);
> +		goto put_table;
> +	}
> +
> +	return 0;
> +
> +put_table:
> +	dev_pm_opp_put_opp_table(emc->opp_table);
> +
> +	return err;
> +}
> +
>  static int tegra_emc_probe(struct platform_device *pdev)
>  {
>  	struct device_node *np;
> @@ -717,8 +885,13 @@ static int tegra_emc_probe(struct platform_device *pdev)
>  		goto unset_cb;
>  	}
>  
> +	err = tegra_emc_opp_table_init(emc);
> +	if (err)
> +		goto unreg_notifier;
> +
>  	platform_set_drvdata(pdev, emc);
>  	tegra_emc_debugfs_init(emc);
> +	tegra_emc_interconnect_init(emc);
>  
>  	/*
>  	 * Don't allow the kernel module to be unloaded. Unloading adds some
> @@ -729,6 +902,8 @@ static int tegra_emc_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> +unreg_notifier:
> +	clk_notifier_unregister(emc->clk, &emc->clk_nb);
>  unset_cb:
>  	tegra20_clk_set_emc_round_callback(NULL, NULL);
>  
> @@ -747,6 +922,7 @@ static struct platform_driver tegra_emc_driver = {
>  		.name = "tegra20-emc",
>  		.of_match_table = tegra_emc_of_match,
>  		.suppress_bind_attrs = true,
> +		.sync_state = icc_sync_state,
>  	},
>  };
>  module_platform_driver(tegra_emc_driver);
> diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c
> index a8098bff91d9..5127e8e8250f 100644
> --- a/drivers/memory/tegra/tegra20.c
> +++ b/drivers/memory/tegra/tegra20.c
> @@ -280,6 +280,39 @@ static const struct tegra_mc_reset_ops tegra20_mc_reset_ops = {
>  	.reset_status = tegra20_mc_reset_status,
>  };
>  
> +static int tegra20_mc_icc_set(struct icc_node *src, struct icc_node *dst)
> +{
> +	/*
> +	 * Technically, it should be possible to tune arbitration knobs here,
> +	 * but the default values are known to work well on all devices.
> +	 * Hence nothing to do here so far.
> +	 */
> +	return 0;
> +}
> +
> +static int tegra20_mc_icc_aggreate(struct icc_node *node, u32 tag, u32 avg_bw,
> +				   u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> +{
> +	/*
> +	 * ISO clients need to reserve extra bandwidth up-front because
> +	 * there could high bandwidth pressure during initial fulling-up

"filling of the client's FIFO buffers"

> +	 * of the client's FIFO buffers. Secondly, we need to take into
> +	 * account impurities of the memory subsystem.
> +	 */
> +	if (tag == TEGRA_MC_ICC_TAG_ISO)
> +		peak_bw = tegra_mc_scale_percents(peak_bw, 300);

300% sounds a bit excessive. Do we really need that much?

> +
> +	*agg_avg += avg_bw;
> +	*agg_peak = max(*agg_peak, peak_bw);

I'm not very familiar with ICC, but shouldn't the aggregated peak value
be the sum of the current aggregated peak and the new peak bandwidth?
Currently you're selecting the maximum peak bandwidth across all
clients, so isn't that going to be too small if for whatever reason
multiple clients need peak bandwidth at the same time?

Thierry

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
  2020-10-27  8:54     ` Krzysztof Kozlowski
@ 2020-10-27 19:17       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 11:54, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
>> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
>> reprogrammed when memory frequency changes. Tegra Memory Controller sits
>> behind EMC and these controllers are tightly coupled. This patch adds the
>> new phandle property which allows to properly express connection of EMC
>> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
>> par with Tegra30+ EMC bindings, which is handy to have.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>> index 567cffd37f3f..1b0d4417aad8 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>> @@ -12,6 +12,7 @@ Properties:
>>    irrespective of ram-code configuration.
>>  - interrupts : Should contain EMC General interrupt.
>>  - clocks : Should contain EMC clock.
>> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> 
> It looks like you adding a required property which is an ABI break.
The T20 EMC driver is unused so far in upstream and it will become used
only once this series is applied. Hence it's fine to change the ABI.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
@ 2020-10-27 19:17       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 11:54, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
>> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
>> reprogrammed when memory frequency changes. Tegra Memory Controller sits
>> behind EMC and these controllers are tightly coupled. This patch adds the
>> new phandle property which allows to properly express connection of EMC
>> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
>> par with Tegra30+ EMC bindings, which is handy to have.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>> index 567cffd37f3f..1b0d4417aad8 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>> @@ -12,6 +12,7 @@ Properties:
>>    irrespective of ram-code configuration.
>>  - interrupts : Should contain EMC General interrupt.
>>  - clocks : Should contain EMC clock.
>> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> 
> It looks like you adding a required property which is an ABI break.
The T20 EMC driver is unused so far in upstream and it will become used
only once this series is applied. Hence it's fine to change the ABI.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
  2020-10-27  8:55     ` Krzysztof Kozlowski
@ 2020-10-27 19:17       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 11:55, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:48AM +0300, Dmitry Osipenko wrote:
>> Memory controller is interconnected with memory clients and with the
>> External Memory Controller. Document new interconnect property which
>> turns memory controller into interconnect provider.
>>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
>> index e55328237df4..739b7c6f2e26 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
>> @@ -16,6 +16,8 @@ Required properties:
>>    IOMMU specifier needed to encode an address. GART supports only a single
>>    address space that is shared by all devices, therefore no additional
>>    information needed for the address encoding.
>> +- #interconnect-cells : Should be 1. This cell represents memory client.
>> +  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.
> 
> This is a list of required properties so you break the ABI. All existing
> DTBs will be affected.

This is optional property for the older DTBs, but for newer DTs it's
mandatory. IIUC, it should be defined as a required property in the
binding.

Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
interconnect framework", which check presence of the ICC DT property.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
@ 2020-10-27 19:17       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:17 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 11:55, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:48AM +0300, Dmitry Osipenko wrote:
>> Memory controller is interconnected with memory clients and with the
>> External Memory Controller. Document new interconnect property which
>> turns memory controller into interconnect provider.
>>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
>>  1 file changed, 3 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
>> index e55328237df4..739b7c6f2e26 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
>> @@ -16,6 +16,8 @@ Required properties:
>>    IOMMU specifier needed to encode an address. GART supports only a single
>>    address space that is shared by all devices, therefore no additional
>>    information needed for the address encoding.
>> +- #interconnect-cells : Should be 1. This cell represents memory client.
>> +  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.
> 
> This is a list of required properties so you break the ABI. All existing
> DTBs will be affected.

This is optional property for the older DTBs, but for newer DTs it's
mandatory. IIUC, it should be defined as a required property in the
binding.

Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
interconnect framework", which check presence of the ICC DT property.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
  2020-10-27  9:05     ` Krzysztof Kozlowski
@ 2020-10-27 19:18       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 12:05, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:52AM +0300, Dmitry Osipenko wrote:
>> Memory controller is interconnected with memory clients and with the
>> External Memory Controller. Document new interconnect property which
>> turns memory controller into interconnect provider.
>>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
>> index 84fd57bcf0dc..5436e6d420bc 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
>> @@ -57,6 +57,9 @@ properties:
>>    "#iommu-cells":
>>      const: 1
>>  
>> +  "#interconnect-cells":
>> +    const: 1
>> +
>>  patternProperties:
>>    "^emc-timings-[0-9]+$":
>>      type: object
>> @@ -120,6 +123,7 @@ required:
>>    - clock-names
>>    - "#reset-cells"
>>    - "#iommu-cells"
>> +  - "#interconnect-cells"
> 
> Rob,
> 
> You were fine with adding a new required property which breaks all
> existing DTBs?

This is a required property for the new bindings and optional for the
older. Does it really need to be made optional in the binding?

> Were these bindings marked as unstable? The patchset does not even
> say/scream that it breaks the ABI, so this might be quite a surprise for
> someone...

Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
interconnect framework" patch, which check presence of the new ICC DT
property.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
@ 2020-10-27 19:18       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 12:05, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:52AM +0300, Dmitry Osipenko wrote:
>> Memory controller is interconnected with memory clients and with the
>> External Memory Controller. Document new interconnect property which
>> turns memory controller into interconnect provider.
>>
>> Acked-by: Rob Herring <robh@kernel.org>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
>>  1 file changed, 5 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
>> index 84fd57bcf0dc..5436e6d420bc 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
>> @@ -57,6 +57,9 @@ properties:
>>    "#iommu-cells":
>>      const: 1
>>  
>> +  "#interconnect-cells":
>> +    const: 1
>> +
>>  patternProperties:
>>    "^emc-timings-[0-9]+$":
>>      type: object
>> @@ -120,6 +123,7 @@ required:
>>    - clock-names
>>    - "#reset-cells"
>>    - "#iommu-cells"
>> +  - "#interconnect-cells"
> 
> Rob,
> 
> You were fine with adding a new required property which breaks all
> existing DTBs?

This is a required property for the new bindings and optional for the
older. Does it really need to be made optional in the binding?

> Were these bindings marked as unstable? The patchset does not even
> say/scream that it breaks the ABI, so this might be quite a surprise for
> someone...

Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
interconnect framework" patch, which check presence of the new ICC DT
property.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
  2020-10-27 10:25     ` Krzysztof Kozlowski
@ 2020-10-27 19:19       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 13:25, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
>> External memory controller is interconnected with memory controller and
>> with external memory. Document new interconnect property which turns
>> External Memory Controller into interconnect provider.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>> index 278549f9e051..ac00832ceac1 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>> @@ -29,6 +29,9 @@ properties:
>>      items:
>>        - const: emc
>>  
>> +  "#interconnect-cells":
>> +    const: 0
>> +
>>    nvidia,memory-controller:
>>      $ref: /schemas/types.yaml#/definitions/phandle
>>      description:
>> @@ -327,6 +330,7 @@ required:
>>    - clocks
>>    - clock-names
>>    - nvidia,memory-controller
>> +  - "#interconnect-cells"
> 
> Another required property, what about all existing users of this binding?

EMC/devfreq drivers check presence of the new properties and ask users
to upgrade the DT. The kernel will continue to work fine using older
DTBs, but devfreq driver won't load.

>>  additionalProperties: false
>>  
>> @@ -345,6 +349,7 @@ examples:
>>  
>>          #iommu-cells = <1>;
>>          #reset-cells = <1>;
>> +        #interconnect-cells = <1>;
> 
> You meant '0'?

'1' is for the "mc" node in the example (not "emc" node).

Anyways, I'll move this hunk to the previous patch in order to fix the
kernel bot warning.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
@ 2020-10-27 19:19       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:19 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 13:25, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
>> External memory controller is interconnected with memory controller and
>> with external memory. Document new interconnect property which turns
>> External Memory Controller into interconnect provider.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>>  1 file changed, 7 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>> index 278549f9e051..ac00832ceac1 100644
>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>> @@ -29,6 +29,9 @@ properties:
>>      items:
>>        - const: emc
>>  
>> +  "#interconnect-cells":
>> +    const: 0
>> +
>>    nvidia,memory-controller:
>>      $ref: /schemas/types.yaml#/definitions/phandle
>>      description:
>> @@ -327,6 +330,7 @@ required:
>>    - clocks
>>    - clock-names
>>    - nvidia,memory-controller
>> +  - "#interconnect-cells"
> 
> Another required property, what about all existing users of this binding?

EMC/devfreq drivers check presence of the new properties and ask users
to upgrade the DT. The kernel will continue to work fine using older
DTBs, but devfreq driver won't load.

>>  additionalProperties: false
>>  
>> @@ -345,6 +349,7 @@ examples:
>>  
>>          #iommu-cells = <1>;
>>          #reset-cells = <1>;
>> +        #interconnect-cells = <1>;
> 
> You meant '0'?

'1' is for the "mc" node in the example (not "emc" node).

Anyways, I'll move this hunk to the previous patch in order to fix the
kernel bot warning.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-27  9:02     ` Krzysztof Kozlowski
@ 2020-10-27 19:22       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:22 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 12:02, Krzysztof Kozlowski пишет:
>> @@ -31,17 +32,34 @@ Example:
>>  		...
>>  	};
>>  
>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> Hyphens for node name.

We already use underscores for the Tegra CPU OPP table.

https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4

What makes you think that hyphens will be a better choice? Is it a
documented naming convention?

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-27 19:22       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:22 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 12:02, Krzysztof Kozlowski пишет:
>> @@ -31,17 +32,34 @@ Example:
>>  		...
>>  	};
>>  
>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> Hyphens for node name.

We already use underscores for the Tegra CPU OPP table.

https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4

What makes you think that hyphens will be a better choice? Is it a
documented naming convention?
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-27 13:22     ` Thierry Reding
@ 2020-10-27 19:23       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:23 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 16:22, Thierry Reding пишет:
> On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
>> External Memory Controller can gather various hardware statistics that
>> are intended to be used for debugging purposes and for dynamic frequency
>> scaling of memory bus.
>>
>> Document the new mfd-simple compatible and EMC statistics sub-device.
>> The subdev contains EMC DFS OPP table and interconnect paths to be used
>> for dynamic scaling of system's memory bandwidth based on EMC utilization
>> statistics.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> Why does this have to be modelled as a separate device? Isn't this just
> using a couple of registers out of the EMC register range? If so, this
> would better just be integrated into the parent node and implemented as
> part of the EMC driver. No need to further complicate things by adding
> a dummy child.

Maybe true, I'll take a closer look.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-27 19:23       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:23 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette

27.10.2020 16:22, Thierry Reding пишет:
> On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
>> External Memory Controller can gather various hardware statistics that
>> are intended to be used for debugging purposes and for dynamic frequency
>> scaling of memory bus.
>>
>> Document the new mfd-simple compatible and EMC statistics sub-device.
>> The subdev contains EMC DFS OPP table and interconnect paths to be used
>> for dynamic scaling of system's memory bandwidth based on EMC utilization
>> statistics.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> Why does this have to be modelled as a separate device? Isn't this just
> using a couple of registers out of the EMC register range? If so, this
> would better just be integrated into the parent node and implemented as
> part of the EMC driver. No need to further complicate things by adding
> a dummy child.

Maybe true, I'll take a closer look.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 22/52] ARM: tegra: Add interconnect properties to Tegra30 device-tree
  2020-10-27  9:15     ` Krzysztof Kozlowski
@ 2020-10-27 19:23       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 12:15, Krzysztof Kozlowski пишет:
...>> @@ -748,15 +770,18 @@ mc: memory-controller@7000f000 {
>>  
>>  		#iommu-cells = <1>;
>>  		#reset-cells = <1>;
>> +		#interconnect-cells = <1>;
>>  	};
>>  
>> -	memory-controller@7000f400 {
>> +	emc: memory-controller@7000f400 {
>>  		compatible = "nvidia,tegra30-emc";
>>  		reg = <0x7000f400 0x400>;
>>  		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
>>  		clocks = <&tegra_car TEGRA30_CLK_EMC>;
>>  
>>  		nvidia,memory-controller = <&mc>;
>> +
> 
> No need for blank line.

It's needed to make MC and EMC nodes look consistent. See the MC node
above which has the blank line.

> 
>> +		#interconnect-cells = <0>;
>>  	};
>>  
>>  	fuse@7000f800 {

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 22/52] ARM: tegra: Add interconnect properties to Tegra30 device-tree
@ 2020-10-27 19:23       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 12:15, Krzysztof Kozlowski пишет:
...>> @@ -748,15 +770,18 @@ mc: memory-controller@7000f000 {
>>  
>>  		#iommu-cells = <1>;
>>  		#reset-cells = <1>;
>> +		#interconnect-cells = <1>;
>>  	};
>>  
>> -	memory-controller@7000f400 {
>> +	emc: memory-controller@7000f400 {
>>  		compatible = "nvidia,tegra30-emc";
>>  		reg = <0x7000f400 0x400>;
>>  		interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
>>  		clocks = <&tegra_car TEGRA30_CLK_EMC>;
>>  
>>  		nvidia,memory-controller = <&mc>;
>> +
> 
> No need for blank line.

It's needed to make MC and EMC nodes look consistent. See the MC node
above which has the blank line.

> 
>> +		#interconnect-cells = <0>;
>>  	};
>>  
>>  	fuse@7000f800 {
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
  2020-10-27  9:42     ` Krzysztof Kozlowski
@ 2020-10-27 19:24       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:24 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 12:42, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:17:11AM +0300, Dmitry Osipenko wrote:
>> Multiple Tegra drivers need to retrieve Memory Controller and there is
>> duplication of the retrieval code among the drivers. This patch removes
>> the duplication and fixes put_device() which was missed in the duplicated
>> code.
>>
>> EMC drivers now use new common devm_tegra_get_memory_controller() helper
>> instead of opencoding the MC retrieval.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
>>  drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
>>  drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
>>  drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
>>  include/soc/tegra/mc.h                   | 10 +++++
>>  5 files changed, 74 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
>> index ec8403557ed4..12ea2c79205a 100644
>> --- a/drivers/memory/tegra/mc.c
>> +++ b/drivers/memory/tegra/mc.c
>> @@ -42,6 +42,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
>>  };
>>  MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
>>  
>> +static void tegra_mc_devm_action_put_device(void *data)
>> +{
>> +	struct tegra_mc *mc = data;
>> +
>> +	put_device(mc->dev);
>> +}
>> +
>> +/**
>> + * devm_tegra_get_memory_controller() - get Tegra Memory Controller handle
>> + * @dev: device pointer for the consumer device
>> + *
>> + * This function will search for the Memory Controller node in a device-tree
>> + * and retrieve the Memory Controller handle.
>> + *
>> + * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
>> + */
>> +struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev)
> 
> Usually 'get' is a suffix (for example in clk, gpiod, iio, led), so:
> devm_tegra_memory_controller_get()

Alright, I'll rename it in v7.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller()
@ 2020-10-27 19:24       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:24 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 12:42, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:17:11AM +0300, Dmitry Osipenko wrote:
>> Multiple Tegra drivers need to retrieve Memory Controller and there is
>> duplication of the retrieval code among the drivers. This patch removes
>> the duplication and fixes put_device() which was missed in the duplicated
>> code.
>>
>> EMC drivers now use new common devm_tegra_get_memory_controller() helper
>> instead of opencoding the MC retrieval.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/memory/tegra/mc.c                | 48 ++++++++++++++++++++++++
>>  drivers/memory/tegra/tegra124-emc.c      | 18 ++-------
>>  drivers/memory/tegra/tegra210-emc-core.c | 39 +++++--------------
>>  drivers/memory/tegra/tegra30-emc.c       | 18 ++-------
>>  include/soc/tegra/mc.h                   | 10 +++++
>>  5 files changed, 74 insertions(+), 59 deletions(-)
>>
>> diff --git a/drivers/memory/tegra/mc.c b/drivers/memory/tegra/mc.c
>> index ec8403557ed4..12ea2c79205a 100644
>> --- a/drivers/memory/tegra/mc.c
>> +++ b/drivers/memory/tegra/mc.c
>> @@ -42,6 +42,54 @@ static const struct of_device_id tegra_mc_of_match[] = {
>>  };
>>  MODULE_DEVICE_TABLE(of, tegra_mc_of_match);
>>  
>> +static void tegra_mc_devm_action_put_device(void *data)
>> +{
>> +	struct tegra_mc *mc = data;
>> +
>> +	put_device(mc->dev);
>> +}
>> +
>> +/**
>> + * devm_tegra_get_memory_controller() - get Tegra Memory Controller handle
>> + * @dev: device pointer for the consumer device
>> + *
>> + * This function will search for the Memory Controller node in a device-tree
>> + * and retrieve the Memory Controller handle.
>> + *
>> + * Return: ERR_PTR() on error or a valid pointer to a struct tegra_mc.
>> + */
>> +struct tegra_mc *devm_tegra_get_memory_controller(struct device *dev)
> 
> Usually 'get' is a suffix (for example in clk, gpiod, iio, led), so:
> devm_tegra_memory_controller_get()

Alright, I'll rename it in v7.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
  2020-10-27 19:17       ` Dmitry Osipenko
@ 2020-10-27 19:30         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:30 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 11:54, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> >> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> >> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> >> behind EMC and these controllers are tightly coupled. This patch adds the
> >> new phandle property which allows to properly express connection of EMC
> >> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> >> par with Tegra30+ EMC bindings, which is handy to have.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
> >>  1 file changed, 2 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> >> index 567cffd37f3f..1b0d4417aad8 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> >> @@ -12,6 +12,7 @@ Properties:
> >>    irrespective of ram-code configuration.
> >>  - interrupts : Should contain EMC General interrupt.
> >>  - clocks : Should contain EMC clock.
> >> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> > 
> > It looks like you adding a required property which is an ABI break.
> The T20 EMC driver is unused so far in upstream and it will become used
> only once this series is applied. Hence it's fine to change the ABI.

The ABI is not about upstream, but downstream. There are no other
upstreams using this ABI. Unless you have in mind that existing T20 EMC
driver was a noop, doing absolutely nothing, therefore there is no
breakage of any other users?

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
@ 2020-10-27 19:30         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:30 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 11:54, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> >> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> >> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> >> behind EMC and these controllers are tightly coupled. This patch adds the
> >> new phandle property which allows to properly express connection of EMC
> >> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> >> par with Tegra30+ EMC bindings, which is handy to have.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
> >>  1 file changed, 2 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> >> index 567cffd37f3f..1b0d4417aad8 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> >> @@ -12,6 +12,7 @@ Properties:
> >>    irrespective of ram-code configuration.
> >>  - interrupts : Should contain EMC General interrupt.
> >>  - clocks : Should contain EMC clock.
> >> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> > 
> > It looks like you adding a required property which is an ABI break.
> The T20 EMC driver is unused so far in upstream and it will become used
> only once this series is applied. Hence it's fine to change the ABI.

The ABI is not about upstream, but downstream. There are no other
upstreams using this ABI. Unless you have in mind that existing T20 EMC
driver was a noop, doing absolutely nothing, therefore there is no
breakage of any other users?

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 29/52] memory: tegra-mc: Add interconnect framework
  2020-10-27 13:48     ` Thierry Reding
@ 2020-10-27 19:30       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:30 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 16:48, Thierry Reding пишет:
...
>> +static struct icc_node_data *
>> +tegra_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
>> +{
>> +	struct icc_provider *provider = data;
>> +	unsigned int idx = spec->args[0];
>> +	struct icc_node_data *ndata;
>> +	struct icc_node *node;
>> +
>> +	list_for_each_entry(node, &provider->nodes, node_list) {
>> +		if (node->id != idx)
>> +			continue;
>> +
>> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
>> +		if (!ndata)
>> +			return ERR_PTR(-ENOMEM);
>> +
>> +		ndata->node = node;
>> +
>> +		/* these clients are isochronous by default on all SoCs */
>> +		if (strstarts(node->name, "display") ||
>> +		    strstarts(node->name, "ptc") ||
>> +		    strstarts(node->name, "vi"))
>> +			ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> 
> This looks like something that might be better left to the drivers to
> decide. Doing this here seems okay for now, but I suspect that this will
> get fairly complicated to keep accurate as we add more clients later on.

It's not a problem to add a driver-specific hook for the
xlate_extended(), like it's done for the aggregate() and set() hooks below.

...
>> +static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
>> +{
>> +	struct icc_node *node;
>> +	unsigned int i;
>> +	int err;
>> +
>> +	/* older device-trees don't have interconnect properties */
>> +	if (!of_find_property(mc->dev->of_node, "#interconnect-cells", NULL) ||
>> +	    !mc->soc->icc_ops)
>> +		return 0;
> 
> This indicates that this property is indeed optional, so the bindings
> should reflect that.

Yes, but the property isn't optional for the newer binding. Does it
really need to be documented as optional?

>> +	mc->provider.dev = mc->dev;
>> +	mc->provider.data = &mc->provider;
>> +	mc->provider.set = mc->soc->icc_ops->set;
>> +	mc->provider.aggregate = mc->soc->icc_ops->aggregate;
>> +	mc->provider.xlate_extended = tegra_mc_of_icc_xlate_extended;
>> +
>> +	err = icc_provider_add(&mc->provider);
>> +	if (err)
>> +		goto err_msg;
>> +
>> +	/* create Memory Controller node */
>> +	node = icc_node_create(TEGRA_ICC_MC);
>> +	err = PTR_ERR_OR_ZERO(node);
>> +	if (err)
>> +		goto del_provider;
>> +
>> +	node->name = "Memory Controller";
>> +	icc_node_add(node, &mc->provider);
>> +
>> +	/* link Memory Controller to External Memory Controller */
>> +	err = icc_link_create(node, TEGRA_ICC_EMC);
>> +	if (err)
>> +		goto remove_nodes;
>> +
>> +	for (i = 0; i < mc->soc->num_clients; i++) {
>> +		/* create MC client node */
>> +		node = icc_node_create(mc->soc->clients[i].id);
>> +		err = PTR_ERR_OR_ZERO(node);
>> +		if (err)
>> +			goto remove_nodes;
>> +
>> +		node->name = mc->soc->clients[i].name;
>> +		icc_node_add(node, &mc->provider);
> 
> I'm not fully familiar with how these nodes are set up, but would it be
> possible to set the isochronous tag here already? I'd still prefer this
> to be up to the drivers because I think that nicely localizes the
> device-specific information in the driver, but if that's not an option,
> then doing it here, based on lookup data from the MC clients table
> sounds like the next best thing.

The tag needs to be set by xlate_extended(), otherwise it won't be
applied by default.

https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/interconnect/core.c#L501

...
>>  static int tegra_mc_probe(struct platform_device *pdev)
>>  {
>>  	struct resource *res;
>> @@ -747,6 +874,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
>>  		}
>>  	}
>>  
>> +	tegra_mc_interconnect_setup(mc);
> 
> Do you want to check the return value here for errors? If not, might as
> well make the function return void.

The error won't be fatal and shouldn't block the rest functionality of
the MC driver.

It's possible to return void, but it's not necessary because compiler
will take care of optimizing the code and to me it's more consistent to
have error code returned by the function.

Perhaps should be better to just add a comment telling that error
skipping is intentional?

...
>> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
>> index afa3ba45c9e6..abeb6a2cc36a 100644
>> --- a/drivers/memory/tegra/mc.h
>> +++ b/drivers/memory/tegra/mc.h
>> @@ -115,4 +115,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
>>  extern const struct tegra_mc_soc tegra210_mc_soc;
>>  #endif
>>  
>> +/*
>> + * These IDs are for internal use of Tegra's ICC, the values are chosen
>> + * such that they don't conflict with the device-tree ICC node IDs.
>> + */
>> +#define TEGRA_ICC_EMC		1000
>> +#define TEGRA_ICC_EMEM		2000
>> +#define TEGRA_ICC_MC		3000
> 
> Sounds to me like these could equally well be 1000, 1001 and 1002. Why
> leave these large holes in the number space?

There is no specific reason, I can change the numbers if you want.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 29/52] memory: tegra-mc: Add interconnect framework
@ 2020-10-27 19:30       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:30 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette

27.10.2020 16:48, Thierry Reding пишет:
...
>> +static struct icc_node_data *
>> +tegra_mc_of_icc_xlate_extended(struct of_phandle_args *spec, void *data)
>> +{
>> +	struct icc_provider *provider = data;
>> +	unsigned int idx = spec->args[0];
>> +	struct icc_node_data *ndata;
>> +	struct icc_node *node;
>> +
>> +	list_for_each_entry(node, &provider->nodes, node_list) {
>> +		if (node->id != idx)
>> +			continue;
>> +
>> +		ndata = kzalloc(sizeof(*ndata), GFP_KERNEL);
>> +		if (!ndata)
>> +			return ERR_PTR(-ENOMEM);
>> +
>> +		ndata->node = node;
>> +
>> +		/* these clients are isochronous by default on all SoCs */
>> +		if (strstarts(node->name, "display") ||
>> +		    strstarts(node->name, "ptc") ||
>> +		    strstarts(node->name, "vi"))
>> +			ndata->tag = TEGRA_MC_ICC_TAG_ISO;
> 
> This looks like something that might be better left to the drivers to
> decide. Doing this here seems okay for now, but I suspect that this will
> get fairly complicated to keep accurate as we add more clients later on.

It's not a problem to add a driver-specific hook for the
xlate_extended(), like it's done for the aggregate() and set() hooks below.

...
>> +static int tegra_mc_interconnect_setup(struct tegra_mc *mc)
>> +{
>> +	struct icc_node *node;
>> +	unsigned int i;
>> +	int err;
>> +
>> +	/* older device-trees don't have interconnect properties */
>> +	if (!of_find_property(mc->dev->of_node, "#interconnect-cells", NULL) ||
>> +	    !mc->soc->icc_ops)
>> +		return 0;
> 
> This indicates that this property is indeed optional, so the bindings
> should reflect that.

Yes, but the property isn't optional for the newer binding. Does it
really need to be documented as optional?

>> +	mc->provider.dev = mc->dev;
>> +	mc->provider.data = &mc->provider;
>> +	mc->provider.set = mc->soc->icc_ops->set;
>> +	mc->provider.aggregate = mc->soc->icc_ops->aggregate;
>> +	mc->provider.xlate_extended = tegra_mc_of_icc_xlate_extended;
>> +
>> +	err = icc_provider_add(&mc->provider);
>> +	if (err)
>> +		goto err_msg;
>> +
>> +	/* create Memory Controller node */
>> +	node = icc_node_create(TEGRA_ICC_MC);
>> +	err = PTR_ERR_OR_ZERO(node);
>> +	if (err)
>> +		goto del_provider;
>> +
>> +	node->name = "Memory Controller";
>> +	icc_node_add(node, &mc->provider);
>> +
>> +	/* link Memory Controller to External Memory Controller */
>> +	err = icc_link_create(node, TEGRA_ICC_EMC);
>> +	if (err)
>> +		goto remove_nodes;
>> +
>> +	for (i = 0; i < mc->soc->num_clients; i++) {
>> +		/* create MC client node */
>> +		node = icc_node_create(mc->soc->clients[i].id);
>> +		err = PTR_ERR_OR_ZERO(node);
>> +		if (err)
>> +			goto remove_nodes;
>> +
>> +		node->name = mc->soc->clients[i].name;
>> +		icc_node_add(node, &mc->provider);
> 
> I'm not fully familiar with how these nodes are set up, but would it be
> possible to set the isochronous tag here already? I'd still prefer this
> to be up to the drivers because I think that nicely localizes the
> device-specific information in the driver, but if that's not an option,
> then doing it here, based on lookup data from the MC clients table
> sounds like the next best thing.

The tag needs to be set by xlate_extended(), otherwise it won't be
applied by default.

https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/interconnect/core.c#L501

...
>>  static int tegra_mc_probe(struct platform_device *pdev)
>>  {
>>  	struct resource *res;
>> @@ -747,6 +874,8 @@ static int tegra_mc_probe(struct platform_device *pdev)
>>  		}
>>  	}
>>  
>> +	tegra_mc_interconnect_setup(mc);
> 
> Do you want to check the return value here for errors? If not, might as
> well make the function return void.

The error won't be fatal and shouldn't block the rest functionality of
the MC driver.

It's possible to return void, but it's not necessary because compiler
will take care of optimizing the code and to me it's more consistent to
have error code returned by the function.

Perhaps should be better to just add a comment telling that error
skipping is intentional?

...
>> diff --git a/drivers/memory/tegra/mc.h b/drivers/memory/tegra/mc.h
>> index afa3ba45c9e6..abeb6a2cc36a 100644
>> --- a/drivers/memory/tegra/mc.h
>> +++ b/drivers/memory/tegra/mc.h
>> @@ -115,4 +115,12 @@ extern const struct tegra_mc_soc tegra132_mc_soc;
>>  extern const struct tegra_mc_soc tegra210_mc_soc;
>>  #endif
>>  
>> +/*
>> + * These IDs are for internal use of Tegra's ICC, the values are chosen
>> + * such that they don't conflict with the device-tree ICC node IDs.
>> + */
>> +#define TEGRA_ICC_EMC		1000
>> +#define TEGRA_ICC_EMEM		2000
>> +#define TEGRA_ICC_MC		3000
> 
> Sounds to me like these could equally well be 1000, 1001 and 1002. Why
> leave these large holes in the number space?

There is no specific reason, I can change the numbers if you want.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
  2020-10-27 19:17       ` Dmitry Osipenko
@ 2020-10-27 19:34         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:34 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 10:17:48PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 11:55, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:48AM +0300, Dmitry Osipenko wrote:
> >> Memory controller is interconnected with memory clients and with the
> >> External Memory Controller. Document new interconnect property which
> >> turns memory controller into interconnect provider.
> >>
> >> Acked-by: Rob Herring <robh@kernel.org>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> >> index e55328237df4..739b7c6f2e26 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> >> @@ -16,6 +16,8 @@ Required properties:
> >>    IOMMU specifier needed to encode an address. GART supports only a single
> >>    address space that is shared by all devices, therefore no additional
> >>    information needed for the address encoding.
> >> +- #interconnect-cells : Should be 1. This cell represents memory client.
> >> +  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.
> > 
> > This is a list of required properties so you break the ABI. All existing
> > DTBs will be affected.
> 
> This is optional property for the older DTBs, but for newer DTs it's
> mandatory.

We do not consider here "older" or "newer" DTBs, but existing ones in
the world using this binding.

If it was optional so far, it cannot be made mandatory without changing
the ABI. Which is an ABI break.

> IIUC, it should be defined as a required property in the
> binding.
> 
> Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
> interconnect framework", which check presence of the ICC DT property.

The implementation indeed does not enforce it (except adding error msg,
about which I commented). Therefore it should be an optional property.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property
@ 2020-10-27 19:34         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:34 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 10:17:48PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 11:55, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:48AM +0300, Dmitry Osipenko wrote:
> >> Memory controller is interconnected with memory clients and with the
> >> External Memory Controller. Document new interconnect property which
> >> turns memory controller into interconnect provider.
> >>
> >> Acked-by: Rob Herring <robh@kernel.org>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra20-mc.txt          | 3 +++
> >>  1 file changed, 3 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> >> index e55328237df4..739b7c6f2e26 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-mc.txt
> >> @@ -16,6 +16,8 @@ Required properties:
> >>    IOMMU specifier needed to encode an address. GART supports only a single
> >>    address space that is shared by all devices, therefore no additional
> >>    information needed for the address encoding.
> >> +- #interconnect-cells : Should be 1. This cell represents memory client.
> >> +  The assignments may be found in header file <dt-bindings/memory/tegra20-mc.h>.
> > 
> > This is a list of required properties so you break the ABI. All existing
> > DTBs will be affected.
> 
> This is optional property for the older DTBs, but for newer DTs it's
> mandatory.

We do not consider here "older" or "newer" DTBs, but existing ones in
the world using this binding.

If it was optional so far, it cannot be made mandatory without changing
the ABI. Which is an ABI break.

> IIUC, it should be defined as a required property in the
> binding.
> 
> Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
> interconnect framework", which check presence of the ICC DT property.

The implementation indeed does not enforce it (except adding error msg,
about which I commented). Therefore it should be an optional property.

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 32/52] memory: tegra20-emc: Continue probing if timings are missing in device-tree
  2020-10-27 13:52     ` Thierry Reding
@ 2020-10-27 19:38       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:38 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 16:52, Thierry Reding пишет:
> On Mon, Oct 26, 2020 at 01:17:15AM +0300, Dmitry Osipenko wrote:
>> EMC driver will become mandatory after turning it into interconnect
>> provider because interconnect users, like display controller driver, will
>> fail to probe using newer device-trees that have interconnect properties.
>> Thus make EMC driver to probe even if timings are missing in device-tree.
> 
> Does it really have to be mandatory? Sounds like that's going to make it
> unnecessarily complicated to merge all of this. Is it complicated to
> make interconnect support optional in consumer drivers?

Interconnect provider can't be optional if interconnect properties
present in a device-tree because drivers that use ICC path will get
-EPROBE_DEFER until ICC provider is registered.

Older device-trees don't have ICC properties, and thus, the ICC
users/consumers will get a dummy NULL ICC path in this case. I.e. ICC
core handles this for us.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 32/52] memory: tegra20-emc: Continue probing if timings are missing in device-tree
@ 2020-10-27 19:38       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 19:38 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette

27.10.2020 16:52, Thierry Reding пишет:
> On Mon, Oct 26, 2020 at 01:17:15AM +0300, Dmitry Osipenko wrote:
>> EMC driver will become mandatory after turning it into interconnect
>> provider because interconnect users, like display controller driver, will
>> fail to probe using newer device-trees that have interconnect properties.
>> Thus make EMC driver to probe even if timings are missing in device-tree.
> 
> Does it really have to be mandatory? Sounds like that's going to make it
> unnecessarily complicated to merge all of this. Is it complicated to
> make interconnect support optional in consumer drivers?

Interconnect provider can't be optional if interconnect properties
present in a device-tree because drivers that use ICC path will get
-EPROBE_DEFER until ICC provider is registered.

Older device-trees don't have ICC properties, and thus, the ICC
users/consumers will get a dummy NULL ICC path in this case. I.e. ICC
core handles this for us.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
  2020-10-27 19:18       ` Dmitry Osipenko
@ 2020-10-27 19:39         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 10:18:35PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 12:05, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:52AM +0300, Dmitry Osipenko wrote:
> >> Memory controller is interconnected with memory clients and with the
> >> External Memory Controller. Document new interconnect property which
> >> turns memory controller into interconnect provider.
> >>
> >> Acked-by: Rob Herring <robh@kernel.org>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
> >>  1 file changed, 5 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> >> index 84fd57bcf0dc..5436e6d420bc 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> >> @@ -57,6 +57,9 @@ properties:
> >>    "#iommu-cells":
> >>      const: 1
> >>  
> >> +  "#interconnect-cells":
> >> +    const: 1
> >> +
> >>  patternProperties:
> >>    "^emc-timings-[0-9]+$":
> >>      type: object
> >> @@ -120,6 +123,7 @@ required:
> >>    - clock-names
> >>    - "#reset-cells"
> >>    - "#iommu-cells"
> >> +  - "#interconnect-cells"
> > 
> > Rob,
> > 
> > You were fine with adding a new required property which breaks all
> > existing DTBs?
> 
> This is a required property for the new bindings and optional for the
> older. Does it really need to be made optional in the binding?

Mhmm... that's an interesting point. I assumed that the bindings should
reflect current status of the ABI, but I could imagine that you update
the bindings while keeping the driver working with older DTBs.

How do you actually track then the ABI? If incompatible change can be
added to the bindings, later anyone anytime can also update the driver
to enforce the bindings. To require such property.

Best regards,
Krzysztof


> 
> > Were these bindings marked as unstable? The patchset does not even
> > say/scream that it breaks the ABI, so this might be quite a surprise for
> > someone...
> 
> Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
> interconnect framework" patch, which check presence of the new ICC DT
> property.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property
@ 2020-10-27 19:39         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 10:18:35PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 12:05, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:52AM +0300, Dmitry Osipenko wrote:
> >> Memory controller is interconnected with memory clients and with the
> >> External Memory Controller. Document new interconnect property which
> >> turns memory controller into interconnect provider.
> >>
> >> Acked-by: Rob Herring <robh@kernel.org>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra30-mc.yaml       | 5 +++++
> >>  1 file changed, 5 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> >> index 84fd57bcf0dc..5436e6d420bc 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra30-mc.yaml
> >> @@ -57,6 +57,9 @@ properties:
> >>    "#iommu-cells":
> >>      const: 1
> >>  
> >> +  "#interconnect-cells":
> >> +    const: 1
> >> +
> >>  patternProperties:
> >>    "^emc-timings-[0-9]+$":
> >>      type: object
> >> @@ -120,6 +123,7 @@ required:
> >>    - clock-names
> >>    - "#reset-cells"
> >>    - "#iommu-cells"
> >> +  - "#interconnect-cells"
> > 
> > Rob,
> > 
> > You were fine with adding a new required property which breaks all
> > existing DTBs?
> 
> This is a required property for the new bindings and optional for the
> older. Does it really need to be made optional in the binding?

Mhmm... that's an interesting point. I assumed that the bindings should
reflect current status of the ABI, but I could imagine that you update
the bindings while keeping the driver working with older DTBs.

How do you actually track then the ABI? If incompatible change can be
added to the bindings, later anyone anytime can also update the driver
to enforce the bindings. To require such property.

Best regards,
Krzysztof


> 
> > Were these bindings marked as unstable? The patchset does not even
> > say/scream that it breaks the ABI, so this might be quite a surprise for
> > someone...
> 
> Please see tegra_mc_interconnect_setup() in "memory: tegra-mc: Add
> interconnect framework" patch, which check presence of the new ICC DT
> property.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-27 19:22       ` Dmitry Osipenko
@ 2020-10-27 19:44         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
> >> @@ -31,17 +32,34 @@ Example:
> >>  		...
> >>  	};
> >>  
> >> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> > Hyphens for node name.
> 
> We already use underscores for the Tegra CPU OPP table.
> 
> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
> 
> What makes you think that hyphens will be a better choice? Is it a
> documented naming convention?

Unfortunately that's the source of confusion also for me because
Devicetree spec mentions both of them (and does not specify preferences).

The choice of dashes/hyphens comes now explicitly from all dtschema
files.  Previously, the documentation were emails from Rob. :)

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-27 19:44         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
> >> @@ -31,17 +32,34 @@ Example:
> >>  		...
> >>  	};
> >>  
> >> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> > Hyphens for node name.
> 
> We already use underscores for the Tegra CPU OPP table.
> 
> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
> 
> What makes you think that hyphens will be a better choice? Is it a
> documented naming convention?

Unfortunately that's the source of confusion also for me because
Devicetree spec mentions both of them (and does not specify preferences).

The choice of dashes/hyphens comes now explicitly from all dtschema
files.  Previously, the documentation were emails from Rob. :)

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
  2020-10-27 19:19       ` Dmitry Osipenko
@ 2020-10-27 19:48         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:48 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 10:19:28PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 13:25, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
> >> External memory controller is interconnected with memory controller and
> >> with external memory. Document new interconnect property which turns
> >> External Memory Controller into interconnect provider.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
> >>  1 file changed, 7 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >> index 278549f9e051..ac00832ceac1 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >> @@ -29,6 +29,9 @@ properties:
> >>      items:
> >>        - const: emc
> >>  
> >> +  "#interconnect-cells":
> >> +    const: 0
> >> +
> >>    nvidia,memory-controller:
> >>      $ref: /schemas/types.yaml#/definitions/phandle
> >>      description:
> >> @@ -327,6 +330,7 @@ required:
> >>    - clocks
> >>    - clock-names
> >>    - nvidia,memory-controller
> >> +  - "#interconnect-cells"
> > 
> > Another required property, what about all existing users of this binding?
> 
> EMC/devfreq drivers check presence of the new properties and ask users
> to upgrade the DT. The kernel will continue to work fine using older
> DTBs, but devfreq driver won't load.

If the devfreq was working fine before (with these older DTBs and older
kernel) then you break the feature.

If devfreq was not working or was not stable enough, then nothing is
broken so such change is accepted.

Which one is then?

> 
> >>  additionalProperties: false
> >>  
> >> @@ -345,6 +349,7 @@ examples:
> >>  
> >>          #iommu-cells = <1>;
> >>          #reset-cells = <1>;
> >> +        #interconnect-cells = <1>;
> > 
> > You meant '0'?
> 
> '1' is for the "mc" node in the example (not "emc" node).
> 
> Anyways, I'll move this hunk to the previous patch in order to fix the
> kernel bot warning.

Right, thanks.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
@ 2020-10-27 19:48         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-27 19:48 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 10:19:28PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 13:25, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
> >> External memory controller is interconnected with memory controller and
> >> with external memory. Document new interconnect property which turns
> >> External Memory Controller into interconnect provider.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
> >>  1 file changed, 7 insertions(+)
> >>
> >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >> index 278549f9e051..ac00832ceac1 100644
> >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >> @@ -29,6 +29,9 @@ properties:
> >>      items:
> >>        - const: emc
> >>  
> >> +  "#interconnect-cells":
> >> +    const: 0
> >> +
> >>    nvidia,memory-controller:
> >>      $ref: /schemas/types.yaml#/definitions/phandle
> >>      description:
> >> @@ -327,6 +330,7 @@ required:
> >>    - clocks
> >>    - clock-names
> >>    - nvidia,memory-controller
> >> +  - "#interconnect-cells"
> > 
> > Another required property, what about all existing users of this binding?
> 
> EMC/devfreq drivers check presence of the new properties and ask users
> to upgrade the DT. The kernel will continue to work fine using older
> DTBs, but devfreq driver won't load.

If the devfreq was working fine before (with these older DTBs and older
kernel) then you break the feature.

If devfreq was not working or was not stable enough, then nothing is
broken so such change is accepted.

Which one is then?

> 
> >>  additionalProperties: false
> >>  
> >> @@ -345,6 +349,7 @@ examples:
> >>  
> >>          #iommu-cells = <1>;
> >>          #reset-cells = <1>;
> >> +        #interconnect-cells = <1>;
> > 
> > You meant '0'?
> 
> '1' is for the "mc" node in the example (not "emc" node).
> 
> Anyways, I'll move this hunk to the previous patch in order to fix the
> kernel bot warning.

Right, thanks.

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
  2020-10-27 19:48         ` Krzysztof Kozlowski
@ 2020-10-27 20:16           ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:16 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 22:48, Krzysztof Kozlowski пишет:
> On Tue, Oct 27, 2020 at 10:19:28PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 13:25, Krzysztof Kozlowski пишет:
>>> On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
>>>> External memory controller is interconnected with memory controller and
>>>> with external memory. Document new interconnect property which turns
>>>> External Memory Controller into interconnect provider.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>>>>  1 file changed, 7 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>>>> index 278549f9e051..ac00832ceac1 100644
>>>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>>>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>>>> @@ -29,6 +29,9 @@ properties:
>>>>      items:
>>>>        - const: emc
>>>>  
>>>> +  "#interconnect-cells":
>>>> +    const: 0
>>>> +
>>>>    nvidia,memory-controller:
>>>>      $ref: /schemas/types.yaml#/definitions/phandle
>>>>      description:
>>>> @@ -327,6 +330,7 @@ required:
>>>>    - clocks
>>>>    - clock-names
>>>>    - nvidia,memory-controller
>>>> +  - "#interconnect-cells"
>>>
>>> Another required property, what about all existing users of this binding?
>>
>> EMC/devfreq drivers check presence of the new properties and ask users
>> to upgrade the DT. The kernel will continue to work fine using older
>> DTBs, but devfreq driver won't load.
> 
> If the devfreq was working fine before (with these older DTBs and older
> kernel) then you break the feature.
> 
> If devfreq was not working or was not stable enough, then nothing is
> broken so such change is accepted.
> 
> Which one is then?

Definitely the latter. The current devfreq works okay'ish, but we rely
on hardware to recover from temporal FIFO underflows and it's a
user-visible problem which this series addresses.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
@ 2020-10-27 20:16           ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:16 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 22:48, Krzysztof Kozlowski пишет:
> On Tue, Oct 27, 2020 at 10:19:28PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 13:25, Krzysztof Kozlowski пишет:
>>> On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
>>>> External memory controller is interconnected with memory controller and
>>>> with external memory. Document new interconnect property which turns
>>>> External Memory Controller into interconnect provider.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
>>>>  1 file changed, 7 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>>>> index 278549f9e051..ac00832ceac1 100644
>>>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>>>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
>>>> @@ -29,6 +29,9 @@ properties:
>>>>      items:
>>>>        - const: emc
>>>>  
>>>> +  "#interconnect-cells":
>>>> +    const: 0
>>>> +
>>>>    nvidia,memory-controller:
>>>>      $ref: /schemas/types.yaml#/definitions/phandle
>>>>      description:
>>>> @@ -327,6 +330,7 @@ required:
>>>>    - clocks
>>>>    - clock-names
>>>>    - nvidia,memory-controller
>>>> +  - "#interconnect-cells"
>>>
>>> Another required property, what about all existing users of this binding?
>>
>> EMC/devfreq drivers check presence of the new properties and ask users
>> to upgrade the DT. The kernel will continue to work fine using older
>> DTBs, but devfreq driver won't load.
> 
> If the devfreq was working fine before (with these older DTBs and older
> kernel) then you break the feature.
> 
> If devfreq was not working or was not stable enough, then nothing is
> broken so such change is accepted.
> 
> Which one is then?

Definitely the latter. The current devfreq works okay'ish, but we rely
on hardware to recover from temporal FIFO underflows and it's a
user-visible problem which this series addresses.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-27 19:44         ` Krzysztof Kozlowski
@ 2020-10-27 20:18           ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 22:44, Krzysztof Kozlowski пишет:
> On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
>>>> @@ -31,17 +32,34 @@ Example:
>>>>  		...
>>>>  	};
>>>>  
>>>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
>>> Hyphens for node name.
>>
>> We already use underscores for the Tegra CPU OPP table.
>>
>> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
>>
>> What makes you think that hyphens will be a better choice? Is it a
>> documented naming convention?
> 
> Unfortunately that's the source of confusion also for me because
> Devicetree spec mentions both of them (and does not specify preferences).
> 
> The choice of dashes/hyphens comes now explicitly from all dtschema
> files.  Previously, the documentation were emails from Rob. :)

Okay, I'll change it in v7. So far I haven't seen warnings about it from
the schema-checker.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-27 20:18           ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:18 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 22:44, Krzysztof Kozlowski пишет:
> On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
>>>> @@ -31,17 +32,34 @@ Example:
>>>>  		...
>>>>  	};
>>>>  
>>>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
>>> Hyphens for node name.
>>
>> We already use underscores for the Tegra CPU OPP table.
>>
>> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
>>
>> What makes you think that hyphens will be a better choice? Is it a
>> documented naming convention?
> 
> Unfortunately that's the source of confusion also for me because
> Devicetree spec mentions both of them (and does not specify preferences).
> 
> The choice of dashes/hyphens comes now explicitly from all dtschema
> files.  Previously, the documentation were emails from Rob. :)

Okay, I'll change it in v7. So far I haven't seen warnings about it from
the schema-checker.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
  2020-10-27 14:11     ` Thierry Reding
@ 2020-10-27 20:22       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:22 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 17:11, Thierry Reding пишет:
...
>> +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
>> +{
>> +	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
>> +	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
>> +	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
>> +	unsigned long long rate = max(avg_bw, peak_bw);
>> +	unsigned int dram_data_bus_width_bytes = 4;
> 
> Perhaps use something shorter for this variable (like dram_bus_width)? Also,
> since it's never modified, perhaps make it const? Or a #define?

It actually could be 2, depending on a board configuration, but I don't
know whether a 16bit bus was ever used in a wild. AFAIK, nv-tegra
kernels assumes 32bit bus for all devices.

...
>> +err_msg:
>> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
> 
> It might be worth duplicating this error message to the failure
> locations so that the exact failure can be identified.

I think it should be better to extend error messages on by as-needed
basis. It's very unlikely that we will ever see this error in practice.
Okay?

...
>> +	 * of the client's FIFO buffers. Secondly, we need to take into
>> +	 * account impurities of the memory subsystem.
>> +	 */
>> +	if (tag == TEGRA_MC_ICC_TAG_ISO)
>> +		peak_bw = tegra_mc_scale_percents(peak_bw, 300);
> 
> 300% sounds a bit excessive. Do we really need that much?

It should be possible to drop it to 150% by tuning priority timers and
hysteresis of the clients, but some of those configurations are placed
within device registers range and we will need a more complicated
bandwidth manager.

The 300% is an overestimation, but it's better to overestimate for the
starter than have an unusable devices. This is what nv-tegra kernel does
as well, btw.

>> +
>> +	*agg_avg += avg_bw;
>> +	*agg_peak = max(*agg_peak, peak_bw);
> 
> I'm not very familiar with ICC, but shouldn't the aggregated peak value
> be the sum of the current aggregated peak and the new peak bandwidth?
> Currently you're selecting the maximum peak bandwidth across all
> clients, so isn't that going to be too small if for whatever reason
> multiple clients need peak bandwidth at the same time?

It's up to the platform drivers to decide how to interpret and use the
avg and peak values.

Please see the above emc_icc_set() which selects max of (avg, peak)
values, but maybe it also should be good to move it out from ICC set()
to the ICC aggregate() callback:

*agg_peak = max(*agg_peak, *agg_avg);

I'll need to take a closer look.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
@ 2020-10-27 20:22       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:22 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette

27.10.2020 17:11, Thierry Reding пишет:
...
>> +static int emc_icc_set(struct icc_node *src, struct icc_node *dst)
>> +{
>> +	struct tegra_emc *emc = to_tegra_emc_provider(dst->provider);
>> +	unsigned long long peak_bw = icc_units_to_bps(dst->peak_bw);
>> +	unsigned long long avg_bw = icc_units_to_bps(dst->avg_bw);
>> +	unsigned long long rate = max(avg_bw, peak_bw);
>> +	unsigned int dram_data_bus_width_bytes = 4;
> 
> Perhaps use something shorter for this variable (like dram_bus_width)? Also,
> since it's never modified, perhaps make it const? Or a #define?

It actually could be 2, depending on a board configuration, but I don't
know whether a 16bit bus was ever used in a wild. AFAIK, nv-tegra
kernels assumes 32bit bus for all devices.

...
>> +err_msg:
>> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
> 
> It might be worth duplicating this error message to the failure
> locations so that the exact failure can be identified.

I think it should be better to extend error messages on by as-needed
basis. It's very unlikely that we will ever see this error in practice.
Okay?

...
>> +	 * of the client's FIFO buffers. Secondly, we need to take into
>> +	 * account impurities of the memory subsystem.
>> +	 */
>> +	if (tag == TEGRA_MC_ICC_TAG_ISO)
>> +		peak_bw = tegra_mc_scale_percents(peak_bw, 300);
> 
> 300% sounds a bit excessive. Do we really need that much?

It should be possible to drop it to 150% by tuning priority timers and
hysteresis of the clients, but some of those configurations are placed
within device registers range and we will need a more complicated
bandwidth manager.

The 300% is an overestimation, but it's better to overestimate for the
starter than have an unusable devices. This is what nv-tegra kernel does
as well, btw.

>> +
>> +	*agg_avg += avg_bw;
>> +	*agg_peak = max(*agg_peak, peak_bw);
> 
> I'm not very familiar with ICC, but shouldn't the aggregated peak value
> be the sum of the current aggregated peak and the new peak bandwidth?
> Currently you're selecting the maximum peak bandwidth across all
> clients, so isn't that going to be too small if for whatever reason
> multiple clients need peak bandwidth at the same time?

It's up to the platform drivers to decide how to interpret and use the
avg and peak values.

Please see the above emc_icc_set() which selects max of (avg, peak)
values, but maybe it also should be good to move it out from ICC set()
to the ICC aggregate() callback:

*agg_peak = max(*agg_peak, *agg_avg);

I'll need to take a closer look.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
  2020-10-27 10:09     ` Krzysztof Kozlowski
@ 2020-10-27 20:25       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:25 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 13:09, Krzysztof Kozlowski пишет:
...
>> +err_msg:
>> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
> 
> You will print such errors on all existing DTBs. Since it is not a
> failure of probe (it is actually quite expected, normal situation when
> booting with older DTB), let's change it to warning (here and in all
> other places and drivers).

The existing DTBs will be stopped on the error message below.

>> +
>> +	return err;
>> +}
>> +
>> +static int tegra_emc_opp_table_init(struct tegra_emc *emc)
>> +{
>> +	const char *rname = "core";
>> +	int err;
>> +
>> +	/*
>> +	 * Legacy device-trees don't have OPP table and EMC driver isn't
>> +	 * useful in this case.
>> +	 */
>> +	if (!device_property_present(emc->dev, "operating-points-v2")) {
>> +		dev_err(emc->dev, "OPP table not found\n");
>> +		dev_err(emc->dev, "please update your device tree\n");
>> +		return -ENODEV;
>> +	}

The existing DTBs are stopped here.

...
>> +	err = tegra_emc_opp_table_init(emc);
>> +	if (err)
>> +		goto unreg_notifier;
> 
> This looks like the ABI break I mentioned around DT bindings. Are the
> bindings marked as unstable?

This T20 EMC driver wasn't ever used so far at all and this series makes
it useful. Hence I think it should be fine to assume that the T20 EMC
ABI is unstable.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
@ 2020-10-27 20:25       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:25 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 13:09, Krzysztof Kozlowski пишет:
...
>> +err_msg:
>> +	dev_err(emc->dev, "failed to initialize ICC: %d\n", err);
> 
> You will print such errors on all existing DTBs. Since it is not a
> failure of probe (it is actually quite expected, normal situation when
> booting with older DTB), let's change it to warning (here and in all
> other places and drivers).

The existing DTBs will be stopped on the error message below.

>> +
>> +	return err;
>> +}
>> +
>> +static int tegra_emc_opp_table_init(struct tegra_emc *emc)
>> +{
>> +	const char *rname = "core";
>> +	int err;
>> +
>> +	/*
>> +	 * Legacy device-trees don't have OPP table and EMC driver isn't
>> +	 * useful in this case.
>> +	 */
>> +	if (!device_property_present(emc->dev, "operating-points-v2")) {
>> +		dev_err(emc->dev, "OPP table not found\n");
>> +		dev_err(emc->dev, "please update your device tree\n");
>> +		return -ENODEV;
>> +	}

The existing DTBs are stopped here.

...
>> +	err = tegra_emc_opp_table_init(emc);
>> +	if (err)
>> +		goto unreg_notifier;
> 
> This looks like the ABI break I mentioned around DT bindings. Are the
> bindings marked as unstable?

This T20 EMC driver wasn't ever used so far at all and this series makes
it useful. Hence I think it should be fine to assume that the T20 EMC
ABI is unstable.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
  2020-10-27  5:10     ` Viresh Kumar
@ 2020-10-27 20:26       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:26 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

27.10.2020 08:10, Viresh Kumar пишет:
> On 26-10-20, 01:17, Dmitry Osipenko wrote:
>> This patch fixes lockup which happens when OPP table is released if
>> interconnect provider uses OPP in the icc_provider->set() callback
>> and bandwidth of the ICC path is set to 0 by the ICC core when path
>> is released. The icc_put() doesn't need the opp_table_lock protection,
>> hence let's move it outside of the lock in order to resolve the problem.
>>
>> In particular this fixes tegra-devfreq driver lockup on trying to unload
>> the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
>> provider also uses OPP for DVFS, hence they both take same opp_table_lock
>> when OPP table of the devfreq is released.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
...
> 
> Never make such _fixes_ part of such a big patchset. Always send them
> separately.

Perhaps it's not obvious from the commit description that this patch
doesn't fix any known problems of the current mainline kernel and it's
needed only for the new patches.

> Having said that, I already have a patch with me which shall fix it for you as
> well:

I see that yours fix is already applied, thanks!

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
@ 2020-10-27 20:26       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:26 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, linux-pm, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

27.10.2020 08:10, Viresh Kumar пишет:
> On 26-10-20, 01:17, Dmitry Osipenko wrote:
>> This patch fixes lockup which happens when OPP table is released if
>> interconnect provider uses OPP in the icc_provider->set() callback
>> and bandwidth of the ICC path is set to 0 by the ICC core when path
>> is released. The icc_put() doesn't need the opp_table_lock protection,
>> hence let's move it outside of the lock in order to resolve the problem.
>>
>> In particular this fixes tegra-devfreq driver lockup on trying to unload
>> the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
>> provider also uses OPP for DVFS, hence they both take same opp_table_lock
>> when OPP table of the devfreq is released.
>>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
...
> 
> Never make such _fixes_ part of such a big patchset. Always send them
> separately.

Perhaps it's not obvious from the commit description that this patch
doesn't fix any known problems of the current mainline kernel and it's
needed only for the new patches.

> Having said that, I already have a patch with me which shall fix it for you as
> well:

I see that yours fix is already applied, thanks!
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
  2020-10-27 10:27     ` Krzysztof Kozlowski
@ 2020-10-27 20:30       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:30 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 13:27, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:17:24AM +0300, Dmitry Osipenko wrote:
>> Use devm_platform_ioremap_resource() helper which makes code a bit
>> cleaner.
> 
> Such cleanups (and few other in this patchset) should be at beginning of
> patchset or even as part of a separate one.  I think there is not much
> stopping anyone from applying these... except that you put them in the
> middle of big dependency.

Some of these cleanup patches can't be applied separately without a need
to make a rebase. I think it should be more preferred to have all the
patches within a single series.

I'll try to reorder the patches in v7 if this will ease the review, thanks.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
@ 2020-10-27 20:30       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:30 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 13:27, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:17:24AM +0300, Dmitry Osipenko wrote:
>> Use devm_platform_ioremap_resource() helper which makes code a bit
>> cleaner.
> 
> Such cleanups (and few other in this patchset) should be at beginning of
> patchset or even as part of a separate one.  I think there is not much
> stopping anyone from applying these... except that you put them in the
> middle of big dependency.

Some of these cleanup patches can't be applied separately without a need
to make a rebase. I think it should be more preferred to have all the
patches within a single series.

I'll try to reorder the patches in v7 if this will ease the review, thanks.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
  2020-10-27  8:52       ` Krzysztof Kozlowski
@ 2020-10-27 20:31         ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:31 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Chanwoo Choi, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Rob Herring, Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm, linux-kernel,
	dri-devel, devicetree

27.10.2020 11:52, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 10:14:10PM +0300, Dmitry Osipenko wrote:
>> 26.10.2020 18:08, Krzysztof Kozlowski пишет:
>>> On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
>>>> Hello,
>>>>
>>>> This series brings initial support for memory interconnect to Tegra20,
>>>> Tegra30 and Tegra124 SoCs.
>>>>
>>>> For the starter only display controllers and devfreq devices are getting
>>>> interconnect API support, others could be supported later on. The display
>>>> controllers have the biggest demand for interconnect API right now because
>>>> dynamic memory frequency scaling can't be done safely without taking into
>>>> account bandwidth requirement from the displays. In particular this series
>>>> fixes distorted display output on T30 Ouya and T124 TK1 devices.
>>>
>>> Hi,
>>>
>>> You introduced in v6 multiple new patches. Could you describe the
>>> dependencies, if any?
>>
>> Hello,
>>
>> The v6 dropped some older patches and replaced them with the new
>> patches. Previously I wanted to postpone the more complex changes for
>> later times, like supporting OPP tables and DVFS, but then the review
>> started to take more time than was expected and there was enough time to
>> complete those features.
>>
>> There are five basic sets of patches:
>>
>> 	1. DT bindings
>> 	2. DT changes
>> 	3. SoC, clk and memory
>> 	4. devfreq
>> 	5. DRM
>>
>> Each set could be applied separately.
>>
>> Memory patches have a build dependency on the SoC and clk patches.
>>
>> The "tegra-mc: Add interconnect framework" and "Add and use
>> devm_tegra_get_memory_controller()" are the root build dependencies for
>> all memory/ patches. Other patches are grouped per SoC generation
>> (Tegra20/30/124), patches within a SoC-gen group are interdependent.
>>
>> I suppose the best variant would be to merge the whole series via
>> tegra-tree in order to preserve logical order of the patches. Although,
>> merging each set of patches separately also should be okay to do.
> 
> Thanks for explanation. I already have three patches for Tegra MC (and
> probably two more will be respun) so this might be conflict-prone. The
> easiest in such case is to provide me soc and clk patches on the branch,
> so I could keep all Tegra MC together.

Okay, but those T210 patches don't touch the same code, neither same
source files. For now there should be no merge conflicts.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs
@ 2020-10-27 20:31         ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:31 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 11:52, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 10:14:10PM +0300, Dmitry Osipenko wrote:
>> 26.10.2020 18:08, Krzysztof Kozlowski пишет:
>>> On Mon, Oct 26, 2020 at 01:16:43AM +0300, Dmitry Osipenko wrote:
>>>> Hello,
>>>>
>>>> This series brings initial support for memory interconnect to Tegra20,
>>>> Tegra30 and Tegra124 SoCs.
>>>>
>>>> For the starter only display controllers and devfreq devices are getting
>>>> interconnect API support, others could be supported later on. The display
>>>> controllers have the biggest demand for interconnect API right now because
>>>> dynamic memory frequency scaling can't be done safely without taking into
>>>> account bandwidth requirement from the displays. In particular this series
>>>> fixes distorted display output on T30 Ouya and T124 TK1 devices.
>>>
>>> Hi,
>>>
>>> You introduced in v6 multiple new patches. Could you describe the
>>> dependencies, if any?
>>
>> Hello,
>>
>> The v6 dropped some older patches and replaced them with the new
>> patches. Previously I wanted to postpone the more complex changes for
>> later times, like supporting OPP tables and DVFS, but then the review
>> started to take more time than was expected and there was enough time to
>> complete those features.
>>
>> There are five basic sets of patches:
>>
>> 	1. DT bindings
>> 	2. DT changes
>> 	3. SoC, clk and memory
>> 	4. devfreq
>> 	5. DRM
>>
>> Each set could be applied separately.
>>
>> Memory patches have a build dependency on the SoC and clk patches.
>>
>> The "tegra-mc: Add interconnect framework" and "Add and use
>> devm_tegra_get_memory_controller()" are the root build dependencies for
>> all memory/ patches. Other patches are grouped per SoC generation
>> (Tegra20/30/124), patches within a SoC-gen group are interdependent.
>>
>> I suppose the best variant would be to merge the whole series via
>> tegra-tree in order to preserve logical order of the patches. Although,
>> merging each set of patches separately also should be okay to do.
> 
> Thanks for explanation. I already have three patches for Tegra MC (and
> probably two more will be respun) so this might be conflict-prone. The
> easiest in such case is to provide me soc and clk patches on the branch,
> so I could keep all Tegra MC together.

Okay, but those T210 patches don't touch the same code, neither same
source files. For now there should be no merge conflicts.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
  2020-10-27 19:30         ` Krzysztof Kozlowski
@ 2020-10-27 20:37           ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:37 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 22:30, Krzysztof Kozlowski пишет:
> On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 11:54, Krzysztof Kozlowski пишет:
>>> On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
>>>> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
>>>> reprogrammed when memory frequency changes. Tegra Memory Controller sits
>>>> behind EMC and these controllers are tightly coupled. This patch adds the
>>>> new phandle property which allows to properly express connection of EMC
>>>> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
>>>> par with Tegra30+ EMC bindings, which is handy to have.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>>>>  1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>>>> index 567cffd37f3f..1b0d4417aad8 100644
>>>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>>>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>>>> @@ -12,6 +12,7 @@ Properties:
>>>>    irrespective of ram-code configuration.
>>>>  - interrupts : Should contain EMC General interrupt.
>>>>  - clocks : Should contain EMC clock.
>>>> +- nvidia,memory-controller : Phandle of the Memory Controller node.
>>>
>>> It looks like you adding a required property which is an ABI break.
>> The T20 EMC driver is unused so far in upstream and it will become used
>> only once this series is applied. Hence it's fine to change the ABI.
> 
> The ABI is not about upstream, but downstream. There are no other
> upstreams using this ABI. Unless you have in mind that existing T20 EMC
> driver was a noop, doing absolutely nothing, therefore there is no
> breakage of any other users?

The T20 EMC driver was a 100% noop for now. It's safe to change the ABI.

The T30/124 EMC drivers have users, but these are unsafe drivers (with
the known issues) until this series is applied.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
@ 2020-10-27 20:37           ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:37 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 22:30, Krzysztof Kozlowski пишет:
> On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 11:54, Krzysztof Kozlowski пишет:
>>> On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
>>>> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
>>>> reprogrammed when memory frequency changes. Tegra Memory Controller sits
>>>> behind EMC and these controllers are tightly coupled. This patch adds the
>>>> new phandle property which allows to properly express connection of EMC
>>>> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
>>>> par with Tegra30+ EMC bindings, which is handy to have.
>>>>
>>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>>> ---
>>>>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>>>>  1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>>>> index 567cffd37f3f..1b0d4417aad8 100644
>>>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>>>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
>>>> @@ -12,6 +12,7 @@ Properties:
>>>>    irrespective of ram-code configuration.
>>>>  - interrupts : Should contain EMC General interrupt.
>>>>  - clocks : Should contain EMC clock.
>>>> +- nvidia,memory-controller : Phandle of the Memory Controller node.
>>>
>>> It looks like you adding a required property which is an ABI break.
>> The T20 EMC driver is unused so far in upstream and it will become used
>> only once this series is applied. Hence it's fine to change the ABI.
> 
> The ABI is not about upstream, but downstream. There are no other
> upstreams using this ABI. Unless you have in mind that existing T20 EMC
> driver was a noop, doing absolutely nothing, therefore there is no
> breakage of any other users?

The T20 EMC driver was a 100% noop for now. It's safe to change the ABI.

The T30/124 EMC drivers have users, but these are unsafe drivers (with
the known issues) until this series is applied.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 20/52] ARM: tegra: Correct EMC registers size in Tegra20 device-tree
  2020-10-27  9:10     ` Krzysztof Kozlowski
@ 2020-10-27 20:43       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:43 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 12:10, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:17:03AM +0300, Dmitry Osipenko wrote:
>> The Tegra20 EMC registers size should be twice bigger. This patch fixes
>> the size.
> 
> Don't use "This patch" (this appears here). Better to use:
> "Fix the size of ..." or just "The size should be twice bigger" as it is
> obvious that you fix it.
> 
> https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L151
> 
> Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Thanks, I wasn't aware that it's a preferred wording style now.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 20/52] ARM: tegra: Correct EMC registers size in Tegra20 device-tree
@ 2020-10-27 20:43       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 20:43 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

27.10.2020 12:10, Krzysztof Kozlowski пишет:
> On Mon, Oct 26, 2020 at 01:17:03AM +0300, Dmitry Osipenko wrote:
>> The Tegra20 EMC registers size should be twice bigger. This patch fixes
>> the size.
> 
> Don't use "This patch" (this appears here). Better to use:
> "Fix the size of ..." or just "The size should be twice bigger" as it is
> obvious that you fix it.
> 
> https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L151
> 
> Acked-by: Krzysztof Kozlowski <krzk@kernel.org>

Thanks, I wasn't aware that it's a preferred wording style now.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
  2020-10-27 20:22       ` Dmitry Osipenko
@ 2020-10-27 21:12         ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 21:12 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Jonathan Hunter, Georgi Djakov, Rob Herring, Michael Turquette,
	Stephen Boyd, Peter De Schrijver, MyungJoo Ham, Kyungmin Park,
	Chanwoo Choi, Mikko Perttunen, Viresh Kumar, Peter Geis,
	Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

27.10.2020 23:22, Dmitry Osipenko пишет:
...
>>> +
>>> +	*agg_avg += avg_bw;
>>> +	*agg_peak = max(*agg_peak, peak_bw);
>>
>> I'm not very familiar with ICC, but shouldn't the aggregated peak value
>> be the sum of the current aggregated peak and the new peak bandwidth?
>> Currently you're selecting the maximum peak bandwidth across all
>> clients, so isn't that going to be too small if for whatever reason
>> multiple clients need peak bandwidth at the same time?

The current variant with max-peak selection should be okay since it
takes into account the competing ISO bandwidths of other devices by
overestimating the bandwidth.

For now we have only display ISO clients and it won't be a problem to
tune the algorithm later on if it won't work well for other ISO clients.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 33/52] memory: tegra20: Support interconnect framework
@ 2020-10-27 21:12         ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-27 21:12 UTC (permalink / raw)
  To: Thierry Reding
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Rob Herring, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette

27.10.2020 23:22, Dmitry Osipenko пишет:
...
>>> +
>>> +	*agg_avg += avg_bw;
>>> +	*agg_peak = max(*agg_peak, peak_bw);
>>
>> I'm not very familiar with ICC, but shouldn't the aggregated peak value
>> be the sum of the current aggregated peak and the new peak bandwidth?
>> Currently you're selecting the maximum peak bandwidth across all
>> clients, so isn't that going to be too small if for whatever reason
>> multiple clients need peak bandwidth at the same time?

The current variant with max-peak selection should be okay since it
takes into account the competing ISO bandwidths of other devices by
overestimating the bandwidth.

For now we have only display ISO clients and it won't be a problem to
tune the algorithm later on if it won't work well for other ISO clients.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
  2020-10-27 20:26       ` Dmitry Osipenko
@ 2020-10-28  4:03         ` Viresh Kumar
  -1 siblings, 0 replies; 290+ messages in thread
From: Viresh Kumar @ 2020-10-28  4:03 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

On 27-10-20, 23:26, Dmitry Osipenko wrote:
> 27.10.2020 08:10, Viresh Kumar пишет:
> > On 26-10-20, 01:17, Dmitry Osipenko wrote:
> >> This patch fixes lockup which happens when OPP table is released if
> >> interconnect provider uses OPP in the icc_provider->set() callback
> >> and bandwidth of the ICC path is set to 0 by the ICC core when path
> >> is released. The icc_put() doesn't need the opp_table_lock protection,
> >> hence let's move it outside of the lock in order to resolve the problem.
> >>
> >> In particular this fixes tegra-devfreq driver lockup on trying to unload
> >> the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
> >> provider also uses OPP for DVFS, hence they both take same opp_table_lock
> >> when OPP table of the devfreq is released.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> ...
> > 
> > Never make such _fixes_ part of such a big patchset. Always send them
> > separately.
> 
> Perhaps it's not obvious from the commit description that this patch
> doesn't fix any known problems of the current mainline kernel and it's
> needed only for the new patches.

No, I understood that we started getting the warning now only after
some other patches of yours. Nevertheless, it should be considered as
a fix only as that generated lockdep because of locking placement. And
so sending such stuff separately is better as that allows people to
apply it fast.

> > Having said that, I already have a patch with me which shall fix it for you as
> > well:
> 
> I see that yours fix is already applied, thanks!

I hope it worked for you. Thanks.

-- 
viresh

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock
@ 2020-10-28  4:03         ` Viresh Kumar
  0 siblings, 0 replies; 290+ messages in thread
From: Viresh Kumar @ 2020-10-28  4:03 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, linux-pm, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

On 27-10-20, 23:26, Dmitry Osipenko wrote:
> 27.10.2020 08:10, Viresh Kumar пишет:
> > On 26-10-20, 01:17, Dmitry Osipenko wrote:
> >> This patch fixes lockup which happens when OPP table is released if
> >> interconnect provider uses OPP in the icc_provider->set() callback
> >> and bandwidth of the ICC path is set to 0 by the ICC core when path
> >> is released. The icc_put() doesn't need the opp_table_lock protection,
> >> hence let's move it outside of the lock in order to resolve the problem.
> >>
> >> In particular this fixes tegra-devfreq driver lockup on trying to unload
> >> the driver module. The devfreq driver uses OPP-bandwidth API and its ICC
> >> provider also uses OPP for DVFS, hence they both take same opp_table_lock
> >> when OPP table of the devfreq is released.
> >>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> ...
> > 
> > Never make such _fixes_ part of such a big patchset. Always send them
> > separately.
> 
> Perhaps it's not obvious from the commit description that this patch
> doesn't fix any known problems of the current mainline kernel and it's
> needed only for the new patches.

No, I understood that we started getting the warning now only after
some other patches of yours. Nevertheless, it should be considered as
a fix only as that generated lockdep because of locking placement. And
so sending such stuff separately is better as that allows people to
apply it fast.

> > Having said that, I already have a patch with me which shall fix it for you as
> > well:
> 
> I see that yours fix is already applied, thanks!

I hope it worked for you. Thanks.

-- 
viresh
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 03/52] dt-bindings: memory: tegra20: emc: Correct registers range in example
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-28 15:16     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:16 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Jonathan Hunter, Kyungmin Park, Krzysztof Kozlowski,
	Thierry Reding, Nicolas Chauvet, linux-tegra, MyungJoo Ham,
	Peter Geis, Rob Herring, linux-pm, Chanwoo Choi, Mikko Perttunen,
	Michael Turquette, Viresh Kumar, Stephen Boyd, Georgi Djakov,
	devicetree, linux-kernel, Peter De Schrijver, dri-devel

On Mon, 26 Oct 2020 01:16:46 +0300, Dmitry Osipenko wrote:
> There is superfluous zero in the registers base address and registers
> size should be twice bigger.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 03/52] dt-bindings: memory: tegra20: emc: Correct registers range in example
@ 2020-10-28 15:16     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:16 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: dri-devel, devicetree, Mikko Perttunen, Chanwoo Choi, linux-pm,
	Nicolas Chauvet, Viresh Kumar, Michael Turquette, Stephen Boyd,
	Krzysztof Kozlowski, Jonathan Hunter, Rob Herring, Kyungmin Park,
	Thierry Reding, MyungJoo Ham, Peter Geis, linux-tegra,
	Peter De Schrijver, Georgi Djakov, linux-kernel

On Mon, 26 Oct 2020 01:16:46 +0300, Dmitry Osipenko wrote:
> There is superfluous zero in the registers base address and registers
> size should be twice bigger.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 

Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
  2020-10-27 19:30         ` Krzysztof Kozlowski
@ 2020-10-28 15:23           ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 08:30:39PM +0100, Krzysztof Kozlowski wrote:
> On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
> > 27.10.2020 11:54, Krzysztof Kozlowski пишет:
> > > On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> > >> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> > >> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> > >> behind EMC and these controllers are tightly coupled. This patch adds the
> > >> new phandle property which allows to properly express connection of EMC
> > >> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> > >> par with Tegra30+ EMC bindings, which is handy to have.
> > >>
> > >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > >> ---
> > >>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
> > >>  1 file changed, 2 insertions(+)
> > >>
> > >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > >> index 567cffd37f3f..1b0d4417aad8 100644
> > >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > >> @@ -12,6 +12,7 @@ Properties:
> > >>    irrespective of ram-code configuration.
> > >>  - interrupts : Should contain EMC General interrupt.
> > >>  - clocks : Should contain EMC clock.
> > >> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> > > 
> > > It looks like you adding a required property which is an ABI break.
> > The T20 EMC driver is unused so far in upstream and it will become used
> > only once this series is applied. Hence it's fine to change the ABI.
> 
> The ABI is not about upstream, but downstream. 

"If it's not upstream, it doesn't exist."

Though we do have to account for out of tree users where the DT is not 
in tree, but upstream drivers are used. Downstream as in vendor kernels 
typically has loads of other crap.

> There are no other
> upstreams using this ABI. Unless you have in mind that existing T20 EMC
> driver was a noop, doing absolutely nothing, therefore there is no
> breakage of any other users?

ABI breaks are ultimately up to the platform maintainers to decide.

Rob

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
@ 2020-10-28 15:23           ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:23 UTC (permalink / raw)
  To: Krzysztof Kozlowski
  Cc: Peter De Schrijver, Mikko Perttunen, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, dri-devel, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Dmitry Osipenko, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 08:30:39PM +0100, Krzysztof Kozlowski wrote:
> On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
> > 27.10.2020 11:54, Krzysztof Kozlowski пишет:
> > > On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> > >> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> > >> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> > >> behind EMC and these controllers are tightly coupled. This patch adds the
> > >> new phandle property which allows to properly express connection of EMC
> > >> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> > >> par with Tegra30+ EMC bindings, which is handy to have.
> > >>
> > >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > >> ---
> > >>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
> > >>  1 file changed, 2 insertions(+)
> > >>
> > >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > >> index 567cffd37f3f..1b0d4417aad8 100644
> > >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > >> @@ -12,6 +12,7 @@ Properties:
> > >>    irrespective of ram-code configuration.
> > >>  - interrupts : Should contain EMC General interrupt.
> > >>  - clocks : Should contain EMC clock.
> > >> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> > > 
> > > It looks like you adding a required property which is an ABI break.
> > The T20 EMC driver is unused so far in upstream and it will become used
> > only once this series is applied. Hence it's fine to change the ABI.
> 
> The ABI is not about upstream, but downstream. 

"If it's not upstream, it doesn't exist."

Though we do have to account for out of tree users where the DT is not 
in tree, but upstream drivers are used. Downstream as in vendor kernels 
typically has loads of other crap.

> There are no other
> upstreams using this ABI. Unless you have in mind that existing T20 EMC
> driver was a noop, doing absolutely nothing, therefore there is no
> breakage of any other users?

ABI breaks are ultimately up to the platform maintainers to decide.

Rob
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia, memory-controller property
  2020-10-25 22:16   ` [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia, memory-controller property Dmitry Osipenko
@ 2020-10-28 15:23     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:23 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Stephen Boyd, linux-pm, Georgi Djakov, Peter De Schrijver,
	Peter Geis, Jonathan Hunter, Rob Herring, Kyungmin Park,
	Nicolas Chauvet, Krzysztof Kozlowski, devicetree, Chanwoo Choi,
	Thierry Reding, Michael Turquette, Mikko Perttunen, MyungJoo Ham,
	dri-devel, linux-kernel, linux-tegra, Viresh Kumar

On Mon, 26 Oct 2020 01:16:47 +0300, Dmitry Osipenko wrote:
> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> behind EMC and these controllers are tightly coupled. This patch adds the
> new phandle property which allows to properly express connection of EMC
> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> par with Tegra30+ EMC bindings, which is handy to have.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia, memory-controller property
@ 2020-10-28 15:23     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:23 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: dri-devel, devicetree, Mikko Perttunen, Chanwoo Choi, linux-pm,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-kernel,
	Krzysztof Kozlowski, Jonathan Hunter, Nicolas Chauvet,
	Kyungmin Park, Rob Herring, Thierry Reding, MyungJoo Ham,
	Peter Geis, linux-tegra, Michael Turquette, Georgi Djakov

On Mon, 26 Oct 2020 01:16:47 +0300, Dmitry Osipenko wrote:
> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> behind EMC and these controllers are tightly coupled. This patch adds the
> new phandle property which allows to properly express connection of EMC
> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> par with Tegra30+ EMC bindings, which is handy to have.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
>  1 file changed, 2 insertions(+)
> 

Acked-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-27 20:18           ` Dmitry Osipenko
@ 2020-10-28 15:26             ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:26 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Krzysztof Kozlowski, Thierry Reding, Jonathan Hunter,
	Georgi Djakov, Michael Turquette, Stephen Boyd,
	Peter De Schrijver, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
	Mikko Perttunen, Viresh Kumar, Peter Geis, Nicolas Chauvet,
	linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 11:18:34PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 22:44, Krzysztof Kozlowski пишет:
> > On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
> >> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
> >>>> @@ -31,17 +32,34 @@ Example:
> >>>>  		...
> >>>>  	};
> >>>>  
> >>>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> >>> Hyphens for node name.
> >>
> >> We already use underscores for the Tegra CPU OPP table.
> >>
> >> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
> >>
> >> What makes you think that hyphens will be a better choice? Is it a
> >> documented naming convention?
> > 
> > Unfortunately that's the source of confusion also for me because
> > Devicetree spec mentions both of them (and does not specify preferences).
> > 
> > The choice of dashes/hyphens comes now explicitly from all dtschema
> > files.  Previously, the documentation were emails from Rob. :)
> 
> Okay, I'll change it in v7. So far I haven't seen warnings about it from
> the schema-checker.

dtc with W=2 will warn.

The bigger issue is the name should be generic.

Rob


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-28 15:26             ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:26 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 11:18:34PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 22:44, Krzysztof Kozlowski пишет:
> > On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
> >> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
> >>>> @@ -31,17 +32,34 @@ Example:
> >>>>  		...
> >>>>  	};
> >>>>  
> >>>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> >>> Hyphens for node name.
> >>
> >> We already use underscores for the Tegra CPU OPP table.
> >>
> >> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
> >>
> >> What makes you think that hyphens will be a better choice? Is it a
> >> documented naming convention?
> > 
> > Unfortunately that's the source of confusion also for me because
> > Devicetree spec mentions both of them (and does not specify preferences).
> > 
> > The choice of dashes/hyphens comes now explicitly from all dtschema
> > files.  Previously, the documentation were emails from Rob. :)
> 
> Okay, I'll change it in v7. So far I haven't seen warnings about it from
> the schema-checker.

dtc with W=2 will warn.

The bigger issue is the name should be generic.

Rob

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-28 15:28     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:28 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
> External Memory Controller can gather various hardware statistics that
> are intended to be used for debugging purposes and for dynamic frequency
> scaling of memory bus.
> 
> Document the new mfd-simple compatible and EMC statistics sub-device.

It's simple-mfd.

That should only be used if the child has no dependencies on the parent 
node (and driver).

> The subdev contains EMC DFS OPP table and interconnect paths to be used
> for dynamic scaling of system's memory bandwidth based on EMC utilization
> statistics.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 8d09b228ac42..382aabcd6952 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -4,7 +4,7 @@ Properties:
>  - name : Should be emc
>  - #address-cells : Should be 1
>  - #size-cells : Should be 0
> -- compatible : Should contain "nvidia,tegra20-emc".
> +- compatible : Should contain "nvidia,tegra20-emc" and "simple-mfd".
>  - reg : Offset and length of the register set for the device
>  - nvidia,use-ram-code : If present, the sub-nodes will be addressed
>    and chosen using the ramcode board selector. If omitted, only one
> @@ -17,7 +17,8 @@ Properties:
>  - core-supply: Phandle of voltage regulator of the SoC "core" power domain.
>  - operating-points-v2: See ../bindings/opp/opp.txt for details.
>  
> -Child device nodes describe the memory settings for different configurations and clock rates.
> +Child device nodes describe the memory settings for different configurations and clock rates,
> +as well as EMC activity statistics collection sub-device.
>  
>  Example:
>  
> @@ -31,17 +32,34 @@ Example:
>  		...
>  	};
>  
> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> +		compatible = "operating-points-v2";
> +
> +		opp@36000000 {
> +			opp-hz = /bits/ 64 <36000000>;
> +			opp-peak-kBps = <144000>;
> +		};
> +		...
> +	};
> +
>  	memory-controller@7000f400 {
>  		#address-cells = < 1 >;
>  		#size-cells = < 0 >;
>  		#interconnect-cells = < 0 >;
> -		compatible = "nvidia,tegra20-emc";
> +		compatible = "nvidia,tegra20-emc", "simple-mfd";
>  		reg = <0x7000f400 0x400>;
>  		interrupts = <0 78 0x04>;
>  		clocks = <&tegra_car TEGRA20_CLK_EMC>;
>  		nvidia,memory-controller = <&mc>;
>  		core-supply = <&core_vdd_reg>;
>  		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
> +
> +		emc-stats {
> +			compatible = "nvidia,tegra20-emc-statistics";
> +			operating-points-v2 = <&emc_bw_dfs_opp_table>;
> +			interconnects = <&mc TEGRA20_MC_MPCORER &emc>;
> +			interconnect-names = "cpu";
> +		};
>  	}
>  
>  
> @@ -120,3 +138,22 @@ Properties:
>  						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>  						 0 0 0 0 >;
>  		};
> +
> +
> +
> +Embedded Memory Controller statistics gathering sub-device
> +
> +EMC statistics subdev gathers information about hardware utilization
> +which is intended to be used for debugging purposes and for dynamic
> +frequency scaling based on the collected stats.
> +
> +Properties:
> +- name : Should be emc-stats.
> +- compatible : Should contain "nvidia,tegra20-emc-statistics".
> +- operating-points-v2: See ../bindings/opp/opp.txt for details.
> +- interconnects: Should contain entries for memory clients sitting on
> +                 MC->EMC memory interconnect path.
> +- interconnect-names: Should include name of the interconnect path for each
> +                      interconnect entry. Consult TRM documentation for
> +                      information about available memory clients, see MEMORY
> +                      CONTROLLER section.
> -- 
> 2.27.0
> 

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-28 15:28     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:28 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Georgi Djakov, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Jonathan Hunter, Michael Turquette

On Mon, Oct 26, 2020 at 01:16:51AM +0300, Dmitry Osipenko wrote:
> External Memory Controller can gather various hardware statistics that
> are intended to be used for debugging purposes and for dynamic frequency
> scaling of memory bus.
> 
> Document the new mfd-simple compatible and EMC statistics sub-device.

It's simple-mfd.

That should only be used if the child has no dependencies on the parent 
node (and driver).

> The subdev contains EMC DFS OPP table and interconnect paths to be used
> for dynamic scaling of system's memory bandwidth based on EMC utilization
> statistics.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra20-emc.txt | 43 +++++++++++++++++--
>  1 file changed, 40 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> index 8d09b228ac42..382aabcd6952 100644
> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> @@ -4,7 +4,7 @@ Properties:
>  - name : Should be emc
>  - #address-cells : Should be 1
>  - #size-cells : Should be 0
> -- compatible : Should contain "nvidia,tegra20-emc".
> +- compatible : Should contain "nvidia,tegra20-emc" and "simple-mfd".
>  - reg : Offset and length of the register set for the device
>  - nvidia,use-ram-code : If present, the sub-nodes will be addressed
>    and chosen using the ramcode board selector. If omitted, only one
> @@ -17,7 +17,8 @@ Properties:
>  - core-supply: Phandle of voltage regulator of the SoC "core" power domain.
>  - operating-points-v2: See ../bindings/opp/opp.txt for details.
>  
> -Child device nodes describe the memory settings for different configurations and clock rates.
> +Child device nodes describe the memory settings for different configurations and clock rates,
> +as well as EMC activity statistics collection sub-device.
>  
>  Example:
>  
> @@ -31,17 +32,34 @@ Example:
>  		...
>  	};
>  
> +	emc_bw_dfs_opp_table: emc_opp_table1 {
> +		compatible = "operating-points-v2";
> +
> +		opp@36000000 {
> +			opp-hz = /bits/ 64 <36000000>;
> +			opp-peak-kBps = <144000>;
> +		};
> +		...
> +	};
> +
>  	memory-controller@7000f400 {
>  		#address-cells = < 1 >;
>  		#size-cells = < 0 >;
>  		#interconnect-cells = < 0 >;
> -		compatible = "nvidia,tegra20-emc";
> +		compatible = "nvidia,tegra20-emc", "simple-mfd";
>  		reg = <0x7000f400 0x400>;
>  		interrupts = <0 78 0x04>;
>  		clocks = <&tegra_car TEGRA20_CLK_EMC>;
>  		nvidia,memory-controller = <&mc>;
>  		core-supply = <&core_vdd_reg>;
>  		operating-points-v2 = <&emc_icc_dvfs_opp_table>;
> +
> +		emc-stats {
> +			compatible = "nvidia,tegra20-emc-statistics";
> +			operating-points-v2 = <&emc_bw_dfs_opp_table>;
> +			interconnects = <&mc TEGRA20_MC_MPCORER &emc>;
> +			interconnect-names = "cpu";
> +		};
>  	}
>  
>  
> @@ -120,3 +138,22 @@ Properties:
>  						 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>  						 0 0 0 0 >;
>  		};
> +
> +
> +
> +Embedded Memory Controller statistics gathering sub-device
> +
> +EMC statistics subdev gathers information about hardware utilization
> +which is intended to be used for debugging purposes and for dynamic
> +frequency scaling based on the collected stats.
> +
> +Properties:
> +- name : Should be emc-stats.
> +- compatible : Should contain "nvidia,tegra20-emc-statistics".
> +- operating-points-v2: See ../bindings/opp/opp.txt for details.
> +- interconnects: Should contain entries for memory clients sitting on
> +                 MC->EMC memory interconnect path.
> +- interconnect-names: Should include name of the interconnect path for each
> +                      interconnect entry. Consult TRM documentation for
> +                      information about available memory clients, see MEMORY
> +                      CONTROLLER section.
> -- 
> 2.27.0
> 
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 11/52] dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-28 15:29     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:29 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Kyungmin Park, Michael Turquette, Nicolas Chauvet, linux-kernel,
	Georgi Djakov, MyungJoo Ham, devicetree, dri-devel, Viresh Kumar,
	linux-tegra, linux-pm, Rob Herring, Mikko Perttunen,
	Krzysztof Kozlowski, Peter De Schrijver, Jonathan Hunter,
	Chanwoo Choi, Thierry Reding, Peter Geis, Stephen Boyd

On Mon, 26 Oct 2020 01:16:54 +0300, Dmitry Osipenko wrote:
> Document new OPP table and voltage regulator properties which are needed
> for supporting dynamic voltage-frequency scaling of the memory controller.
> Some boards may have a fixed core voltage regulator, hence it's optional
> because frequency scaling still may be desired.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra30-emc.yaml       | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 11/52] dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator
@ 2020-10-28 15:29     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:29 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, Chanwoo Choi, Stephen Boyd,
	linux-pm, Nicolas Chauvet, Viresh Kumar, Michael Turquette,
	linux-kernel, dri-devel, Jonathan Hunter, Rob Herring,
	Kyungmin Park, MyungJoo Ham, Thierry Reding, Krzysztof Kozlowski,
	Peter Geis, linux-tegra, Peter De Schrijver, Georgi Djakov

On Mon, 26 Oct 2020 01:16:54 +0300, Dmitry Osipenko wrote:
> Document new OPP table and voltage regulator properties which are needed
> for supporting dynamic voltage-frequency scaling of the memory controller.
> Some boards may have a fixed core voltage regulator, hence it's optional
> because frequency scaling still may be desired.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra30-emc.yaml       | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 14/52] dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-28 15:30     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:30 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Stephen Boyd, devicetree, Kyungmin Park, Mikko Perttunen,
	linux-kernel, Krzysztof Kozlowski, MyungJoo Ham, dri-devel,
	Chanwoo Choi, Michael Turquette, Peter De Schrijver, linux-tegra,
	Jonathan Hunter, Georgi Djakov, Viresh Kumar, linux-pm,
	Rob Herring, Peter Geis, Thierry Reding, Nicolas Chauvet

On Mon, 26 Oct 2020 01:16:57 +0300, Dmitry Osipenko wrote:
> Document new OPP table and voltage regulator properties which are needed
> for supporting dynamic voltage-frequency scaling of the memory controller.
> Some boards may have a fixed core voltage regulator, hence it's optional
> because frequency scaling still may be desired.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra124-emc.yaml       | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 14/52] dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator
@ 2020-10-28 15:30     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:30 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, Rob Herring, linux-pm, Stephen Boyd,
	Viresh Kumar, Michael Turquette, linux-kernel,
	Krzysztof Kozlowski, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, MyungJoo Ham, Thierry Reding, dri-devel,
	Peter Geis, linux-tegra, Nicolas Chauvet, Peter De Schrijver,
	Georgi Djakov

On Mon, 26 Oct 2020 01:16:57 +0300, Dmitry Osipenko wrote:
> Document new OPP table and voltage regulator properties which are needed
> for supporting dynamic voltage-frequency scaling of the memory controller.
> Some boards may have a fixed core voltage regulator, hence it's optional
> because frequency scaling still may be desired.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../memory-controllers/nvidia,tegra124-emc.yaml       | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 15/52] dt-bindings: tegra30-actmon: Document OPP and interconnect properties
  2020-10-25 22:16   ` Dmitry Osipenko
@ 2020-10-28 15:30     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:30 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Stephen Boyd, Thierry Reding, Peter Geis, Krzysztof Kozlowski,
	devicetree, Kyungmin Park, Michael Turquette, Peter De Schrijver,
	linux-kernel, Jonathan Hunter, Rob Herring, Nicolas Chauvet,
	dri-devel, Viresh Kumar, linux-tegra, Georgi Djakov,
	Chanwoo Choi, linux-pm, MyungJoo Ham, Mikko Perttunen

On Mon, 26 Oct 2020 01:16:58 +0300, Dmitry Osipenko wrote:
> Document EMC DFS OPP table and interconnect paths that will be used
> for scaling of system's memory bandwidth based on memory utilization
> statistics. Previously ACTMON was supposed to drive EMC clock rate
> directly, but now it should do it using interconnect framework in order
> to support shared voltage scaling in addition to the frequency scaling.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../arm/tegra/nvidia,tegra30-actmon.txt       | 25 +++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 15/52] dt-bindings: tegra30-actmon: Document OPP and interconnect properties
@ 2020-10-28 15:30     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:30 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, Chanwoo Choi, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Jonathan Hunter, Rob Herring,
	Kyungmin Park, Thierry Reding, dri-devel, Peter Geis,
	linux-tegra, MyungJoo Ham, Peter De Schrijver, Georgi Djakov

On Mon, 26 Oct 2020 01:16:58 +0300, Dmitry Osipenko wrote:
> Document EMC DFS OPP table and interconnect paths that will be used
> for scaling of system's memory bandwidth based on memory utilization
> statistics. Previously ACTMON was supposed to drive EMC clock rate
> directly, but now it should do it using interconnect framework in order
> to support shared voltage scaling in addition to the frequency scaling.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  .../arm/tegra/nvidia,tegra30-actmon.txt       | 25 +++++++++++++++++++
>  1 file changed, 25 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 19/52] dt-bindings: memory: tegra124: Add memory client IDs
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-10-28 15:31     ` Rob Herring
  -1 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:31 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Mikko Perttunen, Peter Geis, Peter De Schrijver, devicetree,
	Rob Herring, Viresh Kumar, Nicolas Chauvet, Georgi Djakov,
	Stephen Boyd, Krzysztof Kozlowski, linux-tegra, Kyungmin Park,
	linux-kernel, Chanwoo Choi, MyungJoo Ham, Thierry Reding,
	dri-devel, Jonathan Hunter, Michael Turquette, linux-pm

On Mon, 26 Oct 2020 01:17:02 +0300, Dmitry Osipenko wrote:
> Each memory client have a unique hardware ID, this patch adds these IDs.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  include/dt-bindings/memory/tegra124-mc.h | 68 ++++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 19/52] dt-bindings: memory: tegra124: Add memory client IDs
@ 2020-10-28 15:31     ` Rob Herring
  0 siblings, 0 replies; 290+ messages in thread
From: Rob Herring @ 2020-10-28 15:31 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: devicetree, Mikko Perttunen, dri-devel, Chanwoo Choi,
	Nicolas Chauvet, Viresh Kumar, Peter De Schrijver, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Jonathan Hunter, Stephen Boyd,
	Kyungmin Park, Rob Herring, Thierry Reding, MyungJoo Ham,
	Peter Geis, linux-tegra, Michael Turquette, Georgi Djakov

On Mon, 26 Oct 2020 01:17:02 +0300, Dmitry Osipenko wrote:
> Each memory client have a unique hardware ID, this patch adds these IDs.
> 
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  include/dt-bindings/memory/tegra124-mc.h | 68 ++++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
> 

Reviewed-by: Rob Herring <robh@kernel.org>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
  2020-10-28 15:23           ` Rob Herring
@ 2020-10-28 15:35             ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-28 15:35 UTC (permalink / raw)
  To: Rob Herring
  Cc: Dmitry Osipenko, Thierry Reding, Jonathan Hunter, Georgi Djakov,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Wed, Oct 28, 2020 at 10:23:03AM -0500, Rob Herring wrote:
> On Tue, Oct 27, 2020 at 08:30:39PM +0100, Krzysztof Kozlowski wrote:
> > On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
> > > 27.10.2020 11:54, Krzysztof Kozlowski пишет:
> > > > On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> > > >> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> > > >> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> > > >> behind EMC and these controllers are tightly coupled. This patch adds the
> > > >> new phandle property which allows to properly express connection of EMC
> > > >> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> > > >> par with Tegra30+ EMC bindings, which is handy to have.
> > > >>
> > > >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > > >> ---
> > > >>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
> > > >>  1 file changed, 2 insertions(+)
> > > >>
> > > >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > > >> index 567cffd37f3f..1b0d4417aad8 100644
> > > >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > > >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > > >> @@ -12,6 +12,7 @@ Properties:
> > > >>    irrespective of ram-code configuration.
> > > >>  - interrupts : Should contain EMC General interrupt.
> > > >>  - clocks : Should contain EMC clock.
> > > >> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> > > > 
> > > > It looks like you adding a required property which is an ABI break.
> > > The T20 EMC driver is unused so far in upstream and it will become used
> > > only once this series is applied. Hence it's fine to change the ABI.
> > 
> > The ABI is not about upstream, but downstream. 
> 
> "If it's not upstream, it doesn't exist."
> 
> Though we do have to account for out of tree users where the DT is not 
> in tree, but upstream drivers are used. Downstream as in vendor kernels 
> typically has loads of other crap.

That's the case I am referring to. Maybe not in case of Tegra, but
multiple other designs are quite popular in industrial uses and their
DTSes were not upstreamed.

This is anyway different case, as Dmitry explained - nothing got broken
because not much was working before around this.

> 
> > There are no other
> > upstreams using this ABI. Unless you have in mind that existing T20 EMC
> > driver was a noop, doing absolutely nothing, therefore there is no
> > breakage of any other users?
> 
> ABI breaks are ultimately up to the platform maintainers to decide.

Cool! That reshapes significantly my existing point of view, especially
about discussions on Exynos bindings (long time ago). Thanks for
clarification.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property
@ 2020-10-28 15:35             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-28 15:35 UTC (permalink / raw)
  To: Rob Herring
  Cc: Peter De Schrijver, Mikko Perttunen, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, dri-devel, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Dmitry Osipenko, Georgi Djakov, devicetree

On Wed, Oct 28, 2020 at 10:23:03AM -0500, Rob Herring wrote:
> On Tue, Oct 27, 2020 at 08:30:39PM +0100, Krzysztof Kozlowski wrote:
> > On Tue, Oct 27, 2020 at 10:17:19PM +0300, Dmitry Osipenko wrote:
> > > 27.10.2020 11:54, Krzysztof Kozlowski пишет:
> > > > On Mon, Oct 26, 2020 at 01:16:47AM +0300, Dmitry Osipenko wrote:
> > > >> Tegra20 External Memory Controller talks to DRAM chips and it needs to be
> > > >> reprogrammed when memory frequency changes. Tegra Memory Controller sits
> > > >> behind EMC and these controllers are tightly coupled. This patch adds the
> > > >> new phandle property which allows to properly express connection of EMC
> > > >> and MC hardware in a device-tree, it also put the Tegra20 EMC binding on
> > > >> par with Tegra30+ EMC bindings, which is handy to have.
> > > >>
> > > >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> > > >> ---
> > > >>  .../bindings/memory-controllers/nvidia,tegra20-emc.txt          | 2 ++
> > > >>  1 file changed, 2 insertions(+)
> > > >>
> > > >> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > > >> index 567cffd37f3f..1b0d4417aad8 100644
> > > >> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > > >> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra20-emc.txt
> > > >> @@ -12,6 +12,7 @@ Properties:
> > > >>    irrespective of ram-code configuration.
> > > >>  - interrupts : Should contain EMC General interrupt.
> > > >>  - clocks : Should contain EMC clock.
> > > >> +- nvidia,memory-controller : Phandle of the Memory Controller node.
> > > > 
> > > > It looks like you adding a required property which is an ABI break.
> > > The T20 EMC driver is unused so far in upstream and it will become used
> > > only once this series is applied. Hence it's fine to change the ABI.
> > 
> > The ABI is not about upstream, but downstream. 
> 
> "If it's not upstream, it doesn't exist."
> 
> Though we do have to account for out of tree users where the DT is not 
> in tree, but upstream drivers are used. Downstream as in vendor kernels 
> typically has loads of other crap.

That's the case I am referring to. Maybe not in case of Tegra, but
multiple other designs are quite popular in industrial uses and their
DTSes were not upstreamed.

This is anyway different case, as Dmitry explained - nothing got broken
because not much was working before around this.

> 
> > There are no other
> > upstreams using this ABI. Unless you have in mind that existing T20 EMC
> > driver was a noop, doing absolutely nothing, therefore there is no
> > breakage of any other users?
> 
> ABI breaks are ultimately up to the platform maintainers to decide.

Cool! That reshapes significantly my existing point of view, especially
about discussions on Exynos bindings (long time ago). Thanks for
clarification.

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
  2020-10-27 20:16           ` Dmitry Osipenko
@ 2020-10-28 19:27             ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-28 19:27 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 11:16:29PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 22:48, Krzysztof Kozlowski пишет:
> > On Tue, Oct 27, 2020 at 10:19:28PM +0300, Dmitry Osipenko wrote:
> >> 27.10.2020 13:25, Krzysztof Kozlowski пишет:
> >>> On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
> >>>> External memory controller is interconnected with memory controller and
> >>>> with external memory. Document new interconnect property which turns
> >>>> External Memory Controller into interconnect provider.
> >>>>
> >>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >>>> ---
> >>>>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
> >>>>  1 file changed, 7 insertions(+)
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >>>> index 278549f9e051..ac00832ceac1 100644
> >>>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >>>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >>>> @@ -29,6 +29,9 @@ properties:
> >>>>      items:
> >>>>        - const: emc
> >>>>  
> >>>> +  "#interconnect-cells":
> >>>> +    const: 0
> >>>> +
> >>>>    nvidia,memory-controller:
> >>>>      $ref: /schemas/types.yaml#/definitions/phandle
> >>>>      description:
> >>>> @@ -327,6 +330,7 @@ required:
> >>>>    - clocks
> >>>>    - clock-names
> >>>>    - nvidia,memory-controller
> >>>> +  - "#interconnect-cells"
> >>>
> >>> Another required property, what about all existing users of this binding?
> >>
> >> EMC/devfreq drivers check presence of the new properties and ask users
> >> to upgrade the DT. The kernel will continue to work fine using older
> >> DTBs, but devfreq driver won't load.
> > 
> > If the devfreq was working fine before (with these older DTBs and older
> > kernel) then you break the feature.
> > 
> > If devfreq was not working or was not stable enough, then nothing is
> > broken so such change is accepted.
> > 
> > Which one is then?
> 
> Definitely the latter. The current devfreq works okay'ish, but we rely
> on hardware to recover from temporal FIFO underflows and it's a
> user-visible problem which this series addresses.

I understand. Fine with me, thanks for explanation.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: Document new interconnect property
@ 2020-10-28 19:27             ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-28 19:27 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 11:16:29PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 22:48, Krzysztof Kozlowski пишет:
> > On Tue, Oct 27, 2020 at 10:19:28PM +0300, Dmitry Osipenko wrote:
> >> 27.10.2020 13:25, Krzysztof Kozlowski пишет:
> >>> On Mon, Oct 26, 2020 at 01:16:56AM +0300, Dmitry Osipenko wrote:
> >>>> External memory controller is interconnected with memory controller and
> >>>> with external memory. Document new interconnect property which turns
> >>>> External Memory Controller into interconnect provider.
> >>>>
> >>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >>>> ---
> >>>>  .../bindings/memory-controllers/nvidia,tegra124-emc.yaml   | 7 +++++++
> >>>>  1 file changed, 7 insertions(+)
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >>>> index 278549f9e051..ac00832ceac1 100644
> >>>> --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >>>> +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
> >>>> @@ -29,6 +29,9 @@ properties:
> >>>>      items:
> >>>>        - const: emc
> >>>>  
> >>>> +  "#interconnect-cells":
> >>>> +    const: 0
> >>>> +
> >>>>    nvidia,memory-controller:
> >>>>      $ref: /schemas/types.yaml#/definitions/phandle
> >>>>      description:
> >>>> @@ -327,6 +330,7 @@ required:
> >>>>    - clocks
> >>>>    - clock-names
> >>>>    - nvidia,memory-controller
> >>>> +  - "#interconnect-cells"
> >>>
> >>> Another required property, what about all existing users of this binding?
> >>
> >> EMC/devfreq drivers check presence of the new properties and ask users
> >> to upgrade the DT. The kernel will continue to work fine using older
> >> DTBs, but devfreq driver won't load.
> > 
> > If the devfreq was working fine before (with these older DTBs and older
> > kernel) then you break the feature.
> > 
> > If devfreq was not working or was not stable enough, then nothing is
> > broken so such change is accepted.
> > 
> > Which one is then?
> 
> Definitely the latter. The current devfreq works okay'ish, but we rely
> on hardware to recover from temporal FIFO underflows and it's a
> user-visible problem which this series addresses.

I understand. Fine with me, thanks for explanation.

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
  2020-10-27 20:30       ` Dmitry Osipenko
@ 2020-10-28 19:28         ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-28 19:28 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, linux-tegra, linux-pm,
	linux-kernel, dri-devel, devicetree

On Tue, Oct 27, 2020 at 11:30:31PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 13:27, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:17:24AM +0300, Dmitry Osipenko wrote:
> >> Use devm_platform_ioremap_resource() helper which makes code a bit
> >> cleaner.
> > 
> > Such cleanups (and few other in this patchset) should be at beginning of
> > patchset or even as part of a separate one.  I think there is not much
> > stopping anyone from applying these... except that you put them in the
> > middle of big dependency.
> 
> Some of these cleanup patches can't be applied separately without a need
> to make a rebase. I think it should be more preferred to have all the
> patches within a single series.
> 
> I'll try to reorder the patches in v7 if this will ease the review, thanks.

If feasible, that would be good. Thanks.

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource()
@ 2020-10-28 19:28         ` Krzysztof Kozlowski
  0 siblings, 0 replies; 290+ messages in thread
From: Krzysztof Kozlowski @ 2020-10-28 19:28 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Rob Herring, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

On Tue, Oct 27, 2020 at 11:30:31PM +0300, Dmitry Osipenko wrote:
> 27.10.2020 13:27, Krzysztof Kozlowski пишет:
> > On Mon, Oct 26, 2020 at 01:17:24AM +0300, Dmitry Osipenko wrote:
> >> Use devm_platform_ioremap_resource() helper which makes code a bit
> >> cleaner.
> > 
> > Such cleanups (and few other in this patchset) should be at beginning of
> > patchset or even as part of a separate one.  I think there is not much
> > stopping anyone from applying these... except that you put them in the
> > middle of big dependency.
> 
> Some of these cleanup patches can't be applied separately without a need
> to make a rebase. I think it should be more preferred to have all the
> patches within a single series.
> 
> I'll try to reorder the patches in v7 if this will ease the review, thanks.

If feasible, that would be good. Thanks.

Best regards,
Krzysztof

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
  2020-10-28 15:26             ` Rob Herring
@ 2020-10-31 19:53               ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-31 19:53 UTC (permalink / raw)
  To: Rob Herring
  Cc: Krzysztof Kozlowski, Thierry Reding, Jonathan Hunter,
	Georgi Djakov, Michael Turquette, Stephen Boyd,
	Peter De Schrijver, MyungJoo Ham, Kyungmin Park, Chanwoo Choi,
	Mikko Perttunen, Viresh Kumar, Peter Geis, Nicolas Chauvet,
	linux-tegra, linux-pm, linux-kernel, dri-devel, devicetree

28.10.2020 18:26, Rob Herring пишет:
> On Tue, Oct 27, 2020 at 11:18:34PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 22:44, Krzysztof Kozlowski пишет:
>>> On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
>>>> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
>>>>>> @@ -31,17 +32,34 @@ Example:
>>>>>>  		...
>>>>>>  	};
>>>>>>  
>>>>>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
>>>>> Hyphens for node name.
>>>>
>>>> We already use underscores for the Tegra CPU OPP table.
>>>>
>>>> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
>>>>
>>>> What makes you think that hyphens will be a better choice? Is it a
>>>> documented naming convention?
>>>
>>> Unfortunately that's the source of confusion also for me because
>>> Devicetree spec mentions both of them (and does not specify preferences).
>>>
>>> The choice of dashes/hyphens comes now explicitly from all dtschema
>>> files.  Previously, the documentation were emails from Rob. :)
>>
>> Okay, I'll change it in v7. So far I haven't seen warnings about it from
>> the schema-checker.
> 
> dtc with W=2 will warn.
> 
> The bigger issue is the name should be generic.

Indeed, thanks. I'll correct the name.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device
@ 2020-10-31 19:53               ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-10-31 19:53 UTC (permalink / raw)
  To: Rob Herring
  Cc: Peter De Schrijver, Mikko Perttunen, dri-devel, Nicolas Chauvet,
	Stephen Boyd, Viresh Kumar, Michael Turquette, linux-pm,
	linux-kernel, Krzysztof Kozlowski, Jonathan Hunter, Chanwoo Choi,
	Kyungmin Park, Thierry Reding, MyungJoo Ham, Peter Geis,
	linux-tegra, Georgi Djakov, devicetree

28.10.2020 18:26, Rob Herring пишет:
> On Tue, Oct 27, 2020 at 11:18:34PM +0300, Dmitry Osipenko wrote:
>> 27.10.2020 22:44, Krzysztof Kozlowski пишет:
>>> On Tue, Oct 27, 2020 at 10:22:19PM +0300, Dmitry Osipenko wrote:
>>>> 27.10.2020 12:02, Krzysztof Kozlowski пишет:
>>>>>> @@ -31,17 +32,34 @@ Example:
>>>>>>  		...
>>>>>>  	};
>>>>>>  
>>>>>> +	emc_bw_dfs_opp_table: emc_opp_table1 {
>>>>> Hyphens for node name.
>>>>
>>>> We already use underscores for the Tegra CPU OPP table.
>>>>
>>>> https://elixir.bootlin.com/linux/v5.10-rc1/source/arch/arm/boot/dts/tegra20-cpu-opp.dtsi#L4
>>>>
>>>> What makes you think that hyphens will be a better choice? Is it a
>>>> documented naming convention?
>>>
>>> Unfortunately that's the source of confusion also for me because
>>> Devicetree spec mentions both of them (and does not specify preferences).
>>>
>>> The choice of dashes/hyphens comes now explicitly from all dtschema
>>> files.  Previously, the documentation were emails from Rob. :)
>>
>> Okay, I'll change it in v7. So far I haven't seen warnings about it from
>> the schema-checker.
> 
> dtc with W=2 will warn.
> 
> The bigger issue is the name should be generic.

Indeed, thanks. I'll correct the name.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-11-01 13:31     ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 13:31 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

Hi Dmitry,

This patch contains the three features as following:
1. Use interconnect interface for controlling the clock instead of
controlling it direclty
2. Use EMC_STAT instead of IMC_STAT
3. Change polling_interval and upthreshold for more fast responsiveness

I think you need to make the separate patches for each role.
But, if it is difficult or not proper to split out 1,2 roles, you can
make two patches for 1,2 and 3 roles.

Also, if you want to get more responsiveness, you could use delayed timer
instead of deferrable timer by editing the devfreq_dev_profile structure.

Regards,
Chanwoo Choi



On Mon, Oct 26, 2020 at 7:21 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> External (EMC) and Internal Memory Controllers (IMC) have a nearly
> identical statistics gathering module. This patch switches driver to use
> EMC_STAT instead of IMC_STAT and adds device-tree support which brings ICC
> support and makes driver to use bandwidth OPPs defined in device-tree.
>
> The previous tegra20-devfreq variant was depending on presence of both
> EMC and IMC drivers simultaneously because it wasn't apparent how to use
> EMC_STAT properly back in the day. Dependency on the IMC driver is gone
> after this patch.
>
> The older variant of the devfreq driver also isn't suitable anymore
> because EMC got support for interconnect framework and DVFS, hence
> tegra20-devfreq shouldn't drive the EMC clock directly, but use OPP
> API for issuing memory bandwidth requests.
>
> The polling interval is changed from 500ms to 30ms in order to improve
> responsiveness of the system in general and because EMC clock is now
> allowed to go lower than before since display driver supports ICC now
> as well.
>
> The parent EMC device is an MFD device now and tegra20-devfreq its
> sub-device. Devfreq driver uses SYSCON API for retrieving regmap of the
> EMC registers from the parent device.
>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/Kconfig           |   1 +
>  drivers/devfreq/tegra20-devfreq.c | 174 +++++++++++++-----------------
>  2 files changed, 75 insertions(+), 100 deletions(-)
>
> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> index 0ee36ae2fa79..1bd225e571df 100644
> --- a/drivers/devfreq/Kconfig
> +++ b/drivers/devfreq/Kconfig
> @@ -126,6 +126,7 @@ config ARM_TEGRA20_DEVFREQ
>         depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
>         depends on COMMON_CLK
>         select DEVFREQ_GOV_SIMPLE_ONDEMAND
> +       select MFD_SYSCON
>         help
>           This adds the DEVFREQ driver for the Tegra20 family of SoCs.
>           It reads Memory Controller counters and adjusts the operating
> diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
> index fd801534771d..0a36b085d32a 100644
> --- a/drivers/devfreq/tegra20-devfreq.c
> +++ b/drivers/devfreq/tegra20-devfreq.c
> @@ -7,180 +7,148 @@
>
>  #include <linux/clk.h>
>  #include <linux/devfreq.h>
> -#include <linux/io.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_opp.h>
> +#include <linux/regmap.h>
>  #include <linux/slab.h>
>
> -#include <soc/tegra/mc.h>
> -
>  #include "governor.h"
>
> -#define MC_STAT_CONTROL                                0x90
> -#define MC_STAT_EMC_CLOCK_LIMIT                        0xa0
> -#define MC_STAT_EMC_CLOCKS                     0xa4
> -#define MC_STAT_EMC_CONTROL                    0xa8
> -#define MC_STAT_EMC_COUNT                      0xb8
> +#define EMC_STAT_CONTROL                       0x160
> +#define EMC_STAT_LLMC_CONTROL                  0x178
> +#define EMC_STAT_PWR_CLOCK_LIMIT               0x198
> +#define EMC_STAT_PWR_CLOCKS                    0x19c
> +#define EMC_STAT_PWR_COUNT                     0x1a0
>
> -#define EMC_GATHER_CLEAR                       (1 << 8)
> -#define EMC_GATHER_ENABLE                      (3 << 8)
> +#define EMC_PWR_GATHER_CLEAR                   (1 << 8)
> +#define EMC_PWR_GATHER_DISABLE                 (2 << 8)
> +#define EMC_PWR_GATHER_ENABLE                  (3 << 8)
>
>  struct tegra_devfreq {
> +       struct devfreq_simple_ondemand_data ondemand_data;
> +       struct opp_table *opp_table;
>         struct devfreq *devfreq;
>         struct clk *emc_clock;
> -       void __iomem *regs;
> +       struct regmap *rmap;
>  };
>
>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>                                 u32 flags)
>  {
> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> -       struct devfreq *devfreq = tegra->devfreq;
>         struct dev_pm_opp *opp;
> -       unsigned long rate;
> -       int err;
> +       int ret;
>
>         opp = devfreq_recommended_opp(dev, freq, flags);
> -       if (IS_ERR(opp))
> +       if (IS_ERR(opp)) {
> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
>                 return PTR_ERR(opp);
> +       }
>
> -       rate = dev_pm_opp_get_freq(opp);
> +       ret = dev_pm_opp_set_bw(dev, opp);
>         dev_pm_opp_put(opp);
>
> -       err = clk_set_min_rate(tegra->emc_clock, rate);
> -       if (err)
> -               return err;
> -
> -       err = clk_set_rate(tegra->emc_clock, 0);
> -       if (err)
> -               goto restore_min_rate;
> -
> -       return 0;
> -
> -restore_min_rate:
> -       clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
> -
> -       return err;
> +       return ret;
>  }
>
>  static int tegra_devfreq_get_dev_status(struct device *dev,
>                                         struct devfreq_dev_status *stat)
>  {
>         struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> +       u32 count, clocks;
>
> -       /*
> -        * EMC_COUNT returns number of memory events, that number is lower
> -        * than the number of clocks. Conversion ratio of 1/8 results in a
> -        * bit higher bandwidth than actually needed, it is good enough for
> -        * the time being because drivers don't support requesting minimum
> -        * needed memory bandwidth yet.
> -        *
> -        * TODO: adjust the ratio value once relevant drivers will support
> -        * memory bandwidth management.
> -        */
> -       stat->busy_time = readl_relaxed(tegra->regs + MC_STAT_EMC_COUNT);
> -       stat->total_time = readl_relaxed(tegra->regs + MC_STAT_EMC_CLOCKS) / 8;
> -       stat->current_frequency = clk_get_rate(tegra->emc_clock);
> +       /* freeze counters */
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_DISABLE);
> +
> +       /* number of clocks when EMC request was accepted */
> +       regmap_read(tegra->rmap, EMC_STAT_PWR_COUNT, &count);
> +       /* total number of clocks while PWR_GATHER control was set to ENABLE */
> +       regmap_read(tegra->rmap, EMC_STAT_PWR_CLOCKS, &clocks);
>
> -       writel_relaxed(EMC_GATHER_CLEAR, tegra->regs + MC_STAT_CONTROL);
> -       writel_relaxed(EMC_GATHER_ENABLE, tegra->regs + MC_STAT_CONTROL);
> +       /* clear counters and restart */
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_CLEAR);
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_ENABLE);
> +
> +       stat->busy_time = count;
> +       stat->total_time = clocks;
> +       stat->current_frequency = clk_get_rate(tegra->emc_clock);
>
>         return 0;
>  }
>
>  static struct devfreq_dev_profile tegra_devfreq_profile = {
> -       .polling_ms     = 500,
> +       .polling_ms     = 30,
>         .target         = tegra_devfreq_target,
>         .get_dev_status = tegra_devfreq_get_dev_status,
>  };
>
> -static struct tegra_mc *tegra_get_memory_controller(void)
> -{
> -       struct platform_device *pdev;
> -       struct device_node *np;
> -       struct tegra_mc *mc;
> -
> -       np = of_find_compatible_node(NULL, NULL, "nvidia,tegra20-mc-gart");
> -       if (!np)
> -               return ERR_PTR(-ENOENT);
> -
> -       pdev = of_find_device_by_node(np);
> -       of_node_put(np);
> -       if (!pdev)
> -               return ERR_PTR(-ENODEV);
> -
> -       mc = platform_get_drvdata(pdev);
> -       if (!mc)
> -               return ERR_PTR(-EPROBE_DEFER);
> -
> -       return mc;
> -}
> -
>  static int tegra_devfreq_probe(struct platform_device *pdev)
>  {
> +       struct device_node *emc_np = pdev->dev.parent->of_node;
>         struct tegra_devfreq *tegra;
> -       struct tegra_mc *mc;
> -       unsigned long max_rate;
> -       unsigned long rate;
>         int err;
>
> -       mc = tegra_get_memory_controller();
> -       if (IS_ERR(mc)) {
> -               err = PTR_ERR(mc);
> -               dev_err(&pdev->dev, "failed to get memory controller: %d\n",
> -                       err);
> -               return err;
> -       }
> -
>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
>         if (!tegra)
>                 return -ENOMEM;
>
>         /* EMC is a system-critical clock that is always enabled */
> -       tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
> +       tegra->emc_clock = devm_get_clk_from_child(&pdev->dev, emc_np, NULL);
>         if (IS_ERR(tegra->emc_clock))
>                 return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
>                                      "failed to get emc clock\n");
>
> -       tegra->regs = mc->regs;
> -
> -       max_rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
> +       tegra->rmap = device_node_to_regmap(emc_np);
> +       if (IS_ERR(tegra->rmap))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->rmap),
> +                                    "failed to get emc regmap\n");
>
> -       for (rate = 0; rate <= max_rate; rate++) {
> -               rate = clk_round_rate(tegra->emc_clock, rate);
> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
> +       if (IS_ERR(tegra->opp_table))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
> +                                    "failed to prepare opp table\n");
>
> -               err = dev_pm_opp_add(&pdev->dev, rate, 0);
> -               if (err) {
> -                       dev_err(&pdev->dev, "failed to add opp: %d\n", err);
> -                       goto remove_opps;
> -               }
> +       err = dev_pm_opp_of_add_table(&pdev->dev);
> +       if (err) {
> +               dev_err(&pdev->dev, "failed to add opp table: %d\n", err);
> +               goto put_table;
>         }
>
> +       /*
> +        * PWR_COUNT is 1/2 of PWR_CLOCKS at max, and thus, the up-threshold
> +        * should be less than 50.  Secondly, multiple active memory clients
> +        * may cause over 20 of lost clock cycles due to stalls caused by
> +        * competing memory accesses.  This means that threshold should be
> +        * set to a less than 30 in order to have a properly working governor.
> +        */
> +       tegra->ondemand_data.upthreshold = 20;
> +
>         /*
>          * Reset statistic gathers state, select global bandwidth for the
>          * statistics collection mode and set clocks counter saturation
>          * limit to maximum.
>          */
> -       writel_relaxed(0x00000000, tegra->regs + MC_STAT_CONTROL);
> -       writel_relaxed(0x00000000, tegra->regs + MC_STAT_EMC_CONTROL);
> -       writel_relaxed(0xffffffff, tegra->regs + MC_STAT_EMC_CLOCK_LIMIT);
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, 0x00000000);
> +       regmap_write(tegra->rmap, EMC_STAT_LLMC_CONTROL, 0x00000000);
> +       regmap_write(tegra->rmap, EMC_STAT_PWR_CLOCK_LIMIT, 0xffffffff);
>
>         platform_set_drvdata(pdev, tegra);
>
>         tegra->devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
> -                                           DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
> +                                           DEVFREQ_GOV_SIMPLE_ONDEMAND,
> +                                           &tegra->ondemand_data);
>         if (IS_ERR(tegra->devfreq)) {
>                 err = PTR_ERR(tegra->devfreq);
> -               goto remove_opps;
> +               goto put_table;
>         }
>
>         return 0;
>
> -remove_opps:
> -       dev_pm_opp_remove_all_dynamic(&pdev->dev);
> +put_table:
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
>
>         return err;
>  }
> @@ -190,21 +158,27 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
>         struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
>
>         devfreq_remove_device(tegra->devfreq);
> -       dev_pm_opp_remove_all_dynamic(&pdev->dev);
> +       dev_pm_opp_of_remove_table(&pdev->dev);
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
>
>         return 0;
>  }
>
> +static const struct of_device_id tegra_devfreq_of_match[] = {
> +       { .compatible = "nvidia,tegra20-emc-statistics" },
> +       { },
> +};
> +
>  static struct platform_driver tegra_devfreq_driver = {
>         .probe          = tegra_devfreq_probe,
>         .remove         = tegra_devfreq_remove,
>         .driver         = {
>                 .name   = "tegra20-devfreq",
> +               .of_match_table = tegra_devfreq_of_match,
>         },
>  };
>  module_platform_driver(tegra_devfreq_driver);
>
> -MODULE_ALIAS("platform:tegra20-devfreq");
>  MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
>  MODULE_DESCRIPTION("NVIDIA Tegra20 devfreq driver");
>  MODULE_LICENSE("GPL v2");
> --
> 2.27.0
>

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
@ 2020-11-01 13:31     ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 13:31 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

Hi Dmitry,

This patch contains the three features as following:
1. Use interconnect interface for controlling the clock instead of
controlling it direclty
2. Use EMC_STAT instead of IMC_STAT
3. Change polling_interval and upthreshold for more fast responsiveness

I think you need to make the separate patches for each role.
But, if it is difficult or not proper to split out 1,2 roles, you can
make two patches for 1,2 and 3 roles.

Also, if you want to get more responsiveness, you could use delayed timer
instead of deferrable timer by editing the devfreq_dev_profile structure.

Regards,
Chanwoo Choi



On Mon, Oct 26, 2020 at 7:21 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> External (EMC) and Internal Memory Controllers (IMC) have a nearly
> identical statistics gathering module. This patch switches driver to use
> EMC_STAT instead of IMC_STAT and adds device-tree support which brings ICC
> support and makes driver to use bandwidth OPPs defined in device-tree.
>
> The previous tegra20-devfreq variant was depending on presence of both
> EMC and IMC drivers simultaneously because it wasn't apparent how to use
> EMC_STAT properly back in the day. Dependency on the IMC driver is gone
> after this patch.
>
> The older variant of the devfreq driver also isn't suitable anymore
> because EMC got support for interconnect framework and DVFS, hence
> tegra20-devfreq shouldn't drive the EMC clock directly, but use OPP
> API for issuing memory bandwidth requests.
>
> The polling interval is changed from 500ms to 30ms in order to improve
> responsiveness of the system in general and because EMC clock is now
> allowed to go lower than before since display driver supports ICC now
> as well.
>
> The parent EMC device is an MFD device now and tegra20-devfreq its
> sub-device. Devfreq driver uses SYSCON API for retrieving regmap of the
> EMC registers from the parent device.
>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/Kconfig           |   1 +
>  drivers/devfreq/tegra20-devfreq.c | 174 +++++++++++++-----------------
>  2 files changed, 75 insertions(+), 100 deletions(-)
>
> diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
> index 0ee36ae2fa79..1bd225e571df 100644
> --- a/drivers/devfreq/Kconfig
> +++ b/drivers/devfreq/Kconfig
> @@ -126,6 +126,7 @@ config ARM_TEGRA20_DEVFREQ
>         depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST
>         depends on COMMON_CLK
>         select DEVFREQ_GOV_SIMPLE_ONDEMAND
> +       select MFD_SYSCON
>         help
>           This adds the DEVFREQ driver for the Tegra20 family of SoCs.
>           It reads Memory Controller counters and adjusts the operating
> diff --git a/drivers/devfreq/tegra20-devfreq.c b/drivers/devfreq/tegra20-devfreq.c
> index fd801534771d..0a36b085d32a 100644
> --- a/drivers/devfreq/tegra20-devfreq.c
> +++ b/drivers/devfreq/tegra20-devfreq.c
> @@ -7,180 +7,148 @@
>
>  #include <linux/clk.h>
>  #include <linux/devfreq.h>
> -#include <linux/io.h>
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> +#include <linux/mfd/syscon.h>
>  #include <linux/of_device.h>
>  #include <linux/platform_device.h>
>  #include <linux/pm_opp.h>
> +#include <linux/regmap.h>
>  #include <linux/slab.h>
>
> -#include <soc/tegra/mc.h>
> -
>  #include "governor.h"
>
> -#define MC_STAT_CONTROL                                0x90
> -#define MC_STAT_EMC_CLOCK_LIMIT                        0xa0
> -#define MC_STAT_EMC_CLOCKS                     0xa4
> -#define MC_STAT_EMC_CONTROL                    0xa8
> -#define MC_STAT_EMC_COUNT                      0xb8
> +#define EMC_STAT_CONTROL                       0x160
> +#define EMC_STAT_LLMC_CONTROL                  0x178
> +#define EMC_STAT_PWR_CLOCK_LIMIT               0x198
> +#define EMC_STAT_PWR_CLOCKS                    0x19c
> +#define EMC_STAT_PWR_COUNT                     0x1a0
>
> -#define EMC_GATHER_CLEAR                       (1 << 8)
> -#define EMC_GATHER_ENABLE                      (3 << 8)
> +#define EMC_PWR_GATHER_CLEAR                   (1 << 8)
> +#define EMC_PWR_GATHER_DISABLE                 (2 << 8)
> +#define EMC_PWR_GATHER_ENABLE                  (3 << 8)
>
>  struct tegra_devfreq {
> +       struct devfreq_simple_ondemand_data ondemand_data;
> +       struct opp_table *opp_table;
>         struct devfreq *devfreq;
>         struct clk *emc_clock;
> -       void __iomem *regs;
> +       struct regmap *rmap;
>  };
>
>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>                                 u32 flags)
>  {
> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> -       struct devfreq *devfreq = tegra->devfreq;
>         struct dev_pm_opp *opp;
> -       unsigned long rate;
> -       int err;
> +       int ret;
>
>         opp = devfreq_recommended_opp(dev, freq, flags);
> -       if (IS_ERR(opp))
> +       if (IS_ERR(opp)) {
> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
>                 return PTR_ERR(opp);
> +       }
>
> -       rate = dev_pm_opp_get_freq(opp);
> +       ret = dev_pm_opp_set_bw(dev, opp);
>         dev_pm_opp_put(opp);
>
> -       err = clk_set_min_rate(tegra->emc_clock, rate);
> -       if (err)
> -               return err;
> -
> -       err = clk_set_rate(tegra->emc_clock, 0);
> -       if (err)
> -               goto restore_min_rate;
> -
> -       return 0;
> -
> -restore_min_rate:
> -       clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
> -
> -       return err;
> +       return ret;
>  }
>
>  static int tegra_devfreq_get_dev_status(struct device *dev,
>                                         struct devfreq_dev_status *stat)
>  {
>         struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> +       u32 count, clocks;
>
> -       /*
> -        * EMC_COUNT returns number of memory events, that number is lower
> -        * than the number of clocks. Conversion ratio of 1/8 results in a
> -        * bit higher bandwidth than actually needed, it is good enough for
> -        * the time being because drivers don't support requesting minimum
> -        * needed memory bandwidth yet.
> -        *
> -        * TODO: adjust the ratio value once relevant drivers will support
> -        * memory bandwidth management.
> -        */
> -       stat->busy_time = readl_relaxed(tegra->regs + MC_STAT_EMC_COUNT);
> -       stat->total_time = readl_relaxed(tegra->regs + MC_STAT_EMC_CLOCKS) / 8;
> -       stat->current_frequency = clk_get_rate(tegra->emc_clock);
> +       /* freeze counters */
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_DISABLE);
> +
> +       /* number of clocks when EMC request was accepted */
> +       regmap_read(tegra->rmap, EMC_STAT_PWR_COUNT, &count);
> +       /* total number of clocks while PWR_GATHER control was set to ENABLE */
> +       regmap_read(tegra->rmap, EMC_STAT_PWR_CLOCKS, &clocks);
>
> -       writel_relaxed(EMC_GATHER_CLEAR, tegra->regs + MC_STAT_CONTROL);
> -       writel_relaxed(EMC_GATHER_ENABLE, tegra->regs + MC_STAT_CONTROL);
> +       /* clear counters and restart */
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_CLEAR);
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, EMC_PWR_GATHER_ENABLE);
> +
> +       stat->busy_time = count;
> +       stat->total_time = clocks;
> +       stat->current_frequency = clk_get_rate(tegra->emc_clock);
>
>         return 0;
>  }
>
>  static struct devfreq_dev_profile tegra_devfreq_profile = {
> -       .polling_ms     = 500,
> +       .polling_ms     = 30,
>         .target         = tegra_devfreq_target,
>         .get_dev_status = tegra_devfreq_get_dev_status,
>  };
>
> -static struct tegra_mc *tegra_get_memory_controller(void)
> -{
> -       struct platform_device *pdev;
> -       struct device_node *np;
> -       struct tegra_mc *mc;
> -
> -       np = of_find_compatible_node(NULL, NULL, "nvidia,tegra20-mc-gart");
> -       if (!np)
> -               return ERR_PTR(-ENOENT);
> -
> -       pdev = of_find_device_by_node(np);
> -       of_node_put(np);
> -       if (!pdev)
> -               return ERR_PTR(-ENODEV);
> -
> -       mc = platform_get_drvdata(pdev);
> -       if (!mc)
> -               return ERR_PTR(-EPROBE_DEFER);
> -
> -       return mc;
> -}
> -
>  static int tegra_devfreq_probe(struct platform_device *pdev)
>  {
> +       struct device_node *emc_np = pdev->dev.parent->of_node;
>         struct tegra_devfreq *tegra;
> -       struct tegra_mc *mc;
> -       unsigned long max_rate;
> -       unsigned long rate;
>         int err;
>
> -       mc = tegra_get_memory_controller();
> -       if (IS_ERR(mc)) {
> -               err = PTR_ERR(mc);
> -               dev_err(&pdev->dev, "failed to get memory controller: %d\n",
> -                       err);
> -               return err;
> -       }
> -
>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
>         if (!tegra)
>                 return -ENOMEM;
>
>         /* EMC is a system-critical clock that is always enabled */
> -       tegra->emc_clock = devm_clk_get(&pdev->dev, "emc");
> +       tegra->emc_clock = devm_get_clk_from_child(&pdev->dev, emc_np, NULL);
>         if (IS_ERR(tegra->emc_clock))
>                 return dev_err_probe(&pdev->dev, PTR_ERR(tegra->emc_clock),
>                                      "failed to get emc clock\n");
>
> -       tegra->regs = mc->regs;
> -
> -       max_rate = clk_round_rate(tegra->emc_clock, ULONG_MAX);
> +       tegra->rmap = device_node_to_regmap(emc_np);
> +       if (IS_ERR(tegra->rmap))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->rmap),
> +                                    "failed to get emc regmap\n");
>
> -       for (rate = 0; rate <= max_rate; rate++) {
> -               rate = clk_round_rate(tegra->emc_clock, rate);
> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
> +       if (IS_ERR(tegra->opp_table))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
> +                                    "failed to prepare opp table\n");
>
> -               err = dev_pm_opp_add(&pdev->dev, rate, 0);
> -               if (err) {
> -                       dev_err(&pdev->dev, "failed to add opp: %d\n", err);
> -                       goto remove_opps;
> -               }
> +       err = dev_pm_opp_of_add_table(&pdev->dev);
> +       if (err) {
> +               dev_err(&pdev->dev, "failed to add opp table: %d\n", err);
> +               goto put_table;
>         }
>
> +       /*
> +        * PWR_COUNT is 1/2 of PWR_CLOCKS at max, and thus, the up-threshold
> +        * should be less than 50.  Secondly, multiple active memory clients
> +        * may cause over 20 of lost clock cycles due to stalls caused by
> +        * competing memory accesses.  This means that threshold should be
> +        * set to a less than 30 in order to have a properly working governor.
> +        */
> +       tegra->ondemand_data.upthreshold = 20;
> +
>         /*
>          * Reset statistic gathers state, select global bandwidth for the
>          * statistics collection mode and set clocks counter saturation
>          * limit to maximum.
>          */
> -       writel_relaxed(0x00000000, tegra->regs + MC_STAT_CONTROL);
> -       writel_relaxed(0x00000000, tegra->regs + MC_STAT_EMC_CONTROL);
> -       writel_relaxed(0xffffffff, tegra->regs + MC_STAT_EMC_CLOCK_LIMIT);
> +       regmap_write(tegra->rmap, EMC_STAT_CONTROL, 0x00000000);
> +       regmap_write(tegra->rmap, EMC_STAT_LLMC_CONTROL, 0x00000000);
> +       regmap_write(tegra->rmap, EMC_STAT_PWR_CLOCK_LIMIT, 0xffffffff);
>
>         platform_set_drvdata(pdev, tegra);
>
>         tegra->devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
> -                                           DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
> +                                           DEVFREQ_GOV_SIMPLE_ONDEMAND,
> +                                           &tegra->ondemand_data);
>         if (IS_ERR(tegra->devfreq)) {
>                 err = PTR_ERR(tegra->devfreq);
> -               goto remove_opps;
> +               goto put_table;
>         }
>
>         return 0;
>
> -remove_opps:
> -       dev_pm_opp_remove_all_dynamic(&pdev->dev);
> +put_table:
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
>
>         return err;
>  }
> @@ -190,21 +158,27 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
>         struct tegra_devfreq *tegra = platform_get_drvdata(pdev);
>
>         devfreq_remove_device(tegra->devfreq);
> -       dev_pm_opp_remove_all_dynamic(&pdev->dev);
> +       dev_pm_opp_of_remove_table(&pdev->dev);
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
>
>         return 0;
>  }
>
> +static const struct of_device_id tegra_devfreq_of_match[] = {
> +       { .compatible = "nvidia,tegra20-emc-statistics" },
> +       { },
> +};
> +
>  static struct platform_driver tegra_devfreq_driver = {
>         .probe          = tegra_devfreq_probe,
>         .remove         = tegra_devfreq_remove,
>         .driver         = {
>                 .name   = "tegra20-devfreq",
> +               .of_match_table = tegra_devfreq_of_match,
>         },
>  };
>  module_platform_driver(tegra_devfreq_driver);
>
> -MODULE_ALIAS("platform:tegra20-devfreq");
>  MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
>  MODULE_DESCRIPTION("NVIDIA Tegra20 devfreq driver");
>  MODULE_LICENSE("GPL v2");
> --
> 2.27.0
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
  2020-11-01 13:31     ` Chanwoo Choi
@ 2020-11-01 14:12       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 14:12 UTC (permalink / raw)
  To: cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

01.11.2020 16:31, Chanwoo Choi пишет:
> Hi Dmitry,
> 
> This patch contains the three features as following:
> 1. Use interconnect interface for controlling the clock instead of
> controlling it direclty
> 2. Use EMC_STAT instead of IMC_STAT
> 3. Change polling_interval and upthreshold for more fast responsiveness
> 
> I think you need to make the separate patches for each role.
> But, if it is difficult or not proper to split out 1,2 roles, you can
> make two patches for 1,2 and 3 roles.

Hello Chanwoo,

We will probably move the Tegra20 EMC_STAT devfreq driver into the
memory driver and remove the older IMC_STAT driver in v7, like it was
suggested by Thierry Reding. This will be a much less invasive code change.

> Also, if you want to get more responsiveness, you could use delayed timer
> instead of deferrable timer by editing the devfreq_dev_profile structure.

Thanks, I'll try the deferrable timer.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
@ 2020-11-01 14:12       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 14:12 UTC (permalink / raw)
  To: cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

01.11.2020 16:31, Chanwoo Choi пишет:
> Hi Dmitry,
> 
> This patch contains the three features as following:
> 1. Use interconnect interface for controlling the clock instead of
> controlling it direclty
> 2. Use EMC_STAT instead of IMC_STAT
> 3. Change polling_interval and upthreshold for more fast responsiveness
> 
> I think you need to make the separate patches for each role.
> But, if it is difficult or not proper to split out 1,2 roles, you can
> make two patches for 1,2 and 3 roles.

Hello Chanwoo,

We will probably move the Tegra20 EMC_STAT devfreq driver into the
memory driver and remove the older IMC_STAT driver in v7, like it was
suggested by Thierry Reding. This will be a much less invasive code change.

> Also, if you want to get more responsiveness, you could use delayed timer
> instead of deferrable timer by editing the devfreq_dev_profile structure.

Thanks, I'll try the deferrable timer.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-11-01 14:39     ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 14:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

Hi Dmitry,

On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> This patch moves ACTMON driver away from generating OPP table by itself,
> transitioning it to use the table which comes from device-tree. This
> change breaks compatibility with older device-trees in order to bring
> support for the interconnect framework to the driver. This is a mandatory
> change which needs to be done in order to implement interconnect-based
> memory DVFS. Users of legacy device-trees will get a message telling that
> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
>  1 file changed, 48 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index 3f732ab53573..1b0b91a71886 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -19,6 +19,8 @@
>  #include <linux/reset.h>
>  #include <linux/workqueue.h>
>
> +#include <soc/tegra/fuse.h>
> +
>  #include "governor.h"
>
>  #define ACTMON_GLB_STATUS                                      0x0
> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
>
>  struct tegra_devfreq {
>         struct devfreq          *devfreq;
> +       struct opp_table        *opp_table;
>
>         struct reset_control    *reset;
>         struct clk              *clock;
> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>                                 u32 flags)
>  {
> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> -       struct devfreq *devfreq = tegra->devfreq;
>         struct dev_pm_opp *opp;
> -       unsigned long rate;
> -       int err;
> +       int ret;
>
>         opp = devfreq_recommended_opp(dev, freq, flags);
>         if (IS_ERR(opp)) {
> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
>                 return PTR_ERR(opp);
>         }
> -       rate = dev_pm_opp_get_freq(opp);
> -       dev_pm_opp_put(opp);
> -
> -       err = clk_set_min_rate(tegra->emc_clock, rate * KHZ);
> -       if (err)
> -               return err;
> -
> -       err = clk_set_rate(tegra->emc_clock, 0);
> -       if (err)
> -               goto restore_min_rate;
>
> -       return 0;
> -
> -restore_min_rate:
> -       clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
> +       ret = dev_pm_opp_set_bw(dev, opp);
> +       dev_pm_opp_put(opp);
>
> -       return err;
> +       return ret;
>  }
>
>  static int tegra_devfreq_get_dev_status(struct device *dev,
> @@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
>         stat->private_data = tegra;
>
>         /* The below are to be used by the other governors */
> -       stat->current_frequency = cur_freq;
> +       stat->current_frequency = cur_freq * KHZ;

I can't find any change related to the frequency unit on this patch.
Do you fix the previous bug of the frequency unit?

>
>         actmon_dev = &tegra->devices[MCALL];
>
> @@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
>                 target_freq = max(target_freq, dev->target_freq);
>         }
>
> -       *freq = target_freq;
> +       *freq = target_freq * KHZ;

ditto.

>
>         return 0;
>  }
> @@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
>
>  static int tegra_devfreq_probe(struct platform_device *pdev)
>  {
> +       u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
>         struct tegra_devfreq_device *dev;
>         struct tegra_devfreq *tegra;
> +       struct opp_table *opp_table;
>         struct devfreq *devfreq;
>         unsigned int i;
>         long rate;
>         int err;
>
> +       /* legacy device-trees don't have OPP table and must be updated */
> +       if (!device_property_present(&pdev->dev, "operating-points-v2")) {
> +               dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
> +               dev_err(&pdev->dev, "please update your device tree\n");
> +               return -ENODEV;
> +       }

As you mentioned, it breaks the old dtb. I have no objection to improving
the driver. Instead, you need confirmation from the Devicetree maintainer.

And,
I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
to check whether a device contains opp-table or not.

> +
>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
>         if (!tegra)
>                 return -ENOMEM;
> @@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>                 return err;
>         }
>
> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
> +       if (IS_ERR(tegra->opp_table))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
> +                                    "Failed to prepare OPP table\n");

As I knew, each device can contain the opp_table on devicetree.
It means that opp_table has not depended to another device driver.
Did you see this exception case with EPROBE_DEFER error?

> +
> +       opp_table = dev_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
> +       err = PTR_ERR_OR_ZERO(opp_table);
> +       if (err) {
> +               dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
> +               goto put_table;
> +       }
> +
> +       err = dev_pm_opp_of_add_table(&pdev->dev);
> +       if (err) {
> +               dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
> +               goto put_hw;
> +       }
> +
>         err = clk_prepare_enable(tegra->clock);
>         if (err) {
>                 dev_err(&pdev->dev,
>                         "Failed to prepare and enable ACTMON clock\n");
> -               return err;
> +               goto remove_table;
>         }
>
>         err = reset_control_reset(tegra->reset);
> @@ -849,23 +864,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>                 dev->regs = tegra->regs + dev->config->offset;
>         }
>
> -       for (rate = 0; rate <= tegra->max_freq * KHZ; rate++) {
> -               rate = clk_round_rate(tegra->emc_clock, rate);
> -
> -               if (rate < 0) {
> -                       dev_err(&pdev->dev,
> -                               "Failed to round clock rate: %ld\n", rate);
> -                       err = rate;
> -                       goto remove_opps;
> -               }
> -
> -               err = dev_pm_opp_add(&pdev->dev, rate / KHZ, 0);
> -               if (err) {
> -                       dev_err(&pdev->dev, "Failed to add OPP: %d\n", err);
> -                       goto remove_opps;
> -               }
> -       }
> -
>         platform_set_drvdata(pdev, tegra);
>
>         tegra->clk_rate_change_nb.notifier_call = tegra_actmon_clk_notify_cb;
> @@ -881,7 +879,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>         }
>
>         tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
> -       tegra_devfreq_profile.initial_freq /= KHZ;
>
>         devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
>                                      "tegra_actmon", NULL);
> @@ -901,6 +898,12 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>         reset_control_reset(tegra->reset);
>  disable_clk:
>         clk_disable_unprepare(tegra->clock);
> +remove_table:
> +       dev_pm_opp_of_remove_table(&pdev->dev);
> +put_hw:
> +       dev_pm_opp_put_supported_hw(tegra->opp_table);
> +put_table:
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
>
>         return err;
>  }
> @@ -912,11 +915,13 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
>         devfreq_remove_device(tegra->devfreq);
>         devfreq_remove_governor(&tegra_devfreq_governor);
>
> -       dev_pm_opp_remove_all_dynamic(&pdev->dev);
> -
>         reset_control_reset(tegra->reset);
>         clk_disable_unprepare(tegra->clock);
>
> +       dev_pm_opp_of_remove_table(&pdev->dev);
> +       dev_pm_opp_put_supported_hw(tegra->opp_table);
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
> +
>         return 0;
>  }
>
> --
> 2.27.0
>


-- 
Best Regards,
Chanwoo Choi

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 14:39     ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 14:39 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

Hi Dmitry,

On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> This patch moves ACTMON driver away from generating OPP table by itself,
> transitioning it to use the table which comes from device-tree. This
> change breaks compatibility with older device-trees in order to bring
> support for the interconnect framework to the driver. This is a mandatory
> change which needs to be done in order to implement interconnect-based
> memory DVFS. Users of legacy device-trees will get a message telling that
> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
>  1 file changed, 48 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index 3f732ab53573..1b0b91a71886 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -19,6 +19,8 @@
>  #include <linux/reset.h>
>  #include <linux/workqueue.h>
>
> +#include <soc/tegra/fuse.h>
> +
>  #include "governor.h"
>
>  #define ACTMON_GLB_STATUS                                      0x0
> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
>
>  struct tegra_devfreq {
>         struct devfreq          *devfreq;
> +       struct opp_table        *opp_table;
>
>         struct reset_control    *reset;
>         struct clk              *clock;
> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>                                 u32 flags)
>  {
> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> -       struct devfreq *devfreq = tegra->devfreq;
>         struct dev_pm_opp *opp;
> -       unsigned long rate;
> -       int err;
> +       int ret;
>
>         opp = devfreq_recommended_opp(dev, freq, flags);
>         if (IS_ERR(opp)) {
> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
>                 return PTR_ERR(opp);
>         }
> -       rate = dev_pm_opp_get_freq(opp);
> -       dev_pm_opp_put(opp);
> -
> -       err = clk_set_min_rate(tegra->emc_clock, rate * KHZ);
> -       if (err)
> -               return err;
> -
> -       err = clk_set_rate(tegra->emc_clock, 0);
> -       if (err)
> -               goto restore_min_rate;
>
> -       return 0;
> -
> -restore_min_rate:
> -       clk_set_min_rate(tegra->emc_clock, devfreq->previous_freq);
> +       ret = dev_pm_opp_set_bw(dev, opp);
> +       dev_pm_opp_put(opp);
>
> -       return err;
> +       return ret;
>  }
>
>  static int tegra_devfreq_get_dev_status(struct device *dev,
> @@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
>         stat->private_data = tegra;
>
>         /* The below are to be used by the other governors */
> -       stat->current_frequency = cur_freq;
> +       stat->current_frequency = cur_freq * KHZ;

I can't find any change related to the frequency unit on this patch.
Do you fix the previous bug of the frequency unit?

>
>         actmon_dev = &tegra->devices[MCALL];
>
> @@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
>                 target_freq = max(target_freq, dev->target_freq);
>         }
>
> -       *freq = target_freq;
> +       *freq = target_freq * KHZ;

ditto.

>
>         return 0;
>  }
> @@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
>
>  static int tegra_devfreq_probe(struct platform_device *pdev)
>  {
> +       u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
>         struct tegra_devfreq_device *dev;
>         struct tegra_devfreq *tegra;
> +       struct opp_table *opp_table;
>         struct devfreq *devfreq;
>         unsigned int i;
>         long rate;
>         int err;
>
> +       /* legacy device-trees don't have OPP table and must be updated */
> +       if (!device_property_present(&pdev->dev, "operating-points-v2")) {
> +               dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
> +               dev_err(&pdev->dev, "please update your device tree\n");
> +               return -ENODEV;
> +       }

As you mentioned, it breaks the old dtb. I have no objection to improving
the driver. Instead, you need confirmation from the Devicetree maintainer.

And,
I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
to check whether a device contains opp-table or not.

> +
>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
>         if (!tegra)
>                 return -ENOMEM;
> @@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>                 return err;
>         }
>
> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
> +       if (IS_ERR(tegra->opp_table))
> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
> +                                    "Failed to prepare OPP table\n");

As I knew, each device can contain the opp_table on devicetree.
It means that opp_table has not depended to another device driver.
Did you see this exception case with EPROBE_DEFER error?

> +
> +       opp_table = dev_pm_opp_set_supported_hw(&pdev->dev, &hw_version, 1);
> +       err = PTR_ERR_OR_ZERO(opp_table);
> +       if (err) {
> +               dev_err(&pdev->dev, "Failed to set supported HW: %d\n", err);
> +               goto put_table;
> +       }
> +
> +       err = dev_pm_opp_of_add_table(&pdev->dev);
> +       if (err) {
> +               dev_err(&pdev->dev, "Failed to add OPP table: %d\n", err);
> +               goto put_hw;
> +       }
> +
>         err = clk_prepare_enable(tegra->clock);
>         if (err) {
>                 dev_err(&pdev->dev,
>                         "Failed to prepare and enable ACTMON clock\n");
> -               return err;
> +               goto remove_table;
>         }
>
>         err = reset_control_reset(tegra->reset);
> @@ -849,23 +864,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>                 dev->regs = tegra->regs + dev->config->offset;
>         }
>
> -       for (rate = 0; rate <= tegra->max_freq * KHZ; rate++) {
> -               rate = clk_round_rate(tegra->emc_clock, rate);
> -
> -               if (rate < 0) {
> -                       dev_err(&pdev->dev,
> -                               "Failed to round clock rate: %ld\n", rate);
> -                       err = rate;
> -                       goto remove_opps;
> -               }
> -
> -               err = dev_pm_opp_add(&pdev->dev, rate / KHZ, 0);
> -               if (err) {
> -                       dev_err(&pdev->dev, "Failed to add OPP: %d\n", err);
> -                       goto remove_opps;
> -               }
> -       }
> -
>         platform_set_drvdata(pdev, tegra);
>
>         tegra->clk_rate_change_nb.notifier_call = tegra_actmon_clk_notify_cb;
> @@ -881,7 +879,6 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>         }
>
>         tegra_devfreq_profile.initial_freq = clk_get_rate(tegra->emc_clock);
> -       tegra_devfreq_profile.initial_freq /= KHZ;
>
>         devfreq = devfreq_add_device(&pdev->dev, &tegra_devfreq_profile,
>                                      "tegra_actmon", NULL);
> @@ -901,6 +898,12 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>         reset_control_reset(tegra->reset);
>  disable_clk:
>         clk_disable_unprepare(tegra->clock);
> +remove_table:
> +       dev_pm_opp_of_remove_table(&pdev->dev);
> +put_hw:
> +       dev_pm_opp_put_supported_hw(tegra->opp_table);
> +put_table:
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
>
>         return err;
>  }
> @@ -912,11 +915,13 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
>         devfreq_remove_device(tegra->devfreq);
>         devfreq_remove_governor(&tegra_devfreq_governor);
>
> -       dev_pm_opp_remove_all_dynamic(&pdev->dev);
> -
>         reset_control_reset(tegra->reset);
>         clk_disable_unprepare(tegra->clock);
>
> +       dev_pm_opp_of_remove_table(&pdev->dev);
> +       dev_pm_opp_put_supported_hw(tegra->opp_table);
> +       dev_pm_opp_put_opp_table(tegra->opp_table);
> +
>         return 0;
>  }
>
> --
> 2.27.0
>


-- 
Best Regards,
Chanwoo Choi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-11-01 14:44     ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 14:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

Hi Dmitry,

On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> This patch moves ACTMON driver away from generating OPP table by itself,
> transitioning it to use the table which comes from device-tree. This
> change breaks compatibility with older device-trees in order to bring
> support for the interconnect framework to the driver. This is a mandatory
> change which needs to be done in order to implement interconnect-based
> memory DVFS. Users of legacy device-trees will get a message telling that
> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
>  1 file changed, 48 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index 3f732ab53573..1b0b91a71886 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -19,6 +19,8 @@
>  #include <linux/reset.h>
>  #include <linux/workqueue.h>
>
> +#include <soc/tegra/fuse.h>
> +

This patch touches the OPP. Is it related to this change?

>  #include "governor.h"
>
>  #define ACTMON_GLB_STATUS                                      0x0
> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
>
>  struct tegra_devfreq {
>         struct devfreq          *devfreq;
> +       struct opp_table        *opp_table;
>
>         struct reset_control    *reset;
>         struct clk              *clock;
> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>                                 u32 flags)
>  {
> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> -       struct devfreq *devfreq = tegra->devfreq;
>         struct dev_pm_opp *opp;
> -       unsigned long rate;
> -       int err;
> +       int ret;
>
>         opp = devfreq_recommended_opp(dev, freq, flags);
>         if (IS_ERR(opp)) {
> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);

You used the 'Failed to' format in almost every error case.
Don't need to change it.
(snip)

Best Regards,
Chanwoo Choi

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 14:44     ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 14:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

Hi Dmitry,

On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> This patch moves ACTMON driver away from generating OPP table by itself,
> transitioning it to use the table which comes from device-tree. This
> change breaks compatibility with older device-trees in order to bring
> support for the interconnect framework to the driver. This is a mandatory
> change which needs to be done in order to implement interconnect-based
> memory DVFS. Users of legacy device-trees will get a message telling that
> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
>  1 file changed, 48 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index 3f732ab53573..1b0b91a71886 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -19,6 +19,8 @@
>  #include <linux/reset.h>
>  #include <linux/workqueue.h>
>
> +#include <soc/tegra/fuse.h>
> +

This patch touches the OPP. Is it related to this change?

>  #include "governor.h"
>
>  #define ACTMON_GLB_STATUS                                      0x0
> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
>
>  struct tegra_devfreq {
>         struct devfreq          *devfreq;
> +       struct opp_table        *opp_table;
>
>         struct reset_control    *reset;
>         struct clk              *clock;
> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>                                 u32 flags)
>  {
> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> -       struct devfreq *devfreq = tegra->devfreq;
>         struct dev_pm_opp *opp;
> -       unsigned long rate;
> -       int err;
> +       int ret;
>
>         opp = devfreq_recommended_opp(dev, freq, flags);
>         if (IS_ERR(opp)) {
> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);

You used the 'Failed to' format in almost every error case.
Don't need to change it.
(snip)

Best Regards,
Chanwoo Choi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 52/52] PM / devfreq: tegra30: Separate configurations per-SoC generation
  2020-10-25 22:17   ` Dmitry Osipenko
@ 2020-11-01 15:20     ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

Hi Dmitry,

I added the review about 'ARRAY_SIZE(tegra124_device_configs)'.
Except for this, it looks good to me.

On Mon, Oct 26, 2020 at 7:21 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> Previously we were using count-weight of the T124 for T30 in order to
> get EMC clock rate that was reasonable for T30. In fact the count-weight
> should be x2 times smaller on T30, but then devfreq was producing a bit
> too low EMC clock rate for ISO memory clients, like display controller
> for example.
>
> Now both Tegra ACTMON and Tegra DRM display drivers support interconnect
> framework and display driver tells to ICC what a minimum memory bandwidth
> is needed, preventing FIFO underflows. Thus, now we can use a proper
> count-weight value for Tegra30 and MC_ALL device config needs a bit more
> aggressive boosting.
>
> This patch adds a separate ACTMON driver configuration that is specific
> to Tegra30.
>
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 68 ++++++++++++++++++++++++-------
>  1 file changed, 54 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index 1b0b91a71886..95aba89eae88 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -57,13 +57,6 @@
>  #define ACTMON_BELOW_WMARK_WINDOW                              3
>  #define ACTMON_BOOST_FREQ_STEP                                 16000
>
> -/*
> - * Activity counter is incremented every 256 memory transactions, and each
> - * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is
> - * 4 * 256 = 1024.
> - */
> -#define ACTMON_COUNT_WEIGHT                                    0x400
> -
>  /*
>   * ACTMON_AVERAGE_WINDOW_LOG2: default value for @DEV_CTRL_K_VAL, which
>   * translates to 2 ^ (K_VAL + 1). ex: 2 ^ (6 + 1) = 128
> @@ -111,7 +104,7 @@ enum tegra_actmon_device {
>         MCCPU,
>  };
>
> -static const struct tegra_devfreq_device_config actmon_device_configs[] = {
> +static const struct tegra_devfreq_device_config tegra124_device_configs[] = {
>         {
>                 /* MCALL: All memory accesses (including from the CPUs) */
>                 .offset = 0x1c0,
> @@ -133,6 +126,28 @@ static const struct tegra_devfreq_device_config actmon_device_configs[] = {
>         },
>  };
>
> +static const struct tegra_devfreq_device_config tegra30_device_configs[] = {
> +       {
> +               /* MCALL: All memory accesses (including from the CPUs) */
> +               .offset = 0x1c0,
> +               .irq_mask = 1 << 26,
> +               .boost_up_coeff = 200,
> +               .boost_down_coeff = 50,
> +               .boost_up_threshold = 20,
> +               .boost_down_threshold = 10,
> +       },
> +       {
> +               /* MCCPU: memory accesses from the CPUs */
> +               .offset = 0x200,
> +               .irq_mask = 1 << 25,
> +               .boost_up_coeff = 800,
> +               .boost_down_coeff = 40,
> +               .boost_up_threshold = 27,
> +               .boost_down_threshold = 10,
> +               .avg_dependency_threshold = 16000, /* 16MHz in kHz units */
> +       },
> +};
> +
>  /**
>   * struct tegra_devfreq_device - state specific to an ACTMON device
>   *
> @@ -155,6 +170,12 @@ struct tegra_devfreq_device {
>         unsigned long target_freq;
>  };
>
> +struct tegra_devfreq_soc_data {
> +       const struct tegra_devfreq_device_config *configs;
> +       /* Weight value for count measurements */
> +       unsigned int count_weight;
> +};
> +
>  struct tegra_devfreq {
>         struct devfreq          *devfreq;
>         struct opp_table        *opp_table;
> @@ -171,11 +192,13 @@ struct tegra_devfreq {
>         struct delayed_work     cpufreq_update_work;
>         struct notifier_block   cpu_rate_change_nb;
>
> -       struct tegra_devfreq_device devices[ARRAY_SIZE(actmon_device_configs)];
> +       struct tegra_devfreq_device devices[ARRAY_SIZE(tegra124_device_configs)];

When there is one tegra_devfreq_device_config[] array, this style is not wrong.
But, after adding the specific config array for each device,
you better specify the correct array size for each case.

Even if there is no runtime error on tegra30 soc, it is not proper to use
ARRAY_SIZE(tegra124_device_configs). You can allocate the array
of tegra_devfreq_device[] or use fixed the array size (2).

>
>         unsigned int            irq;
>
>         bool                    started;
> +
> +       const struct tegra_devfreq_soc_data *soc;
>  };
>
>  struct tegra_actmon_emc_ratio {
> @@ -488,7 +511,7 @@ static void tegra_actmon_configure_device(struct tegra_devfreq *tegra,
>         tegra_devfreq_update_avg_wmark(tegra, dev);
>         tegra_devfreq_update_wmark(tegra, dev);
>
> -       device_writel(dev, ACTMON_COUNT_WEIGHT, ACTMON_DEV_COUNT_WEIGHT);
> +       device_writel(dev, tegra->soc->count_weight, ACTMON_DEV_COUNT_WEIGHT);
>         device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS);
>
>         val |= ACTMON_DEV_CTRL_ENB_PERIODIC;
> @@ -781,6 +804,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>         if (!tegra)
>                 return -ENOMEM;
>
> +       tegra->soc = of_device_get_match_data(&pdev->dev);
> +
>         tegra->regs = devm_platform_ioremap_resource(pdev, 0);
>         if (IS_ERR(tegra->regs))
>                 return PTR_ERR(tegra->regs);
> @@ -858,9 +883,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>
>         tegra->max_freq = rate / KHZ;
>
> -       for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) {
> +       for (i = 0; i < ARRAY_SIZE(tegra124_device_configs); i++) {

ditto. Use ARRARY_SIZE(soc->configs) instead of
ARRAY_SIZE(tegra124_device_configs).

>                 dev = tegra->devices + i;
> -               dev->config = actmon_device_configs + i;
> +               dev->config = tegra->soc->configs + i;
>                 dev->regs = tegra->regs + dev->config->offset;
>         }
>
> @@ -925,9 +950,24 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
>         return 0;
>  }
>
> +static const struct tegra_devfreq_soc_data tegra124_soc = {
> +       .configs = tegra124_device_configs,
> +
> +       /*
> +        * Activity counter is incremented every 256 memory transactions,
> +        * and each transaction takes 4 EMC clocks.
> +        */
> +       .count_weight = 4 * 256,
> +};
> +
> +static const struct tegra_devfreq_soc_data tegra30_soc = {
> +       .configs = tegra30_device_configs,
> +       .count_weight = 2 * 256,
> +};
> +
>  static const struct of_device_id tegra_devfreq_of_match[] = {
> -       { .compatible = "nvidia,tegra30-actmon" },
> -       { .compatible = "nvidia,tegra124-actmon" },
> +       { .compatible = "nvidia,tegra30-actmon",  .data = &tegra30_soc, },
> +       { .compatible = "nvidia,tegra124-actmon", .data = &tegra124_soc, },
>         { },
>  };
>
> --
> 2.27.0
>


-- 
Best Regards,
Chanwoo Choi

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 52/52] PM / devfreq: tegra30: Separate configurations per-SoC generation
@ 2020-11-01 15:20     ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:20 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

Hi Dmitry,

I added the review about 'ARRAY_SIZE(tegra124_device_configs)'.
Except for this, it looks good to me.

On Mon, Oct 26, 2020 at 7:21 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> Previously we were using count-weight of the T124 for T30 in order to
> get EMC clock rate that was reasonable for T30. In fact the count-weight
> should be x2 times smaller on T30, but then devfreq was producing a bit
> too low EMC clock rate for ISO memory clients, like display controller
> for example.
>
> Now both Tegra ACTMON and Tegra DRM display drivers support interconnect
> framework and display driver tells to ICC what a minimum memory bandwidth
> is needed, preventing FIFO underflows. Thus, now we can use a proper
> count-weight value for Tegra30 and MC_ALL device config needs a bit more
> aggressive boosting.
>
> This patch adds a separate ACTMON driver configuration that is specific
> to Tegra30.
>
> Tested-by: Peter Geis <pgwipeout@gmail.com>
> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> ---
>  drivers/devfreq/tegra30-devfreq.c | 68 ++++++++++++++++++++++++-------
>  1 file changed, 54 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> index 1b0b91a71886..95aba89eae88 100644
> --- a/drivers/devfreq/tegra30-devfreq.c
> +++ b/drivers/devfreq/tegra30-devfreq.c
> @@ -57,13 +57,6 @@
>  #define ACTMON_BELOW_WMARK_WINDOW                              3
>  #define ACTMON_BOOST_FREQ_STEP                                 16000
>
> -/*
> - * Activity counter is incremented every 256 memory transactions, and each
> - * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is
> - * 4 * 256 = 1024.
> - */
> -#define ACTMON_COUNT_WEIGHT                                    0x400
> -
>  /*
>   * ACTMON_AVERAGE_WINDOW_LOG2: default value for @DEV_CTRL_K_VAL, which
>   * translates to 2 ^ (K_VAL + 1). ex: 2 ^ (6 + 1) = 128
> @@ -111,7 +104,7 @@ enum tegra_actmon_device {
>         MCCPU,
>  };
>
> -static const struct tegra_devfreq_device_config actmon_device_configs[] = {
> +static const struct tegra_devfreq_device_config tegra124_device_configs[] = {
>         {
>                 /* MCALL: All memory accesses (including from the CPUs) */
>                 .offset = 0x1c0,
> @@ -133,6 +126,28 @@ static const struct tegra_devfreq_device_config actmon_device_configs[] = {
>         },
>  };
>
> +static const struct tegra_devfreq_device_config tegra30_device_configs[] = {
> +       {
> +               /* MCALL: All memory accesses (including from the CPUs) */
> +               .offset = 0x1c0,
> +               .irq_mask = 1 << 26,
> +               .boost_up_coeff = 200,
> +               .boost_down_coeff = 50,
> +               .boost_up_threshold = 20,
> +               .boost_down_threshold = 10,
> +       },
> +       {
> +               /* MCCPU: memory accesses from the CPUs */
> +               .offset = 0x200,
> +               .irq_mask = 1 << 25,
> +               .boost_up_coeff = 800,
> +               .boost_down_coeff = 40,
> +               .boost_up_threshold = 27,
> +               .boost_down_threshold = 10,
> +               .avg_dependency_threshold = 16000, /* 16MHz in kHz units */
> +       },
> +};
> +
>  /**
>   * struct tegra_devfreq_device - state specific to an ACTMON device
>   *
> @@ -155,6 +170,12 @@ struct tegra_devfreq_device {
>         unsigned long target_freq;
>  };
>
> +struct tegra_devfreq_soc_data {
> +       const struct tegra_devfreq_device_config *configs;
> +       /* Weight value for count measurements */
> +       unsigned int count_weight;
> +};
> +
>  struct tegra_devfreq {
>         struct devfreq          *devfreq;
>         struct opp_table        *opp_table;
> @@ -171,11 +192,13 @@ struct tegra_devfreq {
>         struct delayed_work     cpufreq_update_work;
>         struct notifier_block   cpu_rate_change_nb;
>
> -       struct tegra_devfreq_device devices[ARRAY_SIZE(actmon_device_configs)];
> +       struct tegra_devfreq_device devices[ARRAY_SIZE(tegra124_device_configs)];

When there is one tegra_devfreq_device_config[] array, this style is not wrong.
But, after adding the specific config array for each device,
you better specify the correct array size for each case.

Even if there is no runtime error on tegra30 soc, it is not proper to use
ARRAY_SIZE(tegra124_device_configs). You can allocate the array
of tegra_devfreq_device[] or use fixed the array size (2).

>
>         unsigned int            irq;
>
>         bool                    started;
> +
> +       const struct tegra_devfreq_soc_data *soc;
>  };
>
>  struct tegra_actmon_emc_ratio {
> @@ -488,7 +511,7 @@ static void tegra_actmon_configure_device(struct tegra_devfreq *tegra,
>         tegra_devfreq_update_avg_wmark(tegra, dev);
>         tegra_devfreq_update_wmark(tegra, dev);
>
> -       device_writel(dev, ACTMON_COUNT_WEIGHT, ACTMON_DEV_COUNT_WEIGHT);
> +       device_writel(dev, tegra->soc->count_weight, ACTMON_DEV_COUNT_WEIGHT);
>         device_writel(dev, ACTMON_INTR_STATUS_CLEAR, ACTMON_DEV_INTR_STATUS);
>
>         val |= ACTMON_DEV_CTRL_ENB_PERIODIC;
> @@ -781,6 +804,8 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>         if (!tegra)
>                 return -ENOMEM;
>
> +       tegra->soc = of_device_get_match_data(&pdev->dev);
> +
>         tegra->regs = devm_platform_ioremap_resource(pdev, 0);
>         if (IS_ERR(tegra->regs))
>                 return PTR_ERR(tegra->regs);
> @@ -858,9 +883,9 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>
>         tegra->max_freq = rate / KHZ;
>
> -       for (i = 0; i < ARRAY_SIZE(actmon_device_configs); i++) {
> +       for (i = 0; i < ARRAY_SIZE(tegra124_device_configs); i++) {

ditto. Use ARRARY_SIZE(soc->configs) instead of
ARRAY_SIZE(tegra124_device_configs).

>                 dev = tegra->devices + i;
> -               dev->config = actmon_device_configs + i;
> +               dev->config = tegra->soc->configs + i;
>                 dev->regs = tegra->regs + dev->config->offset;
>         }
>
> @@ -925,9 +950,24 @@ static int tegra_devfreq_remove(struct platform_device *pdev)
>         return 0;
>  }
>
> +static const struct tegra_devfreq_soc_data tegra124_soc = {
> +       .configs = tegra124_device_configs,
> +
> +       /*
> +        * Activity counter is incremented every 256 memory transactions,
> +        * and each transaction takes 4 EMC clocks.
> +        */
> +       .count_weight = 4 * 256,
> +};
> +
> +static const struct tegra_devfreq_soc_data tegra30_soc = {
> +       .configs = tegra30_device_configs,
> +       .count_weight = 2 * 256,
> +};
> +
>  static const struct of_device_id tegra_devfreq_of_match[] = {
> -       { .compatible = "nvidia,tegra30-actmon" },
> -       { .compatible = "nvidia,tegra124-actmon" },
> +       { .compatible = "nvidia,tegra30-actmon",  .data = &tegra30_soc, },
> +       { .compatible = "nvidia,tegra124-actmon", .data = &tegra124_soc, },
>         { },
>  };
>
> --
> 2.27.0
>


-- 
Best Regards,
Chanwoo Choi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 14:39     ` Chanwoo Choi
@ 2020-11-01 15:23       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 15:23 UTC (permalink / raw)
  To: cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

01.11.2020 17:39, Chanwoo Choi пишет:
> Hi Dmitry,
> 
> On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>
>> This patch moves ACTMON driver away from generating OPP table by itself,
>> transitioning it to use the table which comes from device-tree. This
>> change breaks compatibility with older device-trees in order to bring
>> support for the interconnect framework to the driver. This is a mandatory
>> change which needs to be done in order to implement interconnect-based
>> memory DVFS. Users of legacy device-trees will get a message telling that
>> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
>> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>>
>> Tested-by: Peter Geis <pgwipeout@gmail.com>
>> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
...
>>  static int tegra_devfreq_get_dev_status(struct device *dev,
>> @@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
>>         stat->private_data = tegra;
>>
>>         /* The below are to be used by the other governors */
>> -       stat->current_frequency = cur_freq;
>> +       stat->current_frequency = cur_freq * KHZ;
> 
> I can't find any change related to the frequency unit on this patch.
> Do you fix the previous bug of the frequency unit?

Previously, OPP entries that were generated by the driver used KHz
units. Now, OPP entries are coming from a device-tree and they have Hz
units. This driver operates with KHz internally, hence we need to
convert the units now.

>>
>>         actmon_dev = &tegra->devices[MCALL];
>>
>> @@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
>>                 target_freq = max(target_freq, dev->target_freq);
>>         }
>>
>> -       *freq = target_freq;
>> +       *freq = target_freq * KHZ;
> 
> ditto.
> 
>>
>>         return 0;
>>  }
>> @@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
>>
>>  static int tegra_devfreq_probe(struct platform_device *pdev)
>>  {
>> +       u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
>>         struct tegra_devfreq_device *dev;
>>         struct tegra_devfreq *tegra;
>> +       struct opp_table *opp_table;
>>         struct devfreq *devfreq;
>>         unsigned int i;
>>         long rate;
>>         int err;
>>
>> +       /* legacy device-trees don't have OPP table and must be updated */
>> +       if (!device_property_present(&pdev->dev, "operating-points-v2")) {
>> +               dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
>> +               dev_err(&pdev->dev, "please update your device tree\n");
>> +               return -ENODEV;
>> +       }
> 
> As you mentioned, it breaks the old dtb. I have no objection to improving
> the driver. Instead, you need confirmation from the Devicetree maintainer.

Older DTBs will continue to work, but devfreq driver won't. We already
did this for other Tegra drivers before (CPUFREQ driver for example) and
Rob Herring confirmed that there is no problem here.

> And,
> I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
> to check whether a device contains opp-table or not.

I'm not sure what are the benefits, this will make code less
expressive/readable and we will need to add extra of_node_put(), which
device_property_present() handles for us.

Could you please give the rationale?

>> +
>>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
>>         if (!tegra)
>>                 return -ENOMEM;
>> @@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>>                 return err;
>>         }
>>
>> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
>> +       if (IS_ERR(tegra->opp_table))
>> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
>> +                                    "Failed to prepare OPP table\n");
> 
> As I knew, each device can contain the opp_table on devicetree.
> It means that opp_table has not depended to another device driver.
> Did you see this exception case with EPROBE_DEFER error?

OPP core will try to grab the clock reference for the table and it may
cause EPROBE_DEFER. Although, it shouldn't happen here because we have
devm_clk_get() before the get_opp_table(), hence seems the deferred
probe indeed shouldn't happen in this case.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 15:23       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 15:23 UTC (permalink / raw)
  To: cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

01.11.2020 17:39, Chanwoo Choi пишет:
> Hi Dmitry,
> 
> On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>
>> This patch moves ACTMON driver away from generating OPP table by itself,
>> transitioning it to use the table which comes from device-tree. This
>> change breaks compatibility with older device-trees in order to bring
>> support for the interconnect framework to the driver. This is a mandatory
>> change which needs to be done in order to implement interconnect-based
>> memory DVFS. Users of legacy device-trees will get a message telling that
>> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
>> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>>
>> Tested-by: Peter Geis <pgwipeout@gmail.com>
>> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
...
>>  static int tegra_devfreq_get_dev_status(struct device *dev,
>> @@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
>>         stat->private_data = tegra;
>>
>>         /* The below are to be used by the other governors */
>> -       stat->current_frequency = cur_freq;
>> +       stat->current_frequency = cur_freq * KHZ;
> 
> I can't find any change related to the frequency unit on this patch.
> Do you fix the previous bug of the frequency unit?

Previously, OPP entries that were generated by the driver used KHz
units. Now, OPP entries are coming from a device-tree and they have Hz
units. This driver operates with KHz internally, hence we need to
convert the units now.

>>
>>         actmon_dev = &tegra->devices[MCALL];
>>
>> @@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
>>                 target_freq = max(target_freq, dev->target_freq);
>>         }
>>
>> -       *freq = target_freq;
>> +       *freq = target_freq * KHZ;
> 
> ditto.
> 
>>
>>         return 0;
>>  }
>> @@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
>>
>>  static int tegra_devfreq_probe(struct platform_device *pdev)
>>  {
>> +       u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
>>         struct tegra_devfreq_device *dev;
>>         struct tegra_devfreq *tegra;
>> +       struct opp_table *opp_table;
>>         struct devfreq *devfreq;
>>         unsigned int i;
>>         long rate;
>>         int err;
>>
>> +       /* legacy device-trees don't have OPP table and must be updated */
>> +       if (!device_property_present(&pdev->dev, "operating-points-v2")) {
>> +               dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
>> +               dev_err(&pdev->dev, "please update your device tree\n");
>> +               return -ENODEV;
>> +       }
> 
> As you mentioned, it breaks the old dtb. I have no objection to improving
> the driver. Instead, you need confirmation from the Devicetree maintainer.

Older DTBs will continue to work, but devfreq driver won't. We already
did this for other Tegra drivers before (CPUFREQ driver for example) and
Rob Herring confirmed that there is no problem here.

> And,
> I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
> to check whether a device contains opp-table or not.

I'm not sure what are the benefits, this will make code less
expressive/readable and we will need to add extra of_node_put(), which
device_property_present() handles for us.

Could you please give the rationale?

>> +
>>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
>>         if (!tegra)
>>                 return -ENOMEM;
>> @@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
>>                 return err;
>>         }
>>
>> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
>> +       if (IS_ERR(tegra->opp_table))
>> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
>> +                                    "Failed to prepare OPP table\n");
> 
> As I knew, each device can contain the opp_table on devicetree.
> It means that opp_table has not depended to another device driver.
> Did you see this exception case with EPROBE_DEFER error?

OPP core will try to grab the clock reference for the table and it may
cause EPROBE_DEFER. Although, it shouldn't happen here because we have
devm_clk_get() before the get_opp_table(), hence seems the deferred
probe indeed shouldn't happen in this case.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 14:44     ` Chanwoo Choi
@ 2020-11-01 15:24       ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 15:24 UTC (permalink / raw)
  To: cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

01.11.2020 17:44, Chanwoo Choi пишет:
> Hi Dmitry,
> 
> On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>
>> This patch moves ACTMON driver away from generating OPP table by itself,
>> transitioning it to use the table which comes from device-tree. This
>> change breaks compatibility with older device-trees in order to bring
>> support for the interconnect framework to the driver. This is a mandatory
>> change which needs to be done in order to implement interconnect-based
>> memory DVFS. Users of legacy device-trees will get a message telling that
>> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
>> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>>
>> Tested-by: Peter Geis <pgwipeout@gmail.com>
>> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
>>  1 file changed, 48 insertions(+), 43 deletions(-)
>>
>> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
>> index 3f732ab53573..1b0b91a71886 100644
>> --- a/drivers/devfreq/tegra30-devfreq.c
>> +++ b/drivers/devfreq/tegra30-devfreq.c
>> @@ -19,6 +19,8 @@
>>  #include <linux/reset.h>
>>  #include <linux/workqueue.h>
>>
>> +#include <soc/tegra/fuse.h>
>> +
> 
> This patch touches the OPP. Is it related to this change?

Yes, this is needed for the dev_pm_opp_set_supported_hw().

>>  #include "governor.h"
>>
>>  #define ACTMON_GLB_STATUS                                      0x0
>> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
>>
>>  struct tegra_devfreq {
>>         struct devfreq          *devfreq;
>> +       struct opp_table        *opp_table;
>>
>>         struct reset_control    *reset;
>>         struct clk              *clock;
>> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
>>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>>                                 u32 flags)
>>  {
>> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
>> -       struct devfreq *devfreq = tegra->devfreq;
>>         struct dev_pm_opp *opp;
>> -       unsigned long rate;
>> -       int err;
>> +       int ret;
>>
>>         opp = devfreq_recommended_opp(dev, freq, flags);
>>         if (IS_ERR(opp)) {
>> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
>> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
> 
> You used the 'Failed to' format in almost every error case.
> Don't need to change it.
> (snip)

Good catch, thanks.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 15:24       ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 15:24 UTC (permalink / raw)
  To: cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

01.11.2020 17:44, Chanwoo Choi пишет:
> Hi Dmitry,
> 
> On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>
>> This patch moves ACTMON driver away from generating OPP table by itself,
>> transitioning it to use the table which comes from device-tree. This
>> change breaks compatibility with older device-trees in order to bring
>> support for the interconnect framework to the driver. This is a mandatory
>> change which needs to be done in order to implement interconnect-based
>> memory DVFS. Users of legacy device-trees will get a message telling that
>> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
>> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
>>
>> Tested-by: Peter Geis <pgwipeout@gmail.com>
>> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>> ---
>>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
>>  1 file changed, 48 insertions(+), 43 deletions(-)
>>
>> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
>> index 3f732ab53573..1b0b91a71886 100644
>> --- a/drivers/devfreq/tegra30-devfreq.c
>> +++ b/drivers/devfreq/tegra30-devfreq.c
>> @@ -19,6 +19,8 @@
>>  #include <linux/reset.h>
>>  #include <linux/workqueue.h>
>>
>> +#include <soc/tegra/fuse.h>
>> +
> 
> This patch touches the OPP. Is it related to this change?

Yes, this is needed for the dev_pm_opp_set_supported_hw().

>>  #include "governor.h"
>>
>>  #define ACTMON_GLB_STATUS                                      0x0
>> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
>>
>>  struct tegra_devfreq {
>>         struct devfreq          *devfreq;
>> +       struct opp_table        *opp_table;
>>
>>         struct reset_control    *reset;
>>         struct clk              *clock;
>> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
>>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
>>                                 u32 flags)
>>  {
>> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
>> -       struct devfreq *devfreq = tegra->devfreq;
>>         struct dev_pm_opp *opp;
>> -       unsigned long rate;
>> -       int err;
>> +       int ret;
>>
>>         opp = devfreq_recommended_opp(dev, freq, flags);
>>         if (IS_ERR(opp)) {
>> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
>> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
> 
> You used the 'Failed to' format in almost every error case.
> Don't need to change it.
> (snip)

Good catch, thanks.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 15:23       ` Dmitry Osipenko
@ 2020-11-01 15:44         ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

Hi Dmitry,

On Mon, Nov 2, 2020 at 12:23 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> 01.11.2020 17:39, Chanwoo Choi пишет:
> > Hi Dmitry,
> >
> > On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
> >>
> >> This patch moves ACTMON driver away from generating OPP table by itself,
> >> transitioning it to use the table which comes from device-tree. This
> >> change breaks compatibility with older device-trees in order to bring
> >> support for the interconnect framework to the driver. This is a mandatory
> >> change which needs to be done in order to implement interconnect-based
> >> memory DVFS. Users of legacy device-trees will get a message telling that
> >> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> >> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
> >>
> >> Tested-by: Peter Geis <pgwipeout@gmail.com>
> >> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> ...
> >>  static int tegra_devfreq_get_dev_status(struct device *dev,
> >> @@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
> >>         stat->private_data = tegra;
> >>
> >>         /* The below are to be used by the other governors */
> >> -       stat->current_frequency = cur_freq;
> >> +       stat->current_frequency = cur_freq * KHZ;
> >
> > I can't find any change related to the frequency unit on this patch.
> > Do you fix the previous bug of the frequency unit?
>
> Previously, OPP entries that were generated by the driver used KHz
> units. Now, OPP entries are coming from a device-tree and they have Hz
> units. This driver operates with KHz internally, hence we need to
> convert the units now.

OK. Thanks.

>
> >>
> >>         actmon_dev = &tegra->devices[MCALL];
> >>
> >> @@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
> >>                 target_freq = max(target_freq, dev->target_freq);
> >>         }
> >>
> >> -       *freq = target_freq;
> >> +       *freq = target_freq * KHZ;
> >
> > ditto.
> >
> >>
> >>         return 0;
> >>  }
> >> @@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
> >>
> >>  static int tegra_devfreq_probe(struct platform_device *pdev)
> >>  {
> >> +       u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
> >>         struct tegra_devfreq_device *dev;
> >>         struct tegra_devfreq *tegra;
> >> +       struct opp_table *opp_table;
> >>         struct devfreq *devfreq;
> >>         unsigned int i;
> >>         long rate;
> >>         int err;
> >>
> >> +       /* legacy device-trees don't have OPP table and must be updated */
> >> +       if (!device_property_present(&pdev->dev, "operating-points-v2")) {
> >> +               dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
> >> +               dev_err(&pdev->dev, "please update your device tree\n");
> >> +               return -ENODEV;
> >> +       }
> >
> > As you mentioned, it breaks the old dtb. I have no objection to improving
> > the driver. Instead, you need confirmation from the Devicetree maintainer.
>
> Older DTBs will continue to work, but devfreq driver won't. We already
> did this for other Tegra drivers before (CPUFREQ driver for example) and
> Rob Herring confirmed that there is no problem here.

OK.

>
> > And,
> > I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
> > to check whether a device contains opp-table or not.
>
> I'm not sure what are the benefits, this will make code less
> expressive/readable and we will need to add extra of_node_put(), which
> device_property_present() handles for us.
>
> Could you please give the rationale?

IMO, 'operating-points-v2' word was defined on OPP core. I think that
the external user
of OPP better to use the public helper function instead of using the
interval definition
or value of OPP core directly. Basically, I prefer the provided helper
function if there.
But, it is not critical and doesn't affect the operation. If you want
to keep, it is ok.

>
> >> +
> >>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
> >>         if (!tegra)
> >>                 return -ENOMEM;
> >> @@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
> >>                 return err;
> >>         }
> >>
> >> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
> >> +       if (IS_ERR(tegra->opp_table))
> >> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
> >> +                                    "Failed to prepare OPP table\n");
> >
> > As I knew, each device can contain the opp_table on devicetree.
> > It means that opp_table has not depended to another device driver.
> > Did you see this exception case with EPROBE_DEFER error?
>
> OPP core will try to grab the clock reference for the table and it may
> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
> devm_clk_get() before the get_opp_table(), hence seems the deferred
> probe indeed shouldn't happen in this case.

It is my missing point. If there, you're right.
Could you provide the code point to check the clock reference on the OPP core?

-- 
Best Regards,
Chanwoo Choi

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 15:44         ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:44 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

Hi Dmitry,

On Mon, Nov 2, 2020 at 12:23 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> 01.11.2020 17:39, Chanwoo Choi пишет:
> > Hi Dmitry,
> >
> > On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
> >>
> >> This patch moves ACTMON driver away from generating OPP table by itself,
> >> transitioning it to use the table which comes from device-tree. This
> >> change breaks compatibility with older device-trees in order to bring
> >> support for the interconnect framework to the driver. This is a mandatory
> >> change which needs to be done in order to implement interconnect-based
> >> memory DVFS. Users of legacy device-trees will get a message telling that
> >> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> >> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
> >>
> >> Tested-by: Peter Geis <pgwipeout@gmail.com>
> >> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> ...
> >>  static int tegra_devfreq_get_dev_status(struct device *dev,
> >> @@ -655,7 +643,7 @@ static int tegra_devfreq_get_dev_status(struct device *dev,
> >>         stat->private_data = tegra;
> >>
> >>         /* The below are to be used by the other governors */
> >> -       stat->current_frequency = cur_freq;
> >> +       stat->current_frequency = cur_freq * KHZ;
> >
> > I can't find any change related to the frequency unit on this patch.
> > Do you fix the previous bug of the frequency unit?
>
> Previously, OPP entries that were generated by the driver used KHz
> units. Now, OPP entries are coming from a device-tree and they have Hz
> units. This driver operates with KHz internally, hence we need to
> convert the units now.

OK. Thanks.

>
> >>
> >>         actmon_dev = &tegra->devices[MCALL];
> >>
> >> @@ -705,7 +693,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
> >>                 target_freq = max(target_freq, dev->target_freq);
> >>         }
> >>
> >> -       *freq = target_freq;
> >> +       *freq = target_freq * KHZ;
> >
> > ditto.
> >
> >>
> >>         return 0;
> >>  }
> >> @@ -773,13 +761,22 @@ static struct devfreq_governor tegra_devfreq_governor = {
> >>
> >>  static int tegra_devfreq_probe(struct platform_device *pdev)
> >>  {
> >> +       u32 hw_version = BIT(tegra_sku_info.soc_speedo_id);
> >>         struct tegra_devfreq_device *dev;
> >>         struct tegra_devfreq *tegra;
> >> +       struct opp_table *opp_table;
> >>         struct devfreq *devfreq;
> >>         unsigned int i;
> >>         long rate;
> >>         int err;
> >>
> >> +       /* legacy device-trees don't have OPP table and must be updated */
> >> +       if (!device_property_present(&pdev->dev, "operating-points-v2")) {
> >> +               dev_err(&pdev->dev, "OPP table not found, cannot continue\n");
> >> +               dev_err(&pdev->dev, "please update your device tree\n");
> >> +               return -ENODEV;
> >> +       }
> >
> > As you mentioned, it breaks the old dtb. I have no objection to improving
> > the driver. Instead, you need confirmation from the Devicetree maintainer.
>
> Older DTBs will continue to work, but devfreq driver won't. We already
> did this for other Tegra drivers before (CPUFREQ driver for example) and
> Rob Herring confirmed that there is no problem here.

OK.

>
> > And,
> > I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
> > to check whether a device contains opp-table or not.
>
> I'm not sure what are the benefits, this will make code less
> expressive/readable and we will need to add extra of_node_put(), which
> device_property_present() handles for us.
>
> Could you please give the rationale?

IMO, 'operating-points-v2' word was defined on OPP core. I think that
the external user
of OPP better to use the public helper function instead of using the
interval definition
or value of OPP core directly. Basically, I prefer the provided helper
function if there.
But, it is not critical and doesn't affect the operation. If you want
to keep, it is ok.

>
> >> +
> >>         tegra = devm_kzalloc(&pdev->dev, sizeof(*tegra), GFP_KERNEL);
> >>         if (!tegra)
> >>                 return -ENOMEM;
> >> @@ -821,11 +818,29 @@ static int tegra_devfreq_probe(struct platform_device *pdev)
> >>                 return err;
> >>         }
> >>
> >> +       tegra->opp_table = dev_pm_opp_get_opp_table(&pdev->dev);
> >> +       if (IS_ERR(tegra->opp_table))
> >> +               return dev_err_probe(&pdev->dev, PTR_ERR(tegra->opp_table),
> >> +                                    "Failed to prepare OPP table\n");
> >
> > As I knew, each device can contain the opp_table on devicetree.
> > It means that opp_table has not depended to another device driver.
> > Did you see this exception case with EPROBE_DEFER error?
>
> OPP core will try to grab the clock reference for the table and it may
> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
> devm_clk_get() before the get_opp_table(), hence seems the deferred
> probe indeed shouldn't happen in this case.

It is my missing point. If there, you're right.
Could you provide the code point to check the clock reference on the OPP core?

-- 
Best Regards,
Chanwoo Choi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 15:24       ` Dmitry Osipenko
@ 2020-11-01 15:45         ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:45 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

Hi Dmitry,

On Mon, Nov 2, 2020 at 12:24 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> 01.11.2020 17:44, Chanwoo Choi пишет:
> > Hi Dmitry,
> >
> > On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
> >>
> >> This patch moves ACTMON driver away from generating OPP table by itself,
> >> transitioning it to use the table which comes from device-tree. This
> >> change breaks compatibility with older device-trees in order to bring
> >> support for the interconnect framework to the driver. This is a mandatory
> >> change which needs to be done in order to implement interconnect-based
> >> memory DVFS. Users of legacy device-trees will get a message telling that
> >> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> >> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
> >>
> >> Tested-by: Peter Geis <pgwipeout@gmail.com>
> >> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
> >>  1 file changed, 48 insertions(+), 43 deletions(-)
> >>
> >> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> >> index 3f732ab53573..1b0b91a71886 100644
> >> --- a/drivers/devfreq/tegra30-devfreq.c
> >> +++ b/drivers/devfreq/tegra30-devfreq.c
> >> @@ -19,6 +19,8 @@
> >>  #include <linux/reset.h>
> >>  #include <linux/workqueue.h>
> >>
> >> +#include <soc/tegra/fuse.h>
> >> +
> >
> > This patch touches the OPP. Is it related to this change?
>
> Yes, this is needed for the dev_pm_opp_set_supported_hw().

OK.

>
> >>  #include "governor.h"
> >>
> >>  #define ACTMON_GLB_STATUS                                      0x0
> >> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
> >>
> >>  struct tegra_devfreq {
> >>         struct devfreq          *devfreq;
> >> +       struct opp_table        *opp_table;
> >>
> >>         struct reset_control    *reset;
> >>         struct clk              *clock;
> >> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
> >>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
> >>                                 u32 flags)
> >>  {
> >> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> >> -       struct devfreq *devfreq = tegra->devfreq;
> >>         struct dev_pm_opp *opp;
> >> -       unsigned long rate;
> >> -       int err;
> >> +       int ret;
> >>
> >>         opp = devfreq_recommended_opp(dev, freq, flags);
> >>         if (IS_ERR(opp)) {
> >> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
> >> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
> >
> > You used the 'Failed to' format in almost every error case.
> > Don't need to change it.
> > (snip)
>
> Good catch, thanks.



-- 
Best Regards,
Chanwoo Choi

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 15:45         ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:45 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

Hi Dmitry,

On Mon, Nov 2, 2020 at 12:24 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> 01.11.2020 17:44, Chanwoo Choi пишет:
> > Hi Dmitry,
> >
> > On Mon, Oct 26, 2020 at 7:22 AM Dmitry Osipenko <digetx@gmail.com> wrote:
> >>
> >> This patch moves ACTMON driver away from generating OPP table by itself,
> >> transitioning it to use the table which comes from device-tree. This
> >> change breaks compatibility with older device-trees in order to bring
> >> support for the interconnect framework to the driver. This is a mandatory
> >> change which needs to be done in order to implement interconnect-based
> >> memory DVFS. Users of legacy device-trees will get a message telling that
> >> theirs DT needs to be upgraded. Now ACTMON issues memory bandwidth request
> >> using dev_pm_opp_set_bw(), instead of driving EMC clock rate directly.
> >>
> >> Tested-by: Peter Geis <pgwipeout@gmail.com>
> >> Tested-by: Nicolas Chauvet <kwizart@gmail.com>
> >> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
> >> ---
> >>  drivers/devfreq/tegra30-devfreq.c | 91 ++++++++++++++++---------------
> >>  1 file changed, 48 insertions(+), 43 deletions(-)
> >>
> >> diff --git a/drivers/devfreq/tegra30-devfreq.c b/drivers/devfreq/tegra30-devfreq.c
> >> index 3f732ab53573..1b0b91a71886 100644
> >> --- a/drivers/devfreq/tegra30-devfreq.c
> >> +++ b/drivers/devfreq/tegra30-devfreq.c
> >> @@ -19,6 +19,8 @@
> >>  #include <linux/reset.h>
> >>  #include <linux/workqueue.h>
> >>
> >> +#include <soc/tegra/fuse.h>
> >> +
> >
> > This patch touches the OPP. Is it related to this change?
>
> Yes, this is needed for the dev_pm_opp_set_supported_hw().

OK.

>
> >>  #include "governor.h"
> >>
> >>  #define ACTMON_GLB_STATUS                                      0x0
> >> @@ -155,6 +157,7 @@ struct tegra_devfreq_device {
> >>
> >>  struct tegra_devfreq {
> >>         struct devfreq          *devfreq;
> >> +       struct opp_table        *opp_table;
> >>
> >>         struct reset_control    *reset;
> >>         struct clk              *clock;
> >> @@ -612,34 +615,19 @@ static void tegra_actmon_stop(struct tegra_devfreq *tegra)
> >>  static int tegra_devfreq_target(struct device *dev, unsigned long *freq,
> >>                                 u32 flags)
> >>  {
> >> -       struct tegra_devfreq *tegra = dev_get_drvdata(dev);
> >> -       struct devfreq *devfreq = tegra->devfreq;
> >>         struct dev_pm_opp *opp;
> >> -       unsigned long rate;
> >> -       int err;
> >> +       int ret;
> >>
> >>         opp = devfreq_recommended_opp(dev, freq, flags);
> >>         if (IS_ERR(opp)) {
> >> -               dev_err(dev, "Failed to find opp for %lu Hz\n", *freq);
> >> +               dev_err(dev, "failed to find opp for %lu Hz\n", *freq);
> >
> > You used the 'Failed to' format in almost every error case.
> > Don't need to change it.
> > (snip)
>
> Good catch, thanks.



-- 
Best Regards,
Chanwoo Choi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 15:44         ` Chanwoo Choi
@ 2020-11-01 15:49           ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 15:49 UTC (permalink / raw)
  To: cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

01.11.2020 18:44, Chanwoo Choi пишет:
>> OPP core will try to grab the clock reference for the table and it may
>> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
>> devm_clk_get() before the get_opp_table(), hence seems the deferred
>> probe indeed shouldn't happen in this case.
> It is my missing point. If there, you're right.
> Could you provide the code point to check the clock reference on the OPP core?

Please see it here:

https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/opp/core.c#L1101

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 15:49           ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-01 15:49 UTC (permalink / raw)
  To: cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

01.11.2020 18:44, Chanwoo Choi пишет:
>> OPP core will try to grab the clock reference for the table and it may
>> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
>> devm_clk_get() before the get_opp_table(), hence seems the deferred
>> probe indeed shouldn't happen in this case.
> It is my missing point. If there, you're right.
> Could you provide the code point to check the clock reference on the OPP core?

Please see it here:

https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/opp/core.c#L1101
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 15:49           ` Dmitry Osipenko
@ 2020-11-01 15:57             ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:57 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

On Mon, Nov 2, 2020 at 12:49 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> 01.11.2020 18:44, Chanwoo Choi пишет:
> >> OPP core will try to grab the clock reference for the table and it may
> >> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
> >> devm_clk_get() before the get_opp_table(), hence seems the deferred
> >> probe indeed shouldn't happen in this case.
> > It is my missing point. If there, you're right.
> > Could you provide the code point to check the clock reference on the OPP core?
>
> Please see it here:
>
> https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/opp/core.c#L1101

Thanks. It seems that if device tree node contains the any node,
it is not EPROBE_DEFER because of just using "clk_get(dev, NULL)".

The patch[1] used the 'dev_err_probe' for getting the "emc" clock.
Do you need to check it more?

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git/commit/?h=devfreq-next&id=09d56d92ad25b58113f4ec677e9b1ac1e2c3072b


-- 
Best Regards,
Chanwoo Choi

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-01 15:57             ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-01 15:57 UTC (permalink / raw)
  To: Dmitry Osipenko
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

On Mon, Nov 2, 2020 at 12:49 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>
> 01.11.2020 18:44, Chanwoo Choi пишет:
> >> OPP core will try to grab the clock reference for the table and it may
> >> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
> >> devm_clk_get() before the get_opp_table(), hence seems the deferred
> >> probe indeed shouldn't happen in this case.
> > It is my missing point. If there, you're right.
> > Could you provide the code point to check the clock reference on the OPP core?
>
> Please see it here:
>
> https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/opp/core.c#L1101

Thanks. It seems that if device tree node contains the any node,
it is not EPROBE_DEFER because of just using "clk_get(dev, NULL)".

The patch[1] used the 'dev_err_probe' for getting the "emc" clock.
Do you need to check it more?

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git/commit/?h=devfreq-next&id=09d56d92ad25b58113f4ec677e9b1ac1e2c3072b


-- 
Best Regards,
Chanwoo Choi
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 15:57             ` Chanwoo Choi
@ 2020-11-02 19:58               ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-02 19:58 UTC (permalink / raw)
  To: cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

01.11.2020 18:57, Chanwoo Choi пишет:
> On Mon, Nov 2, 2020 at 12:49 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>
>> 01.11.2020 18:44, Chanwoo Choi пишет:
>>>> OPP core will try to grab the clock reference for the table and it may
>>>> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
>>>> devm_clk_get() before the get_opp_table(), hence seems the deferred
>>>> probe indeed shouldn't happen in this case.
>>> It is my missing point. If there, you're right.
>>> Could you provide the code point to check the clock reference on the OPP core?
>>
>> Please see it here:
>>
>> https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/opp/core.c#L1101
> 
> Thanks. It seems that if device tree node contains the any node,
> it is not EPROBE_DEFER because of just using "clk_get(dev, NULL)".
> 
> The patch[1] used the 'dev_err_probe' for getting the "emc" clock.
> Do you need to check it more?
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git/commit/?h=devfreq-next&id=09d56d92ad25b58113f4ec677e9b1ac1e2c3072b

It should be safe to assume that the EPROBE_DEFER won't happen for
dev_pm_opp_get_opp_table(). I'll improve it in v7, thanks.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-02 19:58               ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-02 19:58 UTC (permalink / raw)
  To: cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

01.11.2020 18:57, Chanwoo Choi пишет:
> On Mon, Nov 2, 2020 at 12:49 AM Dmitry Osipenko <digetx@gmail.com> wrote:
>>
>> 01.11.2020 18:44, Chanwoo Choi пишет:
>>>> OPP core will try to grab the clock reference for the table and it may
>>>> cause EPROBE_DEFER. Although, it shouldn't happen here because we have
>>>> devm_clk_get() before the get_opp_table(), hence seems the deferred
>>>> probe indeed shouldn't happen in this case.
>>> It is my missing point. If there, you're right.
>>> Could you provide the code point to check the clock reference on the OPP core?
>>
>> Please see it here:
>>
>> https://elixir.bootlin.com/linux/v5.10-rc1/source/drivers/opp/core.c#L1101
> 
> Thanks. It seems that if device tree node contains the any node,
> it is not EPROBE_DEFER because of just using "clk_get(dev, NULL)".
> 
> The patch[1] used the 'dev_err_probe' for getting the "emc" clock.
> Do you need to check it more?
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/linux.git/commit/?h=devfreq-next&id=09d56d92ad25b58113f4ec677e9b1ac1e2c3072b

It should be safe to assume that the EPROBE_DEFER won't happen for
dev_pm_opp_get_opp_table(). I'll improve it in v7, thanks.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
  2020-11-01 15:44         ` Chanwoo Choi
@ 2020-11-02 20:00           ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-02 20:00 UTC (permalink / raw)
  To: cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

01.11.2020 18:44, Chanwoo Choi пишет:
>>> I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
>>> to check whether a device contains opp-table or not.
>> I'm not sure what are the benefits, this will make code less
>> expressive/readable and we will need to add extra of_node_put(), which
>> device_property_present() handles for us.
>>
>> Could you please give the rationale?
> IMO, 'operating-points-v2' word was defined on OPP core. I think that
> the external user
> of OPP better to use the public helper function instead of using the
> interval definition
> or value of OPP core directly. Basically, I prefer the provided helper
> function if there.
> But, it is not critical and doesn't affect the operation. If you want
> to keep, it is ok.
> 

I'll prefer to keep it since it's better for the readability of the
code, thanks.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree
@ 2020-11-02 20:00           ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-02 20:00 UTC (permalink / raw)
  To: cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

01.11.2020 18:44, Chanwoo Choi пишет:
>>> I recommend that you use dev_pm_opp_of_get_opp_desc_node(&pdev->dev)
>>> to check whether a device contains opp-table or not.
>> I'm not sure what are the benefits, this will make code less
>> expressive/readable and we will need to add extra of_node_put(), which
>> device_property_present() handles for us.
>>
>> Could you please give the rationale?
> IMO, 'operating-points-v2' word was defined on OPP core. I think that
> the external user
> of OPP better to use the public helper function instead of using the
> interval definition
> or value of OPP core directly. Basically, I prefer the provided helper
> function if there.
> But, it is not critical and doesn't affect the operation. If you want
> to keep, it is ok.
> 

I'll prefer to keep it since it's better for the readability of the
code, thanks.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
  2020-11-01 14:12       ` Dmitry Osipenko
@ 2020-11-02 20:08         ` Dmitry Osipenko
  -1 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-02 20:08 UTC (permalink / raw)
  To: cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Chanwoo Choi, Mikko Perttunen,
	Viresh Kumar, Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski,
	linux-tegra, Linux PM list, linux-kernel, dri-devel, devicetree

01.11.2020 17:12, Dmitry Osipenko пишет:
...
> We will probably move the Tegra20 EMC_STAT devfreq driver into the
> memory driver and remove the older IMC_STAT driver in v7, like it was
> suggested by Thierry Reding. This will be a much less invasive code change.
> 
>> Also, if you want to get more responsiveness, you could use delayed timer
>> instead of deferrable timer by editing the devfreq_dev_profile structure.
> 
> Thanks, I'll try the deferrable timer.

I took a brief look at the delayed timer and I think the deferrable
timer should be more a preferred option because this devfreq drive is
more an assistance for the optimal bandwidth selection and it will be
more preferred to keep system idling whenever possible.

My primary concern is the initial performance lag in a case of
multimedia applications. But this will be resolved by hooking up
performance voting to all drivers, once we will get around to it.

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
@ 2020-11-02 20:08         ` Dmitry Osipenko
  0 siblings, 0 replies; 290+ messages in thread
From: Dmitry Osipenko @ 2020-11-02 20:08 UTC (permalink / raw)
  To: cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Nicolas Chauvet, Stephen Boyd, Viresh Kumar,
	Michael Turquette, Linux PM list, linux-kernel, Rob Herring,
	Jonathan Hunter, Chanwoo Choi, Kyungmin Park, Thierry Reding,
	MyungJoo Ham, Peter Geis, linux-tegra, Georgi Djakov, devicetree

01.11.2020 17:12, Dmitry Osipenko пишет:
...
> We will probably move the Tegra20 EMC_STAT devfreq driver into the
> memory driver and remove the older IMC_STAT driver in v7, like it was
> suggested by Thierry Reding. This will be a much less invasive code change.
> 
>> Also, if you want to get more responsiveness, you could use delayed timer
>> instead of deferrable timer by editing the devfreq_dev_profile structure.
> 
> Thanks, I'll try the deferrable timer.

I took a brief look at the delayed timer and I think the deferrable
timer should be more a preferred option because this devfreq drive is
more an assistance for the optimal bandwidth selection and it will be
more preferred to keep system idling whenever possible.

My primary concern is the initial performance lag in a case of
multimedia applications. But this will be resolved by hooking up
performance voting to all drivers, once we will get around to it.
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
  2020-11-02 20:08         ` Dmitry Osipenko
@ 2020-11-03  2:22           ` Chanwoo Choi
  -1 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-03  2:22 UTC (permalink / raw)
  To: Dmitry Osipenko, cwchoi00
  Cc: Thierry Reding, Jonathan Hunter, Georgi Djakov, Rob Herring,
	Michael Turquette, Stephen Boyd, Peter De Schrijver,
	MyungJoo Ham, Kyungmin Park, Mikko Perttunen, Viresh Kumar,
	Peter Geis, Nicolas Chauvet, Krzysztof Kozlowski, linux-tegra,
	Linux PM list, linux-kernel, dri-devel, devicetree

On 11/3/20 5:08 AM, Dmitry Osipenko wrote:
> 01.11.2020 17:12, Dmitry Osipenko пишет:
> ...
>> We will probably move the Tegra20 EMC_STAT devfreq driver into the
>> memory driver and remove the older IMC_STAT driver in v7, like it was
>> suggested by Thierry Reding. This will be a much less invasive code change.
>>
>>> Also, if you want to get more responsiveness, you could use delayed timer
>>> instead of deferrable timer by editing the devfreq_dev_profile structure.
>>
>> Thanks, I'll try the deferrable timer.
> 
> I took a brief look at the delayed timer and I think the deferrable
> timer should be more a preferred option because this devfreq drive is
> more an assistance for the optimal bandwidth selection and it will be
> more preferred to keep system idling whenever possible.
> 
> My primary concern is the initial performance lag in a case of
> multimedia applications. But this will be resolved by hooking up
> performance voting to all drivers, once we will get around to it.

OK. You can choice the type of timer on both probe
and via sysfs file on the runtime.


-- 
Best Regards,
Chanwoo Choi
Samsung Electronics

^ permalink raw reply	[flat|nested] 290+ messages in thread

* Re: [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree
@ 2020-11-03  2:22           ` Chanwoo Choi
  0 siblings, 0 replies; 290+ messages in thread
From: Chanwoo Choi @ 2020-11-03  2:22 UTC (permalink / raw)
  To: Dmitry Osipenko, cwchoi00
  Cc: Peter De Schrijver, Krzysztof Kozlowski, Mikko Perttunen,
	dri-devel, Linux PM list, Stephen Boyd, Viresh Kumar,
	Michael Turquette, linux-kernel, Rob Herring, Jonathan Hunter,
	Nicolas Chauvet, Kyungmin Park, Thierry Reding, MyungJoo Ham,
	Peter Geis, linux-tegra, Georgi Djakov, devicetree

On 11/3/20 5:08 AM, Dmitry Osipenko wrote:
> 01.11.2020 17:12, Dmitry Osipenko пишет:
> ...
>> We will probably move the Tegra20 EMC_STAT devfreq driver into the
>> memory driver and remove the older IMC_STAT driver in v7, like it was
>> suggested by Thierry Reding. This will be a much less invasive code change.
>>
>>> Also, if you want to get more responsiveness, you could use delayed timer
>>> instead of deferrable timer by editing the devfreq_dev_profile structure.
>>
>> Thanks, I'll try the deferrable timer.
> 
> I took a brief look at the delayed timer and I think the deferrable
> timer should be more a preferred option because this devfreq drive is
> more an assistance for the optimal bandwidth selection and it will be
> more preferred to keep system idling whenever possible.
> 
> My primary concern is the initial performance lag in a case of
> multimedia applications. But this will be resolved by hooking up
> performance voting to all drivers, once we will get around to it.

OK. You can choice the type of timer on both probe
and via sysfs file on the runtime.


-- 
Best Regards,
Chanwoo Choi
Samsung Electronics
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 290+ messages in thread

end of thread, other threads:[~2020-11-03  8:17 UTC | newest]

Thread overview: 290+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-25 22:16 [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs Dmitry Osipenko
2020-10-25 22:16 ` Dmitry Osipenko
2020-10-25 22:16 ` [PATCH v6 01/52] clk: tegra: Export Tegra20 EMC kernel symbols Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27 13:04   ` Thierry Reding
2020-10-27 13:04     ` Thierry Reding
2020-10-25 22:16 ` [PATCH v6 02/52] soc/tegra: fuse: Export tegra_read_ram_code() Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27 13:17   ` Thierry Reding
2020-10-27 13:17     ` Thierry Reding
2020-10-25 22:16 ` [PATCH v6 03/52] dt-bindings: memory: tegra20: emc: Correct registers range in example Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27 13:18   ` Thierry Reding
2020-10-27 13:18     ` Thierry Reding
2020-10-28 15:16   ` Rob Herring
2020-10-28 15:16     ` Rob Herring
2020-10-25 22:16 ` [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property Dmitry Osipenko
2020-10-25 22:16   ` [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia, memory-controller property Dmitry Osipenko
2020-10-27  8:54   ` [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia,memory-controller property Krzysztof Kozlowski
2020-10-27  8:54     ` Krzysztof Kozlowski
2020-10-27 19:17     ` Dmitry Osipenko
2020-10-27 19:17       ` Dmitry Osipenko
2020-10-27 19:30       ` Krzysztof Kozlowski
2020-10-27 19:30         ` Krzysztof Kozlowski
2020-10-27 20:37         ` Dmitry Osipenko
2020-10-27 20:37           ` Dmitry Osipenko
2020-10-28 15:23         ` Rob Herring
2020-10-28 15:23           ` Rob Herring
2020-10-28 15:35           ` Krzysztof Kozlowski
2020-10-28 15:35             ` Krzysztof Kozlowski
2020-10-28 15:23   ` [PATCH v6 04/52] dt-bindings: memory: tegra20: emc: Document nvidia, memory-controller property Rob Herring
2020-10-28 15:23     ` Rob Herring
2020-10-25 22:16 ` [PATCH v6 05/52] dt-bindings: memory: tegra20: mc: Document new interconnect property Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27  8:55   ` Krzysztof Kozlowski
2020-10-27  8:55     ` Krzysztof Kozlowski
2020-10-27 19:17     ` Dmitry Osipenko
2020-10-27 19:17       ` Dmitry Osipenko
2020-10-27 19:34       ` Krzysztof Kozlowski
2020-10-27 19:34         ` Krzysztof Kozlowski
2020-10-25 22:16 ` [PATCH v6 06/52] dt-bindings: memory: tegra20: emc: " Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27  9:03   ` Krzysztof Kozlowski
2020-10-27  9:03     ` Krzysztof Kozlowski
2020-10-25 22:16 ` [PATCH v6 07/52] dt-bindings: memory: tegra20: emc: Document OPP table and voltage regulator Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27  8:57   ` Krzysztof Kozlowski
2020-10-27  8:57     ` Krzysztof Kozlowski
2020-10-25 22:16 ` [PATCH v6 08/52] dt-bindings: memory: tegra20: emc: Document mfd-simple compatible and statistics sub-device Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27  9:02   ` Krzysztof Kozlowski
2020-10-27  9:02     ` Krzysztof Kozlowski
2020-10-27 19:22     ` Dmitry Osipenko
2020-10-27 19:22       ` Dmitry Osipenko
2020-10-27 19:44       ` Krzysztof Kozlowski
2020-10-27 19:44         ` Krzysztof Kozlowski
2020-10-27 20:18         ` Dmitry Osipenko
2020-10-27 20:18           ` Dmitry Osipenko
2020-10-28 15:26           ` Rob Herring
2020-10-28 15:26             ` Rob Herring
2020-10-31 19:53             ` Dmitry Osipenko
2020-10-31 19:53               ` Dmitry Osipenko
2020-10-27 13:22   ` Thierry Reding
2020-10-27 13:22     ` Thierry Reding
2020-10-27 19:23     ` Dmitry Osipenko
2020-10-27 19:23       ` Dmitry Osipenko
2020-10-28 15:28   ` Rob Herring
2020-10-28 15:28     ` Rob Herring
2020-10-25 22:16 ` [PATCH v6 09/52] dt-bindings: memory: tegra30: mc: Document new interconnect property Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-27  9:05   ` Krzysztof Kozlowski
2020-10-27  9:05     ` Krzysztof Kozlowski
2020-10-27 19:18     ` Dmitry Osipenko
2020-10-27 19:18       ` Dmitry Osipenko
2020-10-27 19:39       ` Krzysztof Kozlowski
2020-10-27 19:39         ` Krzysztof Kozlowski
2020-10-25 22:16 ` [PATCH v6 10/52] dt-bindings: memory: tegra30: emc: " Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-25 22:16 ` [PATCH v6 11/52] dt-bindings: memory: tegra30: emc: Document OPP table and voltage regulator Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-28 15:29   ` Rob Herring
2020-10-28 15:29     ` Rob Herring
2020-10-25 22:16 ` [PATCH v6 12/52] dt-bindings: memory: tegra124: mc: Document new interconnect property Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-26 12:49   ` Rob Herring
2020-10-26 12:49     ` Rob Herring
2020-10-25 22:16 ` [PATCH v6 13/52] dt-bindings: memory: tegra124: emc: " Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-26 12:51   ` Rob Herring
2020-10-26 12:51     ` Rob Herring
2020-10-27 10:25   ` Krzysztof Kozlowski
2020-10-27 10:25     ` Krzysztof Kozlowski
2020-10-27 19:19     ` Dmitry Osipenko
2020-10-27 19:19       ` Dmitry Osipenko
2020-10-27 19:48       ` Krzysztof Kozlowski
2020-10-27 19:48         ` Krzysztof Kozlowski
2020-10-27 20:16         ` Dmitry Osipenko
2020-10-27 20:16           ` Dmitry Osipenko
2020-10-28 19:27           ` Krzysztof Kozlowski
2020-10-28 19:27             ` Krzysztof Kozlowski
2020-10-25 22:16 ` [PATCH v6 14/52] dt-bindings: memory: tegra124: emc: Document OPP table and voltage regulator Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-28 15:30   ` Rob Herring
2020-10-28 15:30     ` Rob Herring
2020-10-25 22:16 ` [PATCH v6 15/52] dt-bindings: tegra30-actmon: Document OPP and interconnect properties Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-28 15:30   ` Rob Herring
2020-10-28 15:30     ` Rob Herring
2020-10-25 22:16 ` [PATCH v6 16/52] dt-bindings: host1x: Document new " Dmitry Osipenko
2020-10-25 22:16   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 17/52] dt-bindings: memory: tegra20: Add memory client IDs Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 18/52] dt-bindings: memory: tegra30: " Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 19/52] dt-bindings: memory: tegra124: " Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-28 15:31   ` Rob Herring
2020-10-28 15:31     ` Rob Herring
2020-10-25 22:17 ` [PATCH v6 20/52] ARM: tegra: Correct EMC registers size in Tegra20 device-tree Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27  9:10   ` Krzysztof Kozlowski
2020-10-27  9:10     ` Krzysztof Kozlowski
2020-10-27 20:43     ` Dmitry Osipenko
2020-10-27 20:43       ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 21/52] ARM: tegra: Add interconnect properties to " Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27  9:12   ` Krzysztof Kozlowski
2020-10-27  9:12     ` Krzysztof Kozlowski
2020-10-27 13:30     ` Thierry Reding
2020-10-27 13:30       ` Thierry Reding
2020-10-25 22:17 ` [PATCH v6 22/52] ARM: tegra: Add interconnect properties to Tegra30 device-tree Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27  9:15   ` Krzysztof Kozlowski
2020-10-27  9:15     ` Krzysztof Kozlowski
2020-10-27 19:23     ` Dmitry Osipenko
2020-10-27 19:23       ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 23/52] ARM: tegra: Add interconnect properties to Tegra124 device-tree Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27  9:16   ` Krzysztof Kozlowski
2020-10-27  9:16     ` Krzysztof Kozlowski
2020-10-25 22:17 ` [PATCH v6 24/52] ARM: tegra: Add nvidia,memory-controller phandle to Tegra20 EMC device-tree Dmitry Osipenko
2020-10-25 22:17   ` [PATCH v6 24/52] ARM: tegra: Add nvidia, memory-controller " Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 25/52] ARM: tegra: Add DVFS properties to Tegra20 EMC device-tree node Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27  9:18   ` Krzysztof Kozlowski
2020-10-27  9:18     ` Krzysztof Kozlowski
2020-10-25 22:17 ` [PATCH v6 26/52] ARM: tegra: Add DVFS properties to Tegra30 EMC and ACTMON device-tree nodes Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 27/52] ARM: tegra: Add DVFS properties to Tegra124 " Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 28/52] memory: tegra: Add and use devm_tegra_get_memory_controller() Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27  9:42   ` Krzysztof Kozlowski
2020-10-27  9:42     ` Krzysztof Kozlowski
2020-10-27 19:24     ` Dmitry Osipenko
2020-10-27 19:24       ` Dmitry Osipenko
2020-10-27 13:35   ` Thierry Reding
2020-10-27 13:35     ` Thierry Reding
2020-10-25 22:17 ` [PATCH v6 29/52] memory: tegra-mc: Add interconnect framework Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27 13:48   ` Thierry Reding
2020-10-27 13:48     ` Thierry Reding
2020-10-27 19:30     ` Dmitry Osipenko
2020-10-27 19:30       ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 30/52] memory: tegra20-emc: Make driver modular Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27 13:49   ` Thierry Reding
2020-10-27 13:49     ` Thierry Reding
2020-10-25 22:17 ` [PATCH v6 31/52] memory: tegra20-emc: Use devm_platform_ioremap_resource() Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27 13:50   ` Thierry Reding
2020-10-27 13:50     ` Thierry Reding
2020-10-27 13:57     ` Krzysztof Kozlowski
2020-10-27 13:57       ` Krzysztof Kozlowski
2020-10-25 22:17 ` [PATCH v6 32/52] memory: tegra20-emc: Continue probing if timings are missing in device-tree Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27 13:52   ` Thierry Reding
2020-10-27 13:52     ` Thierry Reding
2020-10-27 19:38     ` Dmitry Osipenko
2020-10-27 19:38       ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 33/52] memory: tegra20: Support interconnect framework Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27 10:09   ` Krzysztof Kozlowski
2020-10-27 10:09     ` Krzysztof Kozlowski
2020-10-27 20:25     ` Dmitry Osipenko
2020-10-27 20:25       ` Dmitry Osipenko
2020-10-27 14:11   ` Thierry Reding
2020-10-27 14:11     ` Thierry Reding
2020-10-27 20:22     ` Dmitry Osipenko
2020-10-27 20:22       ` Dmitry Osipenko
2020-10-27 21:12       ` Dmitry Osipenko
2020-10-27 21:12         ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 34/52] memory: tegra20-emc: Don't parse emc-stats node Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 35/52] memory: tegra: Add missing latency allowness entry for Page Table Cache Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 36/52] memory: tegra: Add FIFO sizes to Tegra30 memory clients Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 37/52] memory: tegra30-emc: Make driver modular Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 38/52] memory: tegra30-emc: Continue probing if timings are missing in device-tree Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 39/52] memory: tegra30: Support interconnect framework Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 40/52] memory: tegra124-emc: Make driver modular Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-26  4:04   ` kernel test robot
2020-10-25 22:17 ` [PATCH v6 41/52] memory: tegra124-emc: Use devm_platform_ioremap_resource() Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27 10:27   ` Krzysztof Kozlowski
2020-10-27 10:27     ` Krzysztof Kozlowski
2020-10-27 20:30     ` Dmitry Osipenko
2020-10-27 20:30       ` Dmitry Osipenko
2020-10-28 19:28       ` Krzysztof Kozlowski
2020-10-28 19:28         ` Krzysztof Kozlowski
2020-10-25 22:17 ` [PATCH v6 42/52] memory: tegra124: Support interconnect framework Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 43/52] memory: tegra: Remove superfluous error messages around platform_get_irq() Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 44/52] drm/tegra: dc: Support memory bandwidth management Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-26  1:50   ` kernel test robot
2020-10-25 22:17 ` [PATCH v6 45/52] drm/tegra: dc: Extend debug stats with total number of events Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-25 22:17 ` [PATCH v6 46/52] opp: Put interconnect paths outside of opp_table_lock Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-27  5:10   ` Viresh Kumar
2020-10-27  5:10     ` Viresh Kumar
2020-10-27 20:26     ` Dmitry Osipenko
2020-10-27 20:26       ` Dmitry Osipenko
2020-10-28  4:03       ` Viresh Kumar
2020-10-28  4:03         ` Viresh Kumar
2020-10-25 22:17 ` [PATCH v6 47/52] PM / devfreq: tegra20: Silence deferred probe error Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-26  3:16   ` Chanwoo Choi
2020-10-26  3:16     ` Chanwoo Choi
2020-10-25 22:17 ` [PATCH v6 48/52] PM / devfreq: tegra20: Relax Kconfig dependency Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-26  3:18   ` Chanwoo Choi
2020-10-26  3:18     ` Chanwoo Choi
2020-10-25 22:17 ` [PATCH v6 49/52] PM / devfreq: tegra20: Convert to EMC_STAT driver, support interconnect and device-tree Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-11-01 13:31   ` Chanwoo Choi
2020-11-01 13:31     ` Chanwoo Choi
2020-11-01 14:12     ` Dmitry Osipenko
2020-11-01 14:12       ` Dmitry Osipenko
2020-11-02 20:08       ` Dmitry Osipenko
2020-11-02 20:08         ` Dmitry Osipenko
2020-11-03  2:22         ` Chanwoo Choi
2020-11-03  2:22           ` Chanwoo Choi
2020-10-25 22:17 ` [PATCH v6 50/52] PM / devfreq: tegra30: Silence deferred probe error Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-26  3:17   ` Chanwoo Choi
2020-10-26  3:17     ` Chanwoo Choi
2020-10-25 22:17 ` [PATCH v6 51/52] PM / devfreq: tegra30: Support interconnect and OPPs from device-tree Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-10-26  2:50   ` kernel test robot
2020-10-26  3:45   ` kernel test robot
2020-11-01 14:39   ` Chanwoo Choi
2020-11-01 14:39     ` Chanwoo Choi
2020-11-01 15:23     ` Dmitry Osipenko
2020-11-01 15:23       ` Dmitry Osipenko
2020-11-01 15:44       ` Chanwoo Choi
2020-11-01 15:44         ` Chanwoo Choi
2020-11-01 15:49         ` Dmitry Osipenko
2020-11-01 15:49           ` Dmitry Osipenko
2020-11-01 15:57           ` Chanwoo Choi
2020-11-01 15:57             ` Chanwoo Choi
2020-11-02 19:58             ` Dmitry Osipenko
2020-11-02 19:58               ` Dmitry Osipenko
2020-11-02 20:00         ` Dmitry Osipenko
2020-11-02 20:00           ` Dmitry Osipenko
2020-11-01 14:44   ` Chanwoo Choi
2020-11-01 14:44     ` Chanwoo Choi
2020-11-01 15:24     ` Dmitry Osipenko
2020-11-01 15:24       ` Dmitry Osipenko
2020-11-01 15:45       ` Chanwoo Choi
2020-11-01 15:45         ` Chanwoo Choi
2020-10-25 22:17 ` [PATCH v6 52/52] PM / devfreq: tegra30: Separate configurations per-SoC generation Dmitry Osipenko
2020-10-25 22:17   ` Dmitry Osipenko
2020-11-01 15:20   ` Chanwoo Choi
2020-11-01 15:20     ` Chanwoo Choi
2020-10-26 15:08 ` [PATCH v6 00/52] Introduce memory interconnect for NVIDIA Tegra SoCs Krzysztof Kozlowski
2020-10-26 15:08   ` Krzysztof Kozlowski
2020-10-26 19:14   ` Dmitry Osipenko
2020-10-26 19:14     ` Dmitry Osipenko
2020-10-27  8:52     ` Krzysztof Kozlowski
2020-10-27  8:52       ` Krzysztof Kozlowski
2020-10-27 20:31       ` Dmitry Osipenko
2020-10-27 20:31         ` Dmitry Osipenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.