[PATCH v2 3/3] remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP

2024-02-12 Thread Abel Vesa
From: Sibi Sankar 

The UEFI loads a lite variant of the ADSP firmware to support charging
use cases. The kernel needs to unload and reload it with the firmware
that has full feature support for audio. This patch arbitarily shutsdown
the lite firmware before loading the full firmware.

Signed-off-by: Sibi Sankar 
Signed-off-by: Abel Vesa 
---
 drivers/remoteproc/qcom_q6v5_pas.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c 
b/drivers/remoteproc/qcom_q6v5_pas.c
index 117fdfdfbc26..581ae5e570e8 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -41,6 +41,7 @@ struct adsp_data {
const char *dtb_firmware_name;
int pas_id;
int dtb_pas_id;
+   int lite_pas_id;
unsigned int minidump_id;
bool auto_boot;
bool decrypt_shutdown;
@@ -77,6 +78,7 @@ struct qcom_adsp {
const char *dtb_firmware_name;
int pas_id;
int dtb_pas_id;
+   int lite_pas_id;
unsigned int minidump_id;
int crash_reason_smem;
bool decrypt_shutdown;
@@ -218,6 +220,9 @@ static int adsp_load(struct rproc *rproc, const struct 
firmware *fw)
/* Store firmware handle to be used in adsp_start() */
adsp->firmware = fw;
 
+   if (adsp->lite_pas_id)
+   ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
+
if (adsp->dtb_pas_id) {
ret = request_firmware(>dtb_firmware, 
adsp->dtb_firmware_name, adsp->dev);
if (ret) {
@@ -720,6 +725,7 @@ static int adsp_probe(struct platform_device *pdev)
adsp->rproc = rproc;
adsp->minidump_id = desc->minidump_id;
adsp->pas_id = desc->pas_id;
+   adsp->lite_pas_id = desc->lite_pas_id;
adsp->info_name = desc->sysmon_name;
adsp->decrypt_shutdown = desc->decrypt_shutdown;
adsp->region_assign_idx = desc->region_assign_idx;
@@ -1020,6 +1026,7 @@ static const struct adsp_data x1e80100_adsp_resource = {
.dtb_firmware_name = "adsp_dtb.mdt",
.pas_id = 1,
.dtb_pas_id = 0x24,
+   .lite_pas_id = 0x1f,
.minidump_id = 5,
.auto_boot = true,
.proxy_pd_names = (char*[]){

-- 
2.34.1




[PATCH v2 2/3] remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP

2024-02-12 Thread Abel Vesa
From: Sibi Sankar 

Add support for PIL loading on ADSP and CDSP on X1E80100 SoCs.

Signed-off-by: Sibi Sankar 
Reviewed-by: Dmitry Baryshkov 
Signed-off-by: Abel Vesa 
---
 drivers/remoteproc/qcom_q6v5_pas.c | 41 ++
 1 file changed, 41 insertions(+)

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c 
b/drivers/remoteproc/qcom_q6v5_pas.c
index d0b1f0f38347..117fdfdfbc26 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -1014,6 +1014,45 @@ static const struct adsp_data sc8280xp_nsp1_resource = {
.ssctl_id = 0x20,
 };
 
+static const struct adsp_data x1e80100_adsp_resource = {
+   .crash_reason_smem = 423,
+   .firmware_name = "adsp.mdt",
+   .dtb_firmware_name = "adsp_dtb.mdt",
+   .pas_id = 1,
+   .dtb_pas_id = 0x24,
+   .minidump_id = 5,
+   .auto_boot = true,
+   .proxy_pd_names = (char*[]){
+   "lcx",
+   "lmx",
+   NULL
+   },
+   .load_state = "adsp",
+   .ssr_name = "lpass",
+   .sysmon_name = "adsp",
+   .ssctl_id = 0x14,
+};
+
+static const struct adsp_data x1e80100_cdsp_resource = {
+   .crash_reason_smem = 601,
+   .firmware_name = "cdsp.mdt",
+   .dtb_firmware_name = "cdsp_dtb.mdt",
+   .pas_id = 18,
+   .dtb_pas_id = 0x25,
+   .minidump_id = 7,
+   .auto_boot = true,
+   .proxy_pd_names = (char*[]){
+   "cx",
+   "mxc",
+   "nsp",
+   NULL
+   },
+   .load_state = "cdsp",
+   .ssr_name = "cdsp",
+   .sysmon_name = "cdsp",
+   .ssctl_id = 0x17,
+};
+
 static const struct adsp_data sm8350_cdsp_resource = {
.crash_reason_smem = 601,
.firmware_name = "cdsp.mdt",
@@ -1318,6 +1357,8 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,sm8650-adsp-pas", .data = _adsp_resource},
{ .compatible = "qcom,sm8650-cdsp-pas", .data = _cdsp_resource},
{ .compatible = "qcom,sm8650-mpss-pas", .data = _mpss_resource},
+   { .compatible = "qcom,x1e80100-adsp-pas", .data = 
_adsp_resource},
+   { .compatible = "qcom,x1e80100-cdsp-pas", .data = 
_cdsp_resource},
{ },
 };
 MODULE_DEVICE_TABLE(of, adsp_of_match);

-- 
2.34.1




[PATCH v2 1/3] dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & cDSP

2024-02-12 Thread Abel Vesa
Document the aDSP and cDSP Peripheral Authentication Service on the
X1E80100 Platform.

Reviewed-by: Krzysztof Kozlowski 
Signed-off-by: Abel Vesa 
---
 Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml 
b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml
index 5f63b6b9a8f5..73fda7565cd1 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml
@@ -22,6 +22,8 @@ properties:
   - qcom,sm8650-adsp-pas
   - qcom,sm8650-cdsp-pas
   - qcom,sm8650-mpss-pas
+  - qcom,x1e80100-adsp-pas
+  - qcom,x1e80100-cdsp-pas
 
   reg:
 maxItems: 1
@@ -69,6 +71,8 @@ allOf:
 - qcom,sm8550-adsp-pas
 - qcom,sm8550-cdsp-pas
 - qcom,sm8650-adsp-pas
+- qcom,x1e80100-adsp-pas
+- qcom,x1e80100-cdsp-pas
 then:
   properties:
 interrupts:
@@ -126,6 +130,7 @@ allOf:
   enum:
 - qcom,sm8550-adsp-pas
 - qcom,sm8650-adsp-pas
+- qcom,x1e80100-adsp-pas
 then:
   properties:
 power-domains:
@@ -159,6 +164,7 @@ allOf:
   enum:
 - qcom,sm8550-cdsp-pas
 - qcom,sm8650-cdsp-pas
+- qcom,x1e80100-cdsp-pas
 then:
   properties:
 power-domains:

-- 
2.34.1




[PATCH v2 0/3] remoteproc: qcom_q6v5_pas: Add aDSP and cDSP for X1E80100

2024-02-12 Thread Abel Vesa
Signed-off-by: Abel Vesa 
---
Changes in v2:
- Added Krzysztof's R-b tag to bindings patch
- Added Dmitry's R-b tag to the X1E80100 related patch
- Dropped the comment about the comment from adsp_load about lite
  version
- Link to v1: 
https://lore.kernel.org/r/20240129-x1e80100-remoteproc-v1-0-15d21ef58...@linaro.org

---
Abel Vesa (1):
  dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & 
cDSP

Sibi Sankar (2):
  remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP
  remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP

 .../bindings/remoteproc/qcom,sm8550-pas.yaml   |  6 +++
 drivers/remoteproc/qcom_q6v5_pas.c | 48 ++
 2 files changed, 54 insertions(+)
---
base-commit: 445a555e0623387fa9b94e68e61681717e70200a
change-id: 20231201-x1e80100-remoteproc-b27da583e8cc

Best regards,
-- 
Abel Vesa 




Re: [PATCH 3/3] remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP

2024-01-31 Thread Abel Vesa
On 24-01-29 17:17:28, Dmitry Baryshkov wrote:
> On Mon, 29 Jan 2024 at 15:35, Abel Vesa  wrote:
> >
> > From: Sibi Sankar 
> >
> > The UEFI loads a lite variant of the ADSP firmware to support charging
> > use cases. The kernel needs to unload and reload it with the firmware
> > that has full feature support for audio. This patch arbitarily shutsdown
> > the lite firmware before loading the full firmware.
> >
> > Signed-off-by: Sibi Sankar 
> > Signed-off-by: Abel Vesa 
> > ---
> >  drivers/remoteproc/qcom_q6v5_pas.c | 8 
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/remoteproc/qcom_q6v5_pas.c 
> > b/drivers/remoteproc/qcom_q6v5_pas.c
> > index 083d71f80e5c..4f6940368eb4 100644
> > --- a/drivers/remoteproc/qcom_q6v5_pas.c
> > +++ b/drivers/remoteproc/qcom_q6v5_pas.c
> > @@ -39,6 +39,7 @@ struct adsp_data {
> > const char *dtb_firmware_name;
> > int pas_id;
> > int dtb_pas_id;
> > +   int lite_pas_id;
> > unsigned int minidump_id;
> > bool auto_boot;
> > bool decrypt_shutdown;
> > @@ -72,6 +73,7 @@ struct qcom_adsp {
> > const char *dtb_firmware_name;
> > int pas_id;
> > int dtb_pas_id;
> > +   int lite_pas_id;
> > unsigned int minidump_id;
> > int crash_reason_smem;
> > bool decrypt_shutdown;
> > @@ -210,6 +212,10 @@ static int adsp_load(struct rproc *rproc, const struct 
> > firmware *fw)
> > /* Store firmware handle to be used in adsp_start() */
> > adsp->firmware = fw;
> >
> > +   /* WIP: Shutdown the ADSP if it's running a lite version of the 
> > firmware*/
> 
> Why is it still marked as WIP?

AFAIU, there was more to be done here w.r.t. preloaded lite version
firmware.

Later, was agreed that that is not case.

So maybe I just need to drop the comment.

Sibi, can you confirm?

> 
> > +   if (adsp->lite_pas_id)
> > +   ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
> > +
> > if (adsp->dtb_pas_id) {
> > ret = request_firmware(>dtb_firmware, 
> > adsp->dtb_firmware_name, adsp->dev);
> > if (ret) {
> > @@ -693,6 +699,7 @@ static int adsp_probe(struct platform_device *pdev)
> > adsp->rproc = rproc;
> > adsp->minidump_id = desc->minidump_id;
> > adsp->pas_id = desc->pas_id;
> > +   adsp->lite_pas_id = desc->lite_pas_id;
> > adsp->info_name = desc->sysmon_name;
> > adsp->decrypt_shutdown = desc->decrypt_shutdown;
> > adsp->region_assign_idx = desc->region_assign_idx;
> > @@ -990,6 +997,7 @@ static const struct adsp_data x1e80100_adsp_resource = {
> > .dtb_firmware_name = "adsp_dtb.mdt",
> > .pas_id = 1,
> > .dtb_pas_id = 0x24,
> > +   .lite_pas_id = 0x1f,
> > .minidump_id = 5,
> > .auto_boot = true,
> > .proxy_pd_names = (char*[]){
> >
> > --
> > 2.34.1
> >
> >
> 
> 
> -- 
> With best wishes
> Dmitry



[PATCH 3/3] remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP

2024-01-29 Thread Abel Vesa
From: Sibi Sankar 

The UEFI loads a lite variant of the ADSP firmware to support charging
use cases. The kernel needs to unload and reload it with the firmware
that has full feature support for audio. This patch arbitarily shutsdown
the lite firmware before loading the full firmware.

Signed-off-by: Sibi Sankar 
Signed-off-by: Abel Vesa 
---
 drivers/remoteproc/qcom_q6v5_pas.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c 
b/drivers/remoteproc/qcom_q6v5_pas.c
index 083d71f80e5c..4f6940368eb4 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -39,6 +39,7 @@ struct adsp_data {
const char *dtb_firmware_name;
int pas_id;
int dtb_pas_id;
+   int lite_pas_id;
unsigned int minidump_id;
bool auto_boot;
bool decrypt_shutdown;
@@ -72,6 +73,7 @@ struct qcom_adsp {
const char *dtb_firmware_name;
int pas_id;
int dtb_pas_id;
+   int lite_pas_id;
unsigned int minidump_id;
int crash_reason_smem;
bool decrypt_shutdown;
@@ -210,6 +212,10 @@ static int adsp_load(struct rproc *rproc, const struct 
firmware *fw)
/* Store firmware handle to be used in adsp_start() */
adsp->firmware = fw;
 
+   /* WIP: Shutdown the ADSP if it's running a lite version of the 
firmware*/
+   if (adsp->lite_pas_id)
+   ret = qcom_scm_pas_shutdown(adsp->lite_pas_id);
+
if (adsp->dtb_pas_id) {
ret = request_firmware(>dtb_firmware, 
adsp->dtb_firmware_name, adsp->dev);
if (ret) {
@@ -693,6 +699,7 @@ static int adsp_probe(struct platform_device *pdev)
adsp->rproc = rproc;
adsp->minidump_id = desc->minidump_id;
adsp->pas_id = desc->pas_id;
+   adsp->lite_pas_id = desc->lite_pas_id;
adsp->info_name = desc->sysmon_name;
adsp->decrypt_shutdown = desc->decrypt_shutdown;
adsp->region_assign_idx = desc->region_assign_idx;
@@ -990,6 +997,7 @@ static const struct adsp_data x1e80100_adsp_resource = {
.dtb_firmware_name = "adsp_dtb.mdt",
.pas_id = 1,
.dtb_pas_id = 0x24,
+   .lite_pas_id = 0x1f,
.minidump_id = 5,
.auto_boot = true,
.proxy_pd_names = (char*[]){

-- 
2.34.1




[PATCH 2/3] remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP

2024-01-29 Thread Abel Vesa
From: Sibi Sankar 

Add support for PIL loading on ADSP and CDSP on X1E80100 SoCs.

Signed-off-by: Sibi Sankar 
Signed-off-by: Abel Vesa 
---
 drivers/remoteproc/qcom_q6v5_pas.c | 41 ++
 1 file changed, 41 insertions(+)

diff --git a/drivers/remoteproc/qcom_q6v5_pas.c 
b/drivers/remoteproc/qcom_q6v5_pas.c
index a9dd58608052..083d71f80e5c 100644
--- a/drivers/remoteproc/qcom_q6v5_pas.c
+++ b/drivers/remoteproc/qcom_q6v5_pas.c
@@ -984,6 +984,45 @@ static const struct adsp_data sc8280xp_nsp1_resource = {
.ssctl_id = 0x20,
 };
 
+static const struct adsp_data x1e80100_adsp_resource = {
+   .crash_reason_smem = 423,
+   .firmware_name = "adsp.mdt",
+   .dtb_firmware_name = "adsp_dtb.mdt",
+   .pas_id = 1,
+   .dtb_pas_id = 0x24,
+   .minidump_id = 5,
+   .auto_boot = true,
+   .proxy_pd_names = (char*[]){
+   "lcx",
+   "lmx",
+   NULL
+   },
+   .load_state = "adsp",
+   .ssr_name = "lpass",
+   .sysmon_name = "adsp",
+   .ssctl_id = 0x14,
+};
+
+static const struct adsp_data x1e80100_cdsp_resource = {
+   .crash_reason_smem = 601,
+   .firmware_name = "cdsp.mdt",
+   .dtb_firmware_name = "cdsp_dtb.mdt",
+   .pas_id = 18,
+   .dtb_pas_id = 0x25,
+   .minidump_id = 7,
+   .auto_boot = true,
+   .proxy_pd_names = (char*[]){
+   "cx",
+   "mxc",
+   "nsp",
+   NULL
+   },
+   .load_state = "cdsp",
+   .ssr_name = "cdsp",
+   .sysmon_name = "cdsp",
+   .ssctl_id = 0x17,
+};
+
 static const struct adsp_data sm8350_cdsp_resource = {
.crash_reason_smem = 601,
.firmware_name = "cdsp.mdt",
@@ -1236,6 +1275,8 @@ static const struct of_device_id adsp_of_match[] = {
{ .compatible = "qcom,sm8550-adsp-pas", .data = _adsp_resource},
{ .compatible = "qcom,sm8550-cdsp-pas", .data = _cdsp_resource},
{ .compatible = "qcom,sm8550-mpss-pas", .data = _mpss_resource},
+   { .compatible = "qcom,x1e80100-adsp-pas", .data = 
_adsp_resource},
+   { .compatible = "qcom,x1e80100-cdsp-pas", .data = 
_cdsp_resource},
{ },
 };
 MODULE_DEVICE_TABLE(of, adsp_of_match);

-- 
2.34.1




[PATCH 1/3] dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & cDSP

2024-01-29 Thread Abel Vesa
Document the aDSP and cDSP Peripheral Authentication Service on the
X1E80100 Platform.

Signed-off-by: Abel Vesa 
---
 Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml 
b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml
index 58120829fb06..95ae32ea8a0a 100644
--- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml
+++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml
@@ -19,6 +19,8 @@ properties:
   - qcom,sm8550-adsp-pas
   - qcom,sm8550-cdsp-pas
   - qcom,sm8550-mpss-pas
+  - qcom,x1e80100-adsp-pas
+  - qcom,x1e80100-cdsp-pas
 
   reg:
 maxItems: 1
@@ -63,6 +65,8 @@ allOf:
   enum:
 - qcom,sm8550-adsp-pas
 - qcom,sm8550-cdsp-pas
+- qcom,x1e80100-adsp-pas
+- qcom,x1e80100-cdsp-pas
 then:
   properties:
 interrupts:
@@ -85,6 +89,7 @@ allOf:
 compatible:
   enum:
 - qcom,sm8550-adsp-pas
+- qcom,x1e80100-adsp-pas
 then:
   properties:
 power-domains:
@@ -116,6 +121,7 @@ allOf:
 compatible:
   enum:
 - qcom,sm8550-cdsp-pas
+- qcom,x1e80100-cdsp-pas
 then:
   properties:
 power-domains:

-- 
2.34.1




[PATCH 0/3] remoteproc: qcom_q6v5_pas: Add aDSP and cDSP for X1E80100

2024-01-29 Thread Abel Vesa
Signed-off-by: Abel Vesa 
---
Abel Vesa (1):
  dt-bindings: remoteproc: qcom,sm8550-pas: document the X1E80100 aDSP & 
cDSP

Sibi Sankar (2):
  remoteproc: qcom_q6v5_pas: Add support for X1E80100 ADSP/CDSP
  remoteproc: qcom_q6v5_pas: Unload lite firmware on ADSP

 .../bindings/remoteproc/qcom,sm8550-pas.yaml   |  6 +++
 drivers/remoteproc/qcom_q6v5_pas.c | 49 ++
 2 files changed, 55 insertions(+)
---
base-commit: 01af33cc9894b4489fb68fa35c40e9fe85df63dc
change-id: 20231201-x1e80100-remoteproc-b27da583e8cc

Best regards,
-- 
Abel Vesa 




Re: [GIT PULL] clk: imx: Updates for v5.13

2021-04-08 Thread Abel Vesa
On 21-04-08 00:06:29, Stephen Boyd wrote:
> Quoting Abel Vesa (2021-04-04 13:40:24)
> > The following changes since commit a38fd8748464831584a19438cbb3082b5a2dab15:
> > 
> >   Linux 5.12-rc2 (2021-03-05 17:33:41 -0800)
> > 
> > are available in the Git repository at:
> > 
> >   git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx
> > 
> > for you to fetch changes up to 054ef44ea3ef2883e0f63c9a54c91c07f321a0b4:
> > 
> >   clk: imx: Reference preceded by free (2021-04-04 22:39:05 +0300)
> > 
> > 
> 
> Thanks. Pulled into clk-next. Next time can you send a signed tag with a
> small blurb about what is included?

Oups, I mistakenly used the branch instead of using the tag.

The tag is here:

https://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git/tag/?h=clk-imx-5.13


[GIT PULL] clk: imx: Updates for v5.13

2021-04-04 Thread Abel Vesa
The following changes since commit a38fd8748464831584a19438cbb3082b5a2dab15:

  Linux 5.12-rc2 (2021-03-05 17:33:41 -0800)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git clk/imx

for you to fetch changes up to 054ef44ea3ef2883e0f63c9a54c91c07f321a0b4:

  clk: imx: Reference preceded by free (2021-04-04 22:39:05 +0300)


Adam Ford (1):
  clk: imx: Fix reparenting of UARTs not associated with stdout

Jian Dong (1):
  clk: imx: Reference preceded by free

Richard Zhu (2):
  clk: imx8mp: Remove the none exist pcie clocks
  clk: imx8mq: Correct the pcie1 sels

 drivers/clk/imx/clk-imx25.c  | 12 +-
 drivers/clk/imx/clk-imx27.c  | 13 +-
 drivers/clk/imx/clk-imx35.c  | 10 +---
 drivers/clk/imx/clk-imx5.c   | 30 +++
 drivers/clk/imx/clk-imx6q.c  | 16 +
 drivers/clk/imx/clk-imx6sl.c | 16 +
 drivers/clk/imx/clk-imx6sll.c| 24 +--
 drivers/clk/imx/clk-imx6sx.c | 16 +
 drivers/clk/imx/clk-imx7d.c  | 22 +
 drivers/clk/imx/clk-imx7ulp.c| 31 ++--
 drivers/clk/imx/clk-imx8mm.c | 18 ++
 drivers/clk/imx/clk-imx8mn.c | 18 ++
 drivers/clk/imx/clk-imx8mp.c | 32 +
 drivers/clk/imx/clk-imx8mq.c | 22 -
 drivers/clk/imx/clk-lpcg-scu.c   |  1 +
 drivers/clk/imx/clk-scu.c|  1 +
 drivers/clk/imx/clk.c| 41 +---
 drivers/clk/imx/clk.h|  4 ++--
 include/dt-bindings/clock/imx8mp-clock.h |  3 ---
 19 files changed, 58 insertions(+), 272 deletions(-)


Re: [PATCH v1 0/2] Add imx8m power domain driver

2021-04-02 Thread Abel Vesa
On 21-04-02 19:48:41, Adrien Grassein wrote:
> Hi,
> 
> Le ven. 2 avr. 2021 à 19:42, Abel Vesa  a écrit :
> >
> > On 21-04-02 18:45:04, Adrien Grassein wrote:
> > > Hi,
> > >
> > > this patch et aims to add the support of the i.MX 8 Power Domain driver.
> > > Some devices (like usbotg2) can't work without this patch as their
> > > attached power domain are down.
> > >
> > > The original drivr was taken from le imx kernel and aapted to fit with
> > > the actual mainline (minor fixes).
> > >
> > > Thanks,
> > >
> >
> > Big NACK for the whole series.
> >
> > This approach has already been rejected upstream.
> 
> So what is the correct approach?
> At this point otg2 node of imx8mm is not working at all (and blocks the whole
> boot of the kernel)
> 

Have a look at this thread:

https://lkml.org/lkml/2020/4/27/706

> >
> > Plus, you changed the original author, this work was originally done by 
> > Jacky Bai.
> 
> I have not changed this, the original author is not mentioned on the
> original patch.

Here is the original commit:

https://github.com/Freescale/linux-fslc/commit/7ebcf5ccf423afe4ccd9c53ef204018b0b653ce0


> 
> >
> > > Adrien Grassein (2):
> > >   dt-bindings: power: Add documentation for imx8m power domain driver
> > >   soc: imx: add Power Domain driver for i.MX8M(M|N|P)
> > >
> > >  .../bindings/power/fsl,imx-power-domain.yaml  |  89 +++
> > >  MAINTAINERS   |  10 +
> > >  drivers/soc/imx/Kconfig   |   7 +
> > >  drivers/soc/imx/Makefile  |   1 +
> > >  drivers/soc/imx/imx8m_pm_domains.c| 233 ++
> > >  include/dt-bindings/power/imx8mm-power.h  |  21 ++
> > >  include/dt-bindings/power/imx8mn-power.h  |  15 ++
> > >  include/dt-bindings/power/imx8mp-power.h  |  28 +++
> > >  include/soc/imx/imx_sip.h |  12 +
> > >  9 files changed, 416 insertions(+)
> > >  create mode 100644 
> > > Documentation/devicetree/bindings/power/fsl,imx-power-domain.yaml
> > >  create mode 100644 drivers/soc/imx/imx8m_pm_domains.c
> > >  create mode 100644 include/dt-bindings/power/imx8mm-power.h
> > >  create mode 100644 include/dt-bindings/power/imx8mn-power.h
> > >  create mode 100644 include/dt-bindings/power/imx8mp-power.h
> > >  create mode 100644 include/soc/imx/imx_sip.h
> > >
> > > --
> > > 2.25.1
> > >
> 
> Thanks,


Re: [PATCH v1 0/2] Add imx8m power domain driver

2021-04-02 Thread Abel Vesa
On 21-04-02 18:45:04, Adrien Grassein wrote:
> Hi,
> 
> this patch et aims to add the support of the i.MX 8 Power Domain driver.
> Some devices (like usbotg2) can't work without this patch as their
> attached power domain are down.
> 
> The original drivr was taken from le imx kernel and aapted to fit with
> the actual mainline (minor fixes).
> 
> Thanks,
> 

Big NACK for the whole series.

This approach has already been rejected upstream.

Plus, you changed the original author, this work was originally done by Jacky 
Bai.

> Adrien Grassein (2):
>   dt-bindings: power: Add documentation for imx8m power domain driver
>   soc: imx: add Power Domain driver for i.MX8M(M|N|P)
> 
>  .../bindings/power/fsl,imx-power-domain.yaml  |  89 +++
>  MAINTAINERS   |  10 +
>  drivers/soc/imx/Kconfig   |   7 +
>  drivers/soc/imx/Makefile  |   1 +
>  drivers/soc/imx/imx8m_pm_domains.c| 233 ++
>  include/dt-bindings/power/imx8mm-power.h  |  21 ++
>  include/dt-bindings/power/imx8mn-power.h  |  15 ++
>  include/dt-bindings/power/imx8mp-power.h  |  28 +++
>  include/soc/imx/imx_sip.h |  12 +
>  9 files changed, 416 insertions(+)
>  create mode 100644 
> Documentation/devicetree/bindings/power/fsl,imx-power-domain.yaml
>  create mode 100644 drivers/soc/imx/imx8m_pm_domains.c
>  create mode 100644 include/dt-bindings/power/imx8mm-power.h
>  create mode 100644 include/dt-bindings/power/imx8mn-power.h
>  create mode 100644 include/dt-bindings/power/imx8mp-power.h
>  create mode 100644 include/soc/imx/imx_sip.h
> 
> -- 
> 2.25.1
> 


Re: [PATCH] clk: imx: reference preceded by free

2021-03-30 Thread Abel Vesa
On 21-03-23 11:10:34, Jian Dong wrote:
> From: Jian Dong 
> 
>  when register failed, clk will be freed, it will generate dangling pointer
>  problem in later reference. it should return directly.
> 
> Signed-off-by: Jian Dong 

Applied, thanks.

> ---
>  drivers/clk/imx/clk-lpcg-scu.c | 1 +
>  drivers/clk/imx/clk-scu.c  | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c
> index 77be763..dd5abd0 100644
> --- a/drivers/clk/imx/clk-lpcg-scu.c
> +++ b/drivers/clk/imx/clk-lpcg-scu.c
> @@ -114,6 +114,7 @@ struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, 
> const char *name,
>   if (ret) {
>   kfree(clk);
>   hw = ERR_PTR(ret);
> + return hw;
>   }
>  
>   if (dev)
> diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c
> index 1f5518b7..f89b4da 100644
> --- a/drivers/clk/imx/clk-scu.c
> +++ b/drivers/clk/imx/clk-scu.c
> @@ -426,6 +426,7 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const 
> char *name,
>   if (ret) {
>   kfree(clk);
>   hw = ERR_PTR(ret);
> + return hw;
>   }
>  
>   if (dev)
> -- 
> 1.9.1
> 
> 


Re: [PATCH] clk: imx8mq: Correct the pcie1 sels

2021-03-30 Thread Abel Vesa
On 21-03-15 16:17:48, Richard Zhu wrote:
> - The sys2_pll_50m should be one of the clock sels of PCIE_AUX clock.
> Change the sys2_pll_500m to sys2_pll_50m.
> - Correct one mis-spell of the imx8mq_pcie1_ctrl_sels definition, from
> "sys2_pll_250m" to "sys2_pll_333m".
> 
> Signed-off-by: Richard Zhu 

Applied, thanks.

> ---
>  drivers/clk/imx/clk-imx8mq.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
> index 4dd4ae9d022b..c66c196f396c 100644
> --- a/drivers/clk/imx/clk-imx8mq.c
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -113,12 +113,12 @@ static const char * const imx8mq_disp_dtrc_sels[] = 
> {"osc_25m", "vpu_pll_out", "
>  static const char * const imx8mq_disp_dc8000_sels[] = {"osc_25m", 
> "vpu_pll_out", "sys1_pll_800m", "sys2_pll_1000m", "sys1_pll_160m", 
> "sys2_pll_100m", "sys3_pll_out", "audio_pll2_out", };
>  
>  static const char * const imx8mq_pcie1_ctrl_sels[] = {"osc_25m", 
> "sys2_pll_250m", "sys2_pll_200m", "sys1_pll_266m",
> -"sys1_pll_800m", 
> "sys2_pll_500m", "sys2_pll_250m", "sys3_pll_out", };
> +"sys1_pll_800m", 
> "sys2_pll_500m", "sys2_pll_333m", "sys3_pll_out", };
>  
>  static const char * const imx8mq_pcie1_phy_sels[] = {"osc_25m", 
> "sys2_pll_100m", "sys2_pll_500m", "clk_ext1", "clk_ext2",
> "clk_ext3", "clk_ext4", };
>  
> -static const char * const imx8mq_pcie1_aux_sels[] = {"osc_25m", 
> "sys2_pll_200m", "sys2_pll_500m", "sys3_pll_out",
> +static const char * const imx8mq_pcie1_aux_sels[] = {"osc_25m", 
> "sys2_pll_200m", "sys2_pll_50m", "sys3_pll_out",
> "sys2_pll_100m", "sys1_pll_80m", 
> "sys1_pll_160m", "sys1_pll_200m", };
>  
>  static const char * const imx8mq_dc_pixel_sels[] = {"osc_25m", 
> "video_pll1_out", "audio_pll2_out", "audio_pll1_out", "sys1_pll_800m", 
> "sys2_pll_1000m", "sys3_pll_out", "clk_ext4", };
> -- 
> 2.17.1


Re: [PATCH] clk: imx8mp: Remove the none exist pcie clocks

2021-03-30 Thread Abel Vesa
On 21-03-15 16:17:47, Richard Zhu wrote:
> In the i.MX8MP PCIe design, the PCIe PHY REF clock comes from external
> OSC or internal system PLL. It is configured in the IOMUX_GPR14 register
> directly, and can't be contolled by CCM at all.
> Remove the PCIE PHY clock from clock driver to clean up codes.
> There is only one PCIe in i.MX8MP, remove the none exist second PCIe
> related clocks.
> Remove the none exsits clocks IDs together.
> 
> Signed-off-by: Richard Zhu 
> Reviewed-by: Jason Liu 

Applied, thanks.

> ---
>  drivers/clk/imx/clk-imx8mp.c | 15 ---
>  include/dt-bindings/clock/imx8mp-clock.h |  3 ---
>  2 files changed, 18 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
> index 2f4e1d674e1c..afbeb6bf1909 100644
> --- a/drivers/clk/imx/clk-imx8mp.c
> +++ b/drivers/clk/imx/clk-imx8mp.c
> @@ -152,10 +152,6 @@ static const char * const imx8mp_can2_sels[] = 
> {"osc_24m", "sys_pll2_200m", "sys
>   "sys_pll1_160m", 
> "sys_pll1_800m", "sys_pll3_out",
>   "sys_pll2_250m", 
> "audio_pll2_out", };
>  
> -static const char * const imx8mp_pcie_phy_sels[] = {"osc_24m", 
> "sys_pll2_100m", "sys_pll2_500m",
> - "clk_ext1", "clk_ext2", 
> "clk_ext3",
> - "clk_ext4", 
> "sys_pll1_400m", };
> -
>  static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", 
> "sys_pll2_200m", "sys_pll2_50m",
>   "sys_pll3_out", 
> "sys_pll2_100m", "sys_pll1_80m",
>   "sys_pll1_160m", 
> "sys_pll1_200m", };
> @@ -380,14 +376,6 @@ static const char * const imx8mp_memrepair_sels[] = 
> {"osc_24m", "sys_pll2_100m",
>   "sys_pll1_800m", 
> "sys_pll2_1000m", "sys_pll3_out",
>   "clk_ext3", 
> "audio_pll2_out", };
>  
> -static const char * const imx8mp_pcie2_ctrl_sels[] = {"osc_24m", 
> "sys_pll2_250m", "sys_pll2_200m",
> -   "sys_pll1_266m", 
> "sys_pll1_800m", "sys_pll2_500m",
> -   "sys_pll2_333m", 
> "sys_pll3_out", };
> -
> -static const char * const imx8mp_pcie2_phy_sels[] = {"osc_24m", 
> "sys_pll2_100m", "sys_pll2_500m",
> -  "clk_ext1", "clk_ext2", 
> "clk_ext3",
> -  "clk_ext4", 
> "sys_pll1_400m", };
> -
>  static const char * const imx8mp_media_mipi_test_byte_sels[] = {"osc_24m", 
> "sys_pll2_200m", "sys_pll2_50m",
>   "sys_pll3_out", 
> "sys_pll2_100m",
>   "sys_pll1_80m", 
> "sys_pll1_160m",
> @@ -585,7 +573,6 @@ static int imx8mp_clocks_probe(struct platform_device 
> *pdev)
>   hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", 
> imx8mp_vpu_g2_sels, ccm_base + 0xa180);
>   hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, 
> ccm_base + 0xa200);
>   hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, 
> ccm_base + 0xa280);
> - hws[IMX8MP_CLK_PCIE_PHY] = imx8m_clk_hw_composite("pcie_phy", 
> imx8mp_pcie_phy_sels, ccm_base + 0xa380);
>   hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", 
> imx8mp_pcie_aux_sels, ccm_base + 0xa400);
>   hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, 
> ccm_base + 0xa480);
>   hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, 
> ccm_base + 0xa500);
> @@ -643,8 +630,6 @@ static int imx8mp_clocks_probe(struct platform_device 
> *pdev)
>   hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = 
> imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base 
> + 0xbe80);
>   hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", 
> imx8mp_media_ldb_sels, ccm_base + 0xbf00);
>   hws[IMX8MP_CLK_MEMREPAIR] = 
> imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base 
> + 0xbf80);
> - hws[IMX8MP_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", 
> imx8mp_pcie2_ctrl_sels, ccm_base + 0xc000);
> - hws[IMX8MP_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", 
> imx8mp_pcie2_phy_sels, ccm_base + 0xc080);
>   hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = 
> imx8m_clk_hw_composite("media_mipi_test_byte", 
> imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
>   hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", 
> imx8mp_ecspi3_sels, ccm_base + 0xc180);
>   hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, 
> ccm_base + 0xc200);
> diff --git a/include/dt-bindings/clock/imx8mp-clock.h 
> b/include/dt-bindings/clock/imx8mp-clock.h
> 

Re: linux-next: bad topic branch merged into the clk-imx tree

2021-03-23 Thread Abel Vesa
On 21-03-24 09:02:43, Stephen Rothwell wrote:
> Hi all,
> 
> Please try to avoid merging branches based on v5.12-rc1-dontuse - ask
> the branch owner to rebase onto (at least) v5.12-rc2.
> 

Oups, fixed now.

> -- 
> Cheers,
> Stephen Rothwell




Re: [PATCH V4] clk: imx: Fix reparenting of UARTs not associated with stdout

2021-03-22 Thread Abel Vesa
On 21-03-13 06:28:17, Adam Ford wrote:
> Most if not all i.MX SoC's call a function which enables all UARTS.
> This is a problem for users who need to re-parent the clock source,
> because any attempt to change the parent results in an busy error
> due to the fact that the clocks have been enabled already.
> 
>   clk: failed to reparent uart1 to sys_pll1_80m: -16
> 
> Instead of pre-initializing all UARTS, scan the device tree to see
> which UART clocks are associated to stdout, and only enable those
> UART clocks if it's needed early.  This will move initialization of
> the remaining clocks until after the parenting of the clocks.
> 
> When the clocks are shutdown, this mechanism will also disable any
> clocks that were pre-initialized.
> 
> Fixes: 9461f7b33d11c ("clk: fix CLK_SET_RATE_GATE with clock rate protection")
> Suggested-by: Aisheng Dong 
> Signed-off-by: Adam Ford 
> Reviewed-by: Abel Vesa 
> Tested-by: Ahmad Fatoum 
> 
> ---
> V4:  Check if of_stdout is available before using it.
>  Re-align #ifdef to remove repeated code.
> V3:  Return a method more closely related to upstream kernel but
>  instead of passing an array of UART's, each SoC passes the max
>  number of UART clocks is has.  The imx clock driver will create
>  an array to enable on startup, and disable later.
> V2:  Attempt to port driver from vendor kernel.
> ---
>  drivers/clk/imx/clk-imx25.c   | 12 +-
>  drivers/clk/imx/clk-imx27.c   | 13 +--
>  drivers/clk/imx/clk-imx35.c   | 10 +
>  drivers/clk/imx/clk-imx5.c| 30 +++--
>  drivers/clk/imx/clk-imx6q.c   | 16 +-
>  drivers/clk/imx/clk-imx6sl.c  | 16 +-
>  drivers/clk/imx/clk-imx6sll.c | 24 +---
>  drivers/clk/imx/clk-imx6sx.c  | 16 +-
>  drivers/clk/imx/clk-imx7d.c   | 22 +--
>  drivers/clk/imx/clk-imx7ulp.c | 31 ++
>  drivers/clk/imx/clk-imx8mm.c  | 18 ++-
>  drivers/clk/imx/clk-imx8mn.c  | 18 ++-
>  drivers/clk/imx/clk-imx8mp.c  | 17 +--
>  drivers/clk/imx/clk-imx8mq.c  | 18 ++-
>  drivers/clk/imx/clk.c | 41 +++
>  drivers/clk/imx/clk.h |  4 ++--
>  16 files changed, 54 insertions(+), 252 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
> index a66cabfbf94f..66192fe0a898 100644
> --- a/drivers/clk/imx/clk-imx25.c
> +++ b/drivers/clk/imx/clk-imx25.c
> @@ -73,16 +73,6 @@ enum mx25_clks {
>  
>  static struct clk *clk[clk_max];
>  
> -static struct clk ** const uart_clks[] __initconst = {
> - [uart_ipg_per],
> - [uart1_ipg],
> - [uart2_ipg],
> - [uart3_ipg],
> - [uart4_ipg],
> - [uart5_ipg],
> - NULL
> -};
> -
>  static int __init __mx25_clocks_init(void __iomem *ccm_base)
>  {
>   BUG_ON(!ccm_base);
> @@ -228,7 +218,7 @@ static int __init __mx25_clocks_init(void __iomem 
> *ccm_base)
>*/
>   clk_set_parent(clk[cko_sel], clk[ipg]);
>  
> - imx_register_uart_clocks(uart_clks);
> + imx_register_uart_clocks(6);
>  
>   return 0;
>  }
> diff --git a/drivers/clk/imx/clk-imx27.c b/drivers/clk/imx/clk-imx27.c
> index 5585ded8b8c6..56a5fc402b10 100644
> --- a/drivers/clk/imx/clk-imx27.c
> +++ b/drivers/clk/imx/clk-imx27.c
> @@ -49,17 +49,6 @@ static const char *ssi_sel_clks[] = { "spll_gate", "mpll", 
> };
>  static struct clk *clk[IMX27_CLK_MAX];
>  static struct clk_onecell_data clk_data;
>  
> -static struct clk ** const uart_clks[] __initconst = {
> - [IMX27_CLK_PER1_GATE],
> - [IMX27_CLK_UART1_IPG_GATE],
> - [IMX27_CLK_UART2_IPG_GATE],
> - [IMX27_CLK_UART3_IPG_GATE],
> - [IMX27_CLK_UART4_IPG_GATE],
> - [IMX27_CLK_UART5_IPG_GATE],
> - [IMX27_CLK_UART6_IPG_GATE],
> - NULL
> -};
> -
>  static void __init _mx27_clocks_init(unsigned long fref)
>  {
>   BUG_ON(!ccm);
> @@ -176,7 +165,7 @@ static void __init _mx27_clocks_init(unsigned long fref)
>  
>   clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
>  
> - imx_register_uart_clocks(uart_clks);
> + imx_register_uart_clocks(7);
>  
>   imx_print_silicon_rev("i.MX27", mx27_revision());
>  }
> diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
> index c1df03665c09..0fe5ac210156 100644
> --- a/drivers/clk/imx/clk-imx35.c
> +++ b/drivers/clk/imx/clk-imx35.c
> @@ -82,14 +82,6 @@ enum mx35_clks {
>  
>  static struct clk *clk[clk_max];
>  
> -static struct clk ** const uart_clks[] __initconst = {
> - [ipg],
> - [

Re: [PATCH V4] clk: imx: Fix reparenting of UARTs not associated with stdout

2021-03-22 Thread Abel Vesa
On 21-03-20 18:00:25, Adam Ford wrote:
> On Sun, Mar 14, 2021 at 4:40 AM Ahmad Fatoum  wrote:
> >
> > On 13.03.21 16:16, Ahmad Fatoum wrote:
> > >> +/* i.MX boards use device trees now.  For build tests without 
> > >> CONFIG_OF, do nothing */
> > >> +#ifdef CONFIG_OF
> > >>  if (imx_keep_uart_clocks) {
> > >>  int i;
> > >>
> > >> -imx_uart_clocks = clks;
> > >> -for (i = 0; imx_uart_clocks[i]; i++)
> > >> -clk_prepare_enable(*imx_uart_clocks[i]);
> > >> +imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), 
> > >> GFP_KERNEL);
> > >> +
> > >> +if (!of_stdout)
> > >> +return;
> > >
> > > Memory leak. Just do if (imx_keep_uart_clocks && of_stdout)
> >
> > Please dismiss. I overlooked that you free it in a later initcall.
> 
> Abel,
> 
> Are you OK with this?  I also have a V5 posted [1] which does what
> Ahmad suggested.
> 

I'm OK with this version. Applied it on my clk/imx branch:
git://git.kernel.org/pub/scm/linux/kernel/git/abelvesa/linux.git

Thanks a lot for all the effort.

> Either of these will fix reparenting issues, but I need this for
> Bluetooth to operate correctly, because both beacon imx8mn and imx8mn
> kits switch the UART parent to an 80MHz clock in order to run at
> 4Mbps.
> 
> thank you,
> 
> adam
> >
> > >>  static int __init imx_clk_disable_uart(void)
> > >>  {
> > >> -if (imx_keep_uart_clocks && imx_uart_clocks) {
> > >> +if (imx_keep_uart_clocks && imx_enabled_uart_clocks) {
> > >>  int i;
> > >>
> > >> -for (i = 0; imx_uart_clocks[i]; i++)
> > >> -clk_disable_unprepare(*imx_uart_clocks[i]);
> > >> +for (i = 0; i < imx_enabled_uart_clocks; i++) {
> > >> +clk_disable_unprepare(imx_uart_clocks[i]);
> > >> +clk_put(imx_uart_clocks[i]);
> > >> +};
> > >> +kfree(imx_uart_clocks);
> > >>  }
> >
> > --
> > Pengutronix e.K.   | |
> > Steuerwalder Str. 21   | http://www.pengutronix.de/  |
> > 31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
> > Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH] clk: imx8mp: Remove the none exist pcie clocks

2021-03-15 Thread Abel Vesa
On 21-03-15 15:39:24, Richard Zhu wrote:
> In the i.MX8MP PCIe design, the PCIe PHY REF clock comes from external
> OSC or internal system PLL. It is configured in the IOMUX_GPR14 register
> directly, and can't be contolled by CCM at all.
> Remove the PCIE PHY clock from clock driver to clean up codes.
> There is only one PCIe in i.MX8MP, remove the none exist second PCIe
> related clocks.
> Remove the none exsits clocks IDs together.
> 

Please resend both patches and add linux-...@vger.kernel.org to cc.

> Signed-off-by: Richard Zhu 
> Reviewed-by: Jason Liu 
> ---
>  drivers/clk/imx/clk-imx8mp.c | 15 ---
>  include/dt-bindings/clock/imx8mp-clock.h |  3 ---
>  2 files changed, 18 deletions(-)
> 
> diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
> index 2f4e1d674e1c..afbeb6bf1909 100644
> --- a/drivers/clk/imx/clk-imx8mp.c
> +++ b/drivers/clk/imx/clk-imx8mp.c
> @@ -152,10 +152,6 @@ static const char * const imx8mp_can2_sels[] = 
> {"osc_24m", "sys_pll2_200m", "sys
>   "sys_pll1_160m", 
> "sys_pll1_800m", "sys_pll3_out",
>   "sys_pll2_250m", 
> "audio_pll2_out", };
>  
> -static const char * const imx8mp_pcie_phy_sels[] = {"osc_24m", 
> "sys_pll2_100m", "sys_pll2_500m",
> - "clk_ext1", "clk_ext2", 
> "clk_ext3",
> - "clk_ext4", 
> "sys_pll1_400m", };
> -
>  static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", 
> "sys_pll2_200m", "sys_pll2_50m",
>   "sys_pll3_out", 
> "sys_pll2_100m", "sys_pll1_80m",
>   "sys_pll1_160m", 
> "sys_pll1_200m", };
> @@ -380,14 +376,6 @@ static const char * const imx8mp_memrepair_sels[] = 
> {"osc_24m", "sys_pll2_100m",
>   "sys_pll1_800m", 
> "sys_pll2_1000m", "sys_pll3_out",
>   "clk_ext3", 
> "audio_pll2_out", };
>  
> -static const char * const imx8mp_pcie2_ctrl_sels[] = {"osc_24m", 
> "sys_pll2_250m", "sys_pll2_200m",
> -   "sys_pll1_266m", 
> "sys_pll1_800m", "sys_pll2_500m",
> -   "sys_pll2_333m", 
> "sys_pll3_out", };
> -
> -static const char * const imx8mp_pcie2_phy_sels[] = {"osc_24m", 
> "sys_pll2_100m", "sys_pll2_500m",
> -  "clk_ext1", "clk_ext2", 
> "clk_ext3",
> -  "clk_ext4", 
> "sys_pll1_400m", };
> -
>  static const char * const imx8mp_media_mipi_test_byte_sels[] = {"osc_24m", 
> "sys_pll2_200m", "sys_pll2_50m",
>   "sys_pll3_out", 
> "sys_pll2_100m",
>   "sys_pll1_80m", 
> "sys_pll1_160m",
> @@ -585,7 +573,6 @@ static int imx8mp_clocks_probe(struct platform_device 
> *pdev)
>   hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", 
> imx8mp_vpu_g2_sels, ccm_base + 0xa180);
>   hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, 
> ccm_base + 0xa200);
>   hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, 
> ccm_base + 0xa280);
> - hws[IMX8MP_CLK_PCIE_PHY] = imx8m_clk_hw_composite("pcie_phy", 
> imx8mp_pcie_phy_sels, ccm_base + 0xa380);
>   hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", 
> imx8mp_pcie_aux_sels, ccm_base + 0xa400);
>   hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, 
> ccm_base + 0xa480);
>   hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, 
> ccm_base + 0xa500);
> @@ -643,8 +630,6 @@ static int imx8mp_clocks_probe(struct platform_device 
> *pdev)
>   hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = 
> imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base 
> + 0xbe80);
>   hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", 
> imx8mp_media_ldb_sels, ccm_base + 0xbf00);
>   hws[IMX8MP_CLK_MEMREPAIR] = 
> imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base 
> + 0xbf80);
> - hws[IMX8MP_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", 
> imx8mp_pcie2_ctrl_sels, ccm_base + 0xc000);
> - hws[IMX8MP_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", 
> imx8mp_pcie2_phy_sels, ccm_base + 0xc080);
>   hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = 
> imx8m_clk_hw_composite("media_mipi_test_byte", 
> imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
>   hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", 
> imx8mp_ecspi3_sels, ccm_base + 0xc180);
>   hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, 
> ccm_base + 0xc200);
> diff --git a/include/dt-bindings/clock/imx8mp-clock.h 

Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-03-10 Thread Abel Vesa
On 21-03-03 10:31:19, Abel Vesa wrote:
> On 21-03-02 13:03:04, Adam Ford wrote:
> > On Mon, Feb 15, 2021 at 7:06 AM Abel Vesa  wrote:
> > >
> > > On 21-02-13 08:44:28, Adam Ford wrote:
> > > > On Wed, Feb 3, 2021 at 3:22 PM Adam Ford  wrote:
> > > > >
> > > > > On Thu, Jan 21, 2021 at 4:24 AM Abel Vesa  wrote:
> > > > > >
> > > > > > On 21-01-21 10:56:17, Sascha Hauer wrote:
> > > > > > > On Wed, Jan 20, 2021 at 06:14:21PM +0200, Abel Vesa wrote:
> > > > > > > > On 21-01-20 16:50:01, Sascha Hauer wrote:
> > > > > > > > > On Wed, Jan 20, 2021 at 05:28:13PM +0200, Abel Vesa wrote:
> > > > > > > > > > On 21-01-20 16:13:05, Sascha Hauer wrote:
> > > > > > > > > > > Hi Abel,
> > > > > > > > > > >
> > > > > > > > > > > On Wed, Jan 20, 2021 at 04:44:54PM +0200, Abel Vesa wrote:
> > > > > > > > > > > > On 21-01-18 08:00:43, Adam Ford wrote:
> > > > > > > > > > > > > On Mon, Jan 18, 2021 at 6:52 AM Abel Vesa 
> > > > > > > > > > > > >  wrote:
> > > > > > > > > >
> > > > > > > > > > ...
> > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > TBH, I'm against the idea of having to call 
> > > > > > > > > > > > > > consumer API from a clock provider driver.
> > > > > > > > > > > > > > I'm still investigating a way of moving the uart 
> > > > > > > > > > > > > > clock control calls in drivers/serial/imx,
> > > > > > > > > > > > > > where they belong.
> > > > > > > > > > > > >
> > > > > > > > > > > > > That makes sense.
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > Just a thought. The uart clock used for console remains 
> > > > > > > > > > > > on from u-boot,
> > > > > > > > > > > > so maybe it's enough to just add the CLK_IGNORE_UNUSED 
> > > > > > > > > > > > flag to all the
> > > > > > > > > > > > uart root clocks and remove the prepare/enable calls 
> > > > > > > > > > > > for uart clocks
> > > > > > > > > > > > for good. I don't really have a way to test it right 
> > > > > > > > > > > > now, but maybe
> > > > > > > > > > > > you could give it a try.
> > > > > > > > > > >
> > > > > > > > > > > That would mean that UART clocks will never be disabled, 
> > > > > > > > > > > regardless of
> > > > > > > > > > > whether they are used for console or not. That doesn't 
> > > > > > > > > > > sound very
> > > > > > > > > > > appealing.
> > > > > > > > > >
> > > > > > > > > > AFAIK, the only uart clock that is enabled by u-boot is the 
> > > > > > > > > > one used for
> > > > > > > > > > the console. Later on, when the serial driver probes, it 
> > > > > > > > > > will enable it itself.
> > > > > > > > > >
> > > > > > > > > > Unless I'm missing something, this is exactly what we need.
> > > > > > > > >
> > > > > > > > > It might enable it, but with CLK_IGNORE_UNUSED the clock 
> > > > > > > > > won't be
> > > > > > > > > disabled again when a port is closed after usage
> > > > > > > >
> > > > > > > > OK, tell me what I'm getting wrong in the following scenario:
> > > > > > > >
> > > > > > > > U-boot leaves the console uart clock enabled. All the other 
> > > > > > > > 

Re: [RFC 00/19] Rework support for i.MX8MQ interconnect with devfreq

2021-03-09 Thread Abel Vesa
On 21-02-25 13:13:17, Martin Kepplinger wrote:
> On 23.02.21 18:20, Abel Vesa wrote:
> > On 21-02-22 17:03:13, Martin Kepplinger wrote:
> > > On 19.02.21 16:59, Abel Vesa wrote:
> > > > This has been on my queue for quite some time now. It is more of a
> > > > proof-of-concept.
> > > > 
> > > > This rework is done with the compatibility of future i.MX platforms in
> > > > mind. For example, the i.MX8MP platform has multiple NoCs. This
> > > > patchsets prepares the imx interconnect and imx devfreq for that too.
> > > > 
> > > > As of now, none of the drivers involved are being used and there is no
> > > > icc consumer on any off the i.MX platforms.
> > > > 
> > > > Basically, the steps taken here are the following:
> > > > 
> > > > 1. Make the dram_apb clock "reparantable" from kernel.
> > > > This is needed in order to keep track of the actual parent of the
> > > > dram_apb clock in the kernel clock hierarchy. Note that the actual
> > > > switch is done EL3 (TF-A).
> > > > 
> > > > 2. Rework the imx-bus so the actual link between the icc and the
> > > > NoCs or the pl301s is not tightly coupled. This allows us to have
> > > > as many NoCs as necessary but also allows as to use the same driver
> > > > for the pl301s. The pl301s have their own clocks too, so we need to
> > > > reduce their rates too.
> > > > 
> > > > 3. Rework the imx8m-ddrc driver. Remove the support for dts defined
> > > > OPPs. The EL3 provides those. So instead of havingi to keep the OPP 
> > > > table in
> > > > both EL3 and kernel in sync, we rely on what the EL3 gives us.
> > > > Also, when the platform suspends, the bus needs to be running at highest
> > > > rate, otherwise there is a chance it might not resume anymore.
> > > > By adding the late system sleep PM ops we can handle that easily.
> > > > 
> > > > 4. Rework the imx interconnect driver to use the fsl,icc-id instead
> > > > of the robust imx_icc_node_adj_desc for linking with the target node.
> > > > By adding the fsl,icc-id property to all the NoC and pl301 dts nodes,
> > > > we can link each icc node to their corresponding NoC, pl301 or dram.
> > > > Basically, when the imx interconnect platform specific driver probes,
> > > > it will take each node defined for that platform and look-up the
> > > > corresponding dts node based on the id and add that as the qos device.
> > > > 
> > > > 5. Added the fec and usdhc as icc consumers. This is just as an example.
> > > > All the other consumers can be added later. Basically, each consumer
> > > > will add a path to their device node and in the driver will have to
> > > > handle that icc path accordingly.
> > > > 
> > > 
> > > thanks for working on this Abel,
> > > 
> > > It looks like the icc path requests don't work for me:
> > > 
> > > when applying this onto v5.11 (without any other workaround in that area,
> > > but some out-of-tree icc-requests like in mxsfb) my rootfs isn't being
> > > mounted anymore. Since you add icc requests to the usdhc driver, there 
> > > could
> > > be something wrong.
> > > 
> > > So I revert 19/19 ("mmc: sdhci-esdhc-imx: Add interconnect support") and
> > > then my imx8mq (Librem 5) rootfs system boots, but all frequencies stay at
> > > the minimum (despite the icc request like this:
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.puri.sm%2Fmartin.kepplinger%2Flinux-next%2F-%2Fcommit%2F1692de27d1475c53574dd7359c68ba613e0fea10data=04%7C01%7Cabel.vesa%40nxp.com%7C9e5a3fe7a3af4aabb84f08d8d986c042%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637498520072719555%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=9ItFarG22Tr%2Bj5MPmZU5xnMc%2B1Sx0o3563L5gdceIi4%3Dreserved=0
> > > so I can't use the display).
> > > 
> > > What could be missing? As I said I'm trying on top of v5.11, (at least I
> > > have the NOC node described:
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.puri.sm%2Fmartin.kepplinger%2Flinux-next%2F-%2Fcommit%2F1d74a24c9944d1bf618abdd57d24101368cc8df0data=04%7C01%7Cabel.vesa%40nxp.com%7C9e5a3fe7a3af4aabb84f08d8d986c042%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637498520072719555%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2lu

[PATCH] clk: Call clk_core_enable_lock variant when lock is needed

2021-03-07 Thread Abel Vesa
Instead of locking explicitly every time, call the clk_core_enable_lock
variant.

Signed-off-by: Abel Vesa 
---
 drivers/clk/clk.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 5052541..fd37773 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2078,12 +2078,8 @@ static void clk_change_rate(struct clk_core *core)
return;
 
if (core->flags & CLK_SET_RATE_UNGATE) {
-   unsigned long flags;
-
clk_core_prepare(core);
-   flags = clk_enable_lock();
-   clk_core_enable(core);
-   clk_enable_unlock(flags);
+   clk_core_enable_lock(core);
}
 
if (core->new_parent && core->new_parent != core->parent) {
@@ -3564,8 +3560,6 @@ static int __clk_core_init(struct clk_core *core)
 * reparenting clocks
 */
if (core->flags & CLK_IS_CRITICAL) {
-   unsigned long flags;
-
ret = clk_core_prepare(core);
if (ret) {
pr_warn("%s: critical clk '%s' failed to prepare\n",
@@ -3573,9 +3567,7 @@ static int __clk_core_init(struct clk_core *core)
goto out;
}
 
-   flags = clk_enable_lock();
-   ret = clk_core_enable(core);
-   clk_enable_unlock(flags);
+   ret = clk_core_enable_lock(core);
if (ret) {
pr_warn("%s: critical clk '%s' failed to enable\n",
   __func__, core->name);
-- 
2.7.4



Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-03-03 Thread Abel Vesa
On 21-03-02 13:03:04, Adam Ford wrote:
> On Mon, Feb 15, 2021 at 7:06 AM Abel Vesa  wrote:
> >
> > On 21-02-13 08:44:28, Adam Ford wrote:
> > > On Wed, Feb 3, 2021 at 3:22 PM Adam Ford  wrote:
> > > >
> > > > On Thu, Jan 21, 2021 at 4:24 AM Abel Vesa  wrote:
> > > > >
> > > > > On 21-01-21 10:56:17, Sascha Hauer wrote:
> > > > > > On Wed, Jan 20, 2021 at 06:14:21PM +0200, Abel Vesa wrote:
> > > > > > > On 21-01-20 16:50:01, Sascha Hauer wrote:
> > > > > > > > On Wed, Jan 20, 2021 at 05:28:13PM +0200, Abel Vesa wrote:
> > > > > > > > > On 21-01-20 16:13:05, Sascha Hauer wrote:
> > > > > > > > > > Hi Abel,
> > > > > > > > > >
> > > > > > > > > > On Wed, Jan 20, 2021 at 04:44:54PM +0200, Abel Vesa wrote:
> > > > > > > > > > > On 21-01-18 08:00:43, Adam Ford wrote:
> > > > > > > > > > > > On Mon, Jan 18, 2021 at 6:52 AM Abel Vesa 
> > > > > > > > > > > >  wrote:
> > > > > > > > >
> > > > > > > > > ...
> > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > TBH, I'm against the idea of having to call consumer 
> > > > > > > > > > > > > API from a clock provider driver.
> > > > > > > > > > > > > I'm still investigating a way of moving the uart 
> > > > > > > > > > > > > clock control calls in drivers/serial/imx,
> > > > > > > > > > > > > where they belong.
> > > > > > > > > > > >
> > > > > > > > > > > > That makes sense.
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > Just a thought. The uart clock used for console remains 
> > > > > > > > > > > on from u-boot,
> > > > > > > > > > > so maybe it's enough to just add the CLK_IGNORE_UNUSED 
> > > > > > > > > > > flag to all the
> > > > > > > > > > > uart root clocks and remove the prepare/enable calls for 
> > > > > > > > > > > uart clocks
> > > > > > > > > > > for good. I don't really have a way to test it right now, 
> > > > > > > > > > > but maybe
> > > > > > > > > > > you could give it a try.
> > > > > > > > > >
> > > > > > > > > > That would mean that UART clocks will never be disabled, 
> > > > > > > > > > regardless of
> > > > > > > > > > whether they are used for console or not. That doesn't 
> > > > > > > > > > sound very
> > > > > > > > > > appealing.
> > > > > > > > >
> > > > > > > > > AFAIK, the only uart clock that is enabled by u-boot is the 
> > > > > > > > > one used for
> > > > > > > > > the console. Later on, when the serial driver probes, it will 
> > > > > > > > > enable it itself.
> > > > > > > > >
> > > > > > > > > Unless I'm missing something, this is exactly what we need.
> > > > > > > >
> > > > > > > > It might enable it, but with CLK_IGNORE_UNUSED the clock won't 
> > > > > > > > be
> > > > > > > > disabled again when a port is closed after usage
> > > > > > >
> > > > > > > OK, tell me what I'm getting wrong in the following scenario:
> > > > > > >
> > > > > > > U-boot leaves the console uart clock enabled. All the other ones 
> > > > > > > are disabled.
> > > > > > >
> > > > > > > Kernel i.MX clk driver registers the uart clocks with flag 
> > > > > > > CLK_IGNORE_UNUSED.
> > > > > >
> > > > > > I was wrong at that point. I originally thought the kernel will 
> > > > > > nev

Re: [PATCH v5 00/14] Add BLK_CTL support for i.MX8MP

2021-03-03 Thread Abel Vesa
On 20-11-03 13:18:12, Abel Vesa wrote:
> The BLK_CTL according to HW design is basically the wrapper of the entire
> function specific group of IPs and holds GPRs that usually cannot be placed
> into one specific IP from that group. Some of these GPRs are used to control
> some clocks, other some resets, others some very specific function that does
> not fit into clocks or resets. Since the clocks are registered using the i.MX
> clock subsystem API, the driver is placed into the clock subsystem, but it
> also registers the resets. For the other functionalities that other GPRs might
> have, the syscon is used.
> 

This approach seems to be introducing a possible ABBA deadlock due to
the core clock and genpd locking. Here is a backtrace I got from Pete
Zhang (he reported the issue on the internal mailing list):

[   11.667711][  T108] -> #1 (>mlock){+.+.}-{3:3}:
[   11.675041][  T108]__lock_acquire+0xae4/0xef8
[   11.680093][  T108]lock_acquire+0xfc/0x2f8
[   11.684888][  T108]__mutex_lock+0x90/0x870
[   11.689685][  T108]mutex_lock_nested+0x44/0x50
[   11.694826][  T108]genpd_lock_mtx+0x18/0x24
[   11.699706][  T108]genpd_runtime_resume+0x90/0x214 (hold 
genpd->mlock)
[   11.705194][  T108]__rpm_callback+0x80/0x2c0
[   11.710160][  T108]rpm_resume+0x468/0x650
[   11.714866][  T108]__pm_runtime_resume+0x60/0x88
[   11.720180][  T108]clk_pm_runtime_get+0x28/0x9c
[   11.725410][  T108]clk_disable_unused_subtree+0x8c/0x144
[   11.731420][  T108]clk_disable_unused_subtree+0x124/0x144
[   11.737518][  T108]clk_disable_unused+0xa4/0x11c (hold prepare_lock)
[   11.742833][  T108]do_one_initcall+0x98/0x178
[   11.747888][  T108]do_initcall_level+0x9c/0xb8
[   11.753028][  T108]do_initcalls+0x54/0x94
[   11.757736][  T108]do_basic_setup+0x24/0x30
[   11.762614][  T108]kernel_init_freeable+0x70/0xa4
[   11.768014][  T108]kernel_init+0x14/0x18c
[   11.772722][  T108]ret_from_fork+0x10/0x18

[   11.777512][  T108] -> #0 (prepare_lock){+.+.}-{3:3}:
[   11.784749][  T108]check_noncircular+0x134/0x13c
[   11.790064][  T108]validate_chain+0x590/0x2a04
[   11.795204][  T108]__lock_acquire+0xae4/0xef8
[   11.800258][  T108]lock_acquire+0xfc/0x2f8
[   11.805050][  T108]__mutex_lock+0x90/0x870
[   11.809841][  T108]mutex_lock_nested+0x44/0x50
[   11.814983][  T108]clk_unprepare+0x5c/0x100 ((hold prepare_lock))
[   11.819864][  T108]imx8m_pd_power_off+0xac/0x110
[   11.825179][  T108]genpd_power_off+0x1b4/0x2dc
[   11.830318][  T108]genpd_power_off_work_fn+0x38/0x58 (hold 
genpd->mlock)
[   11.835981][  T108]process_one_work+0x270/0x444
[   11.841208][  T108]worker_thread+0x280/0x4e4
[   11.846176][  T108]kthread+0x13c/0x14
[   11.850621][  T108]ret_from_fork+0x10/0x18

Now, this has been reproduced only on the NXP internal tree, but I think
it is pretty obvious this could happen in upstream too, with this
patchset applied.

First, my thought was to change the prepare_lock/enable_lock in clock
core, from a global approach to a per clock basis. But that doesn't
actually fix the issue.

The usecase seen above is due to clk_disable_unused, but the same could
happen when a clock consumer calls prepare/unprepare on a clock.

I guess the conclusion is that the current state of the clock core and
genpd implementation does not support a usecase where a clock controller
has a PD which in turn uses another clock (from another clock controller).

Jacky, Pete, did I miss anything here ?

> Changes since v4:
>  * added back the bus_blk_clk in the imx8mp blk_ctl driver (media_blk_ctl)
>  * added the R-b tag from Rob to the documentation patch
> 
> Abel Vesa (14):
>   dt-bindings: clocks: imx8mp: Rename audiomix ids clocks to
> audio_blk_ctl
>   dt-bindings: reset: imx8mp: Add audio blk_ctl reset IDs
>   dt-bindings: clock: imx8mp: Add ids for the audio shared gate
>   dt-bindings: clock: imx8mp: Add media blk_ctl clock IDs
>   dt-bindings: reset: imx8mp: Add media blk_ctl reset IDs
>   dt-bindings: clock: imx8mp: Add hdmi blk_ctl clock IDs
>   dt-bindings: reset: imx8mp: Add hdmi blk_ctl reset IDs
>   clk: imx8mp: Add audio shared gate
>   Documentation: bindings: clk: Add bindings for i.MX BLK_CTL
>   clk: imx: Add generic blk-ctl driver
>   clk: imx: Add blk-ctl driver for i.MX8MP
>   arm64: dts: imx8mp: Add audio_blk_ctl node
>   arm64: dts: imx8mp: Add media_blk_ctl node
>   arm64: dts: imx8mp: Add hdmi_blk_ctl node
> 
>  .../devicetree/bindings/clock/fsl,imx-blk-ctl.yaml |  60 
>  arch/arm64/boot/dts/freescale/imx8mp.dtsi  |  37 +++
>  drivers/clk/imx/Makefile   |   2 +-
>  drivers/clk/imx/clk-blk-

Re: [RFC 00/19] Rework support for i.MX8MQ interconnect with devfreq

2021-02-23 Thread Abel Vesa
On 21-02-22 17:03:13, Martin Kepplinger wrote:
> On 19.02.21 16:59, Abel Vesa wrote:
> > This has been on my queue for quite some time now. It is more of a
> > proof-of-concept.
> > 
> > This rework is done with the compatibility of future i.MX platforms in
> > mind. For example, the i.MX8MP platform has multiple NoCs. This
> > patchsets prepares the imx interconnect and imx devfreq for that too.
> > 
> > As of now, none of the drivers involved are being used and there is no
> > icc consumer on any off the i.MX platforms.
> > 
> > Basically, the steps taken here are the following:
> > 
> > 1. Make the dram_apb clock "reparantable" from kernel.
> > This is needed in order to keep track of the actual parent of the
> > dram_apb clock in the kernel clock hierarchy. Note that the actual
> > switch is done EL3 (TF-A).
> > 
> > 2. Rework the imx-bus so the actual link between the icc and the
> > NoCs or the pl301s is not tightly coupled. This allows us to have
> > as many NoCs as necessary but also allows as to use the same driver
> > for the pl301s. The pl301s have their own clocks too, so we need to
> > reduce their rates too.
> > 
> > 3. Rework the imx8m-ddrc driver. Remove the support for dts defined
> > OPPs. The EL3 provides those. So instead of havingi to keep the OPP table in
> > both EL3 and kernel in sync, we rely on what the EL3 gives us.
> > Also, when the platform suspends, the bus needs to be running at highest
> > rate, otherwise there is a chance it might not resume anymore.
> > By adding the late system sleep PM ops we can handle that easily.
> > 
> > 4. Rework the imx interconnect driver to use the fsl,icc-id instead
> > of the robust imx_icc_node_adj_desc for linking with the target node.
> > By adding the fsl,icc-id property to all the NoC and pl301 dts nodes,
> > we can link each icc node to their corresponding NoC, pl301 or dram.
> > Basically, when the imx interconnect platform specific driver probes,
> > it will take each node defined for that platform and look-up the
> > corresponding dts node based on the id and add that as the qos device.
> > 
> > 5. Added the fec and usdhc as icc consumers. This is just as an example.
> > All the other consumers can be added later. Basically, each consumer
> > will add a path to their device node and in the driver will have to
> > handle that icc path accordingly.
> > 
> 
> thanks for working on this Abel,
> 
> It looks like the icc path requests don't work for me:
> 
> when applying this onto v5.11 (without any other workaround in that area,
> but some out-of-tree icc-requests like in mxsfb) my rootfs isn't being
> mounted anymore. Since you add icc requests to the usdhc driver, there could
> be something wrong.
> 
> So I revert 19/19 ("mmc: sdhci-esdhc-imx: Add interconnect support") and
> then my imx8mq (Librem 5) rootfs system boots, but all frequencies stay at
> the minimum (despite the icc request like this:
> https://source.puri.sm/martin.kepplinger/linux-next/-/commit/1692de27d1475c53574dd7359c68ba613e0fea10
>   
> so I can't use the display).
> 
> What could be missing? As I said I'm trying on top of v5.11, (at least I
> have the NOC node described:
> https://source.puri.sm/martin.kepplinger/linux-next/-/commit/1d74a24c9944d1bf618abdd57d24101368cc8df0
>  
> and (with the revert from 
> https://lore.kernel.org/linux-arm-kernel/20210104120512.gmi2zjz7dzhjussp@fsr-ub1664-175/
> devfreq works without your patchset ) Is there anything I'm missing that is
> not yet merged in v5.11?
> 
> Can I test anything else that would help?
> 

Sorry about this, I messed up the usdhc change.
I tested mostly with nfs rootfs.

I'll just paste here the things that are missing in order for the USHCs to work.
I'll fold them in the next version of this patch set.

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 43760316052f..90398408b55e 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1637,6 +1637,25 @@ opp-133M {
};
};
 
+   pl301_per_m: pl301@9 {
+   compatible = "fsl,imx8m-nic";
+   clocks = < IMX8MQ_CLK_NAND_USDHC_BUS>;
+   operating-points-v2 = <_per_m_opp_table>;
+   #interconnect-cells = <0>;
+   fsl,icc-id = ;
+
+   pl301_per_m_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-25M {
+   

Re: [RFC 14/19] arm64: dts: imx8mq: Add fsl,icc-id to noc node

2021-02-19 Thread Abel Vesa
On 21-02-19 18:00:11, Abel Vesa wrote:
> The fsl,icc-id property here is used to link the icc node
> registered by the imx8mq interconnect driver with the noc
> device. Remove the fsl,ddrc property since it will not be used
> anymore.
> 
> Signed-off-by: Abel Vesa 
> ---
>  arch/arm64/boot/dts/freescale/imx8mq.dtsi |   4 ++--
>  scripts/dtc/fdtoverlay| Bin 0 -> 61280 bytes
>  2 files changed, 2 insertions(+), 2 deletions(-)
>  create mode 100755 scripts/dtc/fdtoverlay
> 
> diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi 
> b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> index ac229a8288cd..e30e948648e9 100644
> --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
> @@ -1195,11 +1195,11 @@ fec1: ethernet@30be {
>   };
>   };
>  
> - noc: interconnect@3270 {
> + noc: noc@3270 {
>   compatible = "fsl,imx8mq-noc", "fsl,imx8m-noc";
>   reg = <0x3270 0x10>;
>   clocks = < IMX8MQ_CLK_NOC>;
> - fsl,ddrc = <>;
> + fsl,icc-id = ;
>   #interconnect-cells = <1>;
>   operating-points-v2 = <_opp_table>;
>  
> diff --git a/scripts/dtc/fdtoverlay b/scripts/dtc/fdtoverlay
> new file mode 100755
> index 
> ..a2b2746882bf8ceac8d0624a90fc36386cf6ac62

Agh, "git add ." mistake. Will remove it in the next version.

> GIT binary patch
> literal 61280
> zcmeEv4_uU0*8ejw>LA23niX4CQ(-}-LRm>_%_9RmlY^3CT55=ZLLsm)2yRxm1Lm{i
> z6x+7D?VopZ`?GKD+wQts>!NE4qJUP0re<17rS*)HO8?NxoZt7{d!J#zq22fW{eJKJ
> z?_+~=Nq?z!ild(OG%{&{8|$#7*xnM{)LiIQ%YC}+FG~_iik0lr
> z71HI>U_i|HXJ;jp@+TuLj^YJIY7uzRNU7cnqWpy@J93n_QzDIIe|uAdLrSS$@5e44
> zdAcBuXN^>{@;ucWM2{jbS?!cV-p-P}_p(GXQUfp4UIj0gDmcE8K9$VjMjBp^WMlme
> zFSq`Y*E7;M5&%96L~7I{aZo**sAm)PjI>h-!blByl1%8|Rw2)=QFi1gZ>L0Zu)n=2
> z;nFAPsJoD!yB=g~dTq+baBjMS)i7wQq8|Ln`wY?EKyv98{WDULmBy8pEWBm>
> zxYEKgr6pz6wPR{0+%o2t@nfsX$KJ^LJpzmnt69@#NiV%v5MK~;Q|jaQJT_&1ad5{&
> zty>-@zKI8-M>zB$d?7COd=2tc|Mk1WUxfQTUg9`Rb8rpLs{#xb@WVm!CN`
> z9H0R|m!Ntigv(JQ68yda;1>-5r{Ri3=dA(YIRn7k27n(K0B#+iUl$C3KYjrC>;d4b
> z2Y|mb0DQ~<@bUrRX9j?~2Y@>VfXf5OAq#LD>h%9i0U*+NJvjjU*#Y3Bhmq(627n(P
> z03JU8|GydlALtR=-8}^8w($9{}C}_%JC!vi;ePCrL8=+Gacxd_g}r*(kx21l;gT
> zO#*K3hc6Y?mbj(z3U^6ap;YCrtSl(5q_nJ{VwqG??Jg+Juaqi_@=Ht03#27QOQ<+6
> zFTbj)sM4LcD8HnXklp2_QUOOnuC%C(Fsq8(z$~h)EGy4L<$QNZc^OeEWMr09NK32A
> zDk@9L+>1b>u)NyMniZ9)bw;?lR9eC*=j9c+msJ$yEhK8haen1us)-h)#YJuaP*Ap5
> zT2xb6;x3X3O3SN?fCgqjh}Z^COUjoPQ5JQ|sUL8j1$kAV zQ7L)STcj+Pb4q>LJ*AEhJ>EF>W{_IEq`XX!%7d(<{^|b+H#!2gIRpba_}^%0
> zB$UmVFD@)8fom~K*9zE^KmHkpK3Yl<`RYqcVu zL*FPiAYX5M480;a*_`n)^orou8bG9meiEGK3*(cp*3KS>;ICkj z!{mQb!r+FkQ^|xdIJIqj>|t<{h4E3t;KY;h$q9oSwnt@i!r%~e=(8XUJ~RZCq~b7m
> zY#6*E3@$=6R$3bd$3TZZbz$)M5LA*@g~8=8cw-pc&>bp%Dhxg>41Y}+{K7E!3t@1I
> zDU8qBFgVT0#-}L^eu)7@+8hQ?2!nTo!M_& z7@zJi_!R~a>FF@|m0@s6_)pRiTNvCD2EQr{ZViK99R@%DcwPeMCGfvj0-wuQe64yu
> zv8dib{--5LZD@8!1v^#GR!b{mI(YL300&1M!C(1GJDwlGP@bkXe<#cD
> zraVn){$`fnL3x_W{A*c$3*~7F^RHp~4V0&;%iqZIf1x~0S^hef|2^f&4f!ir{u#>C
> z6y;yQ^1q}!O-=qBmVbisG$r}%EdL|Q(^TY7Vfi0Yo~9tbjpctpd766sR+g`%JWV-%
> ziRJI7JWVzJ?y~@lT1a`CV*Fh!e=p@}YVmin{0zzur+hQZ-${9zV*G1aehTGjYVogO
> z`P(Q@Q;NTl zJWU<`6qb*oJWUyX8_R! zW~thjGqrD^J#*A{M z-Ja97nzw?9+icZ#rdREQ4xk-UqrgVeGw9=Q0Z=s%4*Y)6Soz9@N@af
> zI?87^9Fgm-P$$*194yH7?|{BqaFL5D`&@ga zRi8W2?$SQiXWb=9POTm4FV`;x1+QvWy}5~YdAru3rgh4X-oVIyvxzuVTRx7~FGR11
> zI~%L>LlpbcgQ^!zxx8*bTe_mDc!E=VJzM)y^_7||)Gw!ZQX;jg>L27#lY?3H%fO4n
> zYe$=|L{*VH99pxQ)*(N74d71LqSMo6ai)Dz-9mz9;hEyiGG}XN8N0Thl9a#%
> zAs6c5OfXBGQ_m2qCv`ie9uP38Ui?)jqJmt%A6THoLBzl6jcXy9B@s6^)jP7q`=D8V
> zQw!>OPykii##n9yYtr|{z2gQaEucjVppQ&0Kaj zhqhan7`YRut$%q3wBq!)a)SdVMy%LfzO|$eE)7itezV9Jf301A@fHk$ck(m8mZVLm
> z-FE26megkbC%lu~);B@o3cTre;*lt#C$7W^s%dP2+l6(9;9E7a;Ik-
> z z3;2iyAO0%z!liw*xfrFX&8~ugp3As!Ct6dRQ;%=123%JFY9!7Qv=f_u$mopFQ=3)K
> zHj_RIWzMwY)m{F3NT}WsiD+ak7U!Fuq^iF|G4HAWDl{d^8>ze*5&;|azzDocqP_HH
> z5*LiarJdDZoi0g=ww2UeCk2L%TS575s`(jXmdPvdjM8L>75AEQYH-s6ShPNA2Bdol
> z{`5y+#hWiB?h;T8q9!8R$k-91a`J07D*E5Pf{dO;`_P)rf9K6!n8_-={!7x?4_G%-
> zn?=39p`O1A_>mi(M2$Xsmn3ceJ*U;4F%W;rgjx$dq!Z_#PC8^o{1n)Z zf$BNZos;WqZ*IQdE~)J;IV@>U8IF1JqGz6xq%Rr?zqQw0H8#-#Q=LqI-51j41e;=G
> zHWMJc_X{*s
> zeIY#bQT+!{khVb&0%DrqdQN+UANWx(4{$4ThrOqLNOh6-5^a~feZ|+E7o0urzHY@=
> z!%d%!tG>fKJF#K6d)j1-#v>a}gSMQtC9K2V*(2l~p07 zB*>YrsI@vf z72c?*^fgubx=$s;f2_EJx+6Cn0da#@dF4)O>g!?ahY>U@LC)MEccit*KU|0WdK)V=
> zNN!g>?}Lw)Bqk}XO

[RFC 14/19] arm64: dts: imx8mq: Add fsl,icc-id to noc node

2021-02-19 Thread Abel Vesa
The fsl,icc-id property here is used to link the icc node
registered by the imx8mq interconnect driver with the noc
device. Remove the fsl,ddrc property since it will not be used
anymore.

Signed-off-by: Abel Vesa 
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi |   4 ++--
 scripts/dtc/fdtoverlay| Bin 0 -> 61280 bytes
 2 files changed, 2 insertions(+), 2 deletions(-)
 create mode 100755 scripts/dtc/fdtoverlay

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index ac229a8288cd..e30e948648e9 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1195,11 +1195,11 @@ fec1: ethernet@30be {
};
};
 
-   noc: interconnect@3270 {
+   noc: noc@3270 {
compatible = "fsl,imx8mq-noc", "fsl,imx8m-noc";
reg = <0x3270 0x10>;
clocks = < IMX8MQ_CLK_NOC>;
-   fsl,ddrc = <>;
+   fsl,icc-id = ;
#interconnect-cells = <1>;
operating-points-v2 = <_opp_table>;
 
diff --git a/scripts/dtc/fdtoverlay b/scripts/dtc/fdtoverlay
new file mode 100755
index 
..a2b2746882bf8ceac8d0624a90fc36386cf6ac62
GIT binary patch
literal 61280
zcmeEv4_uU0*8ejw>LA23niX4CQ(-}-LRm>_%_9RmlY^3CT55=ZLLsm)2yRxm1Lm{i
z6x+7D?VopZ`?GKD+wQts>!NE4qJUP0re<17rS*)HO8?NxoZt7{d!J#zq22fW{eJKJ
z?_+~=Nq?z!ild(OG%{&{8|$#7*xnM{)LiIQ%YC}+FG~_iik0lr
z71HI>U_i|HXJ;jp@+TuLj^YJIY7uzRNU7cnqWpy@J93n_QzDIIe|uAdLrSS$@5e44
zdAcBuXN^>{@;ucWM2{jbS?!cV-p-P}_p(GXQUfp4UIj0gDmcE8K9$VjMjBp^WMlme
zFSq`Y*E7;M5&%96L~7I{aZo**sAm)PjI>h-!blByl1%8|Rw2)=QFi1gZ>L0Zu)n=2
z;nFAPsJoD!yB=g~dTq+baBjMS)i7wQq8|Ln`wY?EKyv98{WDULmBy8pEWBm>
zxYEKgr6pz6wPR{0+%o2t@nfsX$KJ^LJpzmnt69@#NiV%v5MK~;Q|jaQJT_&1ad5{&
zty>-@zKI8-M>zB$d?7COd=2tc|Mk1WUxfQTUg9`Rb8rpLs{#xb@WVm!CN`
z9H0R|m!Ntigv(JQ68yda;1>-5r{Ri3=dA(YIRn7k27n(K0B#+iUl$C3KYjrC>;d4b
z2Y|mb0DQ~<@bUrRX9j?~2Y@>VfXf5OAq#LD>h%9i0U*+NJvjjU*#Y3Bhmq(627n(P
z03JU8|GydlALtR=-8}^8w($9{}C}_%JC!vi;ePCrL8=+Gacxd_g}r*(kx21l;gT
zO#*K3hc6Y?mbj(z3U^6ap;YCrtSl(5q_nJ{VwqG??Jg+Juaqi_@=Ht03#27QOQ<+6
zFTbj)sM4LcD8HnXklp2_QUOOnuC%C(Fsq8(z$~h)EGy4L<$QNZc^OeEWMr09NK32A
zDk@9L+>1b>u)NyMniZ9)bw;?lR9eC*=j9c+msJ$yEhK8haen1us)-h)#YJuaP*Ap5
zT2xb6;x3X3O3SN?fCgqjh}Z^COUjoPQ5JQ|sUL8j1$kAVLJ*AEhJ>EF>W{_IEq`XX!%7d(<{^|b+H#!2gIRpba_}^%0
zB$UmVFD@)8fom~K*9zE^KmHkpK3Yl<`RYqcVu;ICkj|t<{h4E3t;KY;h$q9oSwnt@i!r%~e=(8XUJ~RZCq~b7m
zY#6*E3@$=6R$3bd$3TZZbz$)M5LA*@g~8=8cw-pc&>bp%Dhxg>41Y}+{K7E!3t@1I
zDU8qBFgVT0#-}L^eu)7@+8hQ?2!nTo!M_&FF@|m0@s6_)pRiTNvCD2EQr{ZViK99R@%DcwPeMCGfvj0-wuQe64yu
zv8dib{--5LZD@8!1v^#GR!b{mI(YL300&1M!C(1GJDwlGP@bkXe<#cD
zraVn){$`fnL3x_W{A*c$3*~7F^RHp~4V0&;%iqZIf1x~0S^hef|2^f&4f!ir{u#>C
z6y;yQ^1q}!O-=qBmVbisG$r}%EdL|Q(^TY7Vfi0Yo~9tbjpctpd766sR+g`%JWV-%
ziRJI7JWVzJ?y~@lT1a`CV*Fh!e=p@}YVmin{0zzur+hQZ-${9zV*G1aehTGjYVogO
z`P(Q@Q;NTlLlpbcgQ^!zxx8*bTe_mDc!E=VJzM)y^_7||)Gw!ZQX;jg>L27#lY?3H%fO4n
zYe$=|L{*VH99pxQ)*(N74d71LqSMo6ai)Dz-9mz9;hEyiGG}XN8N0Thl9a#%
zAs6c5OfXBGQ_m2qCv`ie9uP38Ui?)jqJmt%A6THoLBzl6jcXy9B@s6^)jP7q`=D8V
zQw!>OPykii##n9yYtr|{z2gQaEucjVppQ&0Kajze*5&;|azzDocqP_HH
z5*LiarJdDZoi0g=ww2UeCk2L%TS575s`(jXmdPvdjM8L>75AEQYH-s6ShPNA2Bdol
z{`5y+#hWiB?h;T8q9!8R$k-91a`J07D*E5Pf{dO;`_P)rf9K6!n8_-={!7x?4_G%-
zn?=39p`O1A_>mi(M2$Xsmn3ceJ*U;4F%W;rgjx$dq!Z_#PC8^o{1n)ZU8IF1JqGz6xq%Rr?zqQw0H8#-#Q=LqI-51j41e;=G
zHWMJc_X{*s
zeIY#bQT+!{khVb&0%DrqdQN+UANWx(4{$4ThrOqLNOh6-5^a~feZ|+E7o0urzHY@=
z!%d%!tG>fKJF#K6d)j1-#v>a}gSMQtC9K2V*(2l~p07YrsI@vfg!?ahY>U@LC)MEccit*KU|0WdK)V=
zNN!g>?}Lw)Bqk}XO-pdcL;SOtRPaxUcihj`L2p$vc#^=hx0`mzPqfJEwj*cBNZsDB-94mH
zSx+){XdOa+5I+YI5nbL9R%Z_?ycpQY<*ckHp$FQO^(64XCZqq}EQ|IjCTY3D)S}2w
zG=@+JrRM6*v?OU-rO=_BOrp0BJ+FED*p`91ISM093Hja4n^!Hi?-
zR!yhbc%?S?9gkT~?Je!g_9)_d1Lj*v{}G-rW4H^wlEas6R@$S#1VqucXj@v2B`7T)
zBq%Yv<#l^nbW6(z)=^Rr#u>9)iP@rfzK*FG>(Dw8CRi>O~4%gbI^5YJ2#N4
zS3E5y{aW5e_4~>OiUjAQl8_hUK|7(F1s8{aAC2Pq3WhO5i$y2uP(xyPps61uw+MFs
z>XpD^ON&1N9LDUB*S$^*zRwwq+2PBMi|K>{Iec*@(mlCmkmvM}8mmLwk$f!hSjc~P
z-XG!)piOh`EZA@uq$UV{C(-vKQh3d;qH0xW@tmm|;TE=`}X5qK67fdI?z=;sO
zf$G<@`qBTeK8xIDs@hv1WHo|`h8|h-KnTQ&#

[RFC 19/19] mmc: sdhci-esdhc-imx: Add interconnect support

2021-02-19 Thread Abel Vesa
On probe, if the dts node contains a valid icc path, then look for the
fsl,icc-rate property and get the rate. Also set the icc bandwidth
for that path to the nominal rate needed for sdhc to function right.
Then enable and disable the path every time the sdhc is used or not.
This will result in reducing the clock speeds along the icc path
for each pl301 and NoC, but still meet the requirements for all the
other icc consumers.

Signed-off-by: Abel Vesa 
---
 drivers/mmc/host/sdhci-esdhc-imx.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c 
b/drivers/mmc/host/sdhci-esdhc-imx.c
index a20459744d21..65c5caf82e0c 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -9,6 +9,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -287,6 +288,9 @@ struct pltfm_imx_data {
struct clk *clk_ahb;
struct clk *clk_per;
unsigned int actual_clock;
+   struct icc_path *bus_path;
+   unsigned int bus_rate;
+
enum {
NO_CMD_PENDING,  /* no multiblock command pending */
MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
@@ -1539,6 +1543,18 @@ static int sdhci_esdhc_imx_probe(struct platform_device 
*pdev)
if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
cpu_latency_qos_add_request(_data->pm_qos_req, 0);
 
+   imx_data->bus_path = devm_of_icc_get(>dev, "path");
+   if (IS_ERR(imx_data->bus_path)) {
+   return PTR_ERR(imx_data->bus_path);
+   } else if (imx_data->bus_path) {
+   if (of_property_read_u32(pdev->dev.of_node, "fsl,icc-rate", 
_data->bus_rate)) {
+   dev_err(>dev, "icc-rate missing\n");
+   return -EINVAL;
+   }
+
+   err = icc_set_bw(imx_data->bus_path, 0, imx_data->bus_rate);
+   }
+
imx_data->clk_ipg = devm_clk_get(>dev, "ipg");
if (IS_ERR(imx_data->clk_ipg)) {
err = PTR_ERR(imx_data->clk_ipg);
@@ -1720,14 +1736,20 @@ static int sdhci_esdhc_suspend(struct device *dev)
 
ret = mmc_gpio_set_cd_wake(host->mmc, true);
 
+   icc_disable(imx_data->bus_path);
+
return ret;
 }
 
 static int sdhci_esdhc_resume(struct device *dev)
 {
struct sdhci_host *host = dev_get_drvdata(dev);
+   struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+   struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
int ret;
 
+   icc_enable(imx_data->bus_path);
+
ret = pinctrl_pm_select_default_state(dev);
if (ret)
return ret;
@@ -1779,6 +1801,8 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
cpu_latency_qos_remove_request(_data->pm_qos_req);
 
+   icc_disable(imx_data->bus_path);
+
return ret;
 }
 
@@ -1789,6 +1813,8 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
int err;
 
+   icc_enable(imx_data->bus_path);
+
if (imx_data->socdata->flags & ESDHC_FLAG_PMQOS)
cpu_latency_qos_add_request(_data->pm_qos_req, 0);
 
-- 
2.29.2



[RFC 16/19] arm64: dts: imx8mq: Add the interconnect node

2021-02-19 Thread Abel Vesa
The icc node will be probed by the imx8mq interconnect driver.
Will look-up the NoC and all the pl301s (identified by fsl,icc-id property)
and will assign the corresponding icc node to each one of them.
Then, it will register the icc provider.

Signed-off-by: Abel Vesa 
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 5f9ffa465d6c..6a64b4bf31f5 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1627,5 +1627,10 @@ opp-133M {
};
};
};
+
+   icc: interconnect@0 {
+   compatible = "fsl,imx8mq-icc", "fsl,imx8m-icc";
+   #interconnect-cells = <1>;
+   };
};
 };
-- 
2.29.2



[RFC 18/19] net: ethernet: fec_main: Add interconnect support

2021-02-19 Thread Abel Vesa
On probe, if the dts node contains a valid icc path, then look for the
fsl,icc-rate property and get the rate. Also set the icc bandwidth
for that path to the nominal rate needed for fec to function right.
Then enable and disable the path every time the fec is used or not.
This will result in reducing the clock speeds along the icc path
for each pl301 and NoC, but still meet the requirements for all the
other icc consumers.

Signed-off-by: Abel Vesa 
---
 drivers/net/ethernet/freescale/fec.h  |  3 +++
 drivers/net/ethernet/freescale/fec_main.c | 19 +++
 2 files changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/freescale/fec.h 
b/drivers/net/ethernet/freescale/fec.h
index 0602d5d5d2ee..7611492cb800 100644
--- a/drivers/net/ethernet/freescale/fec.h
+++ b/drivers/net/ethernet/freescale/fec.h
@@ -529,6 +529,9 @@ struct fec_enet_private {
unsigned int num_tx_queues;
unsigned int num_rx_queues;
 
+   struct icc_path *bus_path;
+   unsigned int bus_rate;
+
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct fec_enet_priv_tx_q *tx_queue[FEC_ENET_MAX_TX_QS];
struct fec_enet_priv_rx_q *rx_queue[FEC_ENET_MAX_RX_QS];
diff --git a/drivers/net/ethernet/freescale/fec_main.c 
b/drivers/net/ethernet/freescale/fec_main.c
index 3db882322b2b..0ed78b390098 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -47,6 +47,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -3572,6 +3573,18 @@ fec_probe(struct platform_device *pdev)
fep->pdev = pdev;
fep->dev_id = dev_id++;
 
+   fep->bus_path = devm_of_icc_get(>dev, "path");
+   if (IS_ERR(fep->bus_path)) {
+   return PTR_ERR(fep->bus_path);
+   } else if (fep->bus_path) {
+   if (of_property_read_u32(np, "fsl,icc-rate", >bus_rate)) {
+   dev_err(>dev, "icc-rate missing\n");
+   return -EINVAL;
+   }
+
+   icc_set_bw(fep->bus_path, 0, fep->bus_rate);
+   }
+
platform_set_drvdata(pdev, ndev);
 
if ((of_machine_is_compatible("fsl,imx6q") ||
@@ -3826,6 +3839,8 @@ static int __maybe_unused fec_suspend(struct device *dev)
if (fep->clk_enet_out || fep->reg_phy)
fep->link = 0;
 
+   icc_disable(fep->bus_path);
+
return 0;
 }
 
@@ -3836,6 +3851,8 @@ static int __maybe_unused fec_resume(struct device *dev)
int ret;
int val;
 
+   icc_enable(fep->bus_path);
+
if (fep->reg_phy && !(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
ret = regulator_enable(fep->reg_phy);
if (ret)
@@ -3884,6 +3901,7 @@ static int __maybe_unused fec_runtime_suspend(struct 
device *dev)
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_ipg);
 
+   icc_disable(fep->bus_path);
return 0;
 }
 
@@ -3893,6 +3911,7 @@ static int __maybe_unused fec_runtime_resume(struct 
device *dev)
struct fec_enet_private *fep = netdev_priv(ndev);
int ret;
 
+   icc_enable(fep->bus_path);
ret = clk_prepare_enable(fep->clk_ahb);
if (ret)
return ret;
-- 
2.29.2



[RFC 15/19] arm64: dts: imx8mq: Add all pl301 nodes

2021-02-19 Thread Abel Vesa
Add all the pl301s found on i.MX8MQ, according to the bus diagram.
Each pl301 has its own clock, icc id and opp table. They are probed
by the imx-bus driver.

Signed-off-by: Abel Vesa 
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 180 ++
 1 file changed, 180 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index e30e948648e9..5f9ffa465d6c 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1447,5 +1447,185 @@ ddr-pmu@3d80 {
interrupt-parent = <>;
interrupts = ;
};
+
+   pl301_main: pl301@0 {
+   compatible = "fsl,imx8m-nic";
+   clocks = < IMX8MQ_CLK_MAIN_AXI>;
+   operating-points-v2 = <_main_opp_table>;
+   #interconnect-cells = <0>;
+   fsl,icc-id = ;
+
+   pl301_main_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-25M {
+   opp-hz = /bits/ 64 <2500>;
+   };
+   opp-133M {
+   opp-hz = /bits/ 64 <1>;
+   };
+   opp-333M {
+   opp-hz = /bits/ 64 <3>;
+   };
+   };
+   };
+
+   pl301_enet: pl301@1 {
+   compatible = "fsl,imx8m-nic";
+   clocks = < IMX8MQ_CLK_ENET_AXI>;
+   operating-points-v2 = <_enet_opp_table>;
+   #interconnect-cells = <0>;
+   fsl,icc-id = ;
+
+   pl301_enet_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-25M {
+   opp-hz = /bits/ 64 <2500>;
+   };
+   opp-266M {
+   opp-hz = /bits/ 64 <2>;
+   };
+   };
+   };
+
+   pl301_gpu: pl301@2 {
+   compatible = "fsl,imx8m-nic";
+   clocks = < IMX8MQ_CLK_GPU_AXI>;
+   operating-points-v2 = <_gpu_opp_table>;
+   #interconnect-cells = <0>;
+   fsl,icc-id = ;
+
+   pl301_gpu_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-25M {
+   opp-hz = /bits/ 64 <2500>;
+   };
+   opp-800M {
+   opp-hz = /bits/ 64 <8>;
+   };
+   };
+   };
+
+   pl301_dc: pl301@3 {
+   compatible = "fsl,imx8m-nic";
+   clocks = < IMX8MQ_CLK_DISP_AXI>;
+   operating-points-v2 = <_dc_opp_table>;
+   #interconnect-cells = <0>;
+   fsl,icc-id = ;
+
+   pl301_dc_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-25M {
+   opp-hz = /bits/ 64 <2500>;
+   };
+   opp-800M {
+   opp-hz = /bits/ 64 <8>;
+   };
+   };
+   };
+
+   /* PL301_DISPLAY (IPs other than DCSS, inside SUPERMIX) */
+   pl301_display: pl301@4 {
+   compatible = "fsl,imx8m-nic";
+   /* FIXME: don't know which clock yet */
+   clocks = < IMX8MQ_CLK_DUMMY>;
+   operating-points-v2 = <_display_opp_table>;
+   #interconnect-cells = <0>;
+   fsl,icc-id = ;
+
+   pl301_display_opp_table: opp-table {
+   compatible = "operating-points-v2";
+
+   opp-25M {
+   opp-hz = /bits/ 64 <2500>;
+   };
+   opp-333M {
+ 

[RFC 17/19] arm64: dts: imx8mq: Add interconnect properties to icc consumer nodes

2021-02-19 Thread Abel Vesa
We add all the properties necessary to control the interconnect
based on the required rates all the way from consumers to the dram.
The fsl,icc-rate specifies the minimum required rate the consumer needs
in order to operate.
For now, only the fec, usdhc1 and usdhc2 are added as consumers.

Signed-off-by: Abel Vesa 
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 6a64b4bf31f5..43760316052f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1112,6 +1112,9 @@ usdhc1: mmc@30b4 {
 "fsl,imx7d-usdhc";
reg = <0x30b4 0x1>;
interrupts = ;
+   interconnects = < IMX8MQ_ICM_USDHC1  
IMX8MQ_ICS_DRAM>;
+   interconnect-names = "path";
+   fsl,icc-rate = <26>;
clocks = < IMX8MQ_CLK_IPG_ROOT>,
 < IMX8MQ_CLK_NAND_USDHC_BUS>,
 < IMX8MQ_CLK_USDHC1_ROOT>;
@@ -1127,6 +1130,9 @@ usdhc2: mmc@30b5 {
 "fsl,imx7d-usdhc";
reg = <0x30b5 0x1>;
interrupts = ;
+   interconnects = < IMX8MQ_ICM_USDHC2  
IMX8MQ_ICS_DRAM>;
+   interconnect-names = "path";
+   fsl,icc-rate = <26>;
clocks = < IMX8MQ_CLK_IPG_ROOT>,
 < IMX8MQ_CLK_NAND_USDHC_BUS>,
 < IMX8MQ_CLK_USDHC2_ROOT>;
@@ -1169,6 +1175,9 @@ fec1: ethernet@30be {
 ,
 ,
 ;
+   interconnects = < IMX8MQ_ICM_ENET  
IMX8MQ_ICS_DRAM>;
+   interconnect-names = "path";
+   fsl,icc-rate = <80>;
clocks = < IMX8MQ_CLK_ENET1_ROOT>,
 < IMX8MQ_CLK_ENET1_ROOT>,
 < IMX8MQ_CLK_ENET_TIMER>,
-- 
2.29.2



[RFC 09/19] interconnect: imx8: Remove the imx_icc_node_adj_desc

2021-02-19 Thread Abel Vesa
Now that the imx generic interconnect doesn't use the
imx_icc_node_adj_desc, we remove it from all the i.MX8M
platform drivers.

Signed-off-by: Abel Vesa 
---
 drivers/interconnect/imx/imx.h| 19 -
 drivers/interconnect/imx/imx8mm.c | 32 +---
 drivers/interconnect/imx/imx8mn.c | 28 +++--
 drivers/interconnect/imx/imx8mq.c | 35 ++-
 4 files changed, 33 insertions(+), 81 deletions(-)

diff --git a/drivers/interconnect/imx/imx.h b/drivers/interconnect/imx/imx.h
index 75da51076c68..5c9f5138f6aa 100644
--- a/drivers/interconnect/imx/imx.h
+++ b/drivers/interconnect/imx/imx.h
@@ -14,15 +14,6 @@
 
 #define IMX_ICC_MAX_LINKS  4
 
-/*
- * struct imx_icc_node_adj - Describe a dynamic adjustable node
- */
-struct imx_icc_node_adj_desc {
-   unsigned int bw_mul, bw_div;
-   const char *phandle_name;
-   bool main_noc;
-};
-
 /*
  * struct imx_icc_node - Describe an interconnect node
  * @name: name of the node
@@ -35,23 +26,21 @@ struct imx_icc_node_desc {
u16 id;
u16 links[IMX_ICC_MAX_LINKS];
u16 num_links;
-   const struct imx_icc_node_adj_desc *adj;
 };
 
-#define DEFINE_BUS_INTERCONNECT(_name, _id, _adj, ...) \
+#define DEFINE_BUS_INTERCONNECT(_name, _id, ...)   \
{   \
.id = _id,  \
.name = _name,  \
-   .adj = _adj,\
.num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })),  \
.links = { __VA_ARGS__ },   \
}
 
 #define DEFINE_BUS_MASTER(_name, _id, _dest_id)
\
-   DEFINE_BUS_INTERCONNECT(_name, _id, NULL, _dest_id)
+   DEFINE_BUS_INTERCONNECT(_name, _id, _dest_id)
 
-#define DEFINE_BUS_SLAVE(_name, _id, _adj) \
-   DEFINE_BUS_INTERCONNECT(_name, _id, _adj)
+#define DEFINE_BUS_SLAVE(_name, _id)   \
+   DEFINE_BUS_INTERCONNECT(_name, _id)
 
 int imx_icc_register(struct platform_device *pdev,
 struct imx_icc_node_desc *nodes,
diff --git a/drivers/interconnect/imx/imx8mm.c 
b/drivers/interconnect/imx/imx8mm.c
index 1083490bb391..0c16110bef9d 100644
--- a/drivers/interconnect/imx/imx8mm.c
+++ b/drivers/interconnect/imx/imx8mm.c
@@ -14,18 +14,6 @@
 
 #include "imx.h"
 
-static const struct imx_icc_node_adj_desc imx8mm_dram_adj = {
-   .bw_mul = 1,
-   .bw_div = 16,
-   .phandle_name = "fsl,ddrc",
-};
-
-static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
-   .bw_mul = 1,
-   .bw_div = 16,
-   .main_noc = true,
-};
-
 /*
  * Describe bus masters, slaves and connections between them
  *
@@ -33,43 +21,43 @@ static const struct imx_icc_node_adj_desc imx8mm_noc_adj = {
  * PL301 nics which are skipped/merged into PL301_MAIN
  */
 static struct imx_icc_node_desc nodes[] = {
-   DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC, _noc_adj,
+   DEFINE_BUS_INTERCONNECT("NOC", IMX8MM_ICN_NOC,
IMX8MM_ICS_DRAM, IMX8MM_ICN_MAIN),
 
-   DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM, _dram_adj),
-   DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM, NULL),
+   DEFINE_BUS_SLAVE("DRAM", IMX8MM_ICS_DRAM),
+   DEFINE_BUS_SLAVE("OCRAM", IMX8MM_ICS_OCRAM),
DEFINE_BUS_MASTER("A53", IMX8MM_ICM_A53, IMX8MM_ICN_NOC),
 
/* VPUMIX */
DEFINE_BUS_MASTER("VPU H1", IMX8MM_ICM_VPU_H1, IMX8MM_ICN_VIDEO),
DEFINE_BUS_MASTER("VPU G1", IMX8MM_ICM_VPU_G1, IMX8MM_ICN_VIDEO),
DEFINE_BUS_MASTER("VPU G2", IMX8MM_ICM_VPU_G2, IMX8MM_ICN_VIDEO),
-   DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, NULL, 
IMX8MM_ICN_NOC),
+   DEFINE_BUS_INTERCONNECT("PL301_VIDEO", IMX8MM_ICN_VIDEO, 
IMX8MM_ICN_NOC),
 
/* GPUMIX */
DEFINE_BUS_MASTER("GPU 2D", IMX8MM_ICM_GPU2D, IMX8MM_ICN_GPU),
DEFINE_BUS_MASTER("GPU 3D", IMX8MM_ICM_GPU3D, IMX8MM_ICN_GPU),
-   DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, NULL, 
IMX8MM_ICN_NOC),
+   DEFINE_BUS_INTERCONNECT("PL301_GPU", IMX8MM_ICN_GPU, IMX8MM_ICN_NOC),
 
/* DISPLAYMIX */
DEFINE_BUS_MASTER("CSI", IMX8MM_ICM_CSI, IMX8MM_ICN_MIPI),
DEFINE_BUS_MASTER("LCDIF", IMX8MM_ICM_LCDIF, IMX8MM_ICN_MIPI),
-   DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, NULL, 
IMX8MM_ICN_NOC),
+   DEFINE_BUS_INTERCONNECT("PL301_MIPI", IMX8MM_ICN_MIPI, IMX8MM_ICN_NOC),
 
/* HSIO */
DEFINE_BUS_MASTER("USB1", IMX8MM_ICM

[RFC 13/19] arm64: dts: imx8mq: Add fsl,icc-id property to ddrc node

2021-02-19 Thread Abel Vesa
The fsl,icc-id property here is used to link the icc node
registered by the imx8mq interconnect driver with the ddrc
device.

Signed-off-by: Abel Vesa 
---
 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
index 17c449e12c2e..ac229a8288cd 100644
--- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -1433,10 +1433,12 @@ ddrc: memory-controller@3d40 {
compatible = "fsl,imx8mq-ddrc", "fsl,imx8m-ddrc";
reg = <0x3d40 0x40>;
clock-names = "core", "pll", "alt", "apb";
+   fsl,icc-id = ;
clocks = < IMX8MQ_CLK_DRAM_CORE>,
 < IMX8MQ_DRAM_PLL_OUT>,
 < IMX8MQ_CLK_DRAM_ALT>,
 < IMX8MQ_CLK_DRAM_APB>;
+   #interconnect-cells = <0>;
};
 
ddr-pmu@3d80 {
-- 
2.29.2



[RFC 11/19] interconnect: imx8mq: Add of_match_table

2021-02-19 Thread Abel Vesa
The i.MX8MQ driver will probe based on the compatible string
instead of using device data in imx-bus devfreq driver.

Signed-off-by: Abel Vesa 
---
 drivers/interconnect/imx/imx8mq.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/interconnect/imx/imx8mq.c 
b/drivers/interconnect/imx/imx8mq.c
index 010ad3d76286..64321f1d323b 100644
--- a/drivers/interconnect/imx/imx8mq.c
+++ b/drivers/interconnect/imx/imx8mq.c
@@ -6,6 +6,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -88,12 +89,18 @@ static int imx8mq_icc_remove(struct platform_device *pdev)
return imx_icc_unregister(pdev);
 }
 
+static const struct of_device_id imx8mq_icc_of_match[] = {
+   { .compatible = "fsl,imx8mq-icc" },
+   { /* sentinel */ },
+};
+
 static struct platform_driver imx8mq_icc_driver = {
.probe = imx8mq_icc_probe,
.remove = imx8mq_icc_remove,
.driver = {
.name = "imx8mq-interconnect",
.sync_state = icc_sync_state,
+   .of_match_table = of_match_ptr(imx8mq_icc_of_match),
},
 };
 
-- 
2.29.2



[RFC 12/19] interconnect: imx: Add imx_icc_get_bw and imx_icc_aggregate functions

2021-02-19 Thread Abel Vesa
The aggregate function will return whatever is the highest
rate for that specific node. The imx_icc_get_bw sets the
initial avg and peak to 0 in order to avoid setting them to
INT_MAX by the interconnect core.

Signed-off-by: Abel Vesa 
---
 drivers/interconnect/imx/imx.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index db048df80011..5cc1ce55406c 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -25,6 +25,23 @@ struct imx_icc_node {
struct dev_pm_qos_request qos_req;
 };
 
+static int imx_icc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+   *avg = 0;
+   *peak = 0;
+
+   return 0;
+}
+
+static int imx_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
+ u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+   *agg_avg = max(*agg_avg, avg_bw);
+   *agg_peak = max(*agg_peak, peak_bw);
+
+   return 0;
+}
+
 static int imx_icc_node_set(struct icc_node *node)
 {
struct device *dev = node->provider->dev;
@@ -233,7 +250,8 @@ int imx_icc_register(struct platform_device *pdev,
if (!provider)
return -ENOMEM;
provider->set = imx_icc_set;
-   provider->aggregate = icc_std_aggregate;
+   provider->get_bw = imx_icc_get_bw;
+   provider->aggregate = imx_icc_aggregate;
provider->xlate = of_icc_xlate_onecell;
provider->data = data;
provider->dev = dev;
-- 
2.29.2



[RFC 08/19] interconnect: imx: Switch from imx_icc_node_adj_desc to fsl,icc-id node assignment

2021-02-19 Thread Abel Vesa
In order to be able to have more than one NoCs in the interconnect net
we need to decouple the NoC from the dram. So instead of using the
imx_icc_node_adj_desc, we use the fsl,icc-id property that is in
each NoC (or pl301) to the icc node (based on the id) to it.
Along with all the NoC and pl301 nodes in the dts we will have a
interconnect dedicated node. This node will be the actual device of the
icc provider.

Signed-off-by: Abel Vesa 
---
 drivers/interconnect/imx/imx.c | 72 +++---
 1 file changed, 32 insertions(+), 40 deletions(-)

diff --git a/drivers/interconnect/imx/imx.c b/drivers/interconnect/imx/imx.c
index c770951a909c..db048df80011 100644
--- a/drivers/interconnect/imx/imx.c
+++ b/drivers/interconnect/imx/imx.c
@@ -34,9 +34,9 @@ static int imx_icc_node_set(struct icc_node *node)
if (!node_data->qos_dev)
return 0;
 
-   freq = (node->avg_bw + node->peak_bw) * node_data->desc->adj->bw_mul;
-   do_div(freq, node_data->desc->adj->bw_div);
-   dev_dbg(dev, "node %s device %s avg_bw %ukBps peak_bw %ukBps min_freq 
%llukHz\n",
+   freq = max(node->avg_bw, node->peak_bw);
+
+   dev_dbg(dev, "  DBG node %s device %s avg_bw %ukBps peak_bw %ukBps 
min_freq %llukHz\n",
node->name, dev_name(node_data->qos_dev),
node->avg_bw, node->peak_bw, freq);
 
@@ -79,41 +79,35 @@ static int imx_icc_node_init_qos(struct icc_provider 
*provider,
 struct icc_node *node)
 {
struct imx_icc_node *node_data = node->data;
-   const struct imx_icc_node_adj_desc *adj = node_data->desc->adj;
struct device *dev = provider->dev;
-   struct device_node *dn = NULL;
struct platform_device *pdev;
+   struct device_node *np = NULL, *dn = NULL;
+   int idx;
 
-   if (adj->main_noc) {
-   node_data->qos_dev = dev;
-   dev_dbg(dev, "icc node %s[%d] is main noc itself\n",
-   node->name, node->id);
-   } else {
-   dn = of_parse_phandle(dev->of_node, adj->phandle_name, 0);
-   if (!dn) {
-   dev_warn(dev, "Failed to parse %s\n",
-adj->phandle_name);
-   return -ENODEV;
-   }
-   /* Allow scaling to be disabled on a per-node basis */
-   if (!of_device_is_available(dn)) {
-   dev_warn(dev, "Missing property %s, skip scaling %s\n",
-adj->phandle_name, node->name);
-   of_node_put(dn);
-   return 0;
-   }
+   for_each_node_with_property(np, "fsl,icc-id") {
+   of_property_read_u32(np, "fsl,icc-id", );
+   if (idx == node_data->desc->id)
+   dn = np;
+   }
 
-   pdev = of_find_device_by_node(dn);
-   of_node_put(dn);
-   if (!pdev) {
-   dev_warn(dev, "node %s[%d] missing device for %pOF\n",
-node->name, node->id, dn);
-   return -EPROBE_DEFER;
-   }
-   node_data->qos_dev = >dev;
-   dev_dbg(dev, "node %s[%d] has device node %pOF\n",
-   node->name, node->id, dn);
+   if (!dn)
+   return 0;
+
+   if (!of_device_is_available(dn)) {
+   dev_warn(dev, "%pOF is disabled\n", dn);
+   return 0;
+   }
+
+   pdev = of_find_device_by_node(dn);
+   of_node_put(dn);
+   if (!pdev) {
+   dev_warn(dev, "node %s[%d] missing device for %pOF\n",
+node->name, node->id, dn);
+   return -EPROBE_DEFER;
}
+   node_data->qos_dev = >dev;
+   dev_dbg(dev, "node %s[%d] has device node %pOF\n", node->name,
+   node->id, dn);
 
return dev_pm_qos_add_request(node_data->qos_dev,
  _data->qos_req,
@@ -151,12 +145,10 @@ static struct icc_node *imx_icc_node_add(struct 
icc_provider *provider,
node_data->desc = node_desc;
icc_node_add(node, provider);
 
-   if (node_desc->adj) {
-   ret = imx_icc_node_init_qos(provider, node);
-   if (ret < 0) {
-   imx_icc_node_destroy(node);
-   return ERR_PTR(ret);
-   }
+   ret = imx_icc_node_init_qos(provider, node);
+   if (ret < 0) {
+   imx_icc_node_destroy(node);
+   return ERR_PTR(ret);
}
 
return node;
@@ -244,7 +236,7 @@ int imx_icc_register(str

[RFC 10/19] interconnect: imx8mq: Add the pl301_per_m and pl301_wakeup nodes and subnodes

2021-02-19 Thread Abel Vesa
According to the bus diagram, there are two more pl301s that need to
be added here. The pl301_per_m which is an intermediary node between
pl301_main and its masters: usdhc1, usdhc2 and sdma. The pl301_wakeup
is an intermediary node between pl301_main and its masters, in this case
all the SAIs.

Signed-off-by: Abel Vesa 
---
 drivers/interconnect/imx/imx8mq.c | 17 ++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/interconnect/imx/imx8mq.c 
b/drivers/interconnect/imx/imx8mq.c
index b8c36d668946..010ad3d76286 100644
--- a/drivers/interconnect/imx/imx8mq.c
+++ b/drivers/interconnect/imx/imx8mq.c
@@ -57,14 +57,25 @@ static struct imx_icc_node_desc nodes[] = {
DEFINE_BUS_INTERCONNECT("PL301_ENET", IMX8MQ_ICN_ENET, IMX8MQ_ICN_MAIN),
 
/* OTHER */
-   DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_MAIN),
DEFINE_BUS_MASTER("NAND", IMX8MQ_ICM_NAND, IMX8MQ_ICN_MAIN),
-   DEFINE_BUS_MASTER("USDHC1", IMX8MQ_ICM_USDHC1, IMX8MQ_ICN_MAIN),
-   DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_MAIN),
DEFINE_BUS_MASTER("PCIE1", IMX8MQ_ICM_PCIE1, IMX8MQ_ICN_MAIN),
DEFINE_BUS_MASTER("PCIE2", IMX8MQ_ICM_PCIE2, IMX8MQ_ICN_MAIN),
DEFINE_BUS_INTERCONNECT("PL301_MAIN", IMX8MQ_ICN_MAIN,
IMX8MQ_ICN_NOC, IMX8MQ_ICS_OCRAM),
+   DEFINE_BUS_MASTER("SDMA1", IMX8MQ_ICM_SDMA1, IMX8MQ_ICN_PER_M),
+   DEFINE_BUS_MASTER("USDHC1", IMX8MQ_ICM_USDHC1, IMX8MQ_ICN_PER_M),
+   DEFINE_BUS_MASTER("USDHC2", IMX8MQ_ICM_USDHC2, IMX8MQ_ICN_PER_M),
+   DEFINE_BUS_INTERCONNECT("PL301_PER_M", IMX8MQ_ICN_PER_M,
+   IMX8MQ_ICN_MAIN),
+
+   DEFINE_BUS_MASTER("SAI1", IMX8MQ_ICM_SAI1, IMX8MQ_ICN_WAKEUP),
+   DEFINE_BUS_MASTER("SAI2", IMX8MQ_ICM_SAI2, IMX8MQ_ICN_WAKEUP),
+   DEFINE_BUS_MASTER("SAI3", IMX8MQ_ICM_SAI3, IMX8MQ_ICN_WAKEUP),
+   DEFINE_BUS_MASTER("SAI4", IMX8MQ_ICM_SAI4, IMX8MQ_ICN_WAKEUP),
+   DEFINE_BUS_MASTER("SAI5", IMX8MQ_ICM_SAI5, IMX8MQ_ICN_WAKEUP),
+   DEFINE_BUS_MASTER("SAI6", IMX8MQ_ICM_SAI6, IMX8MQ_ICN_WAKEUP),
+   DEFINE_BUS_INTERCONNECT("PL301_WAKEUP", IMX8MQ_ICN_WAKEUP,
+   IMX8MQ_ICN_MAIN),
 };
 
 static int imx8mq_icc_probe(struct platform_device *pdev)
-- 
2.29.2



[RFC 01/19] clk: imx8mq: Replace critical with ignore_unused flag for dram_apb clock

2021-02-19 Thread Abel Vesa
In order to allow the dram_apb to be switched to a different parent,
we need to remove the CLK_IS_CRITICAL flag. This leads to clock
being disabled on clk_disabled_unused call, so add the
CLK_IGNORE_UNUSED instead to avoid that.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-imx8mq.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index 4dd4ae9d022b..992210508411 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -481,7 +481,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
 */
hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base 
+ 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), 
CLK_IS_CRITICAL);
hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", 
imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
-   hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", 
imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+   hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", 
imx8mq_dram_apb_sels, base + 0xa080, CLK_IGNORE_UNUSED | CLK_GET_RATE_NOCACHE);
 
/* IP */
hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", 
imx8mq_vpu_g1_sels, base + 0xa100);
-- 
2.29.2



[RFC 07/19] devfreq: imx8m-ddrc: Add late system sleep PM ops

2021-02-19 Thread Abel Vesa
Seems that, in order to be able to resume from suspend, the dram rate
needs to be the highest one available. Therefore, add the late system
suspend/resume PM ops which set the highest rate on suspend and the
latest one used before suspending on resume.

Signed-off-by: Abel Vesa 
---
 drivers/devfreq/imx8m-ddrc.c | 26 ++
 1 file changed, 26 insertions(+)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index 33de83acfd8b..04347dee781b 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -72,6 +72,8 @@ struct imx8m_ddrc {
struct clk *dram_alt;
struct clk *dram_apb;
 
+   unsigned long suspend_rate;
+   unsigned long resume_rate;
int freq_count;
struct imx8m_ddrc_freq freq_table[IMX8M_DDRC_MAX_FREQ_COUNT];
 };
@@ -271,6 +273,22 @@ static int imx8m_ddrc_target(struct device *dev, unsigned 
long *freq, u32 flags)
return ret;
 }
 
+static int imx8m_ddrc_suspend(struct device *dev)
+{
+   struct imx8m_ddrc *priv = dev_get_drvdata(dev);
+
+   priv->resume_rate = clk_get_rate(priv->dram_core);
+
+   return imx8m_ddrc_target(dev, >suspend_rate, 0);
+}
+
+static int imx8m_ddrc_resume(struct device *dev)
+{
+   struct imx8m_ddrc *priv = dev_get_drvdata(dev);
+
+   return imx8m_ddrc_target(dev, >resume_rate, 0);
+}
+
 static int imx8m_ddrc_get_cur_freq(struct device *dev, unsigned long *freq)
 {
struct imx8m_ddrc *priv = dev_get_drvdata(dev);
@@ -336,6 +354,9 @@ static int imx8m_ddrc_init_freq_info(struct device *dev)
 
if (dev_pm_opp_add(dev, freq->rate * 25, 0))
return -ENODEV;
+
+   if (index ==  0)
+   priv->suspend_rate = freq->rate * 25;
}
 
return 0;
@@ -412,10 +433,15 @@ static const struct of_device_id imx8m_ddrc_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, imx8m_ddrc_of_match);
 
+static const struct dev_pm_ops imx8m_ddrc_pm_ops = {
+   SET_LATE_SYSTEM_SLEEP_PM_OPS(imx8m_ddrc_suspend, imx8m_ddrc_resume)
+};
+
 static struct platform_driver imx8m_ddrc_platdrv = {
.probe  = imx8m_ddrc_probe,
.driver = {
.name   = "imx8m-ddrc-devfreq",
+   .pm = _ddrc_pm_ops,
.of_match_table = of_match_ptr(imx8m_ddrc_of_match),
},
 };
-- 
2.29.2



[RFC 04/19] devfreq: imx-bus: Decouple imx-bus from icc made

2021-02-19 Thread Abel Vesa
The link between an imx-bus device and its icc id will be done
through the fsl,icc-id property in each dts node. The imx
interconnect driver will pick up all the dts nodes that have that
property defined and will link them to the rightfull icc id.

Signed-off-by: Abel Vesa 
---
 drivers/devfreq/imx-bus.c | 40 +++
 1 file changed, 3 insertions(+), 37 deletions(-)

diff --git a/drivers/devfreq/imx-bus.c b/drivers/devfreq/imx-bus.c
index 1c0c92d0eb08..9f0df88b29c1 100644
--- a/drivers/devfreq/imx-bus.c
+++ b/drivers/devfreq/imx-bus.c
@@ -65,36 +65,6 @@ static void imx_bus_exit(struct device *dev)
platform_device_unregister(priv->icc_pdev);
 }
 
-/* imx_bus_init_icc() - register matching icc provider if required */
-static int imx_bus_init_icc(struct device *dev)
-{
-   struct imx_bus *priv = dev_get_drvdata(dev);
-   const char *icc_driver_name;
-
-   if (!of_get_property(dev->of_node, "#interconnect-cells", 0))
-   return 0;
-   if (!IS_ENABLED(CONFIG_INTERCONNECT_IMX)) {
-   dev_warn(dev, "imx interconnect drivers disabled\n");
-   return 0;
-   }
-
-   icc_driver_name = of_device_get_match_data(dev);
-   if (!icc_driver_name) {
-   dev_err(dev, "unknown interconnect driver\n");
-   return 0;
-   }
-
-   priv->icc_pdev = platform_device_register_data(
-   dev, icc_driver_name, -1, NULL, 0);
-   if (IS_ERR(priv->icc_pdev)) {
-   dev_err(dev, "failed to register icc provider %s: %ld\n",
-   icc_driver_name, PTR_ERR(priv->icc_pdev));
-   return PTR_ERR(priv->icc_pdev);
-   }
-
-   return 0;
-}
-
 static int imx_bus_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
@@ -144,10 +114,6 @@ static int imx_bus_probe(struct platform_device *pdev)
goto err;
}
 
-   ret = imx_bus_init_icc(dev);
-   if (ret)
-   goto err;
-
return 0;
 
 err:
@@ -156,9 +122,9 @@ static int imx_bus_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id imx_bus_of_match[] = {
-   { .compatible = "fsl,imx8mq-noc", .data = "imx8mq-interconnect", },
-   { .compatible = "fsl,imx8mm-noc", .data = "imx8mm-interconnect", },
-   { .compatible = "fsl,imx8mn-noc", .data = "imx8mn-interconnect", },
+   { .compatible = "fsl,imx8mq-noc",},
+   { .compatible = "fsl,imx8mm-noc",},
+   { .compatible = "fsl,imx8mn-noc",},
{ .compatible = "fsl,imx8m-noc", },
{ .compatible = "fsl,imx8m-nic", },
{ /* sentinel */ },
-- 
2.29.2



[RFC 05/19] devfreq: imx8m-ddrc: Change governor to powersave

2021-02-19 Thread Abel Vesa
By switching to powersave governor, we allow the imx8m-ddrc to always
run at minimum rate needed by all the running masters.

Signed-off-by: Abel Vesa 
---
 drivers/devfreq/imx8m-ddrc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index bc82d3653bff..3a6c04ba4f2e 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -379,7 +379,7 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct imx8m_ddrc *priv;
-   const char *gov = DEVFREQ_GOV_USERSPACE;
+   const char *gov = DEVFREQ_GOV_POWERSAVE;
int ret;
 
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-- 
2.29.2



[RFC 06/19] devfreq: imx8m-ddrc: Use the opps acquired from EL3

2021-02-19 Thread Abel Vesa
i.MX8M platforms get their dram OPPs from the EL3.
We don't need to duplicate that in the kernel dram dts node.
We should just trust the OPPs provided by the EL3.

Signed-off-by: Abel Vesa 
---
 drivers/devfreq/imx8m-ddrc.c | 49 ++--
 1 file changed, 2 insertions(+), 47 deletions(-)

diff --git a/drivers/devfreq/imx8m-ddrc.c b/drivers/devfreq/imx8m-ddrc.c
index 3a6c04ba4f2e..33de83acfd8b 100644
--- a/drivers/devfreq/imx8m-ddrc.c
+++ b/drivers/devfreq/imx8m-ddrc.c
@@ -333,38 +333,9 @@ static int imx8m_ddrc_init_freq_info(struct device *dev)
if (freq->dram_core_parent_index == 2 &&
freq->dram_alt_parent_index == 0)
return -ENODEV;
-   }
-
-   return 0;
-}
-
-static int imx8m_ddrc_check_opps(struct device *dev)
-{
-   struct imx8m_ddrc *priv = dev_get_drvdata(dev);
-   struct imx8m_ddrc_freq *freq_info;
-   struct dev_pm_opp *opp;
-   unsigned long freq;
-   int i, opp_count;
-
-   /* Enumerate DT OPPs and disable those not supported by firmware */
-   opp_count = dev_pm_opp_get_opp_count(dev);
-   if (opp_count < 0)
-   return opp_count;
-   for (i = 0, freq = 0; i < opp_count; ++i, ++freq) {
-   opp = dev_pm_opp_find_freq_ceil(dev, );
-   if (IS_ERR(opp)) {
-   dev_err(dev, "Failed enumerating OPPs: %ld\n",
-   PTR_ERR(opp));
-   return PTR_ERR(opp);
-   }
-   dev_pm_opp_put(opp);
 
-   freq_info = imx8m_ddrc_find_freq(priv, freq);
-   if (!freq_info) {
-   dev_info(dev, "Disable unsupported OPP %luHz %luMT/s\n",
-   freq, DIV_ROUND_CLOSEST(freq, 25));
-   dev_pm_opp_disable(dev, freq);
-   }
+   if (dev_pm_opp_add(dev, freq->rate * 25, 0))
+   return -ENODEV;
}
 
return 0;
@@ -372,7 +343,6 @@ static int imx8m_ddrc_check_opps(struct device *dev)
 
 static void imx8m_ddrc_exit(struct device *dev)
 {
-   dev_pm_opp_of_remove_table(dev);
 }
 
 static int imx8m_ddrc_probe(struct platform_device *pdev)
@@ -419,16 +389,6 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
return ret;
}
 
-   ret = dev_pm_opp_of_add_table(dev);
-   if (ret < 0) {
-   dev_err(dev, "failed to get OPP table\n");
-   return ret;
-   }
-
-   ret = imx8m_ddrc_check_opps(dev);
-   if (ret < 0)
-   goto err;
-
priv->profile.polling_ms = 1000;
priv->profile.target = imx8m_ddrc_target;
priv->profile.get_dev_status = imx8m_ddrc_get_dev_status;
@@ -441,13 +401,8 @@ static int imx8m_ddrc_probe(struct platform_device *pdev)
if (IS_ERR(priv->devfreq)) {
ret = PTR_ERR(priv->devfreq);
dev_err(dev, "failed to add devfreq device: %d\n", ret);
-   goto err;
}
 
-   return 0;
-
-err:
-   dev_pm_opp_of_remove_table(dev);
return ret;
 }
 
-- 
2.29.2



[RFC 03/19] devfreq: imx-bus: Switch governor to powersave

2021-02-19 Thread Abel Vesa
By switching to powersave governor, we allow the imx-bus to always run
at minimum rate needed by all the running masters.

Signed-off-by: Abel Vesa 
---
 drivers/devfreq/imx-bus.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/devfreq/imx-bus.c b/drivers/devfreq/imx-bus.c
index 4f38455ad742..1c0c92d0eb08 100644
--- a/drivers/devfreq/imx-bus.c
+++ b/drivers/devfreq/imx-bus.c
@@ -99,7 +99,7 @@ static int imx_bus_probe(struct platform_device *pdev)
 {
struct device *dev = >dev;
struct imx_bus *priv;
-   const char *gov = DEVFREQ_GOV_USERSPACE;
+   const char *gov = DEVFREQ_GOV_POWERSAVE;
int ret;
 
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
-- 
2.29.2



[RFC 02/19] dt-bindings: interconnect: imx8mq: Add missing pl301 and SAI ids

2021-02-19 Thread Abel Vesa
According to the bus diagram, there are two more pl301s that need to
be added here. The pl301_per_m which is an intermediary node between
pl301_main and its masters: usdhc1, usdhc2 and sdma. The pl301_wakeup
is an intermediary node between pl301_main and its masters, in this case
all the SAIs.

Signed-off-by: Abel Vesa 
---
 include/dt-bindings/interconnect/imx8mq.h | 9 +
 1 file changed, 9 insertions(+)

diff --git a/include/dt-bindings/interconnect/imx8mq.h 
b/include/dt-bindings/interconnect/imx8mq.h
index 1a4cae7f8be2..1953de8af5cb 100644
--- a/include/dt-bindings/interconnect/imx8mq.h
+++ b/include/dt-bindings/interconnect/imx8mq.h
@@ -44,5 +44,14 @@
 #define IMX8MQ_ICM_PCIE1   26
 #define IMX8MQ_ICM_PCIE2   27
 #define IMX8MQ_ICN_MAIN28
+#define IMX8MQ_ICN_PER_M   30
+
+#define IMX8MQ_ICN_WAKEUP  31
+#define IMX8MQ_ICM_SAI132
+#define IMX8MQ_ICM_SAI233
+#define IMX8MQ_ICM_SAI334
+#define IMX8MQ_ICM_SAI435
+#define IMX8MQ_ICM_SAI536
+#define IMX8MQ_ICM_SAI637
 
 #endif /* __DT_BINDINGS_INTERCONNECT_IMX8MQ_H */
-- 
2.29.2



[RFC 00/19] Rework support for i.MX8MQ interconnect with devfreq

2021-02-19 Thread Abel Vesa
This has been on my queue for quite some time now. It is more of a
proof-of-concept.

This rework is done with the compatibility of future i.MX platforms in
mind. For example, the i.MX8MP platform has multiple NoCs. This
patchsets prepares the imx interconnect and imx devfreq for that too.

As of now, none of the drivers involved are being used and there is no
icc consumer on any off the i.MX platforms.

Basically, the steps taken here are the following:

1. Make the dram_apb clock "reparantable" from kernel.
This is needed in order to keep track of the actual parent of the 
dram_apb clock in the kernel clock hierarchy. Note that the actual
switch is done EL3 (TF-A).

2. Rework the imx-bus so the actual link between the icc and the 
NoCs or the pl301s is not tightly coupled. This allows us to have
as many NoCs as necessary but also allows as to use the same driver
for the pl301s. The pl301s have their own clocks too, so we need to
reduce their rates too.

3. Rework the imx8m-ddrc driver. Remove the support for dts defined
OPPs. The EL3 provides those. So instead of havingi to keep the OPP table in
both EL3 and kernel in sync, we rely on what the EL3 gives us.
Also, when the platform suspends, the bus needs to be running at highest
rate, otherwise there is a chance it might not resume anymore.
By adding the late system sleep PM ops we can handle that easily.

4. Rework the imx interconnect driver to use the fsl,icc-id instead
of the robust imx_icc_node_adj_desc for linking with the target node.
By adding the fsl,icc-id property to all the NoC and pl301 dts nodes,
we can link each icc node to their corresponding NoC, pl301 or dram.
Basically, when the imx interconnect platform specific driver probes,
it will take each node defined for that platform and look-up the
corresponding dts node based on the id and add that as the qos device.

5. Added the fec and usdhc as icc consumers. This is just as an example.
All the other consumers can be added later. Basically, each consumer
will add a path to their device node and in the driver will have to
handle that icc path accordingly.

Abel Vesa (19):
  clk: imx8mq: Replace critical with ignore_unused flag for dram_apb
clock
  dt-bindings: interconnect: imx8mq: Add missing pl301 and SAI ids
  devfreq: imx-bus: Switch governor to powersave
  devfreq: imx-bus: Decouple imx-bus from icc made
  devfreq: imx8m-ddrc: Change governor to powersave
  devfreq: imx8m-ddrc: Use the opps acquired from EL3
  devfreq: imx8m-ddrc: Add late system sleep PM ops
  interconnect: imx: Switch from imx_icc_node_adj_desc to fsl,icc-id
node assignment
  interconnect: imx8: Remove the imx_icc_node_adj_desc
  interconnect: imx8mq: Add the pl301_per_m and pl301_wakeup nodes and
subnodes
  interconnect: imx8mq: Add of_match_table
  interconnect: imx: Add imx_icc_get_bw and imx_icc_aggregate functions
  arm64: dts: imx8mq: Add fsl,icc-id property to ddrc node
  arm64: dts: imx8mq: Add fsl,icc-id to noc node
  arm64: dts: imx8mq: Add all pl301 nodes
  arm64: dts: imx8mq: Add the interconnect node
  arm64: dts: imx8mq: Add interconnect properties to icc consumer nodes
  net: ethernet: fec_main: Add interconnect support
  mmc: sdhci-esdhc-imx: Add interconnect support

 arch/arm64/boot/dts/freescale/imx8mq.dtsi | 200 +-
 drivers/clk/imx/clk-imx8mq.c  |   2 +-
 drivers/devfreq/imx-bus.c |  42 +
 drivers/devfreq/imx8m-ddrc.c  |  75 +++-
 drivers/interconnect/imx/imx.c|  92 +-
 drivers/interconnect/imx/imx.h|  19 +-
 drivers/interconnect/imx/imx8mm.c |  32 ++--
 drivers/interconnect/imx/imx8mn.c |  28 +--
 drivers/interconnect/imx/imx8mq.c |  59 ---
 drivers/mmc/host/sdhci-esdhc-imx.c|  26 +++
 drivers/net/ethernet/freescale/fec.h  |   3 +
 drivers/net/ethernet/freescale/fec_main.c |  19 ++
 include/dt-bindings/interconnect/imx8mq.h |   9 +
 scripts/dtc/fdtoverlay| Bin 0 -> 61280 bytes
 14 files changed, 393 insertions(+), 213 deletions(-)
 create mode 100755 scripts/dtc/fdtoverlay

-- 
2.29.2



Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-02-15 Thread Abel Vesa
On 21-02-13 08:44:28, Adam Ford wrote:
> On Wed, Feb 3, 2021 at 3:22 PM Adam Ford  wrote:
> >
> > On Thu, Jan 21, 2021 at 4:24 AM Abel Vesa  wrote:
> > >
> > > On 21-01-21 10:56:17, Sascha Hauer wrote:
> > > > On Wed, Jan 20, 2021 at 06:14:21PM +0200, Abel Vesa wrote:
> > > > > On 21-01-20 16:50:01, Sascha Hauer wrote:
> > > > > > On Wed, Jan 20, 2021 at 05:28:13PM +0200, Abel Vesa wrote:
> > > > > > > On 21-01-20 16:13:05, Sascha Hauer wrote:
> > > > > > > > Hi Abel,
> > > > > > > >
> > > > > > > > On Wed, Jan 20, 2021 at 04:44:54PM +0200, Abel Vesa wrote:
> > > > > > > > > On 21-01-18 08:00:43, Adam Ford wrote:
> > > > > > > > > > On Mon, Jan 18, 2021 at 6:52 AM Abel Vesa 
> > > > > > > > > >  wrote:
> > > > > > >
> > > > > > > ...
> > > > > > >
> > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > TBH, I'm against the idea of having to call consumer API 
> > > > > > > > > > > from a clock provider driver.
> > > > > > > > > > > I'm still investigating a way of moving the uart clock 
> > > > > > > > > > > control calls in drivers/serial/imx,
> > > > > > > > > > > where they belong.
> > > > > > > > > >
> > > > > > > > > > That makes sense.
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > Just a thought. The uart clock used for console remains on 
> > > > > > > > > from u-boot,
> > > > > > > > > so maybe it's enough to just add the CLK_IGNORE_UNUSED flag 
> > > > > > > > > to all the
> > > > > > > > > uart root clocks and remove the prepare/enable calls for uart 
> > > > > > > > > clocks
> > > > > > > > > for good. I don't really have a way to test it right now, but 
> > > > > > > > > maybe
> > > > > > > > > you could give it a try.
> > > > > > > >
> > > > > > > > That would mean that UART clocks will never be disabled, 
> > > > > > > > regardless of
> > > > > > > > whether they are used for console or not. That doesn't sound 
> > > > > > > > very
> > > > > > > > appealing.
> > > > > > >
> > > > > > > AFAIK, the only uart clock that is enabled by u-boot is the one 
> > > > > > > used for
> > > > > > > the console. Later on, when the serial driver probes, it will 
> > > > > > > enable it itself.
> > > > > > >
> > > > > > > Unless I'm missing something, this is exactly what we need.
> > > > > >
> > > > > > It might enable it, but with CLK_IGNORE_UNUSED the clock won't be
> > > > > > disabled again when a port is closed after usage
> > > > >
> > > > > OK, tell me what I'm getting wrong in the following scenario:
> > > > >
> > > > > U-boot leaves the console uart clock enabled. All the other ones are 
> > > > > disabled.
> > > > >
> > > > > Kernel i.MX clk driver registers the uart clocks with flag 
> > > > > CLK_IGNORE_UNUSED.
> > > >
> > > > I was wrong at that point. I originally thought the kernel will never
> > > > disable these clocks, but in fact it only leaves them enabled during the
> > > > clk_disable_unused call.
> > > >
> > > > However, when CLK_IGNORE_UNUSED becomes relevant it's too late already.
> > > > I just chatted with Lucas and he told me what the original problem was
> > > > that his patch solved.
> > > >
> > > > The problem comes when an unrelated device and the earlycon UART have
> > > > the same parent clocks. The parent clock is enabled, but it's reference
> > > > count is zero. Now when the unrelated device probes and toggles its
> > > > clocks then the shared parent clock will be disabled due to the
> > > > reference count being zero. Next time earlycon 

Re: [RFC] clk: Mark HW enabled clocks as enabled in core

2021-02-02 Thread Abel Vesa
On 21-01-29 09:19:48, Sascha Hauer wrote:
> On Wed, Jan 27, 2021 at 01:16:31PM +0200, Abel Vesa wrote:
> > On 21-01-27 11:47:20, Sascha Hauer wrote:
> > > On Wed, Jan 27, 2021 at 12:12:20PM +0200, Abel Vesa wrote:
> > > > On 21-01-26 15:30:17, Sascha Hauer wrote:
> > > > > On Tue, Jan 26, 2021 at 03:12:39PM +0200, Abel Vesa wrote:
> > > > > > On 21-01-26 12:51:05, Sascha Hauer wrote:
> > > > > > > On Tue, Jan 26, 2021 at 01:21:36PM +0200, Abel Vesa wrote:
> > > > > > > > Some clocks are already enabled in HW even before the kernel
> > > > > > > > starts to boot. So, in order to make sure that these clocks do 
> > > > > > > > not
> > > > > > > > get disabled when clk_disable_unused call is done or when
> > > > > > > > reparenting clocks, we enable them in core on clock 
> > > > > > > > registration.
> > > > > > > > Such a clock will have to be registered with CLK_IGNORE_UNUSED 
> > > > > > > > flag
> > > > > > > > and also needs to have the is_enabled ops implemented.
> > > > > > > > 
> > > > > > > > Signed-off-by: Abel Vesa 
> > > > > > > > ---
> > > > > > > >  drivers/clk/clk.c | 11 ++-
> > > > > > > >  1 file changed, 10 insertions(+), 1 deletion(-)
> > > > > > > > 
> > > > > > > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > > > > > > > index 3d751ae5bc70..26d55851cfa5 100644
> > > > > > > > --- a/drivers/clk/clk.c
> > > > > > > > +++ b/drivers/clk/clk.c
> > > > > > > > @@ -3416,6 +3416,7 @@ static int __clk_core_init(struct 
> > > > > > > > clk_core *core)
> > > > > > > > int ret;
> > > > > > > > struct clk_core *parent;
> > > > > > > > unsigned long rate;
> > > > > > > > +   bool is_hw_enabled = false;
> > > > > > > > int phase;
> > > > > > > >  
> > > > > > > > if (!core)
> > > > > > > > @@ -3558,12 +3559,20 @@ static int __clk_core_init(struct 
> > > > > > > > clk_core *core)
> > > > > > > > rate = 0;
> > > > > > > > core->rate = core->req_rate = rate;
> > > > > > > >  
> > > > > > > > +   /*
> > > > > > > > +* If the clock has the CLK_IGNORE_UNUSED flag set and 
> > > > > > > > it is already
> > > > > > > > +* enabled in HW, enable it in core too so it won't get 
> > > > > > > > accidentally
> > > > > > > > +* disabled when walking the orphan tree and 
> > > > > > > > reparenting clocks
> > > > > > > > +*/
> > > > > > > > +   if (core->flags & CLK_IGNORE_UNUSED && 
> > > > > > > > core->ops->is_enabled)
> > > > > > > > +   is_hw_enabled = clk_core_is_enabled(core);
> > > > > > > > +
> > > > > > > > /*
> > > > > > > >  * Enable CLK_IS_CRITICAL clocks so newly added 
> > > > > > > > critical clocks
> > > > > > > >  * don't get accidentally disabled when walking the 
> > > > > > > > orphan tree and
> > > > > > > >  * reparenting clocks
> > > > > > > >  */
> > > > > > > > -   if (core->flags & CLK_IS_CRITICAL) {
> > > > > > > > +   if (core->flags & CLK_IS_CRITICAL || is_hw_enabled) {
> > > > > > > > unsigned long flags;
> > > > > > > >  
> > > > > > > > ret = clk_core_prepare(core);
> > > > > > > 
> > > > > > > This means that a bootloader enabled clock with CLK_IGNORE_UNUSED 
> > > > > > > flag
> > > > > > > can effectively never be disabled because the prepare/enable 
> > > > > > > count is 1
&

Re: [RFC] clk: Mark HW enabled clocks as enabled in core

2021-01-27 Thread Abel Vesa
On 21-01-27 11:47:20, Sascha Hauer wrote:
> On Wed, Jan 27, 2021 at 12:12:20PM +0200, Abel Vesa wrote:
> > On 21-01-26 15:30:17, Sascha Hauer wrote:
> > > On Tue, Jan 26, 2021 at 03:12:39PM +0200, Abel Vesa wrote:
> > > > On 21-01-26 12:51:05, Sascha Hauer wrote:
> > > > > On Tue, Jan 26, 2021 at 01:21:36PM +0200, Abel Vesa wrote:
> > > > > > Some clocks are already enabled in HW even before the kernel
> > > > > > starts to boot. So, in order to make sure that these clocks do not
> > > > > > get disabled when clk_disable_unused call is done or when
> > > > > > reparenting clocks, we enable them in core on clock registration.
> > > > > > Such a clock will have to be registered with CLK_IGNORE_UNUSED flag
> > > > > > and also needs to have the is_enabled ops implemented.
> > > > > > 
> > > > > > Signed-off-by: Abel Vesa 
> > > > > > ---
> > > > > >  drivers/clk/clk.c | 11 ++-
> > > > > >  1 file changed, 10 insertions(+), 1 deletion(-)
> > > > > > 
> > > > > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > > > > > index 3d751ae5bc70..26d55851cfa5 100644
> > > > > > --- a/drivers/clk/clk.c
> > > > > > +++ b/drivers/clk/clk.c
> > > > > > @@ -3416,6 +3416,7 @@ static int __clk_core_init(struct clk_core 
> > > > > > *core)
> > > > > > int ret;
> > > > > > struct clk_core *parent;
> > > > > > unsigned long rate;
> > > > > > +   bool is_hw_enabled = false;
> > > > > > int phase;
> > > > > >  
> > > > > > if (!core)
> > > > > > @@ -3558,12 +3559,20 @@ static int __clk_core_init(struct clk_core 
> > > > > > *core)
> > > > > > rate = 0;
> > > > > > core->rate = core->req_rate = rate;
> > > > > >  
> > > > > > +   /*
> > > > > > +* If the clock has the CLK_IGNORE_UNUSED flag set and it is 
> > > > > > already
> > > > > > +* enabled in HW, enable it in core too so it won't get 
> > > > > > accidentally
> > > > > > +* disabled when walking the orphan tree and reparenting clocks
> > > > > > +*/
> > > > > > +   if (core->flags & CLK_IGNORE_UNUSED && core->ops->is_enabled)
> > > > > > +   is_hw_enabled = clk_core_is_enabled(core);
> > > > > > +
> > > > > > /*
> > > > > >  * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
> > > > > >  * don't get accidentally disabled when walking the orphan tree 
> > > > > > and
> > > > > >  * reparenting clocks
> > > > > >  */
> > > > > > -   if (core->flags & CLK_IS_CRITICAL) {
> > > > > > +   if (core->flags & CLK_IS_CRITICAL || is_hw_enabled) {
> > > > > > unsigned long flags;
> > > > > >  
> > > > > > ret = clk_core_prepare(core);
> > > > > 
> > > > > This means that a bootloader enabled clock with CLK_IGNORE_UNUSED flag
> > > > > can effectively never be disabled because the prepare/enable count is 
> > > > > 1
> > > > > without any user. This is the behaviour we want to have with critical
> > > > > clocks, but I don't think this is desired for clocks with the
> > > > > CLK_IGNORE_UNUSED flag.
> > > > > 
> > > > 
> > > > Here is the way I see it. Critical clocks means the system can't work
> > > > without, so do not ever disable/unprepare. The "ignore unused" flag
> > > > tells the core to not do anything to this clock, even if it is unused.
> > > > For now, it just leaves the clock alone, but the flag could be used for
> > > > some other stuff in the future.
> > > > 
> > > > Now, the behavior is entirely different.
> > > > 
> > > > For the "critical" clock disable/unprepare, the core does nothing
> > > > (returns without calling the disable/unprepare ops).
> > > > 
> > > > As for the "ignore unused", the clock can be disabled later on,
> > > > which 

Re: [RFC] clk: Mark HW enabled clocks as enabled in core

2021-01-27 Thread Abel Vesa
On 21-01-26 15:30:17, Sascha Hauer wrote:
> On Tue, Jan 26, 2021 at 03:12:39PM +0200, Abel Vesa wrote:
> > On 21-01-26 12:51:05, Sascha Hauer wrote:
> > > On Tue, Jan 26, 2021 at 01:21:36PM +0200, Abel Vesa wrote:
> > > > Some clocks are already enabled in HW even before the kernel
> > > > starts to boot. So, in order to make sure that these clocks do not
> > > > get disabled when clk_disable_unused call is done or when
> > > > reparenting clocks, we enable them in core on clock registration.
> > > > Such a clock will have to be registered with CLK_IGNORE_UNUSED flag
> > > > and also needs to have the is_enabled ops implemented.
> > > > 
> > > > Signed-off-by: Abel Vesa 
> > > > ---
> > > >  drivers/clk/clk.c | 11 ++-
> > > >  1 file changed, 10 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > > > index 3d751ae5bc70..26d55851cfa5 100644
> > > > --- a/drivers/clk/clk.c
> > > > +++ b/drivers/clk/clk.c
> > > > @@ -3416,6 +3416,7 @@ static int __clk_core_init(struct clk_core *core)
> > > > int ret;
> > > > struct clk_core *parent;
> > > > unsigned long rate;
> > > > +   bool is_hw_enabled = false;
> > > > int phase;
> > > >  
> > > > if (!core)
> > > > @@ -3558,12 +3559,20 @@ static int __clk_core_init(struct clk_core 
> > > > *core)
> > > > rate = 0;
> > > > core->rate = core->req_rate = rate;
> > > >  
> > > > +   /*
> > > > +* If the clock has the CLK_IGNORE_UNUSED flag set and it is 
> > > > already
> > > > +* enabled in HW, enable it in core too so it won't get 
> > > > accidentally
> > > > +* disabled when walking the orphan tree and reparenting clocks
> > > > +*/
> > > > +   if (core->flags & CLK_IGNORE_UNUSED && core->ops->is_enabled)
> > > > +   is_hw_enabled = clk_core_is_enabled(core);
> > > > +
> > > > /*
> > > >  * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
> > > >  * don't get accidentally disabled when walking the orphan tree 
> > > > and
> > > >  * reparenting clocks
> > > >  */
> > > > -   if (core->flags & CLK_IS_CRITICAL) {
> > > > +   if (core->flags & CLK_IS_CRITICAL || is_hw_enabled) {
> > > > unsigned long flags;
> > > >  
> > > > ret = clk_core_prepare(core);
> > > 
> > > This means that a bootloader enabled clock with CLK_IGNORE_UNUSED flag
> > > can effectively never be disabled because the prepare/enable count is 1
> > > without any user. This is the behaviour we want to have with critical
> > > clocks, but I don't think this is desired for clocks with the
> > > CLK_IGNORE_UNUSED flag.
> > > 
> > 
> > Here is the way I see it. Critical clocks means the system can't work
> > without, so do not ever disable/unprepare. The "ignore unused" flag
> > tells the core to not do anything to this clock, even if it is unused.
> > For now, it just leaves the clock alone, but the flag could be used for
> > some other stuff in the future.
> > 
> > Now, the behavior is entirely different.
> > 
> > For the "critical" clock disable/unprepare, the core does nothing
> > (returns without calling the disable/unprepare ops).
> > 
> > As for the "ignore unused", the clock can be disabled later on,
> > which would decrement the prepare/enable counter.
> > The imx earlycon serial driver could implement a late initcall,
> > that takes the clocks from the devicetree uart node and disables
> > them. The user doesn't even count in this situation.
> > 
> > Plus, there is no other reason someone would use the CLK_IGNORE_UNUSED,
> > other than leaving a clock that is already enabled stay as is (at least,
> > not with the current implementation). So why not mark it as enabled in 
> > the core, if the HW says it is enabled ?
> 
> The CLK_IGNORE_UNUSED is there from the start of the clock framework, so
> there is no commit message that tells what it shall be used for. AFAIR
> the flag was thought for being used with clocks which should not be
> disabled, but had n

Re: [RFC] clk: Mark HW enabled clocks as enabled in core

2021-01-26 Thread Abel Vesa
On 21-01-26 12:51:05, Sascha Hauer wrote:
> On Tue, Jan 26, 2021 at 01:21:36PM +0200, Abel Vesa wrote:
> > Some clocks are already enabled in HW even before the kernel
> > starts to boot. So, in order to make sure that these clocks do not
> > get disabled when clk_disable_unused call is done or when
> > reparenting clocks, we enable them in core on clock registration.
> > Such a clock will have to be registered with CLK_IGNORE_UNUSED flag
> > and also needs to have the is_enabled ops implemented.
> > 
> > Signed-off-by: Abel Vesa 
> > ---
> >  drivers/clk/clk.c | 11 ++-
> >  1 file changed, 10 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
> > index 3d751ae5bc70..26d55851cfa5 100644
> > --- a/drivers/clk/clk.c
> > +++ b/drivers/clk/clk.c
> > @@ -3416,6 +3416,7 @@ static int __clk_core_init(struct clk_core *core)
> > int ret;
> > struct clk_core *parent;
> > unsigned long rate;
> > +   bool is_hw_enabled = false;
> > int phase;
> >  
> > if (!core)
> > @@ -3558,12 +3559,20 @@ static int __clk_core_init(struct clk_core *core)
> > rate = 0;
> > core->rate = core->req_rate = rate;
> >  
> > +   /*
> > +* If the clock has the CLK_IGNORE_UNUSED flag set and it is already
> > +* enabled in HW, enable it in core too so it won't get accidentally
> > +* disabled when walking the orphan tree and reparenting clocks
> > +*/
> > +   if (core->flags & CLK_IGNORE_UNUSED && core->ops->is_enabled)
> > +   is_hw_enabled = clk_core_is_enabled(core);
> > +
> > /*
> >  * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
> >  * don't get accidentally disabled when walking the orphan tree and
> >  * reparenting clocks
> >  */
> > -   if (core->flags & CLK_IS_CRITICAL) {
> > +   if (core->flags & CLK_IS_CRITICAL || is_hw_enabled) {
> > unsigned long flags;
> >  
> > ret = clk_core_prepare(core);
> 
> This means that a bootloader enabled clock with CLK_IGNORE_UNUSED flag
> can effectively never be disabled because the prepare/enable count is 1
> without any user. This is the behaviour we want to have with critical
> clocks, but I don't think this is desired for clocks with the
> CLK_IGNORE_UNUSED flag.
> 

Here is the way I see it. Critical clocks means the system can't work
without, so do not ever disable/unprepare. The "ignore unused" flag
tells the core to not do anything to this clock, even if it is unused.
For now, it just leaves the clock alone, but the flag could be used for
some other stuff in the future.

Now, the behavior is entirely different.

For the "critical" clock disable/unprepare, the core does nothing
(returns without calling the disable/unprepare ops).

As for the "ignore unused", the clock can be disabled later on,
which would decrement the prepare/enable counter.
The imx earlycon serial driver could implement a late initcall,
that takes the clocks from the devicetree uart node and disables
them. The user doesn't even count in this situation.

Plus, there is no other reason someone would use the CLK_IGNORE_UNUSED,
other than leaving a clock that is already enabled stay as is (at least,
not with the current implementation). So why not mark it as enabled in 
the core, if the HW says it is enabled ?


[RFC] clk: Mark HW enabled clocks as enabled in core

2021-01-26 Thread Abel Vesa
Some clocks are already enabled in HW even before the kernel
starts to boot. So, in order to make sure that these clocks do not
get disabled when clk_disable_unused call is done or when
reparenting clocks, we enable them in core on clock registration.
Such a clock will have to be registered with CLK_IGNORE_UNUSED flag
and also needs to have the is_enabled ops implemented.

Signed-off-by: Abel Vesa 
---
 drivers/clk/clk.c | 11 ++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 3d751ae5bc70..26d55851cfa5 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -3416,6 +3416,7 @@ static int __clk_core_init(struct clk_core *core)
int ret;
struct clk_core *parent;
unsigned long rate;
+   bool is_hw_enabled = false;
int phase;
 
if (!core)
@@ -3558,12 +3559,20 @@ static int __clk_core_init(struct clk_core *core)
rate = 0;
core->rate = core->req_rate = rate;
 
+   /*
+* If the clock has the CLK_IGNORE_UNUSED flag set and it is already
+* enabled in HW, enable it in core too so it won't get accidentally
+* disabled when walking the orphan tree and reparenting clocks
+*/
+   if (core->flags & CLK_IGNORE_UNUSED && core->ops->is_enabled)
+   is_hw_enabled = clk_core_is_enabled(core);
+
/*
 * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
 * don't get accidentally disabled when walking the orphan tree and
 * reparenting clocks
 */
-   if (core->flags & CLK_IS_CRITICAL) {
+   if (core->flags & CLK_IS_CRITICAL || is_hw_enabled) {
unsigned long flags;
 
ret = clk_core_prepare(core);
-- 
2.29.2



Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-01-21 Thread Abel Vesa
On 21-01-21 10:56:17, Sascha Hauer wrote:
> On Wed, Jan 20, 2021 at 06:14:21PM +0200, Abel Vesa wrote:
> > On 21-01-20 16:50:01, Sascha Hauer wrote:
> > > On Wed, Jan 20, 2021 at 05:28:13PM +0200, Abel Vesa wrote:
> > > > On 21-01-20 16:13:05, Sascha Hauer wrote:
> > > > > Hi Abel,
> > > > > 
> > > > > On Wed, Jan 20, 2021 at 04:44:54PM +0200, Abel Vesa wrote:
> > > > > > On 21-01-18 08:00:43, Adam Ford wrote:
> > > > > > > On Mon, Jan 18, 2021 at 6:52 AM Abel Vesa  
> > > > > > > wrote:
> > > > 
> > > > ...
> > > > 
> > > > > > > 
> > > > > > > >
> > > > > > > > TBH, I'm against the idea of having to call consumer API from a 
> > > > > > > > clock provider driver.
> > > > > > > > I'm still investigating a way of moving the uart clock control 
> > > > > > > > calls in drivers/serial/imx,
> > > > > > > > where they belong.
> > > > > > > 
> > > > > > > That makes sense.
> > > > > > > 
> > > > > > 
> > > > > > Just a thought. The uart clock used for console remains on from 
> > > > > > u-boot,
> > > > > > so maybe it's enough to just add the CLK_IGNORE_UNUSED flag to all 
> > > > > > the
> > > > > > uart root clocks and remove the prepare/enable calls for uart 
> > > > > > clocks 
> > > > > > for good. I don't really have a way to test it right now, but maybe
> > > > > > you could give it a try.
> > > > > 
> > > > > That would mean that UART clocks will never be disabled, regardless of
> > > > > whether they are used for console or not. That doesn't sound very
> > > > > appealing.
> > > > 
> > > > AFAIK, the only uart clock that is enabled by u-boot is the one used for
> > > > the console. Later on, when the serial driver probes, it will enable it 
> > > > itself.
> > > > 
> > > > Unless I'm missing something, this is exactly what we need.
> > > 
> > > It might enable it, but with CLK_IGNORE_UNUSED the clock won't be
> > > disabled again when a port is closed after usage
> > 
> > OK, tell me what I'm getting wrong in the following scenario:
> > 
> > U-boot leaves the console uart clock enabled. All the other ones are 
> > disabled.
> > 
> > Kernel i.MX clk driver registers the uart clocks with flag 
> > CLK_IGNORE_UNUSED.
> 
> I was wrong at that point. I originally thought the kernel will never
> disable these clocks, but in fact it only leaves them enabled during the
> clk_disable_unused call.
> 
> However, when CLK_IGNORE_UNUSED becomes relevant it's too late already.
> I just chatted with Lucas and he told me what the original problem was
> that his patch solved.
> 
> The problem comes when an unrelated device and the earlycon UART have
> the same parent clocks. The parent clock is enabled, but it's reference
> count is zero. Now when the unrelated device probes and toggles its
> clocks then the shared parent clock will be disabled due to the
> reference count being zero. Next time earlycon prints a character the
> system hangs because the UART gates are still enabled, but their parent
> clocks no longer are.
> 

Hmm, that is indeed a problem. That's why I think there should be some
kind of NOCACHE flag for almost all the types of clocks. For example,
in this case, it makes sense for the core to check the bit in the register
and then disable the parent based on that instead of relying on the refcount.
Anyway, that's something that needs to be added in the CCF.

> Overall I think Lucas' patches are still valid and relevant and with
> Adams patches we even no longer have to enable all UART clocks, but
> only the ones which are actually needed.

Yeah, for now, I think we can go with Adam's patches. But longterm, I would
like to remove the special case of the uart clocks we have right now in all
the i.MX clock drivers.

> 
> Sascha
> 
> 
> -- 
> Pengutronix e.K.   | |
> Steuerwalder Str. 21   | 
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pengutronix.de%2Fdata=04%7C01%7Cabel.vesa%40nxp.com%7Ceed68987c68f4aeaa63408d8bdf2d051%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637468197861821302%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=X1J8KgxFquNin80zKVz0Ao22vv1MuTMWf91BUTczh9Y%3Dreserved=0
>   |
> 31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
> Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-01-20 Thread Abel Vesa
On 21-01-20 16:50:01, Sascha Hauer wrote:
> On Wed, Jan 20, 2021 at 05:28:13PM +0200, Abel Vesa wrote:
> > On 21-01-20 16:13:05, Sascha Hauer wrote:
> > > Hi Abel,
> > > 
> > > On Wed, Jan 20, 2021 at 04:44:54PM +0200, Abel Vesa wrote:
> > > > On 21-01-18 08:00:43, Adam Ford wrote:
> > > > > On Mon, Jan 18, 2021 at 6:52 AM Abel Vesa  wrote:
> > 
> > ...
> > 
> > > > > 
> > > > > >
> > > > > > TBH, I'm against the idea of having to call consumer API from a 
> > > > > > clock provider driver.
> > > > > > I'm still investigating a way of moving the uart clock control 
> > > > > > calls in drivers/serial/imx,
> > > > > > where they belong.
> > > > > 
> > > > > That makes sense.
> > > > > 
> > > > 
> > > > Just a thought. The uart clock used for console remains on from u-boot,
> > > > so maybe it's enough to just add the CLK_IGNORE_UNUSED flag to all the
> > > > uart root clocks and remove the prepare/enable calls for uart clocks 
> > > > for good. I don't really have a way to test it right now, but maybe
> > > > you could give it a try.
> > > 
> > > That would mean that UART clocks will never be disabled, regardless of
> > > whether they are used for console or not. That doesn't sound very
> > > appealing.
> > 
> > AFAIK, the only uart clock that is enabled by u-boot is the one used for
> > the console. Later on, when the serial driver probes, it will enable it 
> > itself.
> > 
> > Unless I'm missing something, this is exactly what we need.
> 
> It might enable it, but with CLK_IGNORE_UNUSED the clock won't be
> disabled again when a port is closed after usage

OK, tell me what I'm getting wrong in the following scenario:

U-boot leaves the console uart clock enabled. All the other ones are disabled.

Kernel i.MX clk driver registers the uart clocks with flag CLK_IGNORE_UNUSED.

Serial driver probes, then enables/disables the clocks when the port 
opens/closes.

The clk_disable_unused will ignore the uart clocks entirely due to the flag.


Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-01-20 Thread Abel Vesa
On 21-01-20 16:13:05, Sascha Hauer wrote:
> Hi Abel,
> 
> On Wed, Jan 20, 2021 at 04:44:54PM +0200, Abel Vesa wrote:
> > On 21-01-18 08:00:43, Adam Ford wrote:
> > > On Mon, Jan 18, 2021 at 6:52 AM Abel Vesa  wrote:

...

> > > 
> > > >
> > > > TBH, I'm against the idea of having to call consumer API from a clock 
> > > > provider driver.
> > > > I'm still investigating a way of moving the uart clock control calls in 
> > > > drivers/serial/imx,
> > > > where they belong.
> > > 
> > > That makes sense.
> > > 
> > 
> > Just a thought. The uart clock used for console remains on from u-boot,
> > so maybe it's enough to just add the CLK_IGNORE_UNUSED flag to all the
> > uart root clocks and remove the prepare/enable calls for uart clocks 
> > for good. I don't really have a way to test it right now, but maybe
> > you could give it a try.
> 
> That would mean that UART clocks will never be disabled, regardless of
> whether they are used for console or not. That doesn't sound very
> appealing.

AFAIK, the only uart clock that is enabled by u-boot is the one used for
the console. Later on, when the serial driver probes, it will enable it itself.

Unless I'm missing something, this is exactly what we need.


Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-01-20 Thread Abel Vesa
On 21-01-18 08:00:43, Adam Ford wrote:
> On Mon, Jan 18, 2021 at 6:52 AM Abel Vesa  wrote:
> >
> > On 21-01-15 12:29:08, Adam Ford wrote:
> >
> > ...
> >
> > > diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
> > > index a66cabfbf94f..66192fe0a898 100644
> > > --- a/drivers/clk/imx/clk-imx25.c
> > > +++ b/drivers/clk/imx/clk-imx25.c
> > > @@ -73,16 +73,6 @@ enum mx25_clks {
> > >
> > >  static struct clk *clk[clk_max];
> > >
> > > -static struct clk ** const uart_clks[] __initconst = {
> > > - [uart_ipg_per],
> > > - [uart1_ipg],
> > > - [uart2_ipg],
> > > - [uart3_ipg],
> > > - [uart4_ipg],
> > > - [uart5_ipg],
> > > - NULL
> > > -};
> > > -
> >
> > I'm assuming there is another patch that updates the dts files. Right ?
> 
> I have only been able to test this on an i.MX8M Mini.  I need to set
> the parent clock of the i.MX8M Mini to an 80 MHz clock in order to run
> the UART at 4Mbps.   With this patch, I can stop enabling the all the
> UART clocks early and allow the clock parent configuration to occur.
> From what I can tell, the remaining clocks should get activated as
> they are needed, because I was able to use Bluetooth connected to
> UART1 running at 4MBps using a 80MHz clock source with this patch, and
> the clk_summary shows the clock is running at the proper speed.
> Without this patch, the UART fails to re-parent, so I'm stuck at lower
> speeds and that means choppy Bluetooth audio.
> 
> The Kernel that NXP hosts on Code Aurora that they use for Yocto
> attempts scan through stdout to only enable those clocks [1].  I
> attempted to push it upstream, but it was rejected [2].  Sascha
> suggested creating an array which could be filled when the clocks are
> enabled and that array would be used to deactivate the clocks at
> shutdown.  That's what I attempted to do here.
> 
> I don't have older imx boards to know if their device trees are
> configured in such a way without modifications to the device tree or
> not, but since it appears to work for NXP in [2], I assumed it would
> work here.
> 
> [1] - 
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fsource.codeaurora.org%2Fexternal%2Fimx%2Flinux-imx%2Fcommit%2Fdrivers%2Fclk%2Fimx%2Fclk.c%3Fh%3Dimx_5.4.47_2.2.0%26id%3D754ae82cc55b7445545fc2f092a70e0f490e9c1bdata=04%7C01%7Cabel.vesa%40nxp.com%7Cf8922e76fa85485b86c508d8bbb97c47%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637465752633257569%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=bVmPaM1nN7Sm%2BISVvlIBoWYozfJE96fHpw431IEuggk%3Dreserved=0
> [2] - 
> https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fpatchwork.kernel.org%2Fproject%2Flinux-arm-kernel%2Fpatch%2F20201229145130.2680442-1-aford173%40gmail.com%2Fdata=04%7C01%7Cabel.vesa%40nxp.com%7Cf8922e76fa85485b86c508d8bbb97c47%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637465752633257569%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=226HwbeVhZUW%2FJ3hsCSaVIxghOsPBH9EWeF8vFxaTWE%3Dreserved=0
> 
> >
> > TBH, I'm against the idea of having to call consumer API from a clock 
> > provider driver.
> > I'm still investigating a way of moving the uart clock control calls in 
> > drivers/serial/imx,
> > where they belong.
> 
> That makes sense.
> 

Just a thought. The uart clock used for console remains on from u-boot,
so maybe it's enough to just add the CLK_IGNORE_UNUSED flag to all the
uart root clocks and remove the prepare/enable calls for uart clocks 
for good. I don't really have a way to test it right now, but maybe
you could give it a try.



Re: [PATCH V3] clk: imx: Fix reparenting of UARTs not associated with sdout

2021-01-18 Thread Abel Vesa
On 21-01-15 12:29:08, Adam Ford wrote:

...

> diff --git a/drivers/clk/imx/clk-imx25.c b/drivers/clk/imx/clk-imx25.c
> index a66cabfbf94f..66192fe0a898 100644
> --- a/drivers/clk/imx/clk-imx25.c
> +++ b/drivers/clk/imx/clk-imx25.c
> @@ -73,16 +73,6 @@ enum mx25_clks {
>  
>  static struct clk *clk[clk_max];
>  
> -static struct clk ** const uart_clks[] __initconst = {
> - [uart_ipg_per],
> - [uart1_ipg],
> - [uart2_ipg],
> - [uart3_ipg],
> - [uart4_ipg],
> - [uart5_ipg],
> - NULL
> -};
> -

I'm assuming there is another patch that updatesthe dts files. Right ?

TBH, I'm against the idea of having to call consumer API from a clock provider 
driver.
I'm still investigating a way of moving the uart clock control calls in 
drivers/serial/imx,
where they belong.

>  static int __init __mx25_clocks_init(void __iomem *ccm_base)
>  {
>   BUG_ON(!ccm_base);
> @@ -228,7 +218,7 @@ static int __init __mx25_clocks_init(void __iomem 
> *ccm_base)
>*/
>   clk_set_parent(clk[cko_sel], clk[ipg]);
>  
> - imx_register_uart_clocks(uart_clks);
> + imx_register_uart_clocks(6);

Suggestion: Maybe the number of clocks can be determined by the existing clocks 
in that dts node.
Hardcoding is not a good ideea here.

...

>  
> diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c
> index 47882c51cb85..158fe302a8b7 100644
> --- a/drivers/clk/imx/clk.c
> +++ b/drivers/clk/imx/clk.c
> @@ -147,8 +147,10 @@ void imx_cscmr1_fixup(u32 *val)
>  }
>  
>  #ifndef MODULE
> -static int imx_keep_uart_clocks;
> -static struct clk ** const *imx_uart_clocks;
> +
> +static bool imx_keep_uart_clocks;
> +static int imx_enabled_uart_clocks;
> +static struct clk **imx_uart_clocks;
>  
>  static int __init imx_keep_uart_clocks_param(char *str)
>  {
> @@ -161,24 +163,43 @@ __setup_param("earlycon", imx_keep_uart_earlycon,
>  __setup_param("earlyprintk", imx_keep_uart_earlyprintk,
> imx_keep_uart_clocks_param, 0);
>  
> -void imx_register_uart_clocks(struct clk ** const clks[])
> +void imx_register_uart_clocks(unsigned int clk_count)
>  {
> +#ifdef CONFIG_OF
>   if (imx_keep_uart_clocks) {
>   int i;
>  
> - imx_uart_clocks = clks;
> - for (i = 0; imx_uart_clocks[i]; i++)
> - clk_prepare_enable(*imx_uart_clocks[i]);
> + imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), 
> GFP_KERNEL);
> + imx_enabled_uart_clocks = 0;
> +
> + for (i = 0; i < clk_count; i++) {
> + imx_uart_clocks[imx_enabled_uart_clocks] = 
> of_clk_get(of_stdout, i);
> +
> + /* Stop if there are no more of_stdout references */
> + if (IS_ERR(imx_uart_clocks[imx_enabled_uart_clocks]))
> + return;
> +
> + /* Only enable the clock if it's not NULL */
> + if (imx_uart_clocks[imx_enabled_uart_clocks])
> + 
> clk_prepare_enable(imx_uart_clocks[imx_enabled_uart_clocks++]);
> + }
>   }
> +#else
> + /* i.MX boards use device trees now.  For build tests without 
> CONFIG_OF, do nothing */
> + imx_enabled_uart_clocks = 0;
> +#endif

Don't really see the point of this #ifdef here. Just makes the code more messy.

>  }
>  
>  static int __init imx_clk_disable_uart(void)
>  {
> - if (imx_keep_uart_clocks && imx_uart_clocks) {
> + if (imx_keep_uart_clocks && imx_enabled_uart_clocks) {
>   int i;
>  
> - for (i = 0; imx_uart_clocks[i]; i++)
> - clk_disable_unprepare(*imx_uart_clocks[i]);
> + for (i = 0; i < imx_enabled_uart_clocks; i++) {
> + clk_disable_unprepare(imx_uart_clocks[i]);
> + clk_put(imx_uart_clocks[i]);
> + };
> + kfree(imx_uart_clocks);
>   }
>  
>   return 0;
> diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
> index 4f04c8287286..7571603bee23 100644
> --- a/drivers/clk/imx/clk.h
> +++ b/drivers/clk/imx/clk.h
> @@ -11,9 +11,9 @@ extern spinlock_t imx_ccm_lock;
>  void imx_check_clocks(struct clk *clks[], unsigned int count);
>  void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
>  #ifndef MODULE
> -void imx_register_uart_clocks(struct clk ** const clks[]);
> +void imx_register_uart_clocks(unsigned int clk_count);
>  #else
> -static inline void imx_register_uart_clocks(struct clk ** const clks[])
> +static inline void imx_register_uart_clocks(unsigned int clk_count)
>  {
>  }
>  #endif
> -- 
> 2.25.1
> 


[PATCH] MAINTAINERS: Add section for NXP i.MX clock drivers

2021-01-13 Thread Abel Vesa
Add a section for NXP i.MX clock drivers and list myself
as the maintainer.

Signed-off-by: Abel Vesa 
---
 MAINTAINERS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 2894657..9eafd4d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -12827,6 +12827,13 @@ F: drivers/iio/gyro/fxas21002c_core.c
 F: drivers/iio/gyro/fxas21002c_i2c.c
 F: drivers/iio/gyro/fxas21002c_spi.c
 
+NXP i.MX CLOCK DRIVERS
+M: Abel Vesa 
+L: linux-...@vger.kernel.org
+L: linux-...@nxp.com
+S: Maintained
+F: drivers/clk/imx/
+
 NXP i.MX 8MQ DCSS DRIVER
 M: Laurentiu Palcu 
 R: Lucas Stach 
-- 
2.7.4



Re: [PATCH] Revert "clk: imx: fix composite peripheral flags"

2021-01-04 Thread Abel Vesa
On 20-12-31 17:33:40, Fabio Estevam wrote:
> Hi Martin,
> 
> On Thu, Dec 31, 2020 at 11:22 AM Martin Kepplinger
>  wrote:
> >
> > This reverts commit 936c383673b9e3007432f17140ac62de53d87db9.
> >
> > It breaks clock reparenting via devfreq on the imx8mq used in the
> > Librem 5 phone. When switching dram frequency (which worked before)
> > the system now hangs after this where the dram_apb clock cannot be
> > set:
> >
> > [  129.391755] imx8m-ddrc-devfreq 3d40.memory-controller: failed to
> > set dram_apb parent: -16
> > [  129.391959] imx8m-ddrc-devfreq 3d40.memory-controller: ddrc
> > failed freq switch to 2500 from 8: error -16. now at 2500
> > [  129.406133] imx8m-ddrc-devfreq 3d40.memory-controller: failed to
> > update frequency from PM QoS (-16)
> 
> I am wondering whether IMX8MQ_CLK_DRAM_ALT should also be marked as
> CLK_IS_CRITICAL.
> 

Hmm, the way the DRAM clocks are right registered right now is a real mess.
The DRAM clocks on i.MX8M are changed in TF-A, but the kernel still needs to
register them to keep track of the clock tree.

Martin, I already have a patchset waiting to be shipped which doesn't 
only fix the 8MQ, but all the 8M platforms. Unfortunately, I haven't had the 
time
to work on that in the last couple of weeks but I intend to switch back to it 
soon.

Fabio, marking the DRAM clocks as critical will not allow the set_parent to be 
done,
as CLK_IS_CRITICAL flag and set_parent do not go together. As of now the devfreq
tries to reparent to be consistent with TF-A configuration.

My approach here was to make the DRAM clocks read-only. This means adding some 
stuff in the clock core subsystem too.

> Could you please try the following change without the revert?
> 
> --- a/drivers/clk/imx/clk-imx8mq.c
> +++ b/drivers/clk/imx/clk-imx8mq.c
> @@ -458,7 +458,7 @@ static int imx8mq_clocks_probe(struct platform_device 
> *pdev)
>  * Mark with GET_RATE_NOCACHE to always read div value from hardware
>  */
> hws[IMX8MQ_CLK_DRAM_CORE] =
> imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1,
> imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels),
> CLK_IS_CRITICAL);
> -   hws[IMX8MQ_CLK_DRAM_ALT] =
> __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base +
> 0xa000, CLK_GET_RATE_NOCACHE);
> +   hws[IMX8MQ_CLK_DRAM_ALT] =
> __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base +
> 0xa000, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> hws[IMX8MQ_CLK_DRAM_APB] =
> __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base +
> 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
> 
> Thanks


[PATCH v2 3/5] clk: composite: Allow gate ops with only .is_enabled op

2020-11-26 Thread Abel Vesa
Some composite clocks might be enabled/disabled from outside the
clock framework. So allow the composite clock register successfully
with only the .is_enabled op for gate ops.

Signed-off-by: Abel Vesa 
---
 drivers/clk/clk-composite.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c
index 2ddb54f..29f00a9 100644
--- a/drivers/clk/clk-composite.c
+++ b/drivers/clk/clk-composite.c
@@ -278,17 +278,18 @@ static struct clk_hw *__clk_hw_register_composite(struct 
device *dev,
}
 
if (gate_hw && gate_ops) {
-   if (!gate_ops->is_enabled || !gate_ops->enable ||
-   !gate_ops->disable) {
-   hw = ERR_PTR(-EINVAL);
-   goto err;
-   }
-
composite->gate_hw = gate_hw;
composite->gate_ops = gate_ops;
-   clk_composite_ops->is_enabled = clk_composite_is_enabled;
-   clk_composite_ops->enable = clk_composite_enable;
-   clk_composite_ops->disable = clk_composite_disable;
+   if (gate_ops->is_enabled) {
+   clk_composite_ops->is_enabled = 
clk_composite_is_enabled;
+   } else {
+   hw = ERR_PTR(-EINVAL);
+   goto err;
+   }
+   if (gate_ops->enable)
+   clk_composite_ops->enable = clk_composite_enable;
+   if (gate_ops->disable)
+   clk_composite_ops->disable = clk_composite_disable;
}
 
init.ops = clk_composite_ops;
-- 
2.7.4



[PATCH v2 5/5] clk: imx8m: Use dram variant registration for dram clocks

2020-11-26 Thread Abel Vesa
Both dram_apb and dram_alt are controlled by EL3. Using the dram
variant registration of the composite-8m clock, the mux and the
divider will be read only. Do this for all i.MX8M platforms.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-imx8mm.c | 4 ++--
 drivers/clk/imx/clk-imx8mn.c | 4 ++--
 drivers/clk/imx/clk-imx8mp.c | 4 ++--
 drivers/clk/imx/clk-imx8mq.c | 4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c
index 7c90586..f94f0a4 100644
--- a/drivers/clk/imx/clk-imx8mm.c
+++ b/drivers/clk/imx/clk-imx8mm.c
@@ -468,8 +468,8 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
 * DRAM clocks are manipulated from TF-A outside clock framework.
 * Mark with GET_RATE_NOCACHE to always read div value from hardware
 */
-   hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", 
imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
-   hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", 
imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+   hws[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_hw_composite_dram("dram_alt", 
imx8mm_dram_alt_sels, base + 0xa000);
+   hws[IMX8MM_CLK_DRAM_APB] = imx8m_clk_hw_composite_dram("dram_apb", 
imx8mm_dram_apb_sels, base + 0xa080);
 
/* IP */
hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", 
imx8mm_vpu_g1_sels, base + 0xa100);
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
index 3c21db9..eb90879 100644
--- a/drivers/clk/imx/clk-imx8mn.c
+++ b/drivers/clk/imx/clk-imx8mn.c
@@ -451,8 +451,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
 * DRAM clocks are manipulated from TF-A outside clock framework.
 * Mark with GET_RATE_NOCACHE to always read div value from hardware
 */
-   hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", 
imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
-   hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", 
imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+   hws[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_hw_composite_dram("dram_alt", 
imx8mn_dram_alt_sels, base + 0xa000);
+   hws[IMX8MN_CLK_DRAM_APB] = imx8m_clk_hw_composite_dram("dram_apb", 
imx8mn_dram_apb_sels, base + 0xa080);
 
hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", 
imx8mn_disp_pixel_sels, base + 0xa500);
hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, 
base + 0xa600);
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 2f4e1d6..70d671c 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -579,8 +579,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", 
ccm_base + 0x9080, 0, 1);
hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", 
"audio_ahb", ccm_base + 0x9180, 0, 1);
 
-   hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", 
imx8mp_dram_alt_sels, ccm_base + 0xa000);
-   hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", 
imx8mp_dram_apb_sels, ccm_base + 0xa080);
+   hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite_dram("dram_alt", 
imx8mp_dram_alt_sels, ccm_base + 0xa000);
+   hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_dram("dram_apb", 
imx8mp_dram_apb_sels, ccm_base + 0xa080);
hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", 
imx8mp_vpu_g1_sels, ccm_base + 0xa100);
hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", 
imx8mp_vpu_g2_sels, ccm_base + 0xa180);
hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, 
ccm_base + 0xa200);
diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c
index 779ea69..a30642f 100644
--- a/drivers/clk/imx/clk-imx8mq.c
+++ b/drivers/clk/imx/clk-imx8mq.c
@@ -458,8 +458,8 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
 * Mark with GET_RATE_NOCACHE to always read div value from hardware
 */
hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base 
+ 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), 
CLK_IS_CRITICAL);
-   hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", 
imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
-   hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", 
imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+   hws[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_hw_comp

[PATCH v2 1/5] clk: Add clk_gate_ro_ops for read-only gate clocks

2020-11-26 Thread Abel Vesa
The clocks that can be changed from outside of the clock common framework
scope (for example, EL3) need to have only the .is_enabled gate op.

Signed-off-by: Abel Vesa 
---
 drivers/clk/clk-gate.c   | 5 +
 include/linux/clk-provider.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c
index 070dc47..41ca887 100644
--- a/drivers/clk/clk-gate.c
+++ b/drivers/clk/clk-gate.c
@@ -123,6 +123,11 @@ const struct clk_ops clk_gate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_gate_ops);
 
+const struct clk_ops clk_gate_ro_ops = {
+   .is_enabled = clk_gate_is_enabled,
+};
+EXPORT_SYMBOL_GPL(clk_gate_ro_ops);
+
 struct clk_hw *__clk_hw_register_gate(struct device *dev,
struct device_node *np, const char *name,
const char *parent_name, const struct clk_hw *parent_hw,
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 86b7075..81ba1aa 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -483,6 +483,7 @@ struct clk_gate {
 #define CLK_GATE_BIG_ENDIANBIT(2)
 
 extern const struct clk_ops clk_gate_ops;
+extern const struct clk_ops clk_gate_ro_ops;
 struct clk_hw *__clk_hw_register_gate(struct device *dev,
struct device_node *np, const char *name,
const char *parent_name, const struct clk_hw *parent_hw,
-- 
2.7.4



[PATCH v2 4/5] clk: imx: composite-8m: Add DRAM clock registration variant

2020-11-26 Thread Abel Vesa
The switch between parents for dram_apb and dram_alt is done in EL3,
so make all the ops read-only. That means none of the ops that write
any of the registers is used for such a clock.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-composite-8m.c | 12 +++-
 drivers/clk/imx/clk.h  |  7 +++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-composite-8m.c 
b/drivers/clk/imx/clk-composite-8m.c
index 2c309e3..cf0c2b4 100644
--- a/drivers/clk/imx/clk-composite-8m.c
+++ b/drivers/clk/imx/clk-composite-8m.c
@@ -184,6 +184,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char 
*name,
struct clk_mux *mux = NULL;
const struct clk_ops *divider_ops;
const struct clk_ops *mux_ops;
+   const struct clk_ops *gate_ops;
 
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux)
@@ -206,16 +207,25 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char 
*name,
div->width = PCG_CORE_DIV_WIDTH;
divider_ops = _divider_ops;
mux_ops = _clk_composite_mux_ops;
+   gate_ops = _gate_ops;
} else if (composite_flags & IMX_COMPOSITE_BUS) {
div->shift = PCG_PREDIV_SHIFT;
div->width = PCG_PREDIV_WIDTH;
divider_ops = _clk_composite_divider_ops;
mux_ops = _clk_composite_mux_ops;
+   gate_ops = _gate_ops;
+   } else if (composite_flags & IMX_COMPOSITE_RO) {
+   div->shift = PCG_PREDIV_SHIFT;
+   div->width = PCG_PREDIV_WIDTH;
+   divider_ops = _divider_ro_ops;
+   mux_ops = _mux_ro_ops;
+   gate_ops = _gate_ro_ops;
} else {
div->shift = PCG_PREDIV_SHIFT;
div->width = PCG_PREDIV_WIDTH;
divider_ops = _clk_composite_divider_ops;
mux_ops = _mux_ops;
+   gate_ops = _gate_ops;
flags |= CLK_SET_PARENT_GATE;
}
 
@@ -233,7 +243,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char 
*name,
 
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
mux_hw, mux_ops, div_hw,
-   divider_ops, gate_hw, _gate_ops, flags);
+   divider_ops, gate_hw, gate_ops, flags);
if (IS_ERR(hw))
goto fail;
 
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 4f04c82..878ceb0 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -532,6 +532,7 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char 
*parent_name,
 
 #define IMX_COMPOSITE_CORE BIT(0)
 #define IMX_COMPOSITE_BUS  BIT(1)
+#define IMX_COMPOSITE_RO   BIT(2)
 
 struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
const char * const *parent_names,
@@ -557,6 +558,12 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char 
*name,
IMX_COMPOSITE_CORE, \
CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
 
+#define imx8m_clk_hw_composite_dram(name, parent_names, reg) \
+   imx8m_clk_hw_composite_flags(name, parent_names, \
+   ARRAY_SIZE(parent_names), reg, IMX_COMPOSITE_RO, \
+   CLK_GET_RATE_NOCACHE | CLK_GET_PARENT_NOCACHE \
+   | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
+
 #define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \
  flags) \
to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \
-- 
2.7.4



[PATCH v2 2/5] clk: Add CLK_GET_PARENT_NOCACHE flag

2020-11-26 Thread Abel Vesa
This can be used by the clocks that have their parents changed from EL3.
This way the clk_get_parent will read the value from register instead of
using the value stored in the core framework.

Signed-off-by: Abel Vesa 
Suggested-by: Peng Fan 
---
 drivers/clk/clk.c| 31 +--
 include/linux/clk-provider.h |  1 +
 2 files changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index c77feb6..2dd4bf4 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2401,6 +2401,16 @@ int clk_set_max_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL_GPL(clk_set_max_rate);
 
+static struct clk_core *__clk_get_parent(struct clk_core *core)
+{
+   u8 index = 0;
+
+   if (core->num_parents > 1 && core->ops->get_parent)
+   index = core->ops->get_parent(core->hw);
+
+   return clk_core_get_parent_by_index(core, index);
+}
+
 /**
  * clk_get_parent - return the parent of a clk
  * @clk: the clk whose parent gets returned
@@ -2415,24 +2425,17 @@ struct clk *clk_get_parent(struct clk *clk)
return NULL;
 
clk_prepare_lock();
-   /* TODO: Create a per-user clk and change callers to call clk_put */
-   parent = !clk->core->parent ? NULL : clk->core->parent->hw->clk;
+   if (clk->core && (clk->core->flags & CLK_GET_PARENT_NOCACHE))
+   parent = __clk_get_parent(clk->core)->hw->clk;
+   else
+   /* TODO: Create a per-user clk and change callers to call 
clk_put */
+   parent = !clk->core->parent ? NULL : clk->core->parent->hw->clk;
clk_prepare_unlock();
 
return parent;
 }
 EXPORT_SYMBOL_GPL(clk_get_parent);
 
-static struct clk_core *__clk_init_parent(struct clk_core *core)
-{
-   u8 index = 0;
-
-   if (core->num_parents > 1 && core->ops->get_parent)
-   index = core->ops->get_parent(core->hw);
-
-   return clk_core_get_parent_by_index(core, index);
-}
-
 static void clk_core_reparent(struct clk_core *core,
  struct clk_core *new_parent)
 {
@@ -3352,7 +3355,7 @@ static void clk_core_reparent_orphans_nolock(void)
 * parent.
 */
hlist_for_each_entry_safe(orphan, tmp2, _orphan_list, child_node) {
-   struct clk_core *parent = __clk_init_parent(orphan);
+   struct clk_core *parent = __clk_get_parent(orphan);
 
/*
 * We need to use __clk_set_parent_before() and _after() to
@@ -3453,7 +3456,7 @@ static int __clk_core_init(struct clk_core *core)
goto out;
}
 
-   parent = core->parent = __clk_init_parent(core);
+   parent = core->parent = __clk_get_parent(core);
 
/*
 * Populate core->parent if parent has already been clk_core_init'd. If
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 81ba1aa..f871991b 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -32,6 +32,7 @@
 #define CLK_OPS_PARENT_ENABLE  BIT(12)
 /* duty cycle call may be forwarded to the parent clock */
 #define CLK_DUTY_CYCLE_PARENT  BIT(13)
+#define CLK_GET_PARENT_NOCACHE BIT(14) /* read the parent from reg */
 
 struct clk;
 struct clk_hw;
-- 
2.7.4



[PATCH v2 0/5] clk: imx: Register the dram_apb and dram_alt as read-only

2020-11-26 Thread Abel Vesa
On i.MX8M platforms the dram_apb and dram_alt are controlled from EL3.
So in order to keep track of the actual clock tree in kernel, we need to
actually declare the clocks but never write to any of their registes.
We do that by registering the clocks with only the ops that read but never
write the registers.

Changes since v1:
 * allow generic composite clock registration with .is_enabled gate op
   only

Abel Vesa (5):
  clk: Add clk_gate_ro_ops for read-only gate clocks
  clk: Add CLK_GET_PARENT_NOCACHE flag
  clk: composite: Allow gate ops with only .is_enabled op
  clk: imx: composite-8m: Add DRAM clock registration variant
  clk: imx8m: Use dram variant registration for dram clocks

 drivers/clk/clk-composite.c| 19 ++-
 drivers/clk/clk-gate.c |  5 +
 drivers/clk/clk.c  | 31 +--
 drivers/clk/imx/clk-composite-8m.c | 12 +++-
 drivers/clk/imx/clk-imx8mm.c   |  4 ++--
 drivers/clk/imx/clk-imx8mn.c   |  4 ++--
 drivers/clk/imx/clk-imx8mp.c   |  4 ++--
 drivers/clk/imx/clk-imx8mq.c   |  4 ++--
 drivers/clk/imx/clk.h  |  7 +++
 include/linux/clk-provider.h   |  2 ++
 10 files changed, 60 insertions(+), 32 deletions(-)

-- 
2.7.4



Re: [PATCH v5 10/14] clk: imx: Add generic blk-ctl driver

2020-11-17 Thread Abel Vesa
On 20-11-11 17:13:25, Dong Aisheng wrote:
> On Tue, Nov 3, 2020 at 7:22 PM Abel Vesa  wrote:
> ...
> > +static int imx_blk_ctl_reset_set(struct reset_controller_dev *rcdev,
> > + unsigned long id, bool assert)
> > +{
> > +   struct imx_blk_ctl_drvdata *drvdata = container_of(rcdev,
> > +   struct imx_blk_ctl_drvdata, rcdev);
> > +   unsigned int offset = drvdata->rst_hws[id].offset;
> > +   unsigned int shift = drvdata->rst_hws[id].shift;
> > +   unsigned int mask = drvdata->rst_hws[id].mask;
> > +   void __iomem *reg_addr = drvdata->base + offset;
> > +   unsigned long flags;
> > +   u32 reg;
> > +
> > +   if (!assert && !test_bit(1, >rst_hws[id].asserted))
> > +   return -ENODEV;
> 
> What if consumers call deassert first in probe which seems common in kernel?
> It seems will fail.
> e.g.
> probe() {
> reset_control_get()
> reset_control_deassert()
> }
> 
> Regards
> Aisheng
> 

OK, I'm trying to explain here how I know the resets are supposed to be working
and how the BLK_CTL IP is working.


First of, the BLK_CTL bits (resets and clocks) all have the HW init (default) 
values
as 0. Basically, after the blk_ctl PD is powered on, the resets are deasserted 
and
clocks are gated by default. Since the blk_ctl is not the parent of any of the
consumers in devicetree (the reg maps are entirely different anyway), there is 
no
way of ordering the runtime callbacks between the consumer and the blk_ctl. So 
we
might end up having the runtime resume callback after the one from EARC 
(consumer),
for example, which will basically overwrite the value written by EARC driver 
with
whatever was saved on suspend.

Now, about the usage of the reset bits. AFAICT, it would make more sense to 
assert
the reset, then enable the clock, then deassert. This way, you're keeping the
EARC (consumer) in reset (with the clocks on) until you eventually release it 
out of
reset by deasserting. This is how the runtime resume should deal with the reset
and the clock. As for the runtime suspend, the reset can be entirely ignored as 
long
as you're disabling the clock.

This last part will allow the blk_ctl to make the following assumption:
if all the clocks are disabled and none of the reset bits are asserted, I can 
power off.

Now, I know there are drivers outthere that do assert on suspend, but as long 
as the 
clocks are disabled, the assert will have no impact. But maybe in their case 
the reset
controller cannot power down itself.

As for the safekeeping of the register, I'll just drop it due to the following 
arguments:
1. all the clocks are gated by default
2. all resets are deasserted by default
3. when blk_ctl goes down, all the consumers go down. (all have the same PD)

>From 1 and 2 results the IP will not be running and from 3 results the HW state
of every IP becomes HW init state.

> > +
> > +   if (assert && !test_and_set_bit(1, >rst_hws[id].asserted))
> > +   pm_runtime_get_sync(rcdev->dev)
> > +
> > +   spin_lock_irqsave(>lock, flags);
> > +
> > +   reg = readl(reg_addr);
> > +   if (assert)
> > +   writel(reg & ~(mask << shift), reg_addr);
> > +   else
> > +   writel(reg | (mask << shift), reg_addr);
> > +
> > +   spin_unlock_irqrestore(>lock, flags);
> > +
> > +   if (!assert && test_and_clear_bit(1, 
> > >rst_hws[id].asserted))
> > +   pm_runtime_put(rcdev->dev)
> > +
> > +   return 0;
> > +}
> > +
> > +static int imx_blk_ctl_reset_assert(struct reset_controller_dev *rcdev,
> > +  unsigned long id)
> > +{
> > +   return imx_blk_ctl_reset_set(rcdev, id, true);
> > +}
> > +
> > +static int imx_blk_ctl_reset_deassert(struct reset_controller_dev *rcdev,
> > +unsigned long id)
> > +{
> > +   return imx_blk_ctl_reset_set(rcdev, id, false);
> > +}
> > +
> > +static const struct reset_control_ops imx_blk_ctl_reset_ops = {
> > +   .assert = imx_blk_ctl_reset_assert,
> > +   .deassert   = imx_blk_ctl_reset_deassert,
> > +};
> > +
> > +static int imx_blk_ctl_register_reset_controller(struct device *dev)
> > +{
> > +   const struct imx_blk_ctl_dev_data *dev_data = 
> > of_device_get_match_data(dev);
> > +   struct imx_blk_ctl_drvdata *drvdata = dev_get_drvdata(dev);
> > +   int max = dev_data->resets_max;
> > +   struct imx_reset_hw *hws;
> > +   i

[PATCH v5 01/14] dt-bindings: clocks: imx8mp: Rename audiomix ids clocks to audio_blk_ctl

2020-11-03 Thread Abel Vesa
In the reference manual the actual name is Audio BLK_CTL.
Lets make it more obvious here by renaming from audiomix to audio_blk_ctl.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
Reviewed-by: Dong Aisheng 
---
 include/dt-bindings/clock/imx8mp-clock.h | 120 +++
 1 file changed, 60 insertions(+), 60 deletions(-)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h 
b/include/dt-bindings/clock/imx8mp-clock.h
index e8d68fb..89c67b7 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -324,66 +324,66 @@
 
 #define IMX8MP_CLK_END 313
 
-#define IMX8MP_CLK_AUDIOMIX_SAI1_IPG   0
-#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1 1
-#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2 2
-#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK3 3
-#define IMX8MP_CLK_AUDIOMIX_SAI2_IPG   4
-#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1 5
-#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2 6
-#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK3 7
-#define IMX8MP_CLK_AUDIOMIX_SAI3_IPG   8
-#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1 9
-#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2 10
-#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK3 11
-#define IMX8MP_CLK_AUDIOMIX_SAI5_IPG   12
-#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1 13
-#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2 14
-#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK3 15
-#define IMX8MP_CLK_AUDIOMIX_SAI6_IPG   16
-#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1 17
-#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2 18
-#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK3 19
-#define IMX8MP_CLK_AUDIOMIX_SAI7_IPG   20
-#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1 21
-#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2 22
-#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK3 23
-#define IMX8MP_CLK_AUDIOMIX_ASRC_IPG   24
-#define IMX8MP_CLK_AUDIOMIX_PDM_IPG25
-#define IMX8MP_CLK_AUDIOMIX_SDMA2_ROOT 26
-#define IMX8MP_CLK_AUDIOMIX_SDMA3_ROOT 27
-#define IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT 28
-#define IMX8MP_CLK_AUDIOMIX_DSP_ROOT   29
-#define IMX8MP_CLK_AUDIOMIX_DSPDBG_ROOT30
-#define IMX8MP_CLK_AUDIOMIX_EARC_IPG   31
-#define IMX8MP_CLK_AUDIOMIX_OCRAMA_IPG 32
-#define IMX8MP_CLK_AUDIOMIX_AUD2HTX_IPG33
-#define IMX8MP_CLK_AUDIOMIX_EDMA_ROOT  34
-#define IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT35
-#define IMX8MP_CLK_AUDIOMIX_MU2_ROOT   36
-#define IMX8MP_CLK_AUDIOMIX_MU3_ROOT   37
-#define IMX8MP_CLK_AUDIOMIX_EARC_PHY   38
-#define IMX8MP_CLK_AUDIOMIX_PDM_ROOT   39
-#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK1_SEL 40
-#define IMX8MP_CLK_AUDIOMIX_SAI1_MCLK2_SEL 41
-#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK1_SEL 42
-#define IMX8MP_CLK_AUDIOMIX_SAI2_MCLK2_SEL 43
-#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK1_SEL 44
-#define IMX8MP_CLK_AUDIOMIX_SAI3_MCLK2_SEL 45
-#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK1_SEL 46
-#define IMX8MP_CLK_AUDIOMIX_SAI4_MCLK2_SEL 47
-#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1_SEL 48
-#define IMX8MP_CLK_AUDIOMIX_SAI5_MCLK2_SEL 49
-#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK1_SEL 50
-#define IMX8MP_CLK_AUDIOMIX_SAI6_MCLK2_SEL 51
-#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK1_SEL 52
-#define IMX8MP_CLK_AUDIOMIX_SAI7_MCLK2_SEL 53
-#define IMX8MP_CLK_AUDIOMIX_PDM_SEL54
-#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_REF_SEL55
-#define IMX8MP_CLK_AUDIOMIX_SAI_PLL56
-#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_BYPASS 57
-#define IMX8MP_CLK_AUDIOMIX_SAI_PLL_OUT58
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_IPG  0
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_MCLK11
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_MCLK22
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_MCLK33
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI2_IPG  4
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI2_MCLK15
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI2_MCLK26
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI2_MCLK37
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI3_IPG  8
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI3_MCLK19
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI3_MCLK210
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI3_MCLK311
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI5_IPG  12
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI5_MCLK113
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI5_MCLK214
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI5_MCLK315
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI6_IPG  16
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI6_MCLK117
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI6_MCLK218
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI6_MCLK319
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI7_IPG  20
+#define IMX8MP_CLK_AUDIO_BLK_CTL_SAI7_MCLK121
+#define

[PATCH v5 05/14] dt-bindings: reset: imx8mp: Add media blk_ctl reset IDs

2020-11-03 Thread Abel Vesa
These will be used by the imx8mp for blk_ctl driver.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
Reviewed-by: Dong Aisheng 
---
 include/dt-bindings/reset/imx8mp-reset.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/include/dt-bindings/reset/imx8mp-reset.h 
b/include/dt-bindings/reset/imx8mp-reset.h
index 6c7f17f..ba70248 100644
--- a/include/dt-bindings/reset/imx8mp-reset.h
+++ b/include/dt-bindings/reset/imx8mp-reset.h
@@ -52,4 +52,32 @@
 
 #define IMX8MP_AUDIO_BLK_CTL_RESET_NUM 2
 
+#define IMX8MP_MEDIA_BLK_CTL_RESET_MIPI_DSI_PCLK   0
+#define IMX8MP_MEDIA_BLK_CTL_RESET_MIPI_DSI_CLKREF 1
+#define IMX8MP_MEDIA_BLK_CTL_RESET_MIPI_CSI_PCLK   2
+#define IMX8MP_MEDIA_BLK_CTL_RESET_MIPI_CSI_ACLK   3
+#define IMX8MP_MEDIA_BLK_CTL_RESET_LCDIF_PIXEL 4
+#define IMX8MP_MEDIA_BLK_CTL_RESET_LCDIF_APB   5
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISI_PROC6
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISI_APB 7
+#define IMX8MP_MEDIA_BLK_CTL_RESET_BUS_BLK 8
+#define IMX8MP_MEDIA_BLK_CTL_RESET_MIPI_CSI2_PCLK  9
+#define IMX8MP_MEDIA_BLK_CTL_RESET_MIPI_CSI2_ACLK  10
+#define IMX8MP_MEDIA_BLK_CTL_RESET_LCDIF2_PIXEL11
+#define IMX8MP_MEDIA_BLK_CTL_RESET_LCDIF2_APB  12
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISP1_COR13
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISP1_AXI14
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISP1_AHB15
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISP0_COR16
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISP0_AXI17
+#define IMX8MP_MEDIA_BLK_CTL_RESET_ISP0_AHB18
+#define IMX8MP_MEDIA_BLK_CTL_RESET_DWE_COR 19
+#define IMX8MP_MEDIA_BLK_CTL_RESET_DWE_AXI 20
+#define IMX8MP_MEDIA_BLK_CTL_RESET_DWE_AHB 21
+#define IMX8MP_MEDIA_BLK_CTL_RESET_MIPI_DSI2   22
+#define IMX8MP_MEDIA_BLK_CTL_RESET_LCDIF_AXI   23
+#define IMX8MP_MEDIA_BLK_CTL_RESET_LCDIF2_AXI  24
+
+#define IMX8MP_MEDIA_BLK_CTL_RESET_NUM 25
+
 #endif
-- 
2.7.4



[PATCH v5 07/14] dt-bindings: reset: imx8mp: Add hdmi blk_ctl reset IDs

2020-11-03 Thread Abel Vesa
These will be used imx8mp for blk_ctl driver.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
Reviewed-by: Dong Aisheng 
---
 include/dt-bindings/reset/imx8mp-reset.h | 12 
 1 file changed, 12 insertions(+)

diff --git a/include/dt-bindings/reset/imx8mp-reset.h 
b/include/dt-bindings/reset/imx8mp-reset.h
index ba70248..eb9ed21 100644
--- a/include/dt-bindings/reset/imx8mp-reset.h
+++ b/include/dt-bindings/reset/imx8mp-reset.h
@@ -80,4 +80,16 @@
 
 #define IMX8MP_MEDIA_BLK_CTL_RESET_NUM 25
 
+#define IMX8MP_HDMI_BLK_CTL_HDMI_TX_RESET  0
+#define IMX8MP_HDMI_BLK_CTL_HDMI_PHY_RESET 1
+#define IMX8MP_HDMI_BLK_CTL_HDMI_PAI_RESET 2
+#define IMX8MP_HDMI_BLK_CTL_HDMI_PVI_RESET 3
+#define IMX8MP_HDMI_BLK_CTL_HDMI_TRNG_RESET4
+#define IMX8MP_HDMI_BLK_CTL_IRQ_STEER_RESET5
+#define IMX8MP_HDMI_BLK_CTL_HDMI_HDCP_RESET6
+#define IMX8MP_HDMI_BLK_CTL_LCDIF_RESET7
+
+#define IMX8MP_HDMI_BLK_CTL_RESET_NUM  8
+
+
 #endif
-- 
2.7.4



[PATCH v5 06/14] dt-bindings: clock: imx8mp: Add hdmi blk_ctl clock IDs

2020-11-03 Thread Abel Vesa
These will be used by the imx8mp for blk_ctl driver.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
Reviewed-by: Dong Aisheng 
---
 include/dt-bindings/clock/imx8mp-clock.h | 40 
 1 file changed, 40 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h 
b/include/dt-bindings/clock/imx8mp-clock.h
index 12632fa..de7d522 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -424,4 +424,44 @@
 
 #define IMX8MP_CLK_MEDIA_BLK_CTL_END   25
 
+#define IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_APB_CLK 0
+#define IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_B_CLK   1
+#define IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_REF266M_CLK 2
+#define IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_XTAL24M_CLK 3
+#define IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_XTAL32K_CLK 4
+#define IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_TX_PIX_CLK  5
+#define IMX8MP_CLK_HDMI_BLK_CTL_IRQS_STEER_CLK 6
+#define IMX8MP_CLK_HDMI_BLK_CTL_NOC_HDMI_CLK   7
+#define IMX8MP_CLK_HDMI_BLK_CTL_NOC_HDCP_CLK   8
+#define IMX8MP_CLK_HDMI_BLK_CTL_LCDIF_APB_CLK  9
+#define IMX8MP_CLK_HDMI_BLK_CTL_LCDIF_B_CLK10
+#define IMX8MP_CLK_HDMI_BLK_CTL_LCDIF_PDI_CLK  11
+#define IMX8MP_CLK_HDMI_BLK_CTL_LCDIF_PIX_CLK  12
+#define IMX8MP_CLK_HDMI_BLK_CTL_LCDIF_SPU_CLK  13
+#define IMX8MP_CLK_HDMI_BLK_CTL_FDCC_REF_CLK   14
+#define IMX8MP_CLK_HDMI_BLK_CTL_HRV_MWR_APB_CLK15
+#define IMX8MP_CLK_HDMI_BLK_CTL_HRV_MWR_B_CLK  16
+#define IMX8MP_CLK_HDMI_BLK_CTL_HRV_MWR_CEA_CLK17
+#define IMX8MP_CLK_HDMI_BLK_CTL_VSFD_CEA_CLK   18
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_HPI_CLK 19
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_APB_CLK 20
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_CEC_CLK 21
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_ESM_CLK 22
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_GPA_CLK 23
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_PIXEL_CLK   24
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_SFR_CLK 25
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_SKP_CLK 26
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_PREP_CLK27
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_PHY_APB_CLK 28
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_PHY_INT_CLK 29
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_SEC_MEM_CLK 30
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_TRNG_SKP_CLK31
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_VID_LINK_PIX_CLK32
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_TRNG_APB_CLK33
+#define IMX8MP_CLK_HDMI_BLK_CTL_HTXPHY_CLK_SEL 34
+#define IMX8MP_CLK_HDMI_BLK_CTL_LCDIF_CLK_SEL  35
+#define IMX8MP_CLK_HDMI_BLK_CTL_TX_PIPE_CLK_SEL36
+
+#define IMX8MP_CLK_HDMI_BLK_CTL_END37
+
 #endif
-- 
2.7.4



[PATCH v5 12/14] arm64: dts: imx8mp: Add audio_blk_ctl node

2020-11-03 Thread Abel Vesa
Some of the features of the audio_ctl will be used by some
different drivers in a way those drivers will know best, so adding the
syscon compatible we allow those to do just that. Only the resets
and the clocks are registered bit the clk-blk-ctl driver.

Signed-off-by: Abel Vesa 
Reviewed-by: Dong Aisheng 
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 4793122..3716119 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -743,6 +743,21 @@
};
};
 
+   aips5: bus@30c0 {
+   compatible = "fsl,aips-bus", "simple-bus";
+   reg = <0x30c0 0x40>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   audio_blk_ctl: clock-controller@30e2 {
+   compatible = "fsl,imx8mp-audio-blk-ctl", 
"syscon";
+   reg = <0x30e2 0x50c>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   };
+   };
+
gic: interrupt-controller@3880 {
compatible = "arm,gic-v3";
reg = <0x3880 0x1>,
-- 
2.7.4



[PATCH v5 10/14] clk: imx: Add generic blk-ctl driver

2020-11-03 Thread Abel Vesa
The i.MX8MP platform introduces a new type of IP which is called BLK_CTL in
RM and usually is comprised of some GPRs that are considered too
generic to be part of any dedicated IP from that specific subsystem.

In general, some of the GPRs have some clock bits, some have reset bits,
so in order to be able to use the imx clock API, this needs to be
in a clock driver. From there it can use the reset controller API and
leave the rest to the syscon.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/Makefile  |   2 +-
 drivers/clk/imx/clk-blk-ctl.c | 302 ++
 drivers/clk/imx/clk-blk-ctl.h |  80 +++
 3 files changed, 383 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/clk-blk-ctl.c
 create mode 100644 drivers/clk/imx/clk-blk-ctl.h

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index dd6a737..3d6d9cb 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_MXC_CLK) += mxc-clk.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
 obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
-obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
+obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-blk-ctl.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 
 obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
diff --git a/drivers/clk/imx/clk-blk-ctl.c b/drivers/clk/imx/clk-blk-ctl.c
new file mode 100644
index ..9ac0ed0
--- /dev/null
+++ b/drivers/clk/imx/clk-blk-ctl.c
@@ -0,0 +1,302 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright 2020 NXP.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+#include "clk-blk-ctl.h"
+
+struct imx_reset_hw {
+   u32 offset;
+   u32 shift;
+   u32 mask;
+   unsigned long asserted;
+};
+
+struct imx_pm_safekeep_info {
+   uint32_t *regs_values;
+   uint32_t *regs_offsets;
+   uint32_t regs_num;
+};
+
+struct imx_blk_ctl_drvdata {
+   void __iomem *base;
+   struct reset_controller_dev rcdev;
+   struct imx_reset_hw *rst_hws;
+   struct imx_pm_safekeep_info pm_info;
+
+   spinlock_t lock;
+};
+
+static void __maybe_unused imx_blk_ctl_read_write(struct device *dev,
+   bool write)
+{
+   struct imx_blk_ctl_drvdata *drvdata = dev_get_drvdata(dev);
+   struct imx_pm_safekeep_info *pm_info = >pm_info;
+   void __iomem *base = drvdata->base;
+   int i;
+
+   if (!pm_info->regs_num)
+   return;
+
+   for (i = 0; i < pm_info->regs_num; i++) {
+   u32 offset = pm_info->regs_offsets[i];
+
+   if (write)
+   writel(pm_info->regs_values[i], base + offset);
+   else
+   pm_info->regs_values[i] = readl(base + offset);
+   }
+
+}
+
+static int __maybe_unused imx_blk_ctl_runtime_suspend(struct device *dev)
+{
+   imx_blk_ctl_read_write(dev, false);
+
+   return 0;
+}
+
+static int __maybe_unused imx_blk_ctl_runtime_resume(struct device *dev)
+{
+   imx_blk_ctl_read_write(dev, true);
+
+   return 0;
+}
+
+const struct dev_pm_ops imx_blk_ctl_pm_ops = {
+   SET_RUNTIME_PM_OPS(imx_blk_ctl_runtime_suspend,
+  imx_blk_ctl_runtime_resume, NULL)
+   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+  pm_runtime_force_resume)
+};
+EXPORT_SYMBOL_GPL(imx_blk_ctl_pm_ops);
+
+static int imx_blk_ctl_reset_set(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+   struct imx_blk_ctl_drvdata *drvdata = container_of(rcdev,
+   struct imx_blk_ctl_drvdata, rcdev);
+   unsigned int offset = drvdata->rst_hws[id].offset;
+   unsigned int shift = drvdata->rst_hws[id].shift;
+   unsigned int mask = drvdata->rst_hws[id].mask;
+   void __iomem *reg_addr = drvdata->base + offset;
+   unsigned long flags;
+   u32 reg;
+
+   if (!assert && !test_bit(1, >rst_hws[id].asserted))
+   return -ENODEV;
+
+   if (assert && !test_and_set_bit(1, >rst_hws[id].asserted))
+   pm_runtime_get_sync(rcdev->dev);
+
+   spin_lock_irqsave(>lock, flags);
+
+   reg = readl(reg_addr);
+   if (assert)
+   writel(reg & ~(mask << shift), reg_addr);
+   else
+   writel(reg | (mask << shift), reg_addr);
+
+   spin_unlock_irqrestore(>lock, flags);
+
+   if (!assert && test_and_clear_bit(1, >rst_hws[id].asserted))
+   pm_runtime_put(rcdev->dev);
+
+   return 0;
+}
+
+static int imx_blk_ctl_reset_assert(struct reset_controller_dev *rcdev,
+  unsigned long id)
+{
+   return i

[PATCH v5 08/14] clk: imx8mp: Add audio shared gate

2020-11-03 Thread Abel Vesa
According to the RM, the CCGR101 is shared for the following root clocks:
- AUDIO_AHB_CLK_ROOT
- AUDIO_AXI_CLK_ROOT
- SAI2_CLK_ROOT
- SAI3_CLK_ROOT
- SAI5_CLK_ROOT
- SAI6_CLK_ROOT
- SAI7_CLK_ROOT
- PDM_CLK_ROOT

Signed-off-by: Abel Vesa 
Reviewed-by: Dong Aisheng 
---
 drivers/clk/imx/clk-imx8mp.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 3cb2bc4..02469f7 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -17,6 +17,7 @@
 
 static u32 share_count_nand;
 static u32 share_count_media;
+static u32 share_count_audio;
 
 static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", 
"dummy", };
 static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", 
"audio_pll1_ref_sel", };
@@ -725,7 +726,16 @@ static int imx8mp_clocks_probe(struct platform_device 
*pdev)
hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", 
"hdmi_axi", ccm_base + 0x45f0, 0);
hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", 
"ipg_root", ccm_base + 0x4620, 0);
hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", 
ccm_base + 0x4630, 0);
-   hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", 
"ipg_root", ccm_base + 0x4650, 0);
+
+   hws[IMX8MP_CLK_AUDIO_AHB_ROOT] = 
imx_clk_hw_gate2_shared2("audio_ahb_root", "audio_ahb", ccm_base + 0x4650, 0, 
_count_audio);
+   hws[IMX8MP_CLK_AUDIO_AXI_ROOT] = 
imx_clk_hw_gate2_shared2("audio_axi_root", "audio_axi", ccm_base + 0x4650, 0, 
_count_audio);
+   hws[IMX8MP_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root", 
"sai1", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root", 
"sai2", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root", 
"sai3", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root", 
"sai5", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root", 
"sai6", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root", 
"sai7", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root", "pdm", 
ccm_base + 0x4650, 0, _count_audio);
 
hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
 hws[IMX8MP_CLK_A53_CORE]->clk,
-- 
2.7.4



[PATCH v5 09/14] Documentation: bindings: clk: Add bindings for i.MX BLK_CTL

2020-11-03 Thread Abel Vesa
Document the i.MX BLK_CTL with its devicetree properties.

Signed-off-by: Abel Vesa 
Reviewed-by: Dong Aisheng 
Reviewed-by: Rob Herring 
---
 .../devicetree/bindings/clock/fsl,imx-blk-ctl.yaml | 60 ++
 1 file changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml

diff --git a/Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml 
b/Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml
new file mode 100644
index ..5e9eb40
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/fsl,imx-blk-ctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX BLK_CTL
+
+maintainers:
+  - Abel Vesa 
+
+description:
+  i.MX BLK_CTL is a conglomerate of different GPRs that are
+  dedicated to a specific subsystem. Because it usually contains
+  clocks amongst other things, it needs access to the i.MX clocks
+  API. All the other functionalities it provides can work just fine
+  from the clock subsystem tree.
+
+properties:
+  compatible:
+items:
+  - enum:
+ - fsl,imx8mp-audio-blk-ctl
+ - fsl,imx8mp-hdmi-blk-ctl
+ - fsl,imx8mp-media-blk-ctl
+  - const: syscon
+
+  reg:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+audio_blk_ctl: clock-controller@30e2 {
+   compatible = "fsl,imx8mp-audio-blk-ctl", "syscon";
+   reg = <0x30e2 0x1>;
+   power-domains = <_pd>;
+
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+};
-- 
2.7.4



[PATCH v5 03/14] dt-bindings: clock: imx8mp: Add ids for the audio shared gate

2020-11-03 Thread Abel Vesa
All these IDs are for one single HW gate (CCGR101) that is shared
between these root clocks.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
Reviewed-by: Dong Aisheng 
---
 include/dt-bindings/clock/imx8mp-clock.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h 
b/include/dt-bindings/clock/imx8mp-clock.h
index 89c67b7..5fc2c40 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -322,7 +322,17 @@
 #define IMX8MP_CLK_HSIO_AXI311
 #define IMX8MP_CLK_MEDIA_ISP   312
 
-#define IMX8MP_CLK_END 313
+#define IMX8MP_CLK_AUDIO_AHB_ROOT  313
+#define IMX8MP_CLK_AUDIO_AXI_ROOT  314
+#define IMX8MP_CLK_SAI1_ROOT   315
+#define IMX8MP_CLK_SAI2_ROOT   316
+#define IMX8MP_CLK_SAI3_ROOT   317
+#define IMX8MP_CLK_SAI5_ROOT   318
+#define IMX8MP_CLK_SAI6_ROOT   319
+#define IMX8MP_CLK_SAI7_ROOT   320
+#define IMX8MP_CLK_PDM_ROOT321
+
+#define IMX8MP_CLK_END 322
 
 #define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_IPG  0
 #define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_MCLK11
-- 
2.7.4



[PATCH v5 13/14] arm64: dts: imx8mp: Add media_blk_ctl node

2020-11-03 Thread Abel Vesa
Some of the features of the media_ctl will be used by some
different drivers in a way those drivers will know best, so adding the
syscon compatible we allow those to do just that. Only the resets
and the clocks are registered bit the clk-blk-ctl driver.

Signed-off-by: Abel Vesa 
Reviewed-by: Dong Aisheng 
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 3716119..8e1a01f 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -743,6 +743,21 @@
};
};
 
