summaryrefslogtreecommitdiff
path: root/drivers/soc/qcom
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soc/qcom')
-rw-r--r--drivers/soc/qcom/cmd-db.c11
-rw-r--r--drivers/soc/qcom/rpmh-rsc.c43
2 files changed, 51 insertions, 3 deletions
diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c
index 08736ea936a..67be18e89f4 100644
--- a/drivers/soc/qcom/cmd-db.c
+++ b/drivers/soc/qcom/cmd-db.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) "cmd-db: " fmt
+#include <asm/system.h>
#include <dm.h>
#include <dm/ofnode.h>
#include <dm/device_compat.h>
@@ -141,7 +142,7 @@ static int cmd_db_get_header(const char *id, const struct entry_header **eh,
ent = rsc_to_entry_header(rsc_hdr);
for (j = 0; j < le16_to_cpu(rsc_hdr->cnt); j++, ent++) {
- if (memcmp(ent->id, query, sizeof(ent->id)) == 0) {
+ if (strncmp(ent->id, query, sizeof(ent->id)) == 0) {
if (eh)
*eh = ent;
if (rh)
@@ -182,9 +183,10 @@ u32 cmd_db_read_addr(const char *id)
}
EXPORT_SYMBOL_GPL(cmd_db_read_addr);
-int cmd_db_bind(struct udevice *dev)
+static int cmd_db_bind(struct udevice *dev)
{
void __iomem *base;
+ fdt_size_t size;
ofnode node;
if (cmd_db_header)
@@ -194,12 +196,15 @@ int cmd_db_bind(struct udevice *dev)
debug("%s(%s)\n", __func__, ofnode_get_name(node));
- base = (void __iomem *)ofnode_get_addr(node);
+ base = (void __iomem *)ofnode_get_addr_size(node, "reg", &size);
if ((fdt_addr_t)base == FDT_ADDR_T_NONE) {
log_err("%s: Failed to read base address\n", __func__);
return -ENOENT;
}
+ /* On SM8550/SM8650 and newer SoCs cmd-db might not be mapped */
+ mmu_map_region((phys_addr_t)base, (phys_size_t)size, false);
+
cmd_db_header = base;
if (!cmd_db_magic_matches(cmd_db_header)) {
log_err("%s: Invalid Command DB Magic\n", __func__);
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c
index 61fb2e69558..aee9e55194e 100644
--- a/drivers/soc/qcom/rpmh-rsc.c
+++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -294,6 +294,48 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
}
/**
+ * __tcs_set_trigger() - Start xfer on a TCS or unset trigger on a borrowed TCS
+ * @drv: The controller.
+ * @tcs_id: The global ID of this TCS.
+ * @trigger: If true then untrigger/retrigger. If false then just untrigger.
+ *
+ * In the normal case we only ever call with "trigger=true" to start a
+ * transfer. That will un-trigger/disable the TCS from the last transfer
+ * then trigger/enable for this transfer.
+ *
+ * If we borrowed a wake TCS for an active-only transfer we'll also call
+ * this function with "trigger=false" to just do the un-trigger/disable
+ * before using the TCS for wake purposes again.
+ *
+ * Note that the AP is only in charge of triggering active-only transfers.
+ * The AP never triggers sleep/wake values using this function.
+ */
+static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger)
+{
+ u32 enable;
+ u32 reg = drv->regs[RSC_DRV_CONTROL];
+
+ /*
+ * HW req: Clear the DRV_CONTROL and enable TCS again
+ * While clearing ensure that the AMC mode trigger is cleared
+ * and then the mode enable is cleared.
+ */
+ enable = read_tcs_reg(drv, reg, tcs_id);
+ enable &= ~TCS_AMC_MODE_TRIGGER;
+ write_tcs_reg_sync(drv, reg, tcs_id, enable);
+ enable &= ~TCS_AMC_MODE_ENABLE;
+ write_tcs_reg_sync(drv, reg, tcs_id, enable);
+
+ if (trigger) {
+ /* Enable the AMC mode on the TCS and then trigger the TCS */
+ enable = TCS_AMC_MODE_ENABLE;
+ write_tcs_reg_sync(drv, reg, tcs_id, enable);
+ enable |= TCS_AMC_MODE_TRIGGER;
+ write_tcs_reg(drv, reg, tcs_id, enable);
+ }
+}
+
+/**
* rpmh_rsc_send_data() - Write / trigger active-only message.
* @drv: The controller.
* @msg: The data to be sent.
@@ -348,6 +390,7 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg)
* of __tcs_set_trigger() below.
*/
__tcs_buffer_write(drv, tcs_id, 0, msg);
+ __tcs_set_trigger(drv, tcs_id, true);
/* U-Boot: Now wait for the TCS to be cleared, indicating that we're done */
for (i = 0; i < USEC_PER_SEC; i++) {