Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 68d406c1 authored by Vikram Mulukutla's avatar Vikram Mulukutla
Browse files

soc: qcom: scm: Add APIs to allow register access via the secure world



Add an API to allow certain registers to be accessed
via secure world syscalls. Switch existing users to
this new API.

Change-Id: I1c2a67f728ddf486e93751e77853cc50e1b9db21
Signed-off-by: default avatarVikram Mulukutla <markivx@codeaurora.org>
parent b88b93d8
Loading
Loading
Loading
Loading
+8 −18
Original line number Diff line number Diff line
@@ -298,16 +298,12 @@ static struct pll_clk a53_pll1 = {

static DEFINE_SPINLOCK(mux_reg_lock);

#define SCM_IO_READ	0x1
#define SCM_IO_WRITE	0x2

static int cpudiv_get_div(struct div_clk *divclk)
{
	u32 regval;

	if (divclk->priv)
		regval = scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ,
					 *(u32 *)divclk->priv + divclk->offset);
		regval = scm_io_read(*(u32 *)divclk->priv + divclk->offset);
	else
		regval = readl_relaxed(*divclk->base + divclk->offset);

@@ -325,18 +321,15 @@ static void __cpudiv_set_div(struct div_clk *divclk, int div)
	spin_lock_irqsave(&mux_reg_lock, flags);

	if (divclk->priv)
		regval = scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ,
					 *(u32 *)divclk->priv + divclk->offset);
		regval = scm_io_read(*(u32 *)divclk->priv + divclk->offset);
	else
		regval = readl_relaxed(*divclk->base + divclk->offset);


	regval &= ~(divclk->mask << divclk->shift);
	regval |= ((div - 1) & divclk->mask) << divclk->shift;

	if (divclk->priv)
		scm_call_atomic2(SCM_SVC_IO, SCM_IO_WRITE,
				 *(u32 *)divclk->priv + divclk->offset, regval);
		scm_io_write(*(u32 *)divclk->priv + divclk->offset, regval);
	else
		writel_relaxed(regval, *divclk->base + divclk->offset);

@@ -431,18 +424,16 @@ static void __cpu_mux_set_sel(struct mux_clk *mux, int sel)
	spin_lock_irqsave(&mux_reg_lock, flags);

	if (mux->priv)
		regval = scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ,
					  *(u32 *)mux->priv + mux->offset);
		regval = scm_io_read(*(u32 *)mux->priv + mux->offset);
	else
		regval = readl_relaxed(*mux->base + mux->offset);

	regval &= ~(mux->mask << mux->shift);
	regval |= (sel & mux->mask) << mux->shift;

	if (mux->priv) {
		scm_call_atomic2(SCM_SVC_IO, SCM_IO_WRITE,
				 *(u32 *)mux->priv + mux->offset, regval);
	} else
	if (mux->priv)
		scm_io_write(*(u32 *)mux->priv + mux->offset, regval);
	else
		writel_relaxed(regval, *mux->base + mux->offset);

	spin_unlock_irqrestore(&mux_reg_lock, flags);
@@ -479,8 +470,7 @@ static int cpu_mux_get_sel(struct mux_clk *mux)
	u32 regval;

	if (mux->priv)
		regval = scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ,
					  *(u32 *)mux->priv + mux->offset);
		regval = scm_io_read(*(u32 *)mux->priv + mux->offset);
	else
		regval = readl_relaxed(*mux->base + mux->offset);
	return (regval >> mux->shift) & mux->mask;
+4 −7
Original line number Diff line number Diff line
@@ -45,9 +45,6 @@
#define L2_SPM_STS		0xc
#define L2_VREG_CTL		0x1c

#define SCM_IO_READ		1
#define SCM_IO_WRITE		2

/*
 * struct msm_l2ccc_of_info: represents of data for l2 cache clock controller.
 * @compat: compat string for l2 cache clock controller
@@ -141,9 +138,9 @@ static int kick_l2spm_8994(struct device_node *l2ccc_node,
	/* L2 is executing sleep state machine,
	 * let's softly kick it awake
	 */
	val = scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ, (u32)res.start);
	val = scm_io_read((u32)res.start);
	val |= BIT(0);
	scm_call_atomic2(SCM_SVC_IO, SCM_IO_WRITE, (u32)res.start, val);
	scm_io_write((u32)res.start, val);

	/* Wait until the SPM status indicates that the PWR_CTL
	 * bits are clear.
@@ -156,9 +153,9 @@ static int kick_l2spm_8994(struct device_node *l2ccc_node,
		usleep(100);
	}

	val = scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ, (u32)res.start);
	val = scm_io_read((u32)res.start);
	val &= ~BIT(0);
	scm_call_atomic2(SCM_SVC_IO, SCM_IO_WRITE, (u32)res.start, val);
	scm_io_write((u32)res.start, val);

bail_l2_pwr_bit:
	iounmap(l2spm_base);
+37 −0
Original line number Diff line number Diff line
@@ -939,6 +939,43 @@ u32 scm_get_version(void)
}
EXPORT_SYMBOL(scm_get_version);

#define SCM_IO_READ	0x1
#define SCM_IO_WRITE	0x2

u32 scm_io_read(phys_addr_t address)
{
	if (!is_scm_armv8()) {
		return scm_call_atomic1(SCM_SVC_IO, SCM_IO_READ, address);
	} else {
		struct scm_desc desc = {
			.args[0] = address,
			.arginfo = SCM_ARGS(1),
		};
		scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_IO, SCM_IO_READ), &desc);
		return desc.ret[0];
	}
}
EXPORT_SYMBOL(scm_io_read);

int scm_io_write(phys_addr_t address, u32 val)
{
	int ret;

	if (!is_scm_armv8()) {
		ret = scm_call_atomic2(SCM_SVC_IO, SCM_IO_WRITE, address, val);
	} else {
		struct scm_desc desc = {
			.args[0] = address,
			.args[1] = val,
			.arginfo = SCM_ARGS(2),
		};
		ret = scm_call2_atomic(SCM_SIP_FNID(SCM_SVC_IO, SCM_IO_WRITE),
				       &desc);
	}
	return ret;
}
EXPORT_SYMBOL(scm_io_write);

int scm_is_call_available(u32 svc_id, u32 cmd_id)
{
	int ret;
+12 −0
Original line number Diff line number Diff line
@@ -116,6 +116,8 @@ extern int scm_is_call_available(u32 svc_id, u32 cmd_id);
extern int scm_get_feat_version(u32 feat);
extern bool is_scm_armv8(void);
extern int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret);
extern u32 scm_io_read(phys_addr_t address);
extern int scm_io_write(phys_addr_t address, u32 val);

#define SCM_HDCP_MAX_REG 5

@@ -200,5 +202,15 @@ static inline int scm_restore_sec_cfg(u32 device_id, u32 spare, int *scm_ret)
{
	return 0;
}

static inline u32 scm_io_read(phys_addr_t address)
{
	return 0;
}

static inline int scm_io_write(phys_addr_t address, u32 val)
{
	return 0;
}
#endif
#endif