+   aips4: bus@32c0 {
+   compatible = "simple-bus";
+   reg = <0x32c0 0x40>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   media_blk_ctl: clock-controller@32ec {
+   compatible = "fsl,imx8mp-media-blk-ctl", 
"syscon";
+   reg = <0x32ec 0x1>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   };
+   };
+
aips5: bus@30c0 {
compatible = "fsl,aips-bus", "simple-bus";
reg = <0x30c0 0x40>;
-- 
2.7.4



[PATCH v5 00/14] Add BLK_CTL support for i.MX8MP

2020-11-03 Thread Abel Vesa
The BLK_CTL according to HW design is basically the wrapper of the entire
function specific group of IPs and holds GPRs that usually cannot be placed
into one specific IP from that group. Some of these GPRs are used to control
some clocks, other some resets, others some very specific function that does
not fit into clocks or resets. Since the clocks are registered using the i.MX
clock subsystem API, the driver is placed into the clock subsystem, but it
also registers the resets. For the other functionalities that other GPRs might
have, the syscon is used.

Changes since v4:
 * added back the bus_blk_clk in the imx8mp blk_ctl driver (media_blk_ctl)
 * added the R-b tag from Rob to the documentation patch

Abel Vesa (14):
  dt-bindings: clocks: imx8mp: Rename audiomix ids clocks to
audio_blk_ctl
  dt-bindings: reset: imx8mp: Add audio blk_ctl reset IDs
  dt-bindings: clock: imx8mp: Add ids for the audio shared gate
  dt-bindings: clock: imx8mp: Add media blk_ctl clock IDs
  dt-bindings: reset: imx8mp: Add media blk_ctl reset IDs
  dt-bindings: clock: imx8mp: Add hdmi blk_ctl clock IDs
  dt-bindings: reset: imx8mp: Add hdmi blk_ctl reset IDs
  clk: imx8mp: Add audio shared gate
  Documentation: bindings: clk: Add bindings for i.MX BLK_CTL
  clk: imx: Add generic blk-ctl driver
  clk: imx: Add blk-ctl driver for i.MX8MP
  arm64: dts: imx8mp: Add audio_blk_ctl node
  arm64: dts: imx8mp: Add media_blk_ctl node
  arm64: dts: imx8mp: Add hdmi_blk_ctl node

 .../devicetree/bindings/clock/fsl,imx-blk-ctl.yaml |  60 
 arch/arm64/boot/dts/freescale/imx8mp.dtsi  |  37 +++
 drivers/clk/imx/Makefile   |   2 +-
 drivers/clk/imx/clk-blk-ctl-imx8mp.c   | 317 +
 drivers/clk/imx/clk-blk-ctl.c  | 302 
 drivers/clk/imx/clk-blk-ctl.h  |  80 ++
 drivers/clk/imx/clk-imx8mp.c   |  12 +-
 include/dt-bindings/clock/imx8mp-clock.h   | 200 +
 include/dt-bindings/reset/imx8mp-reset.h   |  45 +++
 9 files changed, 992 insertions(+), 63 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml
 create mode 100644 drivers/clk/imx/clk-blk-ctl-imx8mp.c
 create mode 100644 drivers/clk/imx/clk-blk-ctl.c
 create mode 100644 drivers/clk/imx/clk-blk-ctl.h

-- 
2.7.4



[PATCH v5 04/14] dt-bindings: clock: imx8mp: Add media blk_ctl clock IDs

2020-11-03 Thread Abel Vesa
These will be used by the imx8mp for blk_ctl driver.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
Reviewed-by: Dong Aisheng 
---
 include/dt-bindings/clock/imx8mp-clock.h | 28 
 1 file changed, 28 insertions(+)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h 
b/include/dt-bindings/clock/imx8mp-clock.h
index 5fc2c40..12632fa 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -396,4 +396,32 @@
 
 #define IMX8MP_CLK_AUDIO_BLK_CTL_END   59
 
+#define IMX8MP_CLK_MEDIA_BLK_CTL_MIPI_DSI_PCLK 0
+#define IMX8MP_CLK_MEDIA_BLK_CTL_MIPI_DSI_CLKREF   1
+#define IMX8MP_CLK_MEDIA_BLK_CTL_MIPI_CSI_PCLK 2
+#define IMX8MP_CLK_MEDIA_BLK_CTL_MIPI_CSI_ACLK 3
+#define IMX8MP_CLK_MEDIA_BLK_CTL_LCDIF_PIXEL   4
+#define IMX8MP_CLK_MEDIA_BLK_CTL_LCDIF_APB 5
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISI_PROC  6
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISI_APB   7
+#define IMX8MP_CLK_MEDIA_BLK_CTL_BUS_BLK   8
+#define IMX8MP_CLK_MEDIA_BLK_CTL_MIPI_CSI2_PCLK9
+#define IMX8MP_CLK_MEDIA_BLK_CTL_MIPI_CSI2_ACLK10
+#define IMX8MP_CLK_MEDIA_BLK_CTL_LCDIF2_PIXEL  11
+#define IMX8MP_CLK_MEDIA_BLK_CTL_LCDIF2_APB12
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISP1_COR  13
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISP1_AXI  14
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISP1_AHB  15
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISP0_COR  16
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISP0_AXI  17
+#define IMX8MP_CLK_MEDIA_BLK_CTL_ISP0_AHB  18
+#define IMX8MP_CLK_MEDIA_BLK_CTL_DWE_COR   19
+#define IMX8MP_CLK_MEDIA_BLK_CTL_DWE_AXI   20
+#define IMX8MP_CLK_MEDIA_BLK_CTL_DWE_AHB   21
+#define IMX8MP_CLK_MEDIA_BLK_CTL_MIPI_DSI2 22
+#define IMX8MP_CLK_MEDIA_BLK_CTL_LCDIF_AXI 23
+#define IMX8MP_CLK_MEDIA_BLK_CTL_LCDIF2_AXI24
+
+#define IMX8MP_CLK_MEDIA_BLK_CTL_END   25
+
 #endif
-- 
2.7.4



[PATCH v5 02/14] dt-bindings: reset: imx8mp: Add audio blk_ctl reset IDs

2020-11-03 Thread Abel Vesa
These will be used by the imx8mp for blk_ctl driver.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
Reviewed-by: Dong Aisheng 
---
 include/dt-bindings/reset/imx8mp-reset.h | 5 +
 1 file changed, 5 insertions(+)

diff --git a/include/dt-bindings/reset/imx8mp-reset.h 
b/include/dt-bindings/reset/imx8mp-reset.h
index 2e8c910..6c7f17f 100644
--- a/include/dt-bindings/reset/imx8mp-reset.h
+++ b/include/dt-bindings/reset/imx8mp-reset.h
@@ -47,4 +47,9 @@
 
 #define IMX8MP_RESET_NUM   38
 
+#define IMX8MP_AUDIO_BLK_CTL_EARC_RESET0
+#define IMX8MP_AUDIO_BLK_CTL_EARC_PHY_RESET1
+
+#define IMX8MP_AUDIO_BLK_CTL_RESET_NUM 2
+
 #endif
-- 
2.7.4



[PATCH v5 11/14] clk: imx: Add blk-ctl driver for i.MX8MP

2020-11-03 Thread Abel Vesa
This driver is intended to work with the following BLK_CTL IPs found in
i.MX8MP:
 - Audio
 - Media
 - HDMI

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/Makefile |   2 +-
 drivers/clk/imx/clk-blk-ctl-imx8mp.c | 317 +++
 2 files changed, 318 insertions(+), 1 deletion(-)
 create mode 100644 drivers/clk/imx/clk-blk-ctl-imx8mp.c

diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
index 3d6d9cb..6c9b595 100644
--- a/drivers/clk/imx/Makefile
+++ b/drivers/clk/imx/Makefile
@@ -23,7 +23,7 @@ obj-$(CONFIG_MXC_CLK) += mxc-clk.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
 obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
-obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-blk-ctl.o
+obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-blk-ctl.o clk-blk-ctl-imx8mp.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 
 obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
diff --git a/drivers/clk/imx/clk-blk-ctl-imx8mp.c 
b/drivers/clk/imx/clk-blk-ctl-imx8mp.c
new file mode 100644
index ..76bbe67
--- /dev/null
+++ b/drivers/clk/imx/clk-blk-ctl-imx8mp.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2020 NXP.
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk.h"
+#include "clk-blk-ctl.h"
+
+#defineIMX_AUDIO_BLK_CTL_CLKEN00x0
+#defineIMX_AUDIO_BLK_CTL_CLKEN10x4
+#defineIMX_AUDIO_BLK_CTL_EARC  0x200
+#defineIMX_AUDIO_BLK_CTL_SAI1_MCLK_SEL 0x300
+#defineIMX_AUDIO_BLK_CTL_SAI2_MCLK_SEL 0x304
+#defineIMX_AUDIO_BLK_CTL_SAI3_MCLK_SEL 0x308
+#defineIMX_AUDIO_BLK_CTL_SAI5_MCLK_SEL 0x30C
+#defineIMX_AUDIO_BLK_CTL_SAI6_MCLK_SEL 0x310
+#defineIMX_AUDIO_BLK_CTL_SAI7_MCLK_SEL 0x314
+#defineIMX_AUDIO_BLK_CTL_PDM_CLK   0x318
+#defineIMX_AUDIO_BLK_CTL_SAI_PLL_GNRL_CTL  0x400
+#defineIMX_AUDIO_BLK_CTL_SAI_PLL_FDIVL_CTL00x404
+#defineIMX_AUDIO_BLK_CTL_SAI_PLL_FDIVL_CTL10x408
+#defineIMX_AUDIO_BLK_CTL_SAI_PLL_SSCG_CTL  0x40C
+#defineIMX_AUDIO_BLK_CTL_SAI_PLL_MNIT_CTL  0x410
+#defineIMX_AUDIO_BLK_CTL_IPG_LP_CTRL   0x504
+
+#define IMX_MEDIA_BLK_CTL_SFT_RSTN 0x0
+#define IMX_MEDIA_BLK_CTL_CLK_EN   0x4
+
+static int shared_count_pdm;
+
+static const struct imx_pll14xx_rate_table imx_blk_ctl_sai_pll_tbl[] = {
+   PLL_1443X_RATE(65000U, 325, 3, 2, 0),
+};
+
+static const struct imx_pll14xx_clk imx_blk_ctl_sai_pll = {
+   .type = PLL_1443X,
+   .rate_table = imx_blk_ctl_sai_pll_tbl,
+};
+
+static const char * const imx_sai_mclk2_sels[] = {"sai1_root", "sai2_root", 
"sai3_root", "dummy",
+  "sai5_root", "sai6_root", 
"sai7_root", "sai1_mclk",
+  "sai2_mclk", "sai3_mclk", "dummy",
+  "sai5_mclk", "sai6_mclk", 
"sai7_mclk", "spdif1_ext_clk"};
+static const char * const imx_sai1_mclk1_sels[] = {"sai1_root", "sai1_mclk", };
+static const char * const imx_sai2_mclk1_sels[] = {"sai2_root", "sai2_mclk", };
+static const char * const imx_sai3_mclk1_sels[] = {"sai3_root", "sai3_mclk", };
+static const char * const imx_sai5_mclk1_sels[] = {"sai5_root", "sai5_mclk", };
+static const char * const imx_sai6_mclk1_sels[] = {"sai6_root", "sai6_mclk", };
+static const char * const imx_sai7_mclk1_sels[] = {"sai7_root", "sai7_mclk", };
+static const char * const imx_pdm_sels[] = {"pdm_root", "sai_pll_div2", 
"dummy", "dummy" };
+static const char * const imx_sai_pll_ref_sels[] = {"osc_24m", "dummy", 
"dummy", "dummy", };
+static const char * const imx_sai_pll_bypass_sels[] = {"sai_pll", 
"sai_pll_ref_sel", };
+
+static const char * const imx_hdmi_phy_clks_sels[] = {"hdmi_glb_24m", "dummy", 
};
+static const char * const imx_lcdif_clks_sels[] = {"dummy", "hdmi_glb_pix", };
+static const char * const imx_hdmi_pipe_clks_sels[] = {"dummy", 
"hdmi_glb_pix", };
+
+static struct imx_blk_ctl_hw imx8mp_hdmi_blk_ctl_hws[] = {
+   /* clocks */
+   IMX_BLK_CTL_CLK_GATE("hdmi_glb_apb", 
IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_APB_CLK, 0x40, 0, "hdmi_apb"),
+   IMX_BLK_CTL_CLK_GATE("hdmi_glb_b", 
IMX8MP_CLK_HDMI_BLK_CTL_GLOBAL_B_CLK, 0x40, 1, "hdmi_axi"),
+   IMX_BLK_CTL_CLK_GATE("hdmi_glb_ref_266m", 

[PATCH v5 14/14] arm64: dts: imx8mp: Add hdmi_blk_ctl node

2020-11-03 Thread Abel Vesa
Some of the features of the hdmi_ctl will be used by some
different drivers in a way those drivers will know best, so adding the
syscon compatible we allow those to do just that. Only the resets
and the clocks are registered bit the clk-blk-ctl driver.

Signed-off-by: Abel Vesa 
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 8e1a01f..f1c5a07d 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -756,6 +756,13 @@
#clock-cells = <1>;
#reset-cells = <1>;
};
+
+   hdmi_blk_ctl: clock-controller@32fc {
+   compatible = "fsl,imx8mp-hdmi-blk-ctl", 
"syscon";
+   reg = <0x32fc 0x1000>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   };
};
 
aips5: bus@30c0 {
-- 
2.7.4



Re: [PATCH v4 11/14] clk: imx: Add blk-ctl driver for i.MX8MP

2020-10-31 Thread Abel Vesa
On 20-10-31 00:21:01, Adam Ford wrote:
> On Mon, Oct 26, 2020 at 2:33 PM Abel Vesa  wrote:
> >
> > This driver is intended to work with the following BLK_CTL IPs found in
> > i.MX8MP:
> >  - Audio
> >  - Media
> >  - HDMI
> >
> > Signed-off-by: Abel Vesa 
> > ---
> >  drivers/clk/imx/Makefile |   2 +-
> >  drivers/clk/imx/clk-blk-ctl-imx8mp.c | 316 
> > +++
> >  2 files changed, 317 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/clk/imx/clk-blk-ctl-imx8mp.c
> >
> > diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile
> > index 3d6d9cb..6c9b595 100644
> > --- a/drivers/clk/imx/Makefile
> > +++ b/drivers/clk/imx/Makefile
> > @@ -23,7 +23,7 @@ obj-$(CONFIG_MXC_CLK) += mxc-clk.o
> >
> >  obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
> >  obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
> > -obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-blk-ctl.o
> > +obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-blk-ctl.o clk-blk-ctl-imx8mp.o
> >  obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
> >
> >  obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
> > diff --git a/drivers/clk/imx/clk-blk-ctl-imx8mp.c 
> > b/drivers/clk/imx/clk-blk-ctl-imx8mp.c
> > new file mode 100644
> > index ..cee146e
> > --- /dev/null
> > +++ b/drivers/clk/imx/clk-blk-ctl-imx8mp.c
> > @@ -0,0 +1,316 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2020 NXP.
> > + */
> > +
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "clk.h"
> > +#include "clk-blk-ctl.h"
> > +
> > +#defineIMX_AUDIO_BLK_CTL_CLKEN00x0
> > +#defineIMX_AUDIO_BLK_CTL_CLKEN10x4
> > +#defineIMX_AUDIO_BLK_CTL_EARC  0x200
> > +#defineIMX_AUDIO_BLK_CTL_SAI1_MCLK_SEL 0x300
> > +#defineIMX_AUDIO_BLK_CTL_SAI2_MCLK_SEL 0x304
> > +#defineIMX_AUDIO_BLK_CTL_SAI3_MCLK_SEL 0x308
> > +#defineIMX_AUDIO_BLK_CTL_SAI5_MCLK_SEL 0x30C
> > +#defineIMX_AUDIO_BLK_CTL_SAI6_MCLK_SEL 0x310
> > +#defineIMX_AUDIO_BLK_CTL_SAI7_MCLK_SEL 0x314
> > +#defineIMX_AUDIO_BLK_CTL_PDM_CLK   0x318
> > +#defineIMX_AUDIO_BLK_CTL_SAI_PLL_GNRL_CTL  0x400
> > +#defineIMX_AUDIO_BLK_CTL_SAI_PLL_FDIVL_CTL00x404
> > +#defineIMX_AUDIO_BLK_CTL_SAI_PLL_FDIVL_CTL10x408
> > +#defineIMX_AUDIO_BLK_CTL_SAI_PLL_SSCG_CTL  0x40C
> > +#defineIMX_AUDIO_BLK_CTL_SAI_PLL_MNIT_CTL  0x410
> > +#defineIMX_AUDIO_BLK_CTL_IPG_LP_CTRL   0x504
> > +
> > +#define IMX_MEDIA_BLK_CTL_SFT_RSTN 0x0
> > +#define IMX_MEDIA_BLK_CTL_CLK_EN   0x4
> > +
> > +static int shared_count_pdm;
> > +
> > +static const struct imx_pll14xx_rate_table imx_blk_ctl_sai_pll_tbl[] = {
> > +   PLL_1443X_RATE(65000U, 325, 3, 2, 0),
> > +};
> > +
> > +static const struct imx_pll14xx_clk imx_blk_ctl_sai_pll = {
> > +   .type = PLL_1443X,
> > +   .rate_table = imx_blk_ctl_sai_pll_tbl,
> > +};
> > +
> > +static const char * const imx_sai_mclk2_sels[] = {"sai1_root", 
> > "sai2_root", "sai3_root", "dummy",
> > +  "sai5_root", "sai6_root", 
> > "sai7_root", "sai1_mclk",
> > +  "sai2_mclk", "sai3_mclk", 
> > "dummy",
> > +  "sai5_mclk", "sai6_mclk", 
> > "sai7_mclk", "spdif1_ext_clk"};
> > +static const char * const imx_sai1_mclk1_sels[] = {"sai1_root", 
> > "sai1_mclk", };
> > +static const char * const imx_sai2_mclk1_sels[] = {"sai2_root", 
> > "sai2_mclk", };
> > +static const char * const imx_sai3_mclk1_sels[] = {"sai3_root", 
> > "sai3_mclk", };
> > +static const char * const imx_sai5_mclk1_sels[] = {"sai5_root", 
> > "sai5_mclk", };
> > +static const char * const imx_sai6_mclk1_sels[] = {"sai6_root", 
> > "sai6_mclk", };
> > +static const char * 

Re: [RFC 0/3] clk: imx: Implement blk-ctl driver for i.MX8MN

2020-10-29 Thread Abel Vesa
On 20-10-29 12:54:58, Lucas Stach wrote:
> Am Montag, den 26.10.2020, 11:23 -0500 schrieb Adam Ford:
> > On Mon, Oct 26, 2020 at 10:44 AM Lucas Stach  wrote:
> > > Am Montag, den 26.10.2020, 10:12 -0500 schrieb Adam Ford:
> > > > On Mon, Oct 26, 2020 at 9:55 AM Abel Vesa  wrote:
> > > > > On 20-10-25 11:05:32, Adam Ford wrote:
> > > > > > On Sun, Oct 25, 2020 at 7:19 AM Marek Vasut  wrote:
> > > > > > > On 10/25/20 1:05 PM, Abel Vesa wrote:
> > > > > > > 
> > > > > > > [...]
> > > > > > > 
> > > > > > > > > Together, both the GPC and the clk-blk driver should be able 
> > > > > > > > > to pull
> > > > > > > > > the multimedia block out of reset.  Currently, the GPC can 
> > > > > > > > > handle the
> > > > > > > > > USB OTG and the GPU, but the LCDIF and MIPI DSI appear to be 
> > > > > > > > > gated by
> > > > > > > > > the clock block
> > > > > > > > > 
> > > > > > > > > My original patch RFC didn't include the imx8mn node, because 
> > > > > > > > > it
> > > > > > > > > hangs, but the node I added looks like:
> > > > > > > > > 
> > > > > > > > > media_blk_ctl: clock-controller@32e28000 {
> > > > > > > > >  compatible = "fsl,imx8mn-media-blk-ctl", "syscon";
> > > > > > > > >  reg = <0x32e28000 0x1000>;
> > > > > > > > >  #clock-cells = <1>;
> > > > > > > > >  #reset-cells = <1>;
> > > > > > > > > };
> > > > > > > > > 
> > > > > > > > > I was hoping you might have some feedback on the 8mn clk-blk 
> > > > > > > > > driver
> > > > > > > > > since you did the 8mp clk-blk drive and they appear to be very
> > > > > > > > > similar.
> > > > > > > > > 
> > > > > > > > 
> > > > > > > > I'll do you one better still. I'll apply the patch in my tree 
> > > > > > > > and give it
> > > > > > > > a test tomorrow morning.
> > > > > > 
> > > > > > I do have some more updates on how to get the system to not hang, 
> > > > > > and
> > > > > > to enumerate more clocks.
> > > > > > Looking at Marek's work on enabling clocks in the 8MM, he added a
> > > > > > power-domain in dispmix_blk_ctl pointing to the dispmix in the GPC.
> > > > > > By forcing the GPC driver to write 0x1fff  to 32e28004, 0x7f to
> > > > > > 32e28000 and 0x3 to 32e28008, the i.MX8MM can bring the display
> > > > > > clocks out of reset.
> > > > > > 
> > > > > 
> > > > > Yeah, that makes sense. Basically, it was trying to disable unused 
> > > > > clocks
> > > > > (see clk_disable_unused) but in order to disable the clocks from the
> > > > > media BLK_CTL (which I think should be renamed in display BLK_CTL) the
> > > > > PD need to be on. Since you initially didn't give it any PD, it was 
> > > > > trying
> > > > > to blindly write/read the gate bit and therefore freeze.
> > > > > 
> > > > > > Unfortunately, the i.MX8MN needs to have 0x100 written to both
> > > > > > 32e28000 and 32e28004, and the values written for the 8MM are not
> > > > > > compatible.
> > > > > > By forcing the GPC to write those values, I can get  lcdif_pixel_clk
> > > > > > and the mipi_dsi_clkref  appearing on the Nano.
> > > > > 
> > > > > I'm trying to make a branch with all the patches for all i.MX8M so I
> > > > > can keep track of it all. On this branch I've also applied the
> > > > > following patchset from Lucas Stach:
> > > > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.spinics.net%2Flists%2Farm-kernel%2Fmsg843007.htmldata=04%7C01%7Cabel.vesa%40nxp.com%7C7ee028d464cf451e0e2d08d87c0177cd%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637395693031971288%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLC

[PATCH v2 4/5] clk: imx: gate2: Add cgr_mask for more flexible number of control bits

2020-10-28 Thread Abel Vesa
On some i.MX8 platforms, there are HW gates that share the same bit.
So in order to make this clock type more usable, use a mask to specify
how many bits belong to those HW gates.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-gate2.c | 16 ++--
 drivers/clk/imx/clk.h   | 24 
 2 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 40bcc2d..7e4b5e8 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -30,6 +30,7 @@ struct clk_gate2 {
void __iomem*reg;
u8  bit_idx;
u8  cgr_val;
+   u8  cgr_mask;
u8  flags;
spinlock_t  *lock;
unsigned int*share_count;
@@ -43,9 +44,9 @@ static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool 
enable)
u32 reg;
 
reg = readl(gate->reg);
-   reg &= ~(3 << gate->bit_idx);
+   reg &= ~(gate->cgr_mask << gate->bit_idx);
if (enable)
-   reg |= gate->cgr_val << gate->bit_idx;
+   reg |= (gate->cgr_val & gate->cgr_mask) << gate->bit_idx;
writel(reg, gate->reg);
 }
 
@@ -86,11 +87,12 @@ static void clk_gate2_disable(struct clk_hw *hw)
spin_unlock_irqrestore(gate->lock, flags);
 }
 
-static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx, u8 cgr_val)
+static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx,
+   u8 cgr_val, u8 cgr_mask)
 {
u32 val = readl(reg);
 
-   if (((val >> bit_idx) & 3) == cgr_val)
+   if (((val >> bit_idx) & cgr_mask) == cgr_val)
return 1;
 
return 0;
@@ -100,7 +102,8 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
 {
struct clk_gate2 *gate = to_clk_gate2(hw);
 
-   return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx, 
gate->cgr_val);
+   return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx,
+   gate->cgr_val, gate->cgr_mask);
 }
 
 static void clk_gate2_disable_unused(struct clk_hw *hw)
@@ -125,7 +128,7 @@ static const struct clk_ops clk_gate2_ops = {
 
 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
-   void __iomem *reg, u8 bit_idx, u8 cgr_val,
+   void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask,
u8 clk_gate2_flags, spinlock_t *lock,
unsigned int *share_count)
 {
@@ -142,6 +145,7 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, 
const char *name,
gate->reg = reg;
gate->bit_idx = bit_idx;
gate->cgr_val = cgr_val;
+   gate->cgr_mask = cgr_mask;
gate->flags = clk_gate2_flags;
gate->lock = lock;
gate->share_count = share_count;
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 87b2744f..3d8e40b 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -66,9 +66,9 @@ extern struct imx_pll14xx_clk imx_1443x_dram_pll;
to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
 
 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
-   cgr_val, clk_gate_flags, lock, share_count) \
+   cgr_val, cgr_mask, clk_gate_flags, lock, 
share_count) \
to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, 
bit_idx, \
-   cgr_val, clk_gate_flags, lock, share_count))
+   cgr_val, cgr_mask, clk_gate_flags, lock, 
share_count))
 
 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
@@ -196,7 +196,7 @@ struct clk_hw *imx_clk_hw_pllv4(const char *name, const 
char *parent_name,
 
 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
const char *parent_name, unsigned long flags,
-   void __iomem *reg, u8 bit_idx, u8 cgr_val,
+   void __iomem *reg, u8 bit_idx, u8 cgr_val, u8 cgr_mask,
u8 clk_gate_flags, spinlock_t *lock,
unsigned int *share_count);
 
@@ -349,14 +349,14 @@ static inline struct clk_hw *imx_clk_hw_gate2(const char 
*name, const char *pare
void __iomem *reg, u8 shift)
 {
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, 
reg,
-   shift, 0x3, 0, _ccm_lock, NULL);
+   shift, 0x3, 0x3, 0, _ccm_lock, NULL);
 }
 
 static inline struct clk_hw *imx_clk_hw_gate2_flags(const char *name, const 
char *parent,
void __iomem *reg, u8 shift, unsigned long flags)
 {
return 

[PATCH v2 1/5] clk: imx: gate2: Remove the IMX_CLK_GATE2_SINGLE_BIT special case

2020-10-28 Thread Abel Vesa
This was a hack which would allow multiple HW gates to be controlled
by a single bit. The only user of this is the imx_dev_clk_hw_gate_shared
which is not used anywhere as of now. Basically, complicates the logic
of the driver for no reason.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-gate2.c | 28 +++-
 drivers/clk/imx/clk.h   |  5 +
 2 files changed, 8 insertions(+), 25 deletions(-)

diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 7eed708..49952ee 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -49,14 +49,10 @@ static int clk_gate2_enable(struct clk_hw *hw)
if (gate->share_count && (*gate->share_count)++ > 0)
goto out;
 
-   if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
-   ret = clk_gate_ops.enable(hw);
-   } else {
-   reg = readl(gate->reg);
-   reg &= ~(3 << gate->bit_idx);
-   reg |= gate->cgr_val << gate->bit_idx;
-   writel(reg, gate->reg);
-   }
+   reg = readl(gate->reg);
+   reg &= ~(3 << gate->bit_idx);
+   reg |= gate->cgr_val << gate->bit_idx;
+   writel(reg, gate->reg);
 
 out:
