Commit b70c9d37 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'rproc-v4.18' of git://github.com/andersson/remoteproc

Pull remoteproc updates from Bjorn Andersson:
 "This brings a few minor fixes to the Davinci driver, drops a orphan
  include file from the StE cleanup done ealier and introduces support
  for booting the modem on Qualcomm's SDM845 platform"

* tag 'rproc-v4.18' of git://github.com/andersson/remoteproc:
  remoteproc: q6v5: Allow defining GLINK edge for mss remoteproc
  remoteproc: q6v5: Add support for mss remoteproc on SDM845
  remoteproc: q6v5: Introduce reset assert/deassert helper functions
  dt-bindings: remoteproc: Add Q6v5 Modem PIL binding for SDM845
  remoteproc: q6v5: Move proxy unvote to handover irq handler
  remoteproc: q6v5: Return irq from q6v5_request_irq()
  remoteproc/ste: remove abandoned include file
  remoteproc/davinci: use octal permissions for module_param()
  remoteproc/davinci: prepare and unprepare the clock where needed
  remoteproc/davinci: add the missing retval check for clk_enable()
  remoteproc: Remove depends on HAS_DMA in case of platform dependency
  remoteproc: Prevent incorrect rproc state on xfer mem ownership failure
parents 6f75edea 4725496e
...@@ -11,6 +11,7 @@ on the Qualcomm Hexagon core. ...@@ -11,6 +11,7 @@ on the Qualcomm Hexagon core.
"qcom,msm8916-mss-pil", "qcom,msm8916-mss-pil",
"qcom,msm8974-mss-pil" "qcom,msm8974-mss-pil"
"qcom,msm8996-mss-pil" "qcom,msm8996-mss-pil"
"qcom,sdm845-mss-pil"
- reg: - reg:
Usage: required Usage: required
......
...@@ -24,7 +24,6 @@ config IMX_REMOTEPROC ...@@ -24,7 +24,6 @@ config IMX_REMOTEPROC
config OMAP_REMOTEPROC config OMAP_REMOTEPROC
tristate "OMAP remoteproc support" tristate "OMAP remoteproc support"
depends on HAS_DMA
depends on ARCH_OMAP4 || SOC_OMAP5 depends on ARCH_OMAP4 || SOC_OMAP5
depends on OMAP_IOMMU depends on OMAP_IOMMU
select MAILBOX select MAILBOX
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "remoteproc_internal.h" #include "remoteproc_internal.h"
static char *da8xx_fw_name; static char *da8xx_fw_name;
module_param(da8xx_fw_name, charp, S_IRUGO); module_param(da8xx_fw_name, charp, 0444);
MODULE_PARM_DESC(da8xx_fw_name, MODULE_PARM_DESC(da8xx_fw_name,
"Name of DSP firmware file in /lib/firmware (if not specified defaults to 'rproc-dsp-fw')"); "Name of DSP firmware file in /lib/firmware (if not specified defaults to 'rproc-dsp-fw')");
...@@ -138,6 +138,7 @@ static int da8xx_rproc_start(struct rproc *rproc) ...@@ -138,6 +138,7 @@ static int da8xx_rproc_start(struct rproc *rproc)
struct device *dev = rproc->dev.parent; struct device *dev = rproc->dev.parent;
struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv; struct da8xx_rproc *drproc = (struct da8xx_rproc *)rproc->priv;
struct clk *dsp_clk = drproc->dsp_clk; struct clk *dsp_clk = drproc->dsp_clk;
int ret;
/* hw requires the start (boot) address be on 1KB boundary */ /* hw requires the start (boot) address be on 1KB boundary */
if (rproc->bootaddr & 0x3ff) { if (rproc->bootaddr & 0x3ff) {
...@@ -148,7 +149,12 @@ static int da8xx_rproc_start(struct rproc *rproc) ...@@ -148,7 +149,12 @@ static int da8xx_rproc_start(struct rproc *rproc)
writel(rproc->bootaddr, drproc->bootreg); writel(rproc->bootaddr, drproc->bootreg);
clk_enable(dsp_clk); ret = clk_prepare_enable(dsp_clk);
if (ret) {
dev_err(dev, "clk_prepare_enable() failed: %d\n", ret);
return ret;
}
davinci_clk_reset_deassert(dsp_clk); davinci_clk_reset_deassert(dsp_clk);
return 0; return 0;
...@@ -159,7 +165,7 @@ static int da8xx_rproc_stop(struct rproc *rproc) ...@@ -159,7 +165,7 @@ static int da8xx_rproc_stop(struct rproc *rproc)
struct da8xx_rproc *drproc = rproc->priv; struct da8xx_rproc *drproc = rproc->priv;
davinci_clk_reset_assert(drproc->dsp_clk); davinci_clk_reset_assert(drproc->dsp_clk);
clk_disable(drproc->dsp_clk); clk_disable_unprepare(drproc->dsp_clk);
return 0; return 0;
} }
......
...@@ -57,6 +57,8 @@ ...@@ -57,6 +57,8 @@
#define RMB_PMI_META_DATA_REG 0x10 #define RMB_PMI_META_DATA_REG 0x10
#define RMB_PMI_CODE_START_REG 0x14 #define RMB_PMI_CODE_START_REG 0x14
#define RMB_PMI_CODE_LENGTH_REG 0x18 #define RMB_PMI_CODE_LENGTH_REG 0x18
#define RMB_MBA_MSS_STATUS 0x40
#define RMB_MBA_ALT_RESET 0x44
#define RMB_CMD_META_DATA_READY 0x1 #define RMB_CMD_META_DATA_READY 0x1
#define RMB_CMD_LOAD_READY 0x2 #define RMB_CMD_LOAD_READY 0x2
...@@ -104,6 +106,13 @@ ...@@ -104,6 +106,13 @@
#define QDSP6SS_XO_CBCR 0x0038 #define QDSP6SS_XO_CBCR 0x0038
#define QDSP6SS_ACC_OVERRIDE_VAL 0x20 #define QDSP6SS_ACC_OVERRIDE_VAL 0x20
/* QDSP6v65 parameters */
#define QDSP6SS_SLEEP 0x3C
#define QDSP6SS_BOOT_CORE_START 0x400
#define QDSP6SS_BOOT_CMD 0x404
#define SLEEP_CHECK_MAX_LOOPS 200
#define BOOT_FSM_TIMEOUT 10000
struct reg_info { struct reg_info {
struct regulator *reg; struct regulator *reg;
int uV; int uV;
...@@ -121,9 +130,11 @@ struct rproc_hexagon_res { ...@@ -121,9 +130,11 @@ struct rproc_hexagon_res {
struct qcom_mss_reg_res *proxy_supply; struct qcom_mss_reg_res *proxy_supply;
struct qcom_mss_reg_res *active_supply; struct qcom_mss_reg_res *active_supply;
char **proxy_clk_names; char **proxy_clk_names;
char **reset_clk_names;
char **active_clk_names; char **active_clk_names;
int version; int version;
bool need_mem_protection; bool need_mem_protection;
bool has_alt_reset;
}; };
struct q6v5 { struct q6v5 {
...@@ -143,9 +154,15 @@ struct q6v5 { ...@@ -143,9 +154,15 @@ struct q6v5 {
struct qcom_smem_state *state; struct qcom_smem_state *state;
unsigned stop_bit; unsigned stop_bit;
int handover_irq;
bool proxy_unvoted;
struct clk *active_clks[8]; struct clk *active_clks[8];
struct clk *reset_clks[4];
struct clk *proxy_clks[4]; struct clk *proxy_clks[4];
int active_clk_count; int active_clk_count;
int reset_clk_count;
int proxy_clk_count; int proxy_clk_count;
struct reg_info active_regs[1]; struct reg_info active_regs[1];
...@@ -166,10 +183,12 @@ struct q6v5 { ...@@ -166,10 +183,12 @@ struct q6v5 {
void *mpss_region; void *mpss_region;
size_t mpss_size; size_t mpss_size;
struct qcom_rproc_glink glink_subdev;
struct qcom_rproc_subdev smd_subdev; struct qcom_rproc_subdev smd_subdev;
struct qcom_rproc_ssr ssr_subdev; struct qcom_rproc_ssr ssr_subdev;
struct qcom_sysmon *sysmon; struct qcom_sysmon *sysmon;
bool need_mem_protection; bool need_mem_protection;
bool has_alt_reset;
int mpss_perm; int mpss_perm;
int mba_perm; int mba_perm;
int version; int version;
...@@ -179,6 +198,7 @@ enum { ...@@ -179,6 +198,7 @@ enum {
MSS_MSM8916, MSS_MSM8916,
MSS_MSM8974, MSS_MSM8974,
MSS_MSM8996, MSS_MSM8996,
MSS_SDM845,
}; };
static int q6v5_regulator_init(struct device *dev, struct reg_info *regs, static int q6v5_regulator_init(struct device *dev, struct reg_info *regs,
...@@ -333,6 +353,29 @@ static int q6v5_load(struct rproc *rproc, const struct firmware *fw) ...@@ -333,6 +353,29 @@ static int q6v5_load(struct rproc *rproc, const struct firmware *fw)
return 0; return 0;
} }
static int q6v5_reset_assert(struct q6v5 *qproc)
{
if (qproc->has_alt_reset)
return reset_control_reset(qproc->mss_restart);
else
return reset_control_assert(qproc->mss_restart);
}
static int q6v5_reset_deassert(struct q6v5 *qproc)
{
int ret;
if (qproc->has_alt_reset) {
writel(1, qproc->rmb_base + RMB_MBA_ALT_RESET);
ret = reset_control_reset(qproc->mss_restart);
writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET);
} else {
ret = reset_control_deassert(qproc->mss_restart);
}
return ret;
}
static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms) static int q6v5_rmb_pbl_wait(struct q6v5 *qproc, int ms)
{ {
unsigned long timeout; unsigned long timeout;
...@@ -385,8 +428,35 @@ static int q6v5proc_reset(struct q6v5 *qproc) ...@@ -385,8 +428,35 @@ static int q6v5proc_reset(struct q6v5 *qproc)
int ret; int ret;
int i; int i;
if (qproc->version == MSS_SDM845) {
val = readl(qproc->reg_base + QDSP6SS_SLEEP);
val |= 0x1;
writel(val, qproc->reg_base + QDSP6SS_SLEEP);
if (qproc->version == MSS_MSM8996) { ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
val, !(val & BIT(31)), 1,
SLEEP_CHECK_MAX_LOOPS);
if (ret) {
dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
return -ETIMEDOUT;
}
/* De-assert QDSP6 stop core */
writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
/* Trigger boot FSM */
writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
ret = readl_poll_timeout(qproc->rmb_base + RMB_MBA_MSS_STATUS,
val, (val & BIT(0)) != 0, 10, BOOT_FSM_TIMEOUT);
if (ret) {
dev_err(qproc->dev, "Boot FSM failed to complete.\n");
/* Reset the modem so that boot FSM is in reset state */
q6v5_reset_deassert(qproc);
return ret;
}
goto pbl_wait;
} else if (qproc->version == MSS_MSM8996) {
/* Override the ACC value if required */ /* Override the ACC value if required */
writel(QDSP6SS_ACC_OVERRIDE_VAL, writel(QDSP6SS_ACC_OVERRIDE_VAL,
qproc->reg_base + QDSP6SS_STRAP_ACC); qproc->reg_base + QDSP6SS_STRAP_ACC);
...@@ -494,6 +564,7 @@ static int q6v5proc_reset(struct q6v5 *qproc) ...@@ -494,6 +564,7 @@ static int q6v5proc_reset(struct q6v5 *qproc)
val &= ~Q6SS_STOP_CORE; val &= ~Q6SS_STOP_CORE;
writel(val, qproc->reg_base + QDSP6SS_RESET_REG); writel(val, qproc->reg_base + QDSP6SS_RESET_REG);
pbl_wait:
/* Wait for PBL status */ /* Wait for PBL status */
ret = q6v5_rmb_pbl_wait(qproc, 1000); ret = q6v5_rmb_pbl_wait(qproc, 1000);
if (ret == -ETIMEDOUT) { if (ret == -ETIMEDOUT) {
...@@ -727,11 +798,15 @@ static int q6v5_start(struct rproc *rproc) ...@@ -727,11 +798,15 @@ static int q6v5_start(struct rproc *rproc)
int xfermemop_ret; int xfermemop_ret;
int ret; int ret;
qproc->proxy_unvoted = false;
enable_irq(qproc->handover_irq);
ret = q6v5_regulator_enable(qproc, qproc->proxy_regs, ret = q6v5_regulator_enable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count); qproc->proxy_reg_count);
if (ret) { if (ret) {
dev_err(qproc->dev, "failed to enable proxy supplies\n"); dev_err(qproc->dev, "failed to enable proxy supplies\n");
return ret; goto disable_irqs;
} }
ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks, ret = q6v5_clk_enable(qproc->dev, qproc->proxy_clks,
...@@ -747,12 +822,20 @@ static int q6v5_start(struct rproc *rproc) ...@@ -747,12 +822,20 @@ static int q6v5_start(struct rproc *rproc)
dev_err(qproc->dev, "failed to enable supplies\n"); dev_err(qproc->dev, "failed to enable supplies\n");
goto disable_proxy_clk; goto disable_proxy_clk;
} }
ret = reset_control_deassert(qproc->mss_restart);
ret = q6v5_clk_enable(qproc->dev, qproc->reset_clks,
qproc->reset_clk_count);
if (ret) { if (ret) {
dev_err(qproc->dev, "failed to deassert mss restart\n"); dev_err(qproc->dev, "failed to enable reset clocks\n");
goto disable_vdd; goto disable_vdd;
} }
ret = q6v5_reset_deassert(qproc);
if (ret) {
dev_err(qproc->dev, "failed to deassert mss restart\n");
goto disable_reset_clks;
}
ret = q6v5_clk_enable(qproc->dev, qproc->active_clks, ret = q6v5_clk_enable(qproc->dev, qproc->active_clks,
qproc->active_clk_count); qproc->active_clk_count);
if (ret) { if (ret) {
...@@ -761,13 +844,11 @@ static int q6v5_start(struct rproc *rproc) ...@@ -761,13 +844,11 @@ static int q6v5_start(struct rproc *rproc)
} }
/* Assign MBA image access in DDR to q6 */ /* Assign MBA image access in DDR to q6 */
xfermemop_ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true, ret = q6v5_xfer_mem_ownership(qproc, &qproc->mba_perm, true,
qproc->mba_phys, qproc->mba_phys, qproc->mba_size);
qproc->mba_size); if (ret) {
if (xfermemop_ret) {
dev_err(qproc->dev, dev_err(qproc->dev,
"assigning Q6 access to mba memory failed: %d\n", "assigning Q6 access to mba memory failed: %d\n", ret);
xfermemop_ret);
goto disable_active_clks; goto disable_active_clks;
} }
...@@ -810,11 +891,6 @@ static int q6v5_start(struct rproc *rproc) ...@@ -810,11 +891,6 @@ static int q6v5_start(struct rproc *rproc)
"Failed to reclaim mba buffer system may become unstable\n"); "Failed to reclaim mba buffer system may become unstable\n");
qproc->running = true; qproc->running = true;
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
return 0; return 0;
reclaim_mpss: reclaim_mpss:
...@@ -842,7 +918,10 @@ static int q6v5_start(struct rproc *rproc) ...@@ -842,7 +918,10 @@ static int q6v5_start(struct rproc *rproc)
qproc->active_clk_count); qproc->active_clk_count);
assert_reset: assert_reset:
reset_control_assert(qproc->mss_restart); q6v5_reset_assert(qproc);
disable_reset_clks:
q6v5_clk_disable(qproc->dev, qproc->reset_clks,
qproc->reset_clk_count);
disable_vdd: disable_vdd:
q6v5_regulator_disable(qproc, qproc->active_regs, q6v5_regulator_disable(qproc, qproc->active_regs,
qproc->active_reg_count); qproc->active_reg_count);
...@@ -853,6 +932,9 @@ static int q6v5_start(struct rproc *rproc) ...@@ -853,6 +932,9 @@ static int q6v5_start(struct rproc *rproc)
q6v5_regulator_disable(qproc, qproc->proxy_regs, q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count); qproc->proxy_reg_count);
disable_irqs:
disable_irq(qproc->handover_irq);
return ret; return ret;
} }
...@@ -892,7 +974,19 @@ static int q6v5_stop(struct rproc *rproc) ...@@ -892,7 +974,19 @@ static int q6v5_stop(struct rproc *rproc)
qproc->mpss_phys, qproc->mpss_size); qproc->mpss_phys, qproc->mpss_size);
WARN_ON(ret); WARN_ON(ret);
reset_control_assert(qproc->mss_restart); q6v5_reset_assert(qproc);
disable_irq(qproc->handover_irq);
if (!qproc->proxy_unvoted) {
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
}
q6v5_clk_disable(qproc->dev, qproc->reset_clks,
qproc->reset_clk_count);
q6v5_clk_disable(qproc->dev, qproc->active_clks, q6v5_clk_disable(qproc->dev, qproc->active_clks,
qproc->active_clk_count); qproc->active_clk_count);
q6v5_regulator_disable(qproc, qproc->active_regs, q6v5_regulator_disable(qproc, qproc->active_regs,
...@@ -960,7 +1054,7 @@ static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev) ...@@ -960,7 +1054,7 @@ static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t q6v5_handover_interrupt(int irq, void *dev) static irqreturn_t q6v5_ready_interrupt(int irq, void *dev)
{ {
struct q6v5 *qproc = dev; struct q6v5 *qproc = dev;
...@@ -968,6 +1062,20 @@ static irqreturn_t q6v5_handover_interrupt(int irq, void *dev) ...@@ -968,6 +1062,20 @@ static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
{
struct q6v5 *qproc = dev;
q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
qproc->proxy_clk_count);
q6v5_regulator_disable(qproc, qproc->proxy_regs,
qproc->proxy_reg_count);
qproc->proxy_unvoted = true;
return IRQ_HANDLED;
}
static irqreturn_t q6v5_stop_ack_interrupt(int irq, void *dev) static irqreturn_t q6v5_stop_ack_interrupt(int irq, void *dev)
{ {
struct q6v5 *qproc = dev; struct q6v5 *qproc = dev;
...@@ -1051,22 +1159,23 @@ static int q6v5_request_irq(struct q6v5 *qproc, ...@@ -1051,22 +1159,23 @@ static int q6v5_request_irq(struct q6v5 *qproc,
const char *name, const char *name,
irq_handler_t thread_fn) irq_handler_t thread_fn)
{ {
int irq;
int ret; int ret;
ret = platform_get_irq_byname(pdev, name); irq = platform_get_irq_byname(pdev, name);
if (ret < 0) { if (irq < 0) {
dev_err(&pdev->dev, "no %s IRQ defined\n", name); dev_err(&pdev->dev, "no %s IRQ defined\n", name);
return ret; return irq;
} }
ret = devm_request_threaded_irq(&pdev->dev, ret, ret = devm_request_threaded_irq(&pdev->dev, irq,
NULL, thread_fn, NULL, thread_fn,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"q6v5", qproc); "q6v5", qproc);
if (ret) if (ret)
dev_err(&pdev->dev, "request %s IRQ failed\n", name); dev_err(&pdev->dev, "request %s IRQ failed\n", name);
return ret; return ret ? : irq;
} }
static int q6v5_alloc_memory_region(struct q6v5 *qproc) static int q6v5_alloc_memory_region(struct q6v5 *qproc)
...@@ -1157,6 +1266,14 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -1157,6 +1266,14 @@ static int q6v5_probe(struct platform_device *pdev)
} }
qproc->proxy_clk_count = ret; qproc->proxy_clk_count = ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->reset_clks,
desc->reset_clk_names);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to get reset clocks.\n");
goto free_rproc;
}
qproc->reset_clk_count = ret;
ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks, ret = q6v5_init_clocks(&pdev->dev, qproc->active_clks,
desc->active_clk_names); desc->active_clk_names);
if (ret < 0) { if (ret < 0) {
...@@ -1186,6 +1303,7 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -1186,6 +1303,7 @@ static int q6v5_probe(struct platform_device *pdev)
goto free_rproc; goto free_rproc;
qproc->version = desc->version; qproc->version = desc->version;
qproc->has_alt_reset = desc->has_alt_reset;
qproc->need_mem_protection = desc->need_mem_protection; qproc->need_mem_protection = desc->need_mem_protection;
ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt); ret = q6v5_request_irq(qproc, pdev, "wdog", q6v5_wdog_interrupt);
if (ret < 0) if (ret < 0)
...@@ -1195,9 +1313,15 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -1195,9 +1313,15 @@ static int q6v5_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto free_rproc; goto free_rproc;
ret = q6v5_request_irq(qproc, pdev, "ready", q6v5_ready_interrupt);
if (ret < 0)
goto free_rproc;
ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt); ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt);
if (ret < 0) if (ret < 0)
goto free_rproc; goto free_rproc;
qproc->handover_irq = ret;
disable_irq(qproc->handover_irq);
ret = q6v5_request_irq(qproc, pdev, "stop-ack", q6v5_stop_ack_interrupt); ret = q6v5_request_irq(qproc, pdev, "stop-ack", q6v5_stop_ack_interrupt);
if (ret < 0) if (ret < 0)
...@@ -1210,6 +1334,7 @@ static int q6v5_probe(struct platform_device *pdev) ...@@ -1210,6 +1334,7 @@ static int q6v5_probe(struct platform_device *pdev)
} }
qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS); qproc->mpss_perm = BIT(QCOM_SCM_VMID_HLOS);
qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS); qproc->mba_perm = BIT(QCOM_SCM_VMID_HLOS);
qcom_add_glink_subdev(rproc, &qproc->glink_subdev);
qcom_add_smd_subdev(rproc, &qproc->smd_subdev); qcom_add_smd_subdev(rproc, &qproc->smd_subdev);
qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss"); qcom_add_ssr_subdev(rproc, &qproc->ssr_subdev, "mpss");
qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12); qproc->sysmon = qcom_add_sysmon_subdev(rproc, "modem", 0x12);
...@@ -1233,6 +1358,7 @@ static int q6v5_remove(struct platform_device *pdev) ...@@ -1233,6 +1358,7 @@ static int q6v5_remove(struct platform_device *pdev)
rproc_del(qproc->rproc); rproc_del(qproc->rproc);
qcom_remove_sysmon_subdev(qproc->sysmon); qcom_remove_sysmon_subdev(qproc->sysmon);
qcom_remove_glink_subdev(qproc->rproc, &qproc->glink_subdev);
qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev); qcom_remove_smd_subdev(qproc->rproc, &qproc->smd_subdev);
qcom_remove_ssr_subdev(qproc->rproc, &qproc->ssr_subdev); qcom_remove_ssr_subdev(qproc->rproc, &qproc->ssr_subdev);
rproc_free(qproc->rproc); rproc_free(qproc->rproc);
...@@ -1240,6 +1366,31 @@ static int q6v5_remove(struct platform_device *pdev) ...@@ -1240,6 +1366,31 @@ static int q6v5_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct rproc_hexagon_res sdm845_mss = {
.hexagon_mba_image = "mba.mbn",
.proxy_clk_names = (char*[]){
"xo",
"axis2",
"prng",
NULL
},
.reset_clk_names = (char*[]){
"iface",
"snoc_axi",
NULL
},
.active_clk_names = (char*[]){
"bus",
"mem",
"gpll0_mss",
"mnoc_axi",
NULL
},
.need_mem_protection = true,
.has_alt_reset = true,
.version = MSS_SDM845,
};
static const struct rproc_hexagon_res msm8996_mss = { static const struct rproc_hexagon_res msm8996_mss = {
.hexagon_mba_image = "mba.mbn", .hexagon_mba_image = "mba.mbn",
.proxy_clk_names = (char*[]){ .proxy_clk_names = (char*[]){
...@@ -1255,6 +1406,7 @@ static const struct rproc_hexagon_res msm8996_mss = { ...@@ -1255,6 +1406,7 @@ static const struct rproc_hexagon_res msm8996_mss = {
NULL NULL
}, },
.need_mem_protection = true, .need_mem_protection = true,
.has_alt_reset = false,
.version = MSS_MSM8996, .version = MSS_MSM8996,
}; };
...@@ -1286,6 +1438,7 @@ static const struct rproc_hexagon_res msm8916_mss = { ...@@ -1286,6 +1438,7 @@ static const struct rproc_hexagon_res msm8916_mss = {
NULL NULL
}, },
.need_mem_protection = false, .need_mem_protection = false,
.has_alt_reset = false,
.version = MSS_MSM8916, .version = MSS_MSM8916,
}; };
...@@ -1325,6 +1478,7 @@ static const struct rproc_hexagon_res msm8974_mss = { ...@@ -1325,6 +1478,7 @@ static const struct rproc_hexagon_res msm8974_mss = {
NULL NULL
}, },
.need_mem_protection = false, .need_mem_protection = false,
.has_alt_reset = false,
.version = MSS_MSM8974, .version = MSS_MSM8974,
}; };
...@@ -1333,6 +1487,7 @@ static const struct of_device_id q6v5_of_match[] = { ...@@ -1333,6 +1487,7 @@ static const struct of_device_id q6v5_of_match[] = {
{ .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss}, { .compatible = "qcom,msm8916-mss-pil", .data = &msm8916_mss},
{ .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss}, { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
{ .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss}, { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
{ .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, q6v5_of_match); MODULE_DEVICE_TABLE(of, q6v5_of_match);
......
/*
* Copyright (C) ST-Ericsson AB 2012
* Author: Sjur Brendeland / sjur.brandeland@stericsson.com
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef __INC_MODEM_DEV_H
#define __INC_MODEM_DEV_H
#include <linux/types.h>
#include <linux/platform_device.h>
struct ste_modem_device;
/**
* struct ste_modem_dev_cb - Callbacks for modem initiated events.
* @kick: Called when the modem kicks the host.
*
* This structure contains callbacks for actions triggered by the modem.
*/
struct ste_modem_dev_cb {
void (*kick)(struct ste_modem_device *mdev, int notify_id);
};
/**
* struct ste_modem_dev_ops - Functions to control modem and modem interface.
*
* @power: Main power switch, used for cold-start or complete power off.
* @kick: Kick the modem.
* @kick_subscribe: Subscribe for notifications from the modem.
* @setup: Provide callback functions to modem device.
*
* This structure contains functions used by the ste remoteproc driver
* to manage the modem.
*/
struct ste_modem_dev_ops {
int (*power)(struct ste_modem_device *mdev, bool on);
int (*kick)(struct ste_modem_device *mdev, int notify_id);
int (*kick_subscribe)(struct ste_modem_device *mdev, int notify_id);
int (*setup)(struct ste_modem_device *mdev,
struct ste_modem_dev_cb *cfg);
};
/**
* struct ste_modem_device - represent the STE modem device
* @pdev: Reference to platform device
* @ops: Operations used to manage the modem.
* @drv_data: Driver private data.
*/
struct ste_modem_device {
struct platform_device pdev;
struct ste_modem_dev_ops ops;
void *drv_data;
};
#endif /*INC_MODEM_DEV_H*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment