aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/bus/Kconfig1
-rw-r--r--drivers/firmware/qcom_scm-32.c18
-rw-r--r--drivers/firmware/qcom_scm-64.c16
-rw-r--r--drivers/firmware/qcom_scm.c8
-rw-r--r--drivers/firmware/qcom_scm.h2
-rw-r--r--include/linux/qcom_scm.h54
7 files changed, 83 insertions, 17 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 0b1b2687bc04..33c0e0d17650 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1628,6 +1628,7 @@ F: arch/arm64/boot/dts/qcom/*
1628F: drivers/i2c/busses/i2c-qup.c 1628F: drivers/i2c/busses/i2c-qup.c
1629F: drivers/clk/qcom/ 1629F: drivers/clk/qcom/
1630F: drivers/pinctrl/qcom/ 1630F: drivers/pinctrl/qcom/
1631F: drivers/dma/qcom/
1631F: drivers/soc/qcom/ 1632F: drivers/soc/qcom/
1632F: drivers/spi/spi-qup.c 1633F: drivers/spi/spi-qup.c
1633F: drivers/tty/serial/msm_serial.h 1634F: drivers/tty/serial/msm_serial.h
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index b9e8cfc93c7e..0a52da439abf 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -112,6 +112,7 @@ config QCOM_EBI2
112 bool "Qualcomm External Bus Interface 2 (EBI2)" 112 bool "Qualcomm External Bus Interface 2 (EBI2)"
113 depends on HAS_IOMEM 113 depends on HAS_IOMEM
114 depends on ARCH_QCOM || COMPILE_TEST 114 depends on ARCH_QCOM || COMPILE_TEST
115 default ARCH_QCOM
115 help 116 help
116 Say y here to enable support for the Qualcomm External Bus 117 Say y here to enable support for the Qualcomm External Bus
117 Interface 2, which can be used to connect things like NAND Flash, 118 Interface 2, which can be used to connect things like NAND Flash,
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
index c6aeedbdcbb0..8ad226c60374 100644
--- a/drivers/firmware/qcom_scm-32.c
+++ b/drivers/firmware/qcom_scm-32.c
@@ -560,3 +560,21 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
560 560
561 return ret ? : le32_to_cpu(out); 561 return ret ? : le32_to_cpu(out);
562} 562}
563
564int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
565{
566 struct {
567 __le32 state;
568 __le32 id;
569 } req;
570 __le32 scm_ret = 0;
571 int ret;
572
573 req.state = cpu_to_le32(state);
574 req.id = cpu_to_le32(id);
575
576 ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
577 &req, sizeof(req), &scm_ret, sizeof(scm_ret));
578
579 return ret ? : le32_to_cpu(scm_ret);
580}
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
index 4a0f5ead4fb5..4b220abaf363 100644
--- a/drivers/firmware/qcom_scm-64.c
+++ b/drivers/firmware/qcom_scm-64.c
@@ -358,3 +358,19 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
358 358
359 return ret ? : res.a1; 359 return ret ? : res.a1;
360} 360}
361
362int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
363{
364 struct qcom_scm_desc desc = {0};
365 struct arm_smccc_res res;
366 int ret;
367
368 desc.args[0] = state;
369 desc.args[1] = id;
370 desc.arginfo = QCOM_SCM_ARGS(2);
371
372 ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
373 &desc, &res);
374
375 return ret ? : res.a1;
376}
diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c
index 893f953eaccf..d987bcc7489d 100644
--- a/drivers/firmware/qcom_scm.c
+++ b/drivers/firmware/qcom_scm.c
@@ -324,6 +324,12 @@ bool qcom_scm_is_available(void)
324} 324}
325EXPORT_SYMBOL(qcom_scm_is_available); 325EXPORT_SYMBOL(qcom_scm_is_available);
326 326
327int qcom_scm_set_remote_state(u32 state, u32 id)
328{
329 return __qcom_scm_set_remote_state(__scm->dev, state, id);
330}
331EXPORT_SYMBOL(qcom_scm_set_remote_state);
332
327static int qcom_scm_probe(struct platform_device *pdev) 333static int qcom_scm_probe(struct platform_device *pdev)
328{ 334{
329 struct qcom_scm *scm; 335 struct qcom_scm *scm;
@@ -387,7 +393,7 @@ static int qcom_scm_probe(struct platform_device *pdev)
387 393
388static const struct of_device_id qcom_scm_dt_match[] = { 394static const struct of_device_id qcom_scm_dt_match[] = {
389 { .compatible = "qcom,scm-apq8064", 395 { .compatible = "qcom,scm-apq8064",
390 .data = (void *) SCM_HAS_CORE_CLK, 396 /* FIXME: This should have .data = (void *) SCM_HAS_CORE_CLK */
391 }, 397 },
392 { .compatible = "qcom,scm-msm8660", 398 { .compatible = "qcom,scm-msm8660",
393 .data = (void *) SCM_HAS_CORE_CLK, 399 .data = (void *) SCM_HAS_CORE_CLK,
diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h
index 3584b00fe7e6..6a0f15469344 100644
--- a/drivers/firmware/qcom_scm.h
+++ b/drivers/firmware/qcom_scm.h
@@ -15,6 +15,8 @@
15#define QCOM_SCM_SVC_BOOT 0x1 15#define QCOM_SCM_SVC_BOOT 0x1
16#define QCOM_SCM_BOOT_ADDR 0x1 16#define QCOM_SCM_BOOT_ADDR 0x1
17#define QCOM_SCM_BOOT_ADDR_MC 0x11 17#define QCOM_SCM_BOOT_ADDR_MC 0x11
18#define QCOM_SCM_SET_REMOTE_STATE 0xa
19extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id);
18 20
19#define QCOM_SCM_FLAG_HLOS 0x01 21#define QCOM_SCM_FLAG_HLOS 0x01
20#define QCOM_SCM_FLAG_COLDBOOT_MC 0x02 22#define QCOM_SCM_FLAG_COLDBOOT_MC 0x02
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h
index cc32ab852fbc..d32f6f1a5225 100644
--- a/include/linux/qcom_scm.h
+++ b/include/linux/qcom_scm.h
@@ -13,9 +13,9 @@
13#ifndef __QCOM_SCM_H 13#ifndef __QCOM_SCM_H
14#define __QCOM_SCM_H 14#define __QCOM_SCM_H
15 15
16extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); 16#define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
17extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); 17#define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0
18 18#define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1
19#define QCOM_SCM_HDCP_MAX_REQ_CNT 5 19#define QCOM_SCM_HDCP_MAX_REQ_CNT 5
20 20
21struct qcom_scm_hdcp_req { 21struct qcom_scm_hdcp_req {
@@ -23,27 +23,49 @@ struct qcom_scm_hdcp_req {
23 u32 val; 23 u32 val;
24}; 24};
25 25
26#if IS_ENABLED(CONFIG_QCOM_SCM)
27extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
28extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
26extern bool qcom_scm_is_available(void); 29extern bool qcom_scm_is_available(void);
27
28extern bool qcom_scm_hdcp_available(void); 30extern bool qcom_scm_hdcp_available(void);
29extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, 31extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
30 u32 *resp); 32 u32 *resp);
31
32extern bool qcom_scm_pas_supported(u32 peripheral); 33extern bool qcom_scm_pas_supported(u32 peripheral);
33extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, 34extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
34 size_t size); 35 size_t size);
35extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, 36extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
36 phys_addr_t size); 37 phys_addr_t size);
37extern int qcom_scm_pas_auth_and_reset(u32 peripheral); 38extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
38extern int qcom_scm_pas_shutdown(u32 peripheral); 39extern int qcom_scm_pas_shutdown(u32 peripheral);
39
40#define QCOM_SCM_CPU_PWR_DOWN_L2_ON 0x0
41#define QCOM_SCM_CPU_PWR_DOWN_L2_OFF 0x1
42
43extern void qcom_scm_cpu_power_down(u32 flags); 40extern void qcom_scm_cpu_power_down(u32 flags);
44
45#define QCOM_SCM_VERSION(major, minor) (((major) << 16) | ((minor) & 0xFF))
46
47extern u32 qcom_scm_get_version(void); 41extern u32 qcom_scm_get_version(void);
48 42extern int qcom_scm_set_remote_state(u32 state, u32 id);
43#else
44static inline
45int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
46{
47 return -ENODEV;
48}
49static inline
50int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
51{
52 return -ENODEV;
53}
54static inline bool qcom_scm_is_available(void) { return false; }
55static inline bool qcom_scm_hdcp_available(void) { return false; }
56static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
57 u32 *resp) { return -ENODEV; }
58static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; }
59static inline int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
60 size_t size) { return -ENODEV; }
61static inline int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
62 phys_addr_t size) { return -ENODEV; }
63static inline int
64qcom_scm_pas_auth_and_reset(u32 peripheral) { return -ENODEV; }
65static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; }
66static inline void qcom_scm_cpu_power_down(u32 flags) {}
67static inline u32 qcom_scm_get_version(void) { return 0; }
68static inline u32
69qcom_scm_set_remote_state(u32 state,u32 id) { return -ENODEV; }
70#endif
49#endif 71#endif