spin_unlock_irqrestore(gate->lock, flags);
@@ -79,13 +75,9 @@ static void clk_gate2_disable(struct clk_hw *hw)
goto out;
}
 
-   if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT) {
-   clk_gate_ops.disable(hw);
-   } else {
-   reg = readl(gate->reg);
-   reg &= ~(3 << gate->bit_idx);
-   writel(reg, gate->reg);
-   }
+   reg = readl(gate->reg);
+   reg &= ~(3 << gate->bit_idx);
+   writel(reg, gate->reg);
 
 out:
spin_unlock_irqrestore(gate->lock, flags);
@@ -105,9 +97,6 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
 {
struct clk_gate2 *gate = to_clk_gate2(hw);
 
-   if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
-   return clk_gate_ops.is_enabled(hw);
-
return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
 }
 
@@ -117,9 +106,6 @@ static void clk_gate2_disable_unused(struct clk_hw *hw)
unsigned long flags;
u32 reg;
 
-   if (gate->flags & IMX_CLK_GATE2_SINGLE_BIT)
-   return;
-
spin_lock_irqsave(gate->lock, flags);
 
if (!gate->share_count || *gate->share_count == 0) {
diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h
index 3b796b3..87b2744f 100644
--- a/drivers/clk/imx/clk.h
+++ b/drivers/clk/imx/clk.h
@@ -6,8 +6,6 @@
 #include 
 #include 
 
-#define IMX_CLK_GATE2_SINGLE_BIT   1
-
 extern spinlock_t imx_ccm_lock;
 
 void imx_check_clocks(struct clk *clks[], unsigned int count);
@@ -384,8 +382,7 @@ static inline struct clk_hw 
*imx_dev_clk_hw_gate_shared(struct device *dev,
unsigned int *share_count)
 {
return clk_hw_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT |
-   CLK_OPS_PARENT_ENABLE, reg, shift, 0x3,
-   IMX_CLK_GATE2_SINGLE_BIT,
+   CLK_OPS_PARENT_ENABLE, reg, shift, 0x1, 
0,
_ccm_lock, share_count);
 }
 
