aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Mazzucato <nicola.mazzucato@arm.com>2019-07-23 17:10:31 +0100
committerjimqui01 <54316584+jimqui01@users.noreply.github.com>2020-03-02 11:01:53 +0000
commitef5071cbd4f53933fcd79d7d1d634a46396c93a0 (patch)
tree08f98bb174dac38591c68446f5e23ad8a586b882
parenta32191c75de2b4326e4e4104c06a398f91e385b5 (diff)
pl011: Add powerup/powerdown handlers
This patch introduces a configurable power domain identifier such that the driver can be informed of power state changes. This is achieved through notifications for pre_state and post_state power changes. With this power domain identifier the module can receive notifications and action accordingly. The specific action is not yet implemented. Change-Id: I7751b6de5899a2c65aec3aef3e5e4b8c1d0cd07c Signed-off-by: Nicola Mazzucato <nicola.mazzucato@arm.com>
-rw-r--r--module/pl011/include/mod_pl011.h3
-rw-r--r--module/pl011/src/mod_pl011.c104
-rw-r--r--product/juno/scp_ramfw/config_log.c1
-rw-r--r--product/juno/scp_romfw/config_log.c1
-rw-r--r--product/juno/scp_romfw_bypass/config_log.c1
-rw-r--r--product/n1sdp/mcp_ramfw/config_log.c1
-rw-r--r--product/n1sdp/mcp_romfw/config_log.c1
-rw-r--r--product/n1sdp/scp_ramfw/config_log.c1
-rw-r--r--product/n1sdp/scp_romfw/config_log.c1
-rw-r--r--product/rdn1e1/mcp_romfw/config_log.c1
-rw-r--r--product/rdn1e1/scp_ramfw/config_log.c1
-rw-r--r--product/rdn1e1/scp_romfw/config_log.c1
-rw-r--r--product/sgi575/mcp_romfw/config_log.c1
-rw-r--r--product/sgi575/scp_ramfw/config_log.c1
-rw-r--r--product/sgi575/scp_romfw/config_log.c1
-rw-r--r--product/sgm775/scp_ramfw/config_log.c1
-rw-r--r--product/sgm775/scp_romfw/config_log.c1
-rw-r--r--product/sgm776/scp_ramfw/config_log.c1
-rw-r--r--product/sgm776/scp_romfw/config_log.c1
-rw-r--r--product/synquacer/scp_ramfw/config_log_pl011.c1
20 files changed, 118 insertions, 7 deletions
diff --git a/module/pl011/include/mod_pl011.h b/module/pl011/include/mod_pl011.h
index 461ecf27..6164ef32 100644
--- a/module/pl011/include/mod_pl011.h
+++ b/module/pl011/include/mod_pl011.h
@@ -42,6 +42,9 @@ struct mod_pl011_device_config {
/*! Identifier of the clock that this device depends on */
fwk_id_t clock_id;
+
+ /*! Identifier of the power domain that this device depends on */
+ fwk_id_t pd_id;
};
/*!
diff --git a/module/pl011/src/mod_pl011.c b/module/pl011/src/mod_pl011.c
index 56129795..05bffb72 100644
--- a/module/pl011/src/mod_pl011.c
+++ b/module/pl011/src/mod_pl011.c
@@ -188,6 +188,25 @@ static int pl011_start(fwk_id_t id)
config = device_config_table[fwk_id_get_element_idx(id)];
+ /*
+ * Subscribe to power domain pre-state change notifications when identifier
+ * is provided.
+ */
+ #if BUILD_HAS_MOD_POWER_DOMAIN
+ int status;
+ if (!fwk_id_is_type(config->pd_id, FWK_ID_TYPE_NONE)) {
+ status = fwk_notification_subscribe(
+ mod_pd_notification_id_power_state_pre_transition,
+ config->pd_id,
+ id);
+ if (status != FWK_SUCCESS)
+ return status;
+ }
+ #endif
+
+ /*
+ * Subscribe to clock state change notifications if identifier is provided
+ */
if (fwk_id_is_type(config->clock_id, FWK_ID_TYPE_NONE))
return FWK_SUCCESS;
@@ -197,19 +216,13 @@ static int pl011_start(fwk_id_t id)
id);
}
-int pl011_process_notification(
+static int process_clock_notification(
const struct fwk_event *event,
struct fwk_event *resp_event)
{
struct clock_notification_params *params;
struct clock_state_change_pending_resp_params *resp_params;
- assert(
- fwk_id_is_equal(
- event->id,
- mod_clock_notification_id_state_change_pending));
- assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_ELEMENT));
-
resp_params =
(struct clock_state_change_pending_resp_params *)resp_event->params;
resp_params->status = FWK_SUCCESS;
@@ -222,6 +235,83 @@ int pl011_process_notification(
return FWK_SUCCESS;
}
+#if BUILD_HAS_MOD_POWER_DOMAIN
+static int pl011_powerdown(fwk_id_t id)
+{
+ int status;
+
+ const struct mod_pl011_device_config *config =
+ device_config_table[fwk_id_get_element_idx(id)];
+
+ status = fwk_notification_unsubscribe(
+ mod_pd_notification_id_power_state_pre_transition,
+ config->pd_id,
+ id);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ status = fwk_notification_subscribe(
+ mod_pd_notification_id_power_state_transition,
+ config->pd_id,
+ id);
+ return status;
+}
+
+static int pl011_powerup(fwk_id_t id)
+{
+ int status;
+
+ const struct mod_pl011_device_config *config =
+ device_config_table[fwk_id_get_element_idx(id)];
+
+ status = fwk_notification_unsubscribe(
+ mod_pd_notification_id_power_state_transition,
+ config->pd_id,
+ id);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ status = fwk_notification_subscribe(
+ mod_pd_notification_id_power_state_pre_transition,
+ config->pd_id,
+ id);
+ return status;
+}
+#endif
+
+int pl011_process_notification(
+ const struct fwk_event *event,
+ struct fwk_event *resp_event)
+{
+ fwk_assert(fwk_id_is_type(event->target_id, FWK_ID_TYPE_ELEMENT));
+
+ if (fwk_id_is_equal(
+ event->id,
+ mod_clock_notification_id_state_change_pending)) {
+ /*
+ * Clock notification
+ */
+ return process_clock_notification(event, resp_event);
+ #if BUILD_HAS_MOD_POWER_DOMAIN
+ } else if (fwk_id_is_equal(
+ event->id,
+ mod_pd_notification_id_power_state_pre_transition)) {
+ /*
+ * Power domain pre-transition notification
+ */
+ return pl011_powerdown(event->target_id);
+ } else if (fwk_id_is_equal(
+ event->id,
+ mod_pd_notification_id_power_state_transition)) {
+ /*
+ * Power domain post-transition notification
+ */
+ return pl011_powerup(event->target_id);
+ #endif
+ } else
+ return FWK_E_PARAM;
+}
+
const struct fwk_module module_pl011 = {
.name = "PL011",
.type = FWK_MODULE_TYPE_DRIVER,
diff --git a/product/juno/scp_ramfw/config_log.c b/product/juno/scp_ramfw/config_log.c
index 10a6dc3a..bad9cce3 100644
--- a/product/juno/scp_ramfw/config_log.c
+++ b/product/juno/scp_ramfw/config_log.c
@@ -22,6 +22,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
},
},
[1] = {0},
diff --git a/product/juno/scp_romfw/config_log.c b/product/juno/scp_romfw/config_log.c
index 0d4bd460..54342a2c 100644
--- a/product/juno/scp_romfw/config_log.c
+++ b/product/juno/scp_romfw/config_log.c
@@ -29,6 +29,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
* locked.
*/
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
},
},
[1] = {0},
diff --git a/product/juno/scp_romfw_bypass/config_log.c b/product/juno/scp_romfw_bypass/config_log.c
index 0d4bd460..54342a2c 100644
--- a/product/juno/scp_romfw_bypass/config_log.c
+++ b/product/juno/scp_romfw_bypass/config_log.c
@@ -29,6 +29,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
* locked.
*/
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
},
},
[1] = {0},
diff --git a/product/n1sdp/mcp_ramfw/config_log.c b/product/n1sdp/mcp_ramfw/config_log.c
index ceb3542d..e71b9f37 100644
--- a/product/n1sdp/mcp_ramfw/config_log.c
+++ b/product/n1sdp/mcp_ramfw/config_log.c
@@ -25,6 +25,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = CLOCK_RATE_REFCLK,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/n1sdp/mcp_romfw/config_log.c b/product/n1sdp/mcp_romfw/config_log.c
index 8b3eba9b..f584b527 100644
--- a/product/n1sdp/mcp_romfw/config_log.c
+++ b/product/n1sdp/mcp_romfw/config_log.c
@@ -30,6 +30,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = CLOCK_RATE_REFCLK,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/n1sdp/scp_ramfw/config_log.c b/product/n1sdp/scp_ramfw/config_log.c
index 3da2f980..bd57e035 100644
--- a/product/n1sdp/scp_ramfw/config_log.c
+++ b/product/n1sdp/scp_ramfw/config_log.c
@@ -25,6 +25,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = CLOCK_RATE_REFCLK,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/n1sdp/scp_romfw/config_log.c b/product/n1sdp/scp_romfw/config_log.c
index 75cc6f6a..6ca8384d 100644
--- a/product/n1sdp/scp_romfw/config_log.c
+++ b/product/n1sdp/scp_romfw/config_log.c
@@ -30,6 +30,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = CLOCK_RATE_REFCLK,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/rdn1e1/mcp_romfw/config_log.c b/product/rdn1e1/mcp_romfw/config_log.c
index 2d42e797..cb3efd40 100644
--- a/product/rdn1e1/mcp_romfw/config_log.c
+++ b/product/rdn1e1/mcp_romfw/config_log.c
@@ -24,6 +24,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/rdn1e1/scp_ramfw/config_log.c b/product/rdn1e1/scp_ramfw/config_log.c
index d49be810..f72a4331 100644
--- a/product/rdn1e1/scp_ramfw/config_log.c
+++ b/product/rdn1e1/scp_ramfw/config_log.c
@@ -24,6 +24,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/rdn1e1/scp_romfw/config_log.c b/product/rdn1e1/scp_romfw/config_log.c
index 3b227f73..2e092507 100644
--- a/product/rdn1e1/scp_romfw/config_log.c
+++ b/product/rdn1e1/scp_romfw/config_log.c
@@ -24,6 +24,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/sgi575/mcp_romfw/config_log.c b/product/sgi575/mcp_romfw/config_log.c
index 82369295..ff4d82b7 100644
--- a/product/sgi575/mcp_romfw/config_log.c
+++ b/product/sgi575/mcp_romfw/config_log.c
@@ -24,6 +24,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/sgi575/scp_ramfw/config_log.c b/product/sgi575/scp_ramfw/config_log.c
index 046d061c..395ee117 100644
--- a/product/sgi575/scp_ramfw/config_log.c
+++ b/product/sgi575/scp_ramfw/config_log.c
@@ -24,6 +24,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/sgi575/scp_romfw/config_log.c b/product/sgi575/scp_romfw/config_log.c
index 72142959..2bb737de 100644
--- a/product/sgi575/scp_romfw/config_log.c
+++ b/product/sgi575/scp_romfw/config_log.c
@@ -24,6 +24,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/sgm775/scp_ramfw/config_log.c b/product/sgm775/scp_ramfw/config_log.c
index 5f40e967..00ce578b 100644
--- a/product/sgm775/scp_ramfw/config_log.c
+++ b/product/sgm775/scp_ramfw/config_log.c
@@ -28,6 +28,7 @@ static const struct fwk_element pl011_element_table[] = {
.clock_id = FWK_ID_ELEMENT_INIT(
FWK_MODULE_IDX_CLOCK,
CLOCK_DEV_IDX_FCMCLK),
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/sgm775/scp_romfw/config_log.c b/product/sgm775/scp_romfw/config_log.c
index 90cb3c43..bd634fab 100644
--- a/product/sgm775/scp_romfw/config_log.c
+++ b/product/sgm775/scp_romfw/config_log.c
@@ -28,6 +28,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.clock_id = FWK_ID_ELEMENT_INIT(
FWK_MODULE_IDX_CLOCK,
CLOCK_DEV_IDX_SYS_FCMCLK),
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/sgm776/scp_ramfw/config_log.c b/product/sgm776/scp_ramfw/config_log.c
index c418ef46..c3e6978e 100644
--- a/product/sgm776/scp_ramfw/config_log.c
+++ b/product/sgm776/scp_ramfw/config_log.c
@@ -28,6 +28,7 @@ static const struct fwk_element pl011_element_table[] = {
.clock_id = FWK_ID_ELEMENT_INIT(
FWK_MODULE_IDX_CLOCK,
CLOCK_DEV_IDX_INTERCONNECT),
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/sgm776/scp_romfw/config_log.c b/product/sgm776/scp_romfw/config_log.c
index 29fdf358..959c1aa4 100644
--- a/product/sgm776/scp_romfw/config_log.c
+++ b/product/sgm776/scp_romfw/config_log.c
@@ -27,6 +27,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.clock_rate_hz = 24 * FWK_MHZ,
.clock_id = FWK_ID_ELEMENT_INIT(FWK_MODULE_IDX_CLOCK,
CLOCK_DEV_IDX_SYS_NOCMEMCLK),
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },
diff --git a/product/synquacer/scp_ramfw/config_log_pl011.c b/product/synquacer/scp_ramfw/config_log_pl011.c
index ce6388e4..d0a939c8 100644
--- a/product/synquacer/scp_ramfw/config_log_pl011.c
+++ b/product/synquacer/scp_ramfw/config_log_pl011.c
@@ -24,6 +24,7 @@ static const struct fwk_element pl011_element_desc_table[] = {
.baud_rate_bps = 115200,
.clock_rate_hz = 62500 * FWK_KHZ,
.clock_id = FWK_ID_NONE_INIT,
+ .pd_id = FWK_ID_NONE_INIT,
}),
},
[1] = { 0 },