-- 
2.7.4



[PATCH v2 3/5] clk: imx: gate2: Check if clock is enabled against cgr_val

2020-10-28 Thread Abel Vesa
Seems the logic here was wrong all along. For example, if
the cgr_val is 2 (0b10), the clk_gate2_reg_is_enabled would
report the clock as disabled. So check against cgr_val instead.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-gate2.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index e1f6cd9..40bcc2d 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -86,11 +86,11 @@ static void clk_gate2_disable(struct clk_hw *hw)
spin_unlock_irqrestore(gate->lock, flags);
 }
 
-static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx)
+static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx, u8 cgr_val)
 {
u32 val = readl(reg);
 
-   if (((val >> bit_idx) & 1) == 1)
+   if (((val >> bit_idx) & 3) == cgr_val)
return 1;
 
return 0;
@@ -100,7 +100,7 @@ static int clk_gate2_is_enabled(struct clk_hw *hw)
 {
struct clk_gate2 *gate = to_clk_gate2(hw);
 
-   return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx);
+   return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx, 
gate->cgr_val);
 }
 
 static void clk_gate2_disable_unused(struct clk_hw *hw)
-- 
2.7.4



[PATCH v2 0/5] Fix the gate2 and make it more flexible

2020-10-28 Thread Abel Vesa
First version here: https://lkml.org/lkml/2020/10/26/988

Changes since v1:
 * split the work in multiple iterative patches

Abel Vesa (5):
  clk: imx: gate2: Remove the IMX_CLK_GATE2_SINGLE_BIT special case
  clk: imx: gate2: Keep the register writing in on place
  clk: imx: gate2: Check if clock is enabled against cgr_val
  clk: imx: gate2: Add cgr_mask for more flexible number of control bits
  clk: imx: gate2: Add locking in is_enabled op

 drivers/clk/imx/clk-gate2.c | 65 +
 drivers/clk/imx/clk.h   | 27 +--
 2 files changed, 43 insertions(+), 49 deletions(-)

-- 
2.7.4



[PATCH v2 2/5] clk: imx: gate2: Keep the register writing in on place

2020-10-28 Thread Abel Vesa
Move all the register writing to the newly added clk_gate2_do_shared_clks
and call that everywhere need needed. Cleans up the code a little bit.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-gate2.c | 33 -
 1 file changed, 16 insertions(+), 17 deletions(-)

diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 49952ee..e1f6cd9 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -37,10 +37,21 @@ struct clk_gate2 {
 
 #define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)
 
+static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
+{
+   struct clk_gate2 *gate = to_clk_gate2(hw);
+   u32 reg;
+
+   reg = readl(gate->reg);
+   reg &= ~(3 << gate->bit_idx);
+   if (enable)
+   reg |= gate->cgr_val << gate->bit_idx;
+   writel(reg, gate->reg);
+}
+
 static int clk_gate2_enable(struct clk_hw *hw)
 {
struct clk_gate2 *gate = to_clk_gate2(hw);
-   u32 reg;
unsigned long flags;
int ret = 0;
 
@@ -49,11 +60,7 @@ static int clk_gate2_enable(struct clk_hw *hw)
if (gate->share_count && (*gate->share_count)++ > 0)
goto out;
 
-   reg = readl(gate->reg);
-   reg &= ~(3 << gate->bit_idx);
-   reg |= gate->cgr_val << gate->bit_idx;
-   writel(reg, gate->reg);
-
+   clk_gate2_do_shared_clks(hw, true);
 out:
spin_unlock_irqrestore(gate->lock, flags);
 
@@ -63,7 +70,6 @@ static int clk_gate2_enable(struct clk_hw *hw)
 static void clk_gate2_disable(struct clk_hw *hw)
 {
struct clk_gate2 *gate = to_clk_gate2(hw);
-   u32 reg;
unsigned long flags;
 
spin_lock_irqsave(gate->lock, flags);
@@ -75,10 +81,7 @@ static void clk_gate2_disable(struct clk_hw *hw)
goto out;
}
 
-   reg = readl(gate->reg);
-   reg &= ~(3 << gate->bit_idx);
-   writel(reg, gate->reg);
-
+   clk_gate2_do_shared_clks(hw, false);
 out:
spin_unlock_irqrestore(gate->lock, flags);
 }
@@ -104,15 +107,11 @@ static void clk_gate2_disable_unused(struct clk_hw *hw)
 {
struct clk_gate2 *gate = to_clk_gate2(hw);
unsigned long flags;
-   u32 reg;
 
spin_lock_irqsave(gate->lock, flags);
 
-   if (!gate->share_count || *gate->share_count == 0) {
-   reg = readl(gate->reg);
-   reg &= ~(3 << gate->bit_idx);
-   writel(reg, gate->reg);
-   }
+   if (!gate->share_count || *gate->share_count == 0)
+   clk_gate2_do_shared_clks(hw, false);
 
spin_unlock_irqrestore(gate->lock, flags);
 }
-- 
2.7.4



[PATCH v2 5/5] clk: imx: gate2: Add locking in is_enabled op

2020-10-28 Thread Abel Vesa
Protect against enabling/disabling the gate while we're
checking if it is enabled.

Signed-off-by: Abel Vesa 
---
 drivers/clk/imx/clk-gate2.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
index 7e4b5e8..480a184 100644
--- a/drivers/clk/imx/clk-gate2.c
+++ b/drivers/clk/imx/clk-gate2.c
@@ -101,9 +101,17 @@ static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 
bit_idx,
 static int clk_gate2_is_enabled(struct clk_hw *hw)
 {
struct clk_gate2 *gate = to_clk_gate2(hw);
+   unsigned long flags;
+   int ret = 0;
 
-   return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx,
+   spin_lock_irqsave(gate->lock, flags);
+
+   ret = clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx,
gate->cgr_val, gate->cgr_mask);
+
+   spin_unlock_irqrestore(gate->lock, flags);
+
+   return ret;
 }
 
 static void clk_gate2_disable_unused(struct clk_hw *hw)
-- 
2.7.4



Re: [PATCH] clk: imx: gate2: Fix the is_enabled op

2020-10-28 Thread Abel Vesa
On 20-10-28 11:15:52, Sascha Hauer wrote:
> On Wed, Oct 28, 2020 at 11:50:57AM +0200, Abel Vesa wrote:
> > On 20-10-28 09:24:12, Sascha Hauer wrote:
> > > Hi Abel,
> > > 
> > > On Mon, Oct 26, 2020 at 08:50:48PM +0200, Abel Vesa wrote:
> > > > The clock is considered to be enabled only if the controlling bits
> > > > match the cgr_val mask. Also make sure the is_enabled returns the
> > > > correct vaule by locking the access to the register.
> > > > 
> > > > Signed-off-by: Abel Vesa 
> > > > Fixes: 1e54afe9fcfe ("clk: imx: gate2: Allow single bit gating clock")
> > > > ---
> > > >  drivers/clk/imx/clk-gate2.c | 60 
> > > > -
> > > >  drivers/clk/imx/clk.h   |  8 ++
> > > >  2 files changed, 29 insertions(+), 39 deletions(-)
> > > > 
> > > > diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
> > > > index 7eed708..f320bd2b 100644
> > > > --- a/drivers/clk/imx/clk-gate2.c
> > > > +++ b/drivers/clk/imx/clk-gate2.c
> > > > @@ -37,10 +37,22 @@ struct clk_gate2 {
> > > >  
> > > >  #define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)
> > > >  
> > > > +static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
> > > > +{
> > > > +   struct clk_gate2 *gate = to_clk_gate2(hw);
> > > > +   u32 reg;
> > > > +
> > > > +   reg = readl(gate->reg);
> > > > +   if (enable)
> > > > +   reg |= gate->cgr_val << gate->bit_idx;
> > > > +   else
> > > > +   reg &= ~(gate->cgr_val << gate->bit_idx);
> > > 
> > > Shouldn't this be:
> > > 
> > >   reg &= ~(3 << gate->bit_idx);
> > >   if (enable)
> > >   reg |= gate->cgr_val << gate->bit_idx;
> > > 
> > > At least that's how it was without this patch and that's how it makes
> > > sense to me with cgr_val != 3.
> > > 
> > 
> > Well, that's the actual problem. The value 3 forces all the clocks
> > that register with this clock type to have 2 bits for controlling the gate.
> > 
> > My patch (though now I think I should split it into 2 separate patches) 
> > allows
> > two HW gates to be controlled by as many bits necessary. For example, there
> > could be multiple HW gates that are controled by the same bit. By passing
> > the cgr_val when registering the clocks you can specify how many bits (as a 
> > mask)
> > control all those HW gates that share their control bits.
> 
> cgr_val is not a mask, it's a value that shall be written to the two
> bits to enable the clock. cgr_val could also be 0b10, see imx_clk_gate2_cgr().
> 

Oh, I see your point now.

Maybe we should add another member called cgr_mask. That should fix the issue.

> Sascha
> 
> -- 
> Pengutronix e.K.   | |
> Steuerwalder Str. 21   | 
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.pengutronix.de%2Fdata=04%7C01%7Cabel.vesa%40nxp.com%7C03a2a0c430384a43db0708d87b2a762c%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637394769581294045%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=HiJ25Kyi3TS0XJx24G2VExgTntmCT2eKFbzBUe6GBH0%3Dreserved=0
>   |
> 31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
> Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH] clk: imx: gate2: Fix the is_enabled op

2020-10-28 Thread Abel Vesa
On 20-10-28 09:24:12, Sascha Hauer wrote:
> Hi Abel,
> 
> On Mon, Oct 26, 2020 at 08:50:48PM +0200, Abel Vesa wrote:
> > The clock is considered to be enabled only if the controlling bits
> > match the cgr_val mask. Also make sure the is_enabled returns the
> > correct vaule by locking the access to the register.
> > 
> > Signed-off-by: Abel Vesa 
> > Fixes: 1e54afe9fcfe ("clk: imx: gate2: Allow single bit gating clock")
> > ---
> >  drivers/clk/imx/clk-gate2.c | 60 
> > -
> >  drivers/clk/imx/clk.h   |  8 ++
> >  2 files changed, 29 insertions(+), 39 deletions(-)
> > 
> > diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c
> > index 7eed708..f320bd2b 100644
> > --- a/drivers/clk/imx/clk-gate2.c
> > +++ b/drivers/clk/imx/clk-gate2.c
> > @@ -37,10 +37,22 @@ struct clk_gate2 {
> >  
> >  #define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw)
> >  
> > +static void clk_gate2_do_shared_clks(struct clk_hw *hw, bool enable)
> > +{
> > +   struct clk_gate2 *gate = to_clk_gate2(hw);
> > +   u32 reg;
> > +
> > +   reg = readl(gate->reg);
> > +   if (enable)
> > +   reg |= gate->cgr_val << gate->bit_idx;
> > +   else
> > +   reg &= ~(gate->cgr_val << gate->bit_idx);
> 
> Shouldn't this be:
> 
>   reg &= ~(3 << gate->bit_idx);
>   if (enable)
>   reg |= gate->cgr_val << gate->bit_idx;
> 
> At least that's how it was without this patch and that's how it makes
> sense to me with cgr_val != 3.
> 

Well, that's the actual problem. The value 3 forces all the clocks
that register with this clock type to have 2 bits for controlling the gate.

My patch (though now I think I should split it into 2 separate patches) allows
two HW gates to be controlled by as many bits necessary. For example, there
could be multiple HW gates that are controled by the same bit. By passing
the cgr_val when registering the clocks you can specify how many bits (as a 
mask)
control all those HW gates that share their control bits.

> Sascha
> 


Re: [PATCH] clk: imx: remove unneeded semicolon

2020-10-27 Thread Abel Vesa
On 20-10-27 11:57:56, t...@redhat.com wrote:
> From: Tom Rix 
> 
> A semicolon is not needed after a switch statement.
> 
> Signed-off-by: Tom Rix 

Reviewed-by: Abel Vesa 

> ---
>  drivers/clk/imx/clk-pll14xx.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c
> index aba36e4217d2..2b5ed86b9dbb 100644
> --- a/drivers/clk/imx/clk-pll14xx.c
> +++ b/drivers/clk/imx/clk-pll14xx.c
> @@ -416,7 +416,7 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, 
> const char *name,
>  __func__, name);
>   kfree(pll);
>   return ERR_PTR(-EINVAL);
> - };
> + }
>  
>   pll->base = base;
>   pll->hw.init = 
> -- 
> 2.18.1
> 


Re: [RFC 0/3] clk: imx: Implement blk-ctl driver for i.MX8MN

2020-10-27 Thread Abel Vesa
On 20-10-27 11:31:10, Abel Vesa wrote:
> On 20-10-26 16:37:51, Lucas Stach wrote:
> > Am Montag, den 26.10.2020, 16:55 +0200 schrieb Abel Vesa:
> > > On 20-10-25 11:05:32, Adam Ford wrote:
> > > > On Sun, Oct 25, 2020 at 7:19 AM Marek Vasut  wrote:
> > > > > On 10/25/20 1:05 PM, Abel Vesa wrote:
> > > > > 
> > > > > [...]
> > > > > 
> > > > > > > Together, both the GPC and the clk-blk driver should be able to 
> > > > > > > pull
> > > > > > > the multimedia block out of reset.  Currently, the GPC can handle 
> > > > > > > the
> > > > > > > USB OTG and the GPU, but the LCDIF and MIPI DSI appear to be 
> > > > > > > gated by
> > > > > > > the clock block
> > > > > > > 
> > > > > > > My original patch RFC didn't include the imx8mn node, because it
> > > > > > > hangs, but the node I added looks like:
> > > > > > > 
> > > > > > > media_blk_ctl: clock-controller@32e28000 {
> > > > > > >  compatible = "fsl,imx8mn-media-blk-ctl", "syscon";
> > > > > > >  reg = <0x32e28000 0x1000>;
> > > > > > >  #clock-cells = <1>;
> > > > > > >  #reset-cells = <1>;
> > > > > > > };
> > > > > > > 
> > > > > > > I was hoping you might have some feedback on the 8mn clk-blk 
> > > > > > > driver
> > > > > > > since you did the 8mp clk-blk drive and they appear to be very
> > > > > > > similar.
> > > > > > > 
> > > > > > 
> > > > > > I'll do you one better still. I'll apply the patch in my tree and 
> > > > > > give it
> > > > > > a test tomorrow morning.
> > > > 
> > > > I do have some more updates on how to get the system to not hang, and
> > > > to enumerate more clocks.
> > > > Looking at Marek's work on enabling clocks in the 8MM, he added a
> > > > power-domain in dispmix_blk_ctl pointing to the dispmix in the GPC.
> > > > By forcing the GPC driver to write 0x1fff  to 32e28004, 0x7f to
> > > > 32e28000 and 0x3 to 32e28008, the i.MX8MM can bring the display
> > > > clocks out of reset.
> > > > 
> > > 
> > > Yeah, that makes sense. Basically, it was trying to disable unused clocks
> > > (see clk_disable_unused) but in order to disable the clocks from the
> > > media BLK_CTL (which I think should be renamed in display BLK_CTL) the
> > > PD need to be on. Since you initially didn't give it any PD, it was trying
> > > to blindly write/read the gate bit and therefore freeze.
> > > 
> > > > Unfortunately, the i.MX8MN needs to have 0x100 written to both
> > > > 32e28000 and 32e28004, and the values written for the 8MM are not
> > > > compatible.
> > > > By forcing the GPC to write those values, I can get  lcdif_pixel_clk
> > > > and the mipi_dsi_clkref  appearing on the Nano.
> > > 
> > > I'm trying to make a branch with all the patches for all i.MX8M so I
> > > can keep track of it all. On this branch I've also applied the 
> > > following patchset from Lucas Stach:
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.spinics.net%2Flists%2Farm-kernel%2Fmsg843007.htmldata=04%7C01%7Cabel.vesa%40nxp.com%7C5ff46189143747fce45908d87a5b4281%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637393879674506099%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=ELDCbfLvxrB6FLwnsA6VyGlU5V3qpA2ImfPAbZnWyzI%3Dreserved=0
> > > but I'm getting the folowing errors:
> > > 
> > > [   16.690885] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > > [   16.716839] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > > [   16.730500] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > > 
> > > Lucas, any thoughts?
> > > 
> > > Maybe it's something related to 8MN.
> > 
> > The ADB is apparently clocked by one of the BLK_CTL clocks, so the ADB
> > handshake ack will only work when the BLK_CTL clocks are enabled. So I
> > guess the GPC driver should enable those clocks and assert the resets
> > at the right time in the power-up sequencing. Unfortunately this means
> > we can't properly put the BLK

Re: [RFC 0/3] clk: imx: Implement blk-ctl driver for i.MX8MN

2020-10-27 Thread Abel Vesa
On 20-10-26 16:44:13, Lucas Stach wrote:
> Am Montag, den 26.10.2020, 10:12 -0500 schrieb Adam Ford:
> > On Mon, Oct 26, 2020 at 9:55 AM Abel Vesa  wrote:
> > > On 20-10-25 11:05:32, Adam Ford wrote:
> > > > On Sun, Oct 25, 2020 at 7:19 AM Marek Vasut  wrote:
> > > > > On 10/25/20 1:05 PM, Abel Vesa wrote:
> > > > > 
> > > > > [...]
> > > > > 
> > > > > > > Together, both the GPC and the clk-blk driver should be able to 
> > > > > > > pull
> > > > > > > the multimedia block out of reset.  Currently, the GPC can handle 
> > > > > > > the
> > > > > > > USB OTG and the GPU, but the LCDIF and MIPI DSI appear to be 
> > > > > > > gated by
> > > > > > > the clock block
> > > > > > > 
> > > > > > > My original patch RFC didn't include the imx8mn node, because it
> > > > > > > hangs, but the node I added looks like:
> > > > > > > 
> > > > > > > media_blk_ctl: clock-controller@32e28000 {
> > > > > > >  compatible = "fsl,imx8mn-media-blk-ctl", "syscon";
> > > > > > >  reg = <0x32e28000 0x1000>;
> > > > > > >  #clock-cells = <1>;
> > > > > > >  #reset-cells = <1>;
> > > > > > > };
> > > > > > > 
> > > > > > > I was hoping you might have some feedback on the 8mn clk-blk 
> > > > > > > driver
> > > > > > > since you did the 8mp clk-blk drive and they appear to be very
> > > > > > > similar.
> > > > > > > 
> > > > > > 
> > > > > > I'll do you one better still. I'll apply the patch in my tree and 
> > > > > > give it
> > > > > > a test tomorrow morning.
> > > > 
> > > > I do have some more updates on how to get the system to not hang, and
> > > > to enumerate more clocks.
> > > > Looking at Marek's work on enabling clocks in the 8MM, he added a
> > > > power-domain in dispmix_blk_ctl pointing to the dispmix in the GPC.
> > > > By forcing the GPC driver to write 0x1fff  to 32e28004, 0x7f to
> > > > 32e28000 and 0x3 to 32e28008, the i.MX8MM can bring the display
> > > > clocks out of reset.
> > > > 
> > > 
> > > Yeah, that makes sense. Basically, it was trying to disable unused clocks
> > > (see clk_disable_unused) but in order to disable the clocks from the
> > > media BLK_CTL (which I think should be renamed in display BLK_CTL) the
> > > PD need to be on. Since you initially didn't give it any PD, it was trying
> > > to blindly write/read the gate bit and therefore freeze.
> > > 
> > > > Unfortunately, the i.MX8MN needs to have 0x100 written to both
> > > > 32e28000 and 32e28004, and the values written for the 8MM are not
> > > > compatible.
> > > > By forcing the GPC to write those values, I can get  lcdif_pixel_clk
> > > > and the mipi_dsi_clkref  appearing on the Nano.
> > > 
> > > I'm trying to make a branch with all the patches for all i.MX8M so I
> > > can keep track of it all. On this branch I've also applied the
> > > following patchset from Lucas Stach:
> > > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.spinics.net%2Flists%2Farm-kernel%2Fmsg843007.htmldata=04%7C01%7Cabel.vesa%40nxp.com%7C02bcfb84d35f4c41a05e08d879c5fe57%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637393238611075979%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=fQnrRpGOnk0B4tFCFsfadKK2qozZwxK4ddycmv4VPls%3Dreserved=0
> > > but I'm getting the folowing errors:
> > > 
> > > [   16.690885] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > > [   16.716839] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > > [   16.730500] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > > 
> > > Lucas, any thoughts?
> > > 
> > > Maybe it's something related to 8MN.
> > > 
> > I will go back and double check this now that we have both the
> > blt_crl->power-domain and the power-domain->blk_ctl.
> > 
> > > Will dig further, see what pops out.
> > 
> > I wasn't sure which direction to go with the name.  I can rename the
> > media_blk_ctl  driver to display_blk_ctl

Re: [RFC 0/3] clk: imx: Implement blk-ctl driver for i.MX8MN

2020-10-27 Thread Abel Vesa
On 20-10-26 16:37:51, Lucas Stach wrote:
> Am Montag, den 26.10.2020, 16:55 +0200 schrieb Abel Vesa:
> > On 20-10-25 11:05:32, Adam Ford wrote:
> > > On Sun, Oct 25, 2020 at 7:19 AM Marek Vasut  wrote:
> > > > On 10/25/20 1:05 PM, Abel Vesa wrote:
> > > > 
> > > > [...]
> > > > 
> > > > > > Together, both the GPC and the clk-blk driver should be able to pull
> > > > > > the multimedia block out of reset.  Currently, the GPC can handle 
> > > > > > the
> > > > > > USB OTG and the GPU, but the LCDIF and MIPI DSI appear to be gated 
> > > > > > by
> > > > > > the clock block
> > > > > > 
> > > > > > My original patch RFC didn't include the imx8mn node, because it
> > > > > > hangs, but the node I added looks like:
> > > > > > 
> > > > > > media_blk_ctl: clock-controller@32e28000 {
> > > > > >  compatible = "fsl,imx8mn-media-blk-ctl", "syscon";
> > > > > >  reg = <0x32e28000 0x1000>;
> > > > > >  #clock-cells = <1>;
> > > > > >  #reset-cells = <1>;
> > > > > > };
> > > > > > 
> > > > > > I was hoping you might have some feedback on the 8mn clk-blk driver
> > > > > > since you did the 8mp clk-blk drive and they appear to be very
> > > > > > similar.
> > > > > > 
> > > > > 
> > > > > I'll do you one better still. I'll apply the patch in my tree and 
> > > > > give it
> > > > > a test tomorrow morning.
> > > 
> > > I do have some more updates on how to get the system to not hang, and
> > > to enumerate more clocks.
> > > Looking at Marek's work on enabling clocks in the 8MM, he added a
> > > power-domain in dispmix_blk_ctl pointing to the dispmix in the GPC.
> > > By forcing the GPC driver to write 0x1fff  to 32e28004, 0x7f to
> > > 32e28000 and 0x3 to 32e28008, the i.MX8MM can bring the display
> > > clocks out of reset.
> > > 
> > 
> > Yeah, that makes sense. Basically, it was trying to disable unused clocks
> > (see clk_disable_unused) but in order to disable the clocks from the
> > media BLK_CTL (which I think should be renamed in display BLK_CTL) the
> > PD need to be on. Since you initially didn't give it any PD, it was trying
> > to blindly write/read the gate bit and therefore freeze.
> > 
> > > Unfortunately, the i.MX8MN needs to have 0x100 written to both
> > > 32e28000 and 32e28004, and the values written for the 8MM are not
> > > compatible.
> > > By forcing the GPC to write those values, I can get  lcdif_pixel_clk
> > > and the mipi_dsi_clkref  appearing on the Nano.
> > 
> > I'm trying to make a branch with all the patches for all i.MX8M so I
> > can keep track of it all. On this branch I've also applied the 
> > following patchset from Lucas Stach:
> > https://eur01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.spinics.net%2Flists%2Farm-kernel%2Fmsg843007.htmldata=04%7C01%7Cabel.vesa%40nxp.com%7Cc930b0f523c44946a93f08d879c51c3f%7C686ea1d3bc2b4c6fa92cd99c5c301635%7C0%7C0%7C637393234789815116%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000sdata=ZzzUpEiEVcWqQQ5azAx8dkjHgiSMwkK04tqi32uLKbU%3Dreserved=0
> > but I'm getting the folowing errors:
> > 
> > [   16.690885] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > [   16.716839] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > [   16.730500] imx-pgc imx-pgc-domain.3: failed to power up ADB400
> > 
> > Lucas, any thoughts?
> > 
> > Maybe it's something related to 8MN.
> 
> The ADB is apparently clocked by one of the BLK_CTL clocks, so the ADB
> handshake ack will only work when the BLK_CTL clocks are enabled. So I
> guess the GPC driver should enable those clocks and assert the resets
> at the right time in the power-up sequencing. Unfortunately this means
> we can't properly put the BLK_CTL driver in the power-domain without
> having a cyclic dependency in the DT. I'm still thinking about how to
> solve this properly.
> 

I remember we had something similar in our internal tree with the
bus_blk_clk on 8MP, which was added by the media BLK_CTL. What I did was to
just drop the registration of that clock entirely. My rationale was that if
the clock is part of the BLK_CTL but also needed by the BLK_CTL to work,
I can leave it alone (that is, enabled by default) since when the PD will be
powered off the clock will gated too. I guess another option would be to 
mark it as critical, that way, it will never be disabled (will be left alone
by the clk_disable_unused too) but at the same time will be visible in the
clock hierarchy.

> Regards,
> Lucas
> 


[PATCH v4 09/14] Documentation: bindings: clk: Add bindings for i.MX BLK_CTL

2020-10-26 Thread Abel Vesa
Document the i.MX BLK_CTL with its devicetree properties.

Signed-off-by: Abel Vesa 
Reviewed-by: Dong Aisheng 
---
 .../devicetree/bindings/clock/fsl,imx-blk-ctl.yaml | 60 ++
 1 file changed, 60 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml

diff --git a/Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml 
b/Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml
new file mode 100644
index ..5e9eb40
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/fsl,imx-blk-ctl.yaml
@@ -0,0 +1,60 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/fsl,imx-blk-ctl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX BLK_CTL
+
+maintainers:
+  - Abel Vesa 
+
+description:
+  i.MX BLK_CTL is a conglomerate of different GPRs that are
+  dedicated to a specific subsystem. Because it usually contains
+  clocks amongst other things, it needs access to the i.MX clocks
+  API. All the other functionalities it provides can work just fine
+  from the clock subsystem tree.
+
+properties:
+  compatible:
+items:
+  - enum:
+ - fsl,imx8mp-audio-blk-ctl
+ - fsl,imx8mp-hdmi-blk-ctl
+ - fsl,imx8mp-media-blk-ctl
+  - const: syscon
+
+  reg:
+maxItems: 1
+
+  power-domains:
+maxItems: 1
+
+  '#clock-cells':
+const: 1
+
+  '#reset-cells':
+const: 1
+
+required:
+  - compatible
+  - reg
+  - power-domains
+  - '#clock-cells'
+  - '#reset-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+
+audio_blk_ctl: clock-controller@30e2 {
+   compatible = "fsl,imx8mp-audio-blk-ctl", "syscon";
+   reg = <0x30e2 0x1>;
+   power-domains = <_pd>;
+
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+};
-- 
2.7.4



[PATCH v4 03/14] dt-bindings: clock: imx8mp: Add ids for the audio shared gate

2020-10-26 Thread Abel Vesa
All these IDs are for one single HW gate (CCGR101) that is shared
between these root clocks.

Signed-off-by: Abel Vesa 
Acked-by: Rob Herring 
---
 include/dt-bindings/clock/imx8mp-clock.h | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/dt-bindings/clock/imx8mp-clock.h 
b/include/dt-bindings/clock/imx8mp-clock.h
index 89c67b7..5fc2c40 100644
--- a/include/dt-bindings/clock/imx8mp-clock.h
+++ b/include/dt-bindings/clock/imx8mp-clock.h
@@ -322,7 +322,17 @@
 #define IMX8MP_CLK_HSIO_AXI311
 #define IMX8MP_CLK_MEDIA_ISP   312
 
-#define IMX8MP_CLK_END 313
+#define IMX8MP_CLK_AUDIO_AHB_ROOT  313
+#define IMX8MP_CLK_AUDIO_AXI_ROOT  314
+#define IMX8MP_CLK_SAI1_ROOT   315
+#define IMX8MP_CLK_SAI2_ROOT   316
+#define IMX8MP_CLK_SAI3_ROOT   317
+#define IMX8MP_CLK_SAI5_ROOT   318
+#define IMX8MP_CLK_SAI6_ROOT   319
+#define IMX8MP_CLK_SAI7_ROOT   320
+#define IMX8MP_CLK_PDM_ROOT321
+
+#define IMX8MP_CLK_END 322
 
 #define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_IPG  0
 #define IMX8MP_CLK_AUDIO_BLK_CTL_SAI1_MCLK11
-- 
2.7.4



[PATCH v4 08/14] clk: imx8mp: Add audio shared gate

2020-10-26 Thread Abel Vesa
According to the RM, the CCGR101 is shared for the following root clocks:
- AUDIO_AHB_CLK_ROOT
- AUDIO_AXI_CLK_ROOT
- SAI2_CLK_ROOT
- SAI3_CLK_ROOT
- SAI5_CLK_ROOT
- SAI6_CLK_ROOT
- SAI7_CLK_ROOT
- PDM_CLK_ROOT

Signed-off-by: Abel Vesa 
Reviewed-by: Dong Aisheng 
---
 drivers/clk/imx/clk-imx8mp.c | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
index 12ce477..6812a01 100644
--- a/drivers/clk/imx/clk-imx8mp.c
+++ b/drivers/clk/imx/clk-imx8mp.c
@@ -17,6 +17,7 @@
 
 static u32 share_count_nand;
 static u32 share_count_media;
+static u32 share_count_audio;
 
 static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", 
"dummy", };
 static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", 
"audio_pll1_ref_sel", };
@@ -725,7 +726,16 @@ static int imx8mp_clocks_probe(struct platform_device 
*pdev)
hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", 
"hdmi_axi", ccm_base + 0x45f0, 0);
hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", 
"ipg_root", ccm_base + 0x4620, 0);
hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", 
ccm_base + 0x4630, 0);
-   hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", 
"ipg_root", ccm_base + 0x4650, 0);
+
+   hws[IMX8MP_CLK_AUDIO_AHB_ROOT] = 
imx_clk_hw_gate2_shared2("audio_ahb_root", "audio_ahb", ccm_base + 0x4650, 0, 
_count_audio);
+   hws[IMX8MP_CLK_AUDIO_AXI_ROOT] = 
imx_clk_hw_gate2_shared2("audio_axi_root", "audio_axi", ccm_base + 0x4650, 0, 
_count_audio);
+   hws[IMX8MP_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root", 
"sai1", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root", 
"sai2", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root", 
"sai3", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root", 
"sai5", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root", 
"sai6", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root", 
"sai7", ccm_base + 0x4650, 0, _count_audio);
+   hws[IMX8MP_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root", "pdm", 
ccm_base + 0x4650, 0, _count_audio);
 
hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
 hws[IMX8MP_CLK_A53_CORE]->clk,
-- 
2.7.4



[PATCH v4 12/14] arm64: dts: imx8mp: Add audio_blk_ctl node

2020-10-26 Thread Abel Vesa
Some of the features of the audio_ctl will be used by some
different drivers in a way those drivers will know best, so adding the
syscon compatible we allow those to do just that. Only the resets
and the clocks are registered bit the clk-blk-ctl driver.

Signed-off-by: Abel Vesa 
Reviewed-by: Dong Aisheng 
---
 arch/arm64/boot/dts/freescale/imx8mp.dtsi | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi 
b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
index 6038f66..ae161a7 100644
--- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi
+++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -736,6 +736,21 @@
};
};
 
+   aips5: bus@30c0 {
+   compatible = "fsl,aips-bus", "simple-bus";
+   reg = <0x30c0 0x40>;
+   #address-cells = <1>;
+   #size-cells = <1>;
+   ranges;
+
+   audio_blk_ctl: clock-controller@30e2 {
+   compatible = "fsl,imx8mp-audio-blk-ctl", 
"syscon";
+   reg = <0x30e2 0x50c>;
+   #clock-cells = <1>;
+   #reset-cells = <1>;
+   };
+   };
+
gic: interrupt-controller@3880 {
compatible = "arm,gic-v3";
reg = <0x3880 0x1>,
-- 
2.7.4



  1   2   3   4   5   6   7   8   >