Updates for review comments, plus a couple misc qcom-scm fixes
From original cover-letter:
For devices such as 8x74 and 8084, which have a separate OCMEM block used by the GPU (and some other devices), rather than an internal GMEM block inside the GPU, we need a driver to power up and configure OCMEM in order to get the GPU working.
This patchset implements a vastly simplified version of the downstream vendor kernel's OCMEM driver. Currently it is just enough to enable the GPU. But we can worry about other OCMEM users when they have up- stream drivers.
The first patch adds support for the necessary scm interfaces, for the parts of the OCMEM configuration that must be done from secure mode. The second patch can be dropped, as so far this doesn't seem needed for the GPU (I'm just sending the patch now so it can be found later if it turns out to be needed).
The remaining two patches add the OCMEM driver inside drm/msm. If we eventually have other upstream OCMEM users, this would need to be split out. But that should not effect DT bindings, etc, so that is something that can easily be done later when the need arises.
Rob Clark (6): qcom-scm: fix endianess issue in __qcom_scm_is_call_available qcom-scm: fix header compile errors qcom-scm: add missing prototype for qcom_scm_is_available() qcom-scm: add ocmem support drm/msm: update generated headers drm/msm: add OCMEM driver
drivers/firmware/qcom_scm-32.c | 59 +++- drivers/firmware/qcom_scm-64.c | 16 + drivers/firmware/qcom_scm.c | 61 ++++ drivers/firmware/qcom_scm.h | 12 + drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a2xx.xml.h | 9 +- drivers/gpu/drm/msm/adreno/a3xx.xml.h | 27 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 19 +- drivers/gpu/drm/msm/adreno/a4xx.xml.h | 15 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 19 +- drivers/gpu/drm/msm/adreno/adreno_common.xml.h | 13 +- drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h | 9 +- drivers/gpu/drm/msm/dsi/dsi.xml.h | 4 +- drivers/gpu/drm/msm/dsi/mmss_cc.xml.h | 4 +- drivers/gpu/drm/msm/dsi/sfpb.xml.h | 4 +- drivers/gpu/drm/msm/edp/edp.xml.h | 4 +- drivers/gpu/drm/msm/hdmi/hdmi.xml.h | 4 +- drivers/gpu/drm/msm/hdmi/qfprom.xml.h | 4 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h | 4 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 82 ++++- drivers/gpu/drm/msm/mdp/mdp_common.xml.h | 11 +- drivers/gpu/drm/msm/msm_drv.c | 2 + drivers/gpu/drm/msm/msm_gpu.h | 3 + drivers/gpu/drm/msm/ocmem/ocmem.c | 399 +++++++++++++++++++++++++ drivers/gpu/drm/msm/ocmem/ocmem.h | 46 +++ drivers/gpu/drm/msm/ocmem/ocmem.xml.h | 113 +++++++ include/linux/qcom_scm.h | 16 +- 27 files changed, 889 insertions(+), 73 deletions(-) create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.xml.h
Signed-off-by: Rob Clark robdclark@gmail.com --- drivers/firmware/qcom_scm-32.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index e9c306b..c1e4325 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -480,15 +480,15 @@ void __qcom_scm_cpu_power_down(u32 flags) int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id) { int ret; - u32 svc_cmd = (svc_id << 10) | cmd_id; - u32 ret_val = 0; + __le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id); + __le32 ret_val = 0;
ret = qcom_scm_call(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD, &svc_cmd, sizeof(svc_cmd), &ret_val, sizeof(ret_val)); if (ret) return ret;
- return ret_val; + return le32_to_cpu(ret_val); }
int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
On 09/29, Rob Clark wrote:
Signed-off-by: Rob Clark robdclark@gmail.com
Reviewed-by: Stephen Boyd sboyd@codeaurora.org
Add missing #include for types.h to have u32, etc. And fwd declare 'struct cpumask'.
Signed-off-by: Rob Clark robdclark@gmail.com --- include/linux/qcom_scm.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 46d41e4..c536b70 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -13,8 +13,11 @@ #ifndef __QCOM_SCM_H #define __QCOM_SCM_H
-extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); -extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); +#include <linux/types.h> + +struct cpumask; +extern int qcom_scm_set_cold_boot_addr(void *entry, const struct cpumask *cpus); +extern int qcom_scm_set_warm_boot_addr(void *entry, const struct cpumask *cpus);
#define QCOM_SCM_HDCP_MAX_REQ_CNT 5
On 09/29, Rob Clark wrote:
Add missing #include for types.h to have u32, etc. And fwd declare 'struct cpumask'.
Signed-off-by: Rob Clark robdclark@gmail.com
We should change the arguments for the implementation too.
Signed-off-by: Rob Clark robdclark@gmail.com --- include/linux/qcom_scm.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index c536b70..e407c0a 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -26,6 +26,8 @@ struct qcom_scm_hdcp_req { u32 val; };
+extern bool qcom_scm_is_available(void); + extern bool qcom_scm_hdcp_available(void); extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
Add interfaces needed for configuring OCMEM.
Signed-off-by: Rob Clark robdclark@gmail.com --- drivers/firmware/qcom_scm-32.c | 53 ++++++++++++++++++++++++++++++++++++ drivers/firmware/qcom_scm-64.c | 16 +++++++++++ drivers/firmware/qcom_scm.c | 61 ++++++++++++++++++++++++++++++++++++++++++ drivers/firmware/qcom_scm.h | 12 +++++++++ include/linux/qcom_scm.h | 7 +++++ 5 files changed, 149 insertions(+)
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index c1e4325..e1ac97f 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) req, req_cnt * sizeof(*req), resp, sizeof(*resp)); }
+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id) +{ + int ret, scm_ret = 0; + struct msm_scm_sec_cfg { + __le32 id; + __le32 spare; + } cfg; + + cfg.id = cpu_to_le32(sec_id); + + ret = qcom_scm_call(QCOM_SCM_OCMEM_SECURE_SVC, QCOM_SCM_OCMEM_SECURE_CFG, + &cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret)); + + if (ret || scm_ret) + return ret ? ret : -EINVAL; + + return 0; +} + +int __qcom_scm_ocmem_lock(u32 id, u32 offset, u32 size, u32 mode) +{ + struct ocmem_tz_lock { + __le32 id; + __le32 offset; + __le32 size; + __le32 mode; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + request.mode = cpu_to_le32(mode); + + return qcom_scm_call(QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_LOCK_CMD, + &request, sizeof(request), NULL, 0); +} + +int __qcom_scm_ocmem_unlock(u32 id, u32 offset, u32 size) +{ + struct ocmem_tz_unlock { + __le32 id; + __le32 offset; + __le32 size; + } request; + + request.id = cpu_to_le32(id); + request.offset = cpu_to_le32(offset); + request.size = cpu_to_le32(size); + + return qcom_scm_call(QCOM_SCM_OCMEM_SVC, QCOM_SCM_OCMEM_UNLOCK_CMD, + &request, sizeof(request), NULL, 0); +} + bool __qcom_scm_pas_supported(u32 peripheral) { __le32 out; diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c index e64fd92..ef5c59e 100644 --- a/drivers/firmware/qcom_scm-64.c +++ b/drivers/firmware/qcom_scm-64.c @@ -62,6 +62,22 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) return -ENOTSUPP; }
+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_lock(uint32_t id, uint32_t offset, uint32_t size, + uint32_t mode) +{ + return -ENOTSUPP; +} + +int __qcom_scm_ocmem_unlock(uint32_t id, uint32_t offset, uint32_t size) +{ + return -ENOTSUPP; +} + bool __qcom_scm_pas_supported(u32 peripheral) { return false; diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 118df0a..83a6b77 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -154,6 +154,67 @@ int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) EXPORT_SYMBOL(qcom_scm_hdcp_req);
/** + * qcom_scm_ocmem_secure_available() - Check if secure environment supports + * OCMEM. + * + * Return true if OCMEM secure interface is supported, false if not. + */ +bool qcom_scm_ocmem_secure_available(void) +{ + return __qcom_scm_is_call_available(QCOM_SCM_OCMEM_SECURE_SVC, + QCOM_SCM_OCMEM_SECURE_CFG); +} +EXPORT_SYMBOL(qcom_scm_ocmem_secure_available); + +/** + * qcom_scm_ocmem_secure_cfg() - call OCMEM secure cfg interface + */ +int qcom_scm_ocmem_secure_cfg(unsigned sec_id) +{ + return __qcom_scm_ocmem_secure_cfg(sec_id); +} +EXPORT_SYMBOL(qcom_scm_ocmem_secure_cfg); + +/** + * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available + */ +bool qcom_scm_ocmem_lock_available(void) +{ + return __qcom_scm_is_call_available(QCOM_SCM_OCMEM_SVC, + QCOM_SCM_OCMEM_LOCK_CMD); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock_available); + +/** + * qcom_scm_ocmem_lock() - call OCMEM lock interface to assign an OCMEM + * region to the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + * @mode: access mode (WIDE/NARROW) + */ +int qcom_scm_ocmem_lock(u32 id, u32 offset, u32 size, u32 mode) +{ + return __qcom_scm_ocmem_lock(id, offset, size, mode); +} +EXPORT_SYMBOL(qcom_scm_ocmem_lock); + +/** + * qcom_scm_ocmem_unlock() - call OCMEM unlock interface to release an OCMEM + * region from the specified initiator + * + * @id: tz initiator id + * @offset: OCMEM offset + * @size: OCMEM size + */ +int qcom_scm_ocmem_unlock(u32 id, u32 offset, u32 size) +{ + return __qcom_scm_ocmem_unlock(id, offset, size); +} +EXPORT_SYMBOL(qcom_scm_ocmem_unlock); + +/** * qcom_scm_pas_supported() - Check if the peripheral authentication service is * available for the given peripherial * @peripheral: peripheral id diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 220d19c..c41228d 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -36,6 +36,18 @@ extern int __qcom_scm_is_call_available(u32 svc_id, u32 cmd_id); extern int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
+#define QCOM_SCM_OCMEM_SECURE_SVC 0xc +#define QCOM_SCM_OCMEM_SECURE_CFG 0x2 + +extern int __qcom_scm_ocmem_secure_cfg(unsigned sec_id); + +#define QCOM_SCM_OCMEM_SVC 0xf +#define QCOM_SCM_OCMEM_LOCK_CMD 0x1 +#define QCOM_SCM_OCMEM_UNLOCK_CMD 0x2 + +extern int __qcom_scm_ocmem_lock(u32 id, u32 offset, u32 size, u32 mode); +extern int __qcom_scm_ocmem_unlock(u32 id, u32 offset, u32 size); + #define QCOM_SCM_SVC_PIL 0x2 #define QCOM_SCM_PAS_INIT_IMAGE_CMD 0x1 #define QCOM_SCM_PAS_MEM_SETUP_CMD 0x2 diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index e407c0a..86bc6ba7 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -32,6 +32,13 @@ extern bool qcom_scm_hdcp_available(void); extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
+extern bool qcom_scm_ocmem_secure_available(void); +extern int qcom_scm_ocmem_secure_cfg(unsigned sec_id); + +extern bool qcom_scm_ocmem_lock_available(void); +extern int qcom_scm_ocmem_lock(u32 id, u32 offset, u32 size, u32 mode); +extern int qcom_scm_ocmem_unlock(u32 id, u32 offset, u32 size); + extern bool qcom_scm_pas_supported(u32 peripheral); extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size); extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size);
On 09/29, Rob Clark wrote:
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index c1e4325..e1ac97f 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) req, req_cnt * sizeof(*req), resp, sizeof(*resp)); }
+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id) +{
- int ret, scm_ret = 0;
- struct msm_scm_sec_cfg {
We've left these as anonymous structs for things like qcom_scm_set_boot_addr(), maybe we should do the same here.
__le32 id;
__le32 spare;
Also, the iommu driver would use this API and it uses this "spare" element, so perhaps this whole function should be renamed to be more generic and take two values. Downstream the function is called scm_restore_sec_cfg, so maybe something similar. And the service id is MP for "memory protection", so QCOM_SCM_OCMEM_SECURE_SVC could be QCOM_SCM_MEMORY_PROTECTION?
Otherwise this patch looks good.
- } cfg;
- cfg.id = cpu_to_le32(sec_id);
- ret = qcom_scm_call(QCOM_SCM_OCMEM_SECURE_SVC, QCOM_SCM_OCMEM_SECURE_CFG,
&cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret));
- if (ret || scm_ret)
On Tue, Sep 29, 2015 at 5:38 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 09/29, Rob Clark wrote:
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index c1e4325..e1ac97f 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) req, req_cnt * sizeof(*req), resp, sizeof(*resp)); }
+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id) +{
int ret, scm_ret = 0;
struct msm_scm_sec_cfg {
We've left these as anonymous structs for things like qcom_scm_set_boot_addr(), maybe we should do the same here.
__le32 id;
__le32 spare;
Also, the iommu driver would use this API and it uses this "spare" element, so perhaps this whole function should be renamed to be more generic and take two values. Downstream the function is called scm_restore_sec_cfg, so maybe something similar. And the service id is MP for "memory protection", so QCOM_SCM_OCMEM_SECURE_SVC could be QCOM_SCM_MEMORY_PROTECTION?
heh,
#define SCM_SVC_MP 0xC #define IOMMU_SECURE_CFG 2
vs.
#define OCMEM_SECURE_SVC_ID 12 #define OCMEM_SECURE_CFG_ID 0x2
that wasn't obscure at all!
Maybe then there is a better name than spare? Looks like downstream iommu calls it cb_num?
BR, -R
Otherwise this patch looks good.
} cfg;
cfg.id = cpu_to_le32(sec_id);
ret = qcom_scm_call(QCOM_SCM_OCMEM_SECURE_SVC, QCOM_SCM_OCMEM_SECURE_CFG,
&cfg, sizeof(cfg), &scm_ret, sizeof(scm_ret));
if (ret || scm_ret)
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
On 09/29, Rob Clark wrote:
On Tue, Sep 29, 2015 at 5:38 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 09/29, Rob Clark wrote:
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index c1e4325..e1ac97f 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) req, req_cnt * sizeof(*req), resp, sizeof(*resp)); }
+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id) +{
int ret, scm_ret = 0;
struct msm_scm_sec_cfg {
We've left these as anonymous structs for things like qcom_scm_set_boot_addr(), maybe we should do the same here.
__le32 id;
__le32 spare;
Also, the iommu driver would use this API and it uses this "spare" element, so perhaps this whole function should be renamed to be more generic and take two values. Downstream the function is called scm_restore_sec_cfg, so maybe something similar. And the service id is MP for "memory protection", so QCOM_SCM_OCMEM_SECURE_SVC could be QCOM_SCM_MEMORY_PROTECTION?
heh,
#define SCM_SVC_MP 0xC #define IOMMU_SECURE_CFG 2
vs.
#define OCMEM_SECURE_SVC_ID 12 #define OCMEM_SECURE_CFG_ID 0x2
that wasn't obscure at all!
:)
Maybe then there is a better name than spare? Looks like downstream iommu calls it cb_num?
Yeah I think that's the only use to indicate which context bank it is. Maybe we can have a single id configure API and a special iommu context bank API that both funnel into the same private two number API. Otherwise we have a bunch of callers passing 0 for the second argument because they don't care.
On Tue, Sep 29, 2015 at 6:33 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 09/29, Rob Clark wrote:
On Tue, Sep 29, 2015 at 5:38 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 09/29, Rob Clark wrote:
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index c1e4325..e1ac97f 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -500,6 +500,59 @@ int __qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp) req, req_cnt * sizeof(*req), resp, sizeof(*resp)); }
+int __qcom_scm_ocmem_secure_cfg(unsigned sec_id) +{
int ret, scm_ret = 0;
struct msm_scm_sec_cfg {
We've left these as anonymous structs for things like qcom_scm_set_boot_addr(), maybe we should do the same here.
__le32 id;
__le32 spare;
Also, the iommu driver would use this API and it uses this "spare" element, so perhaps this whole function should be renamed to be more generic and take two values. Downstream the function is called scm_restore_sec_cfg, so maybe something similar. And the service id is MP for "memory protection", so QCOM_SCM_OCMEM_SECURE_SVC could be QCOM_SCM_MEMORY_PROTECTION?
heh,
#define SCM_SVC_MP 0xC #define IOMMU_SECURE_CFG 2
vs.
#define OCMEM_SECURE_SVC_ID 12 #define OCMEM_SECURE_CFG_ID 0x2
that wasn't obscure at all!
:)
Maybe then there is a better name than spare? Looks like downstream iommu calls it cb_num?
Yeah I think that's the only use to indicate which context bank it is. Maybe we can have a single id configure API and a special iommu context bank API that both funnel into the same private two number API. Otherwise we have a bunch of callers passing 0 for the second argument because they don't care.
so fwiw, I went thru all the downstream scm_call() callers.. there are a lot of callers to SCM_SVC_MP service (through a couple different #defines), but most of them are different cmd-id's. The ones using SECURE_CFG (0x2) are:
* dwc3_msm_restore_sec_config() * ocmem_restore_sec_program() * msm_iommu_sec_program_iommu()
so we have two points passing in zero for ctx-bank, one that does not. I don't think it is worth having two API's to save hard-coding zero in two places ;-)
BR, -R
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
On 10/01, Rob Clark wrote:
On Tue, Sep 29, 2015 at 6:33 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 09/29, Rob Clark wrote:
On Tue, Sep 29, 2015 at 5:38 PM, Stephen Boyd sboyd@codeaurora.org wrote:
Yeah I think that's the only use to indicate which context bank it is. Maybe we can have a single id configure API and a special iommu context bank API that both funnel into the same private two number API. Otherwise we have a bunch of callers passing 0 for the second argument because they don't care.
so fwiw, I went thru all the downstream scm_call() callers.. there are a lot of callers to SCM_SVC_MP service (through a couple different #defines), but most of them are different cmd-id's. The ones using SECURE_CFG (0x2) are:
- dwc3_msm_restore_sec_config()
- ocmem_restore_sec_program()
- msm_iommu_sec_program_iommu()
so we have two points passing in zero for ctx-bank, one that does not. I don't think it is worth having two API's to save hard-coding zero in two places ;-)
What sources are you looking at? It seems like whatever you have is over a year old. About a year ago, we consolidated all calls to this specific SCM call into a single API called scm_restore_sec_cfg (see commit 9933a272db9a5612bcc2ee0ef9149f70c8166eb3 "qcom: scm: Provide an API that restores security configuration" on msm-3.10).
Looking at our latest msm-3.10 branch I see
drivers/crypto/msm/ice.c: ret = scm_restore_sec_cfg(cbuf.device_id, cbuf.spare, &scm_ret);
cbuf.spare is 0 here.
drivers/iommu/msm_iommu_sec.c: ret = scm_restore_sec_cfg(drvdata->sec_id, ctx_drvdata->num, &scm_ret);
This is the only real user of spare
drivers/pci/host/pci-msm.c: ret = scm_restore_sec_cfg(dev->scm_dev_id, 0, &scm_ret); drivers/scsi/ufs/ufs-qcom.c: ret = scm_restore_sec_cfg(cbuf.device_id, cbuf.spare, &scm_ret);
cbuf.spare is 0 here.
drivers/soc/qcom/ocmem_core.c: rc = scm_restore_sec_cfg(sec_id, 0, &scm_ret); drivers/video/msm/mdss/mdss_mdp.c: ret = scm_restore_sec_cfg(SEC_DEVICE_MDSS, 0, &scm_ret);
So that's 6 callers and 1 uses the second argument.
Update generated headers to pull in OCMEM register definitions.
Signed-off-by: Rob Clark robdclark@gmail.com --- drivers/gpu/drm/msm/adreno/a2xx.xml.h | 9 +- drivers/gpu/drm/msm/adreno/a3xx.xml.h | 27 ++++-- drivers/gpu/drm/msm/adreno/a4xx.xml.h | 15 ++-- drivers/gpu/drm/msm/adreno/adreno_common.xml.h | 13 ++- drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h | 9 +- drivers/gpu/drm/msm/dsi/dsi.xml.h | 4 +- drivers/gpu/drm/msm/dsi/mmss_cc.xml.h | 4 +- drivers/gpu/drm/msm/dsi/sfpb.xml.h | 4 +- drivers/gpu/drm/msm/edp/edp.xml.h | 4 +- drivers/gpu/drm/msm/hdmi/hdmi.xml.h | 4 +- drivers/gpu/drm/msm/hdmi/qfprom.xml.h | 4 +- drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h | 4 +- drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | 82 +++++++++++++++++- drivers/gpu/drm/msm/mdp/mdp_common.xml.h | 11 ++- drivers/gpu/drm/msm/ocmem/ocmem.xml.h | 113 +++++++++++++++++++++++++ 15 files changed, 267 insertions(+), 40 deletions(-) create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.xml.h
diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h index 0261f0d..9e2aceb 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h @@ -8,13 +8,14 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 398 bytes, from 2015-09-24 17:25:31) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55) - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63785 bytes, from 2015-08-14 18:27:06) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors: - Rob Clark robdclark@gmail.com (robclark) diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h index 48d1337..97dc1c6 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h @@ -8,13 +8,14 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 398 bytes, from 2015-09-24 17:25:31) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55) - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63785 bytes, from 2015-08-14 18:27:06) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors: - Rob Clark robdclark@gmail.com (robclark) @@ -280,6 +281,8 @@ enum a3xx_rb_blend_opcode { enum a3xx_intp_mode { SMOOTH = 0, FLAT = 1, + ZERO = 2, + ONE = 3, };
enum a3xx_repl_mode { @@ -680,9 +683,16 @@ static inline uint32_t REG_A3XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000460 #define A3XX_GRAS_CL_CLIP_CNTL_VP_CLIP_CODE_IGNORE 0x00080000 #define A3XX_GRAS_CL_CLIP_CNTL_VP_XFORM_DISABLE 0x00100000 #define A3XX_GRAS_CL_CLIP_CNTL_PERSP_DIVISION_DISABLE 0x00200000 +#define A3XX_GRAS_CL_CLIP_CNTL_ZERO_GB_SCALE_Z 0x00400000 #define A3XX_GRAS_CL_CLIP_CNTL_ZCOORD 0x00800000 #define A3XX_GRAS_CL_CLIP_CNTL_WCOORD 0x01000000 #define A3XX_GRAS_CL_CLIP_CNTL_ZCLIP_DISABLE 0x02000000 +#define A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__MASK 0x1c000000 +#define A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__SHIFT 26 +static inline uint32_t A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES(uint32_t val) +{ + return ((val) << A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__SHIFT) & A3XX_GRAS_CL_CLIP_CNTL_NUM_USER_CLIP_PLANES__MASK; +}
#define REG_A3XX_GRAS_CL_GB_CLIP_ADJ 0x00002044 #define A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ__MASK 0x000003ff @@ -773,7 +783,7 @@ static inline uint32_t A3XX_GRAS_SU_POINT_SIZE(float val) #define A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT 0 static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL(float val) { - return ((((int32_t)(val * 16384.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK; + return ((((int32_t)(val * 1048576.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK; }
#define REG_A3XX_GRAS_SU_POLY_OFFSET_OFFSET 0x0000206d @@ -894,6 +904,9 @@ static inline uint32_t A3XX_RB_MODE_CONTROL_MRT(uint32_t val) #define A3XX_RB_MODE_CONTROL_PACKER_TIMER_ENABLE 0x00010000
#define REG_A3XX_RB_RENDER_CONTROL 0x000020c1 +#define A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE 0x00000001 +#define A3XX_RB_RENDER_CONTROL_YUV_IN_ENABLE 0x00000002 +#define A3XX_RB_RENDER_CONTROL_COV_VALUE_INPUT_ENABLE 0x00000004 #define A3XX_RB_RENDER_CONTROL_FACENESS 0x00000008 #define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__MASK 0x00000ff0 #define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__SHIFT 4 @@ -907,6 +920,8 @@ static inline uint32_t A3XX_RB_RENDER_CONTROL_BIN_WIDTH(uint32_t val) #define A3XX_RB_RENDER_CONTROL_YCOORD 0x00008000 #define A3XX_RB_RENDER_CONTROL_ZCOORD 0x00010000 #define A3XX_RB_RENDER_CONTROL_WCOORD 0x00020000 +#define A3XX_RB_RENDER_CONTROL_I_CLAMP_ENABLE 0x00080000 +#define A3XX_RB_RENDER_CONTROL_COV_VALUE_OUTPUT_ENABLE 0x00100000 #define A3XX_RB_RENDER_CONTROL_ALPHA_TEST 0x00400000 #define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK 0x07000000 #define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT 24 @@ -914,6 +929,8 @@ static inline uint32_t A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(enum adreno_compar { return ((val) << A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT) & A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK; } +#define A3XX_RB_RENDER_CONTROL_ALPHA_TO_COVERAGE 0x40000000 +#define A3XX_RB_RENDER_CONTROL_ALPHA_TO_ONE 0x80000000
#define REG_A3XX_RB_MSAA_CONTROL 0x000020c2 #define A3XX_RB_MSAA_CONTROL_DISABLE 0x00000400 diff --git a/drivers/gpu/drm/msm/adreno/a4xx.xml.h b/drivers/gpu/drm/msm/adreno/a4xx.xml.h index ac55066..99de827 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a4xx.xml.h @@ -8,13 +8,14 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 398 bytes, from 2015-09-24 17:25:31) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55) - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63785 bytes, from 2015-08-14 18:27:06) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors: - Rob Clark robdclark@gmail.com (robclark) @@ -162,10 +163,13 @@ enum a4xx_tex_fmt { TFMT4_8_UNORM = 4, TFMT4_8_8_UNORM = 14, TFMT4_8_8_8_8_UNORM = 28, + TFMT4_8_SNORM = 5, TFMT4_8_8_SNORM = 15, TFMT4_8_8_8_8_SNORM = 29, + TFMT4_8_UINT = 6, TFMT4_8_8_UINT = 16, TFMT4_8_8_8_8_UINT = 30, + TFMT4_8_SINT = 7, TFMT4_8_8_SINT = 17, TFMT4_8_8_8_8_SINT = 31, TFMT4_16_UINT = 21, @@ -246,7 +250,8 @@ enum a4xx_tex_clamp { A4XX_TEX_REPEAT = 0, A4XX_TEX_CLAMP_TO_EDGE = 1, A4XX_TEX_MIRROR_REPEAT = 2, - A4XX_TEX_CLAMP_NONE = 3, + A4XX_TEX_CLAMP_TO_BORDER = 3, + A4XX_TEX_MIRROR_CLAMP = 4, };
enum a4xx_tex_aniso { diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h index 399a9e5..c304468 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h @@ -8,13 +8,14 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 398 bytes, from 2015-09-24 17:25:31) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55) - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63785 bytes, from 2015-08-14 18:27:06) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors: - Rob Clark robdclark@gmail.com (robclark) @@ -85,6 +86,10 @@ enum adreno_rb_blend_factor { FACTOR_CONSTANT_ALPHA = 14, FACTOR_ONE_MINUS_CONSTANT_ALPHA = 15, FACTOR_SRC_ALPHA_SATURATE = 16, + FACTOR_SRC1_COLOR = 20, + FACTOR_ONE_MINUS_SRC1_COLOR = 21, + FACTOR_SRC1_ALPHA = 22, + FACTOR_ONE_MINUS_SRC1_ALPHA = 23, };
enum adreno_rb_surface_endian { diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h index 41904fe..a22fef5 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h @@ -8,13 +8,14 @@ http://github.com/freedreno/envytools/ git clone https://github.com/freedreno/envytools.git
The rules-ng-ng source files this header was generated from are: -- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 364 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 398 bytes, from 2015-09-24 17:25:31) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2015-05-20 20:03:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55) - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67120 bytes, from 2015-08-14 23:22:03) -- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63785 bytes, from 2015-08-14 18:27:06) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00)
Copyright (C) 2013-2015 by the following authors: - Rob Clark robdclark@gmail.com (robclark) diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index 1d2e32f..c208547 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h index 5de505e..cb830a3 100644 --- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h +++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h index 06cbddf..96f7ecb 100644 --- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h +++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) diff --git a/drivers/gpu/drm/msm/edp/edp.xml.h b/drivers/gpu/drm/msm/edp/edp.xml.h index bef1d65..fbef985 100644 --- a/drivers/gpu/drm/msm/edp/edp.xml.h +++ b/drivers/gpu/drm/msm/edp/edp.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h index 0b1b558..84846c4 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h index 2aa23b9..0ae573c 100644 --- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h +++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h index 74b8673..df7e765 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h index 3469f50..87c3141 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) @@ -895,6 +895,7 @@ static inline uint32_t MDP5_PIPE_SRC_OP_MODE_BWC(enum mdp5_pipe_bwc val) #define MDP5_PIPE_SRC_OP_MODE_IGC_ROM_1 0x00040000 #define MDP5_PIPE_SRC_OP_MODE_DEINTERLACE 0x00400000 #define MDP5_PIPE_SRC_OP_MODE_DEINTERLACE_ODD 0x00800000 +#define MDP5_PIPE_SRC_OP_MODE_SW_PIX_EXT_OVERRIDE 0x80000000
static inline uint32_t REG_MDP5_PIPE_SRC_CONSTANT_COLOR(enum mdp5_pipe i0) { return 0x0000003c + __offset_PIPE(i0); }
@@ -932,6 +933,83 @@ static inline uint32_t MDP5_PIPE_DECIMATION_HORZ(uint32_t val) return ((val) << MDP5_PIPE_DECIMATION_HORZ__SHIFT) & MDP5_PIPE_DECIMATION_HORZ__MASK; }
+static inline uint32_t __offset_SW_PIX_EXT(enum mdp_component_type idx) +{ + switch (idx) { + case COMP_0: return 0x00000100; + case COMP_1_2: return 0x00000110; + case COMP_3: return 0x00000120; + default: return INVALID_IDX(idx); + } +} +static inline uint32_t REG_MDP5_PIPE_SW_PIX_EXT(enum mdp5_pipe i0, enum mdp_component_type i1) { return 0x00000000 + __offset_PIPE(i0) + __offset_SW_PIX_EXT(i1); } + +static inline uint32_t REG_MDP5_PIPE_SW_PIX_EXT_LR(enum mdp5_pipe i0, enum mdp_component_type i1) { return 0x00000000 + __offset_PIPE(i0) + __offset_SW_PIX_EXT(i1); } +#define MDP5_PIPE_SW_PIX_EXT_LR_LEFT_RPT__MASK 0x000000ff +#define MDP5_PIPE_SW_PIX_EXT_LR_LEFT_RPT__SHIFT 0 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_LR_LEFT_RPT(uint32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_LR_LEFT_RPT__SHIFT) & MDP5_PIPE_SW_PIX_EXT_LR_LEFT_RPT__MASK; +} +#define MDP5_PIPE_SW_PIX_EXT_LR_LEFT_OVF__MASK 0x0000ff00 +#define MDP5_PIPE_SW_PIX_EXT_LR_LEFT_OVF__SHIFT 8 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_LR_LEFT_OVF(int32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_LR_LEFT_OVF__SHIFT) & MDP5_PIPE_SW_PIX_EXT_LR_LEFT_OVF__MASK; +} +#define MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_RPT__MASK 0x00ff0000 +#define MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_RPT__SHIFT 16 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_RPT(uint32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_RPT__SHIFT) & MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_RPT__MASK; +} +#define MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_OVF__MASK 0xff000000 +#define MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_OVF__SHIFT 24 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_OVF(int32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_OVF__SHIFT) & MDP5_PIPE_SW_PIX_EXT_LR_RIGHT_OVF__MASK; +} + +static inline uint32_t REG_MDP5_PIPE_SW_PIX_EXT_TB(enum mdp5_pipe i0, enum mdp_component_type i1) { return 0x00000004 + __offset_PIPE(i0) + __offset_SW_PIX_EXT(i1); } +#define MDP5_PIPE_SW_PIX_EXT_TB_TOP_RPT__MASK 0x000000ff +#define MDP5_PIPE_SW_PIX_EXT_TB_TOP_RPT__SHIFT 0 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_TB_TOP_RPT(uint32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_TB_TOP_RPT__SHIFT) & MDP5_PIPE_SW_PIX_EXT_TB_TOP_RPT__MASK; +} +#define MDP5_PIPE_SW_PIX_EXT_TB_TOP_OVF__MASK 0x0000ff00 +#define MDP5_PIPE_SW_PIX_EXT_TB_TOP_OVF__SHIFT 8 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_TB_TOP_OVF(int32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_TB_TOP_OVF__SHIFT) & MDP5_PIPE_SW_PIX_EXT_TB_TOP_OVF__MASK; +} +#define MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_RPT__MASK 0x00ff0000 +#define MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_RPT__SHIFT 16 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_RPT(uint32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_RPT__SHIFT) & MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_RPT__MASK; +} +#define MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_OVF__MASK 0xff000000 +#define MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_OVF__SHIFT 24 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_OVF(int32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_OVF__SHIFT) & MDP5_PIPE_SW_PIX_EXT_TB_BOTTOM_OVF__MASK; +} + +static inline uint32_t REG_MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS(enum mdp5_pipe i0, enum mdp_component_type i1) { return 0x00000008 + __offset_PIPE(i0) + __offset_SW_PIX_EXT(i1); } +#define MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_LEFT_RIGHT__MASK 0x0000ffff +#define MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_LEFT_RIGHT__SHIFT 0 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_LEFT_RIGHT(uint32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_LEFT_RIGHT__SHIFT) & MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_LEFT_RIGHT__MASK; +} +#define MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_TOP_BOTTOM__MASK 0xffff0000 +#define MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_TOP_BOTTOM__SHIFT 16 +static inline uint32_t MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_TOP_BOTTOM(uint32_t val) +{ + return ((val) << MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_TOP_BOTTOM__SHIFT) & MDP5_PIPE_SW_PIX_EXT_REQ_PIXELS_TOP_BOTTOM__MASK; +} + static inline uint32_t REG_MDP5_PIPE_SCALE_CONFIG(enum mdp5_pipe i0) { return 0x00000204 + __offset_PIPE(i0); } #define MDP5_PIPE_SCALE_CONFIG_SCALEX_EN 0x00000001 #define MDP5_PIPE_SCALE_CONFIG_SCALEY_EN 0x00000002 diff --git a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h index 4f792c4..2916c4d 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h @@ -11,8 +11,8 @@ The rules-ng-ng source files this header was generated from are: - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2015-05-20 20:03:14) - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20915 bytes, from 2015-05-20 20:03:14) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2576 bytes, from 2015-07-09 22:10:24) -- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 36021 bytes, from 2015-07-09 22:10:24) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2849 bytes, from 2015-09-18 12:07:28) +- /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 37194 bytes, from 2015-09-18 12:07:28) - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 26057 bytes, from 2015-08-14 21:47:57) - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2015-05-20 20:03:07) - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2015-05-20 20:03:14) @@ -78,6 +78,13 @@ enum mdp_alpha_type { BG_PIXEL = 3, };
+enum mdp_component_type { + COMP_0 = 0, + COMP_1_2 = 1, + COMP_3 = 2, + COMP_MAX = 3, +}; + enum mdp_bpc { BPC1 = 0, BPC5 = 1, diff --git a/drivers/gpu/drm/msm/ocmem/ocmem.xml.h b/drivers/gpu/drm/msm/ocmem/ocmem.xml.h new file mode 100644 index 0000000..64ec02e --- /dev/null +++ b/drivers/gpu/drm/msm/ocmem/ocmem.xml.h @@ -0,0 +1,113 @@ +#ifndef OCMEM_XML +#define OCMEM_XML + +/* Autogenerated file, DO NOT EDIT manually! + +This file was generated by the rules-ng-ng headergen tool in this git repository: +http://github.com/freedreno/envytools/ +git clone https://github.com/freedreno/envytools.git + +The rules-ng-ng source files this header was generated from are: +- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml ( 398 bytes, from 2015-09-24 17:25:31) +- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2015-05-20 20:03:07) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2015-05-20 20:03:14) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10755 bytes, from 2015-09-14 20:46:55) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 14968 bytes, from 2015-05-20 20:12:27) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 67771 bytes, from 2015-09-14 20:46:55) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 63970 bytes, from 2015-09-14 20:50:12) +- /home/robclark/src/freedreno/envytools/rnndb/adreno/ocmem.xml ( 1773 bytes, from 2015-09-24 17:30:00) + +Copyright (C) 2013-2015 by the following authors: +- Rob Clark robdclark@gmail.com (robclark) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + + +enum ocmem_macro_state { + PASSTHROUGH = 0, + PERI_ON = 1, + CORE_ON = 2, + CLK_OFF = 4, +}; + +#define REG_OCMEM_HW_VERSION 0x00000000 + +#define REG_OCMEM_HW_PROFILE 0x00000004 +#define OCMEM_HW_PROFILE_NUM_PORTS__MASK 0x0000000f +#define OCMEM_HW_PROFILE_NUM_PORTS__SHIFT 0 +static inline uint32_t OCMEM_HW_PROFILE_NUM_PORTS(uint32_t val) +{ + return ((val) << OCMEM_HW_PROFILE_NUM_PORTS__SHIFT) & OCMEM_HW_PROFILE_NUM_PORTS__MASK; +} +#define OCMEM_HW_PROFILE_NUM_MACROS__MASK 0x00003f00 +#define OCMEM_HW_PROFILE_NUM_MACROS__SHIFT 8 +static inline uint32_t OCMEM_HW_PROFILE_NUM_MACROS(uint32_t val) +{ + return ((val) << OCMEM_HW_PROFILE_NUM_MACROS__SHIFT) & OCMEM_HW_PROFILE_NUM_MACROS__MASK; +} +#define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE 0x00010000 +#define OCMEM_HW_PROFILE_INTERLEAVING 0x00020000 + +#define REG_OCMEM_GEN_STATUS 0x0000000c + +#define REG_OCMEM_PSGSC_STATUS 0x00000038 + +static inline uint32_t REG_OCMEM_PSGSC(uint32_t i0) { return 0x0000003c + 0x1*i0; } + +static inline uint32_t REG_OCMEM_PSGSC_CTL(uint32_t i0) { return 0x0000003c + 0x1*i0; } +#define OCMEM_PSGSC_CTL_MACRO0_MODE__MASK 0x00000007 +#define OCMEM_PSGSC_CTL_MACRO0_MODE__SHIFT 0 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO0_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO0_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO0_MODE__MASK; +} +#define OCMEM_PSGSC_CTL_MACRO1_MODE__MASK 0x00000070 +#define OCMEM_PSGSC_CTL_MACRO1_MODE__SHIFT 4 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO1_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO1_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO1_MODE__MASK; +} +#define OCMEM_PSGSC_CTL_MACRO2_MODE__MASK 0x00000700 +#define OCMEM_PSGSC_CTL_MACRO2_MODE__SHIFT 8 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO2_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO2_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO2_MODE__MASK; +} +#define OCMEM_PSGSC_CTL_MACRO3_MODE__MASK 0x00007000 +#define OCMEM_PSGSC_CTL_MACRO3_MODE__SHIFT 12 +static inline uint32_t OCMEM_PSGSC_CTL_MACRO3_MODE(enum ocmem_macro_state val) +{ + return ((val) << OCMEM_PSGSC_CTL_MACRO3_MODE__SHIFT) & OCMEM_PSGSC_CTL_MACRO3_MODE__MASK; +} + +#define REG_OCMEM_REGION_MODE_CTL 0x00001000 +#define OCMEM_REGION_MODE_CTL_REG0_THIN 0x00000001 +#define OCMEM_REGION_MODE_CTL_REG1_THIN 0x00000002 +#define OCMEM_REGION_MODE_CTL_REG2_THIN 0x00000004 +#define OCMEM_REGION_MODE_CTL_REG3_THIN 0x00000008 + +#define REG_OCMEM_GFX_MPU_START 0x00001004 + +#define REG_OCMEM_GFX_MPU_END 0x00001008 + + +#endif /* OCMEM_XML */
For now, since the GPU is the only upstream consumer, just stuff this into drm/msm. Eventually if we have other consumers, we'll have to split this out and make the allocation less hard coded. But I'll punt on that until I better understand the non-gpu uses-cases (and whether the allocation *really* needs to be as complicated as it is in the downstream driver).
Signed-off-by: Rob Clark robdclark@gmail.com --- drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 19 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 19 +- drivers/gpu/drm/msm/msm_drv.c | 2 + drivers/gpu/drm/msm/msm_gpu.h | 3 + drivers/gpu/drm/msm/ocmem/ocmem.c | 399 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/ocmem/ocmem.h | 46 ++++ 7 files changed, 463 insertions(+), 28 deletions(-) create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 0a543eb..8ddf6fa 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -48,7 +48,8 @@ msm-y := \ msm_iommu.o \ msm_perf.o \ msm_rd.o \ - msm_ringbuffer.o + msm_ringbuffer.o \ + ocmem/ocmem.o
msm-$(CONFIG_DRM_MSM_FBDEV) += msm_fbdev.o msm-$(CONFIG_COMMON_CLK) += mdp/mdp4/mdp4_lvds_pll.o diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index ca29688..2a8bf4c 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -17,10 +17,7 @@ * this program. If not, see http://www.gnu.org/licenses/. */
-#ifdef CONFIG_MSM_OCMEM -# include <mach/ocmem.h> -#endif - +#include "ocmem/ocmem.h" #include "a3xx_gpu.h"
#define A3XX_INT0_MASK \ @@ -322,10 +319,8 @@ static void a3xx_destroy(struct msm_gpu *gpu)
adreno_gpu_cleanup(adreno_gpu);
-#ifdef CONFIG_MSM_OCMEM - if (a3xx_gpu->ocmem_base) + if (a3xx_gpu->ocmem_hdl) ocmem_free(OCMEM_GRAPHICS, a3xx_gpu->ocmem_hdl); -#endif
kfree(a3xx_gpu); } @@ -539,6 +534,7 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) struct msm_gpu *gpu; struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct ocmem_buf *ocmem_hdl; int ret;
if (!pdev) { @@ -569,18 +565,13 @@ struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) goto fail;
/* if needed, allocate gmem: */ - if (adreno_is_a330(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - + ocmem_hdl = ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); + if (!IS_ERR(ocmem_hdl)) { a3xx_gpu->ocmem_hdl = ocmem_hdl; a3xx_gpu->ocmem_base = ocmem_hdl->addr; adreno_gpu->gmem = ocmem_hdl->len; DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, a3xx_gpu->ocmem_base); -#endif }
if (!gpu->mmu) { diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index a53f1be..17f084d 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -10,10 +10,9 @@ * GNU General Public License for more details. * */ + +#include "ocmem/ocmem.h" #include "a4xx_gpu.h" -#ifdef CONFIG_MSM_OCMEM -# include <soc/qcom/ocmem.h> -#endif
#define A4XX_INT0_MASK \ (A4XX_INT0_RBBM_AHB_ERROR | \ @@ -289,10 +288,8 @@ static void a4xx_destroy(struct msm_gpu *gpu)
adreno_gpu_cleanup(adreno_gpu);
-#ifdef CONFIG_MSM_OCMEM - if (a4xx_gpu->ocmem_base) + if (a4xx_gpu->ocmem_hdl) ocmem_free(OCMEM_GRAPHICS, a4xx_gpu->ocmem_hdl); -#endif
kfree(a4xx_gpu); } @@ -538,6 +535,7 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) struct msm_gpu *gpu; struct msm_drm_private *priv = dev->dev_private; struct platform_device *pdev = priv->gpu_pdev; + struct ocmem_buf *ocmem_hdl; int ret;
if (!pdev) { @@ -568,18 +566,13 @@ struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) goto fail;
/* if needed, allocate gmem: */ - if (adreno_is_a4xx(adreno_gpu)) { -#ifdef CONFIG_MSM_OCMEM - /* TODO this is different/missing upstream: */ - struct ocmem_buf *ocmem_hdl = - ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); - + ocmem_hdl = ocmem_allocate(OCMEM_GRAPHICS, adreno_gpu->gmem); + if (!IS_ERR(ocmem_hdl)) { a4xx_gpu->ocmem_hdl = ocmem_hdl; a4xx_gpu->ocmem_base = ocmem_hdl->addr; adreno_gpu->gmem = ocmem_hdl->len; DBG("using %dK of OCMEM at 0x%08x", adreno_gpu->gmem / 1024, a4xx_gpu->ocmem_base); -#endif }
if (!gpu->mmu) { diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 28c9a2a..1b02c2d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1165,6 +1165,7 @@ static int __init msm_drm_register(void) msm_dsi_register(); msm_edp_register(); hdmi_register(); + ocmem_register(); adreno_register(); return platform_driver_register(&msm_platform_driver); } @@ -1175,6 +1176,7 @@ static void __exit msm_drm_unregister(void) platform_driver_unregister(&msm_platform_driver); hdmi_unregister(); adreno_unregister(); + ocmem_unregister(); msm_edp_unregister(); msm_dsi_unregister(); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 2bbe85a..f042ba8 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -172,4 +172,7 @@ struct msm_gpu *adreno_load_gpu(struct drm_device *dev); void __init adreno_register(void); void __exit adreno_unregister(void);
+void __init ocmem_register(void); +void __exit ocmem_unregister(void); + #endif /* __MSM_GPU_H__ */ diff --git a/drivers/gpu/drm/msm/ocmem/ocmem.c b/drivers/gpu/drm/msm/ocmem/ocmem.c new file mode 100644 index 0000000..535d9f7 --- /dev/null +++ b/drivers/gpu/drm/msm/ocmem/ocmem.c @@ -0,0 +1,399 @@ +/* + * Copyright (C) 2015 Red Hat + * Author: Rob Clark robdclark@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see http://www.gnu.org/licenses/. + */ + +#include <linux/qcom_scm.h> +#include <linux/of_device.h> + +#include "msm_drv.h" +#include "ocmem.h" +#include "ocmem.xml.h" + +enum region_mode { + WIDE_MODE = 0x0, + THIN_MODE, + MODE_DEFAULT = WIDE_MODE, +}; + +enum ocmem_tz_client { + TZ_UNUSED = 0x0, + TZ_GRAPHICS, + TZ_VIDEO, + TZ_LP_AUDIO, + TZ_SENSORS, + TZ_OTHER_OS, + TZ_DEBUG, +}; + +struct ocmem_region { + unsigned psgsc_ctrl; + bool interleaved; + enum region_mode mode; + unsigned int num_macros; + enum ocmem_macro_state macro_state[4]; + unsigned long macro_size; + unsigned long region_size; +}; + +struct ocmem_config { + uint8_t num_regions; + uint32_t macro_size; +}; + +struct ocmem { + struct device *dev; + const struct ocmem_config *config; + struct resource *ocmem_mem; + struct clk *core_clk; + struct clk *iface_clk; + void __iomem *mmio; + + unsigned num_ports; + unsigned num_macros; + bool interleaved; + + struct ocmem_region *regions; +}; + +static struct ocmem *ocmem; + +static bool ocmem_exists(void); + +static inline void ocmem_write(struct ocmem *ocmem, u32 reg, u32 data) +{ + msm_writel(data, ocmem->mmio + reg); +} + +static inline u32 ocmem_read(struct ocmem *ocmem, u32 reg) +{ + return msm_readl(ocmem->mmio + reg); +} + +static int ocmem_clk_enable(struct ocmem *ocmem) +{ + int ret; + + ret = clk_prepare_enable(ocmem->core_clk); + if (ret) + return ret; + + ret = clk_prepare_enable(ocmem->iface_clk); + if (ret) + return ret; + + return 0; +} + +static void ocmem_clk_disable(struct ocmem *ocmem) +{ + clk_disable_unprepare(ocmem->iface_clk); + clk_disable_unprepare(ocmem->core_clk); +} + +static int ocmem_dev_remove(struct platform_device *pdev) +{ + ocmem_clk_disable(ocmem); + return 0; +} + +static void update_ocmem(struct ocmem *ocmem) +{ + uint32_t region_mode_ctrl = 0x0; + unsigned pos = 0; + unsigned i = 0; + + if (!qcom_scm_ocmem_lock_available()) { + for (i = 0; i < ocmem->config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + pos = i << 2; + if (region->mode == THIN_MODE) + region_mode_ctrl |= BIT(pos); + } + dev_dbg(ocmem->dev, "ocmem_region_mode_control %x\n", region_mode_ctrl); + ocmem_write(ocmem, REG_OCMEM_REGION_MODE_CTL, region_mode_ctrl); + } + + for (i = 0; i < ocmem->config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + + ocmem_write(ocmem, REG_OCMEM_PSGSC_CTL(i), + OCMEM_PSGSC_CTL_MACRO0_MODE(region->macro_state[0]) | + OCMEM_PSGSC_CTL_MACRO1_MODE(region->macro_state[1]) | + OCMEM_PSGSC_CTL_MACRO2_MODE(region->macro_state[2]) | + OCMEM_PSGSC_CTL_MACRO3_MODE(region->macro_state[3])); + } +} + +static unsigned long phys_to_offset(unsigned long addr) +{ + if ((addr < ocmem->ocmem_mem->start) || + (addr >= ocmem->ocmem_mem->end)) + return 0; + return addr - ocmem->ocmem_mem->start; +} + +static unsigned long device_address(enum ocmem_client client, unsigned long addr) +{ + /* TODO, gpu uses phys_to_offset, but others do not.. */ + return phys_to_offset(addr); +} + +static void update_range(struct ocmem *ocmem, struct ocmem_buf *buf, + enum ocmem_macro_state mstate, enum region_mode rmode) +{ + unsigned long offset = 0; + int i, j; + + /* + * TODO probably should assert somewhere that range is aligned + * to macro boundaries.. + */ + + for (i = 0; i < ocmem->config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + if ((buf->offset <= offset) && (offset < (buf->offset + buf->len))) + region->mode = rmode; + for (j = 0; j < region->num_macros; j++) { + if ((buf->offset <= offset) && (offset < (buf->offset + buf->len))) + region->macro_state[j] = mstate; + offset += region->macro_size; + } + } + + update_ocmem(ocmem); +} + +struct ocmem_buf *ocmem_allocate(enum ocmem_client client, unsigned long size) +{ + struct ocmem_buf *buf; + + if (!ocmem) { + if (ocmem_exists()) + return ERR_PTR(-EPROBE_DEFER); + return ERR_PTR(-ENXIO); + } + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + /* + * TODO less hard-coded allocation that works for more than + * one user: + */ + + buf->offset = 0; + buf->addr = device_address(client, buf->offset); + buf->len = size; + + update_range(ocmem, buf, CORE_ON, WIDE_MODE); + + if (qcom_scm_ocmem_lock_available()) { + int ret; + ret = qcom_scm_ocmem_lock(TZ_GRAPHICS, buf->offset, buf->len, + WIDE_MODE); + if (ret) + dev_err(ocmem->dev, "could not lock: %d\n", ret); + } else { + if (client == OCMEM_GRAPHICS) { + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_START, buf->offset); + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_END, buf->offset + buf->len); + } + } + + return buf; +} + +void ocmem_free(enum ocmem_client client, struct ocmem_buf *buf) +{ + update_range(ocmem, buf, CLK_OFF, MODE_DEFAULT); + + if (qcom_scm_ocmem_lock_available()) { + int ret; + ret = qcom_scm_ocmem_unlock(TZ_GRAPHICS, buf->offset, buf->len); + if (ret) + dev_err(ocmem->dev, "could not unlock: %d\n", ret); + } else { + if (client == OCMEM_GRAPHICS) { + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_START, 0x0); + ocmem_write(ocmem, REG_OCMEM_GFX_MPU_END, 0x0); + } + } + + kfree(buf); +} + +static const struct ocmem_config ocmem_8974_config = { + .num_regions = 3, .macro_size = SZ_128K, +}; + +static const struct of_device_id dt_match[] = { + { .compatible = "qcom,ocmem-msm8974", .data = &ocmem_8974_config }, + {} +}; + +static int ocmem_dev_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct ocmem_config *config = NULL; + uint32_t reg, num_banks, region_size; + const struct of_device_id *match; + int i, j, ret; + + /* we need scm to be available: */ + if (!qcom_scm_is_available()) + return -EPROBE_DEFER; + + match = of_match_device(dt_match, dev); + if (match) + config = match->data; + + if (!config) { + dev_err(dev, "unknown config: %s\n", dev->of_node->name); + return -ENXIO; + } + + ocmem = devm_kzalloc(dev, sizeof(*ocmem), GFP_KERNEL); + if (!ocmem) + return -ENOMEM; + + ocmem->dev = dev; + ocmem->config = config; + + ocmem->core_clk = devm_clk_get(dev, "core_clk"); + if (IS_ERR(ocmem->core_clk)) { + dev_err(dev, "Unable to get the core clock\n"); + return PTR_ERR(ocmem->core_clk); + } + + ocmem->iface_clk = devm_clk_get(dev, "iface_clk"); + if (IS_ERR_OR_NULL(ocmem->iface_clk)) { + ret = PTR_ERR(ocmem->iface_clk); + ocmem->iface_clk = NULL; + /* in probe-defer case, propagate error up and try again later: */ + if (ret == -EPROBE_DEFER) + goto fail; + } + + /* The core clock is synchronous with graphics */ + WARN_ON(clk_set_rate(ocmem->core_clk, 1000) < 0); + + ocmem->mmio = msm_ioremap(pdev, "ocmem_ctrl_physical", "OCMEM"); + if (IS_ERR(ocmem->mmio)) + return PTR_ERR(ocmem->mmio); + + ocmem->ocmem_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "ocmem_physical"); + if (!ocmem->ocmem_mem) { + dev_err(dev, "could not get OCMEM region\n"); + return -ENXIO; + } + + ret = ocmem_clk_enable(ocmem); + if (ret) + goto fail; + + if (qcom_scm_ocmem_secure_available()) { + dev_dbg(dev, "configuring scm\n"); + ret = qcom_scm_ocmem_secure_cfg(0x5); + if (ret) + goto fail; + } + + reg = ocmem_read(ocmem, REG_OCMEM_HW_PROFILE); + ocmem->num_ports = FIELD(reg, OCMEM_HW_PROFILE_NUM_PORTS); + ocmem->num_macros = FIELD(reg, OCMEM_HW_PROFILE_NUM_MACROS); + ocmem->interleaved = !!(reg & OCMEM_HW_PROFILE_INTERLEAVING); + + num_banks = ocmem->num_ports / 2; + region_size = config->macro_size * num_banks; + + dev_info(dev, "%u ports, %u regions, %u macros, %sinterleaved\n", + ocmem->num_ports, config->num_regions, ocmem->num_macros, + ocmem->interleaved ? "" : "not "); + + ocmem->regions = devm_kcalloc(dev, config->num_regions, + sizeof(struct ocmem_region), GFP_KERNEL); + if (!ocmem->regions) { + ret = -ENOMEM; + goto fail; + } + + for (i = 0; i < config->num_regions; i++) { + struct ocmem_region *region = &ocmem->regions[i]; + + if (WARN_ON(num_banks > ARRAY_SIZE(region->macro_state))) { + ret = -EINVAL; + goto fail; + } + + region->mode = MODE_DEFAULT; + region->num_macros = num_banks; + + if ((i == (config->num_regions - 1)) && + (reg & OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE)) { + region->macro_size = config->macro_size / 2; + region->region_size = region_size / 2; + } else { + region->macro_size = config->macro_size; + region->region_size = region_size; + } + + for (j = 0; j < ARRAY_SIZE(region->macro_state); j++) + region->macro_state[j] = CLK_OFF; + } + + return 0; + +fail: + dev_err(dev, "probe failed\n"); + ocmem_dev_remove(pdev); + return ret; +} + +static struct platform_driver ocmem_driver = { + .probe = ocmem_dev_probe, + .remove = ocmem_dev_remove, + .driver = { + .name = "ocmem", + .of_match_table = dt_match, + }, +}; + +static bool ocmem_exists(void) +{ + struct device_driver *drv = &ocmem_driver.driver; + struct device *d; + + d = bus_find_device(&platform_bus_type, NULL, drv, + (void *)platform_bus_type.match); + if (d) { + put_device(d); + return true; + } + + return false; +} + +void __init ocmem_register(void) +{ + platform_driver_register(&ocmem_driver); +} + +void __exit ocmem_unregister(void) +{ + platform_driver_unregister(&ocmem_driver); +} diff --git a/drivers/gpu/drm/msm/ocmem/ocmem.h b/drivers/gpu/drm/msm/ocmem/ocmem.h new file mode 100644 index 0000000..199be98 --- /dev/null +++ b/drivers/gpu/drm/msm/ocmem/ocmem.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015 Red Hat + * Author: Rob Clark robdclark@gmail.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see http://www.gnu.org/licenses/. + */ + +#ifndef __OCMEM_H__ +#define __OCMEM_H__ + +enum ocmem_client { + /* GMEM clients */ + OCMEM_GRAPHICS = 0x0, + /* TCMEM clients */ + OCMEM_VIDEO, + OCMEM_CAMERA, + /* Dummy Clients */ + OCMEM_HP_AUDIO, + OCMEM_VOICE, + /* IMEM Clients */ + OCMEM_LP_AUDIO, + OCMEM_SENSORS, + OCMEM_OTHER_OS, + OCMEM_CLIENT_MAX, +}; + +struct ocmem_buf { + unsigned long offset; + unsigned long addr; + unsigned long len; +}; + +struct ocmem_buf *ocmem_allocate(enum ocmem_client client, unsigned long size); +void ocmem_free(enum ocmem_client client, struct ocmem_buf *buf); + +#endif /* __OCMEM_H__ */
Hi Rob,
Thanks for your work.
On 09/29/2015 10:48 PM, Rob Clark wrote:
For now, since the GPU is the only upstream consumer, just stuff this into drm/msm. Eventually if we have other consumers, we'll have to
As the video encoder/decoder driver (vidc) for apq8084 && msm8974 also use the ocmem for scratch buffers, it might be better to relocate the ocmem driver in drivers/soc/qcom from the beginning?
I'm working on vidc driver upstream version so it will be nice to test ocmem driver from it, too.
split this out and make the allocation less hard coded. But I'll punt on that until I better understand the non-gpu uses-cases (and whether the allocation *really* needs to be as complicated as it is in the downstream driver).
Signed-off-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 19 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 19 +- drivers/gpu/drm/msm/msm_drv.c | 2 + drivers/gpu/drm/msm/msm_gpu.h | 3 + drivers/gpu/drm/msm/ocmem/ocmem.c | 399 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/ocmem/ocmem.h | 46 ++++ 7 files changed, 463 insertions(+), 28 deletions(-) create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h
<snip>
On Wed, Sep 30, 2015 at 3:51 AM, Stanimir Varbanov stanimir.varbanov@linaro.org wrote:
Hi Rob,
Thanks for your work.
On 09/29/2015 10:48 PM, Rob Clark wrote:
For now, since the GPU is the only upstream consumer, just stuff this into drm/msm. Eventually if we have other consumers, we'll have to
As the video encoder/decoder driver (vidc) for apq8084 && msm8974 also use the ocmem for scratch buffers, it might be better to relocate the ocmem driver in drivers/soc/qcom from the beginning?
I wasn't really sure how soon vidc would support 8084/8974 (I assume first target is 8916 which fortunately doesn't have ocmem), or if it was mandatory or just power optimization.. but yes, the plan was to move it somewhere else (not sure quite where, drivers/doc/qcom?) sometime.. Preferably when someone who understands all the other ocmem use-cases better could figure out what we really need to add to the driver.
In downstream driver there is a lot of complexity that appears to be in order to allow two clients to each allocate a portion of a macro within a region (ie. aggregate_macro_state(), apply_macro_vote(), etc), and I wanted to figure out if that is even a valid use-case before trying to make ocmem something that could actually support multiple clients.
There is also some complexity about ensuring that if clients aren't split up on region boundaries, that you don't have one client in region asking for wide-mode and other for narrow-mode.. (switch_region_mode()) but maybe we could handle that by just allocating wide from bottom and narrow from top. Also seems to be some craziness for allowing one client to pre-empt/evict another.. a dm engine, etc, etc..
All I know is gpu just statically allocates one big region aligned chunk of ocmem, so I ignored the rest of the crazy (maybe or maybe not hypothetical) use-cases for now...
BR, -R
I'm working on vidc driver upstream version so it will be nice to test ocmem driver from it, too.
split this out and make the allocation less hard coded. But I'll punt on that until I better understand the non-gpu uses-cases (and whether the allocation *really* needs to be as complicated as it is in the downstream driver).
Signed-off-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 19 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 19 +- drivers/gpu/drm/msm/msm_drv.c | 2 + drivers/gpu/drm/msm/msm_gpu.h | 3 + drivers/gpu/drm/msm/ocmem/ocmem.c | 399 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/ocmem/ocmem.h | 46 ++++ 7 files changed, 463 insertions(+), 28 deletions(-) create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h
<snip>
-- regards, Stan
On Wed, Sep 30, 2015 at 7:31 AM, Rob Clark robdclark@gmail.com wrote:
On Wed, Sep 30, 2015 at 3:51 AM, Stanimir Varbanov stanimir.varbanov@linaro.org wrote:
Hi Rob,
Thanks for your work.
On 09/29/2015 10:48 PM, Rob Clark wrote:
For now, since the GPU is the only upstream consumer, just stuff this into drm/msm. Eventually if we have other consumers, we'll have to
As the video encoder/decoder driver (vidc) for apq8084 && msm8974 also use the ocmem for scratch buffers, it might be better to relocate the ocmem driver in drivers/soc/qcom from the beginning?
I wasn't really sure how soon vidc would support 8084/8974 (I assume first target is 8916 which fortunately doesn't have ocmem), or if it was mandatory or just power optimization.. but yes, the plan was to move it somewhere else (not sure quite where, drivers/doc/qcom?) sometime.. Preferably when someone who understands all the other ocmem use-cases better could figure out what we really need to add to the driver.
In downstream driver there is a lot of complexity that appears to be in order to allow two clients to each allocate a portion of a macro within a region (ie. aggregate_macro_state(), apply_macro_vote(), etc), and I wanted to figure out if that is even a valid use-case before trying to make ocmem something that could actually support multiple clients.
There is also some complexity about ensuring that if clients aren't split up on region boundaries, that you don't have one client in region asking for wide-mode and other for narrow-mode.. (switch_region_mode()) but maybe we could handle that by just allocating wide from bottom and narrow from top. Also seems to be some craziness for allowing one client to pre-empt/evict another.. a dm engine, etc, etc..
All I know is gpu just statically allocates one big region aligned chunk of ocmem, so I ignored the rest of the crazy (maybe or maybe not hypothetical) use-cases for now...
btw, I should add that I don't mind adding it in drivers/soc/qcom (or somewhere else?) to start with if others prefer, I just didn't want to give the wrong impression that it is ready yet for multiple clients.
All I know is the gpu uses it statically and is pretty much useless without ocmem, so for lack of understanding of the other use cases I just tried to add simply what the gpu needs..
BR, -R
I'm working on vidc driver upstream version so it will be nice to test ocmem driver from it, too.
split this out and make the allocation less hard coded. But I'll punt on that until I better understand the non-gpu uses-cases (and whether the allocation *really* needs to be as complicated as it is in the downstream driver).
Signed-off-by: Rob Clark robdclark@gmail.com
drivers/gpu/drm/msm/Makefile | 3 +- drivers/gpu/drm/msm/adreno/a3xx_gpu.c | 19 +- drivers/gpu/drm/msm/adreno/a4xx_gpu.c | 19 +- drivers/gpu/drm/msm/msm_drv.c | 2 + drivers/gpu/drm/msm/msm_gpu.h | 3 + drivers/gpu/drm/msm/ocmem/ocmem.c | 399 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/ocmem/ocmem.h | 46 ++++ 7 files changed, 463 insertions(+), 28 deletions(-) create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.c create mode 100644 drivers/gpu/drm/msm/ocmem/ocmem.h
<snip>
-- regards, Stan
On 09/30/2015 02:45 PM, Rob Clark wrote:
On Wed, Sep 30, 2015 at 7:31 AM, Rob Clark robdclark@gmail.com wrote:
On Wed, Sep 30, 2015 at 3:51 AM, Stanimir Varbanov stanimir.varbanov@linaro.org wrote:
Hi Rob,
Thanks for your work.
On 09/29/2015 10:48 PM, Rob Clark wrote:
For now, since the GPU is the only upstream consumer, just stuff this into drm/msm. Eventually if we have other consumers, we'll have to
As the video encoder/decoder driver (vidc) for apq8084 && msm8974 also use the ocmem for scratch buffers, it might be better to relocate the ocmem driver in drivers/soc/qcom from the beginning?
I wasn't really sure how soon vidc would support 8084/8974 (I assume first target is 8916 which fortunately doesn't have ocmem), or if it
My expectations are that the same driver will work on apq8084, as well.
was mandatory or just power optimization.. but yes, the plan was to move it somewhere else (not sure quite where, drivers/doc/qcom?) sometime.. Preferably when someone who understands all the other ocmem use-cases better could figure out what we really need to add to the driver.
In downstream driver there is a lot of complexity that appears to be in order to allow two clients to each allocate a portion of a macro within a region (ie. aggregate_macro_state(), apply_macro_vote(), etc), and I wanted to figure out if that is even a valid use-case before trying to make ocmem something that could actually support multiple clients.
There is also some complexity about ensuring that if clients aren't split up on region boundaries, that you don't have one client in region asking for wide-mode and other for narrow-mode.. (switch_region_mode()) but maybe we could handle that by just allocating wide from bottom and narrow from top. Also seems to be some craziness for allowing one client to pre-empt/evict another.. a dm engine, etc, etc..
All I know is gpu just statically allocates one big region aligned chunk of ocmem, so I ignored the rest of the crazy (maybe or maybe not hypothetical) use-cases for now...
OK, I will try to sort out ocmem use cases for vidc driver.
btw, I should add that I don't mind adding it in drivers/soc/qcom (or somewhere else?) to start with if others prefer, I just didn't want to give the wrong impression that it is ready yet for multiple clients.
I see. Then to avoid confusions you could remove all clients and keep only graphics from ocmem_client enum.
All I know is the gpu uses it statically and is pretty much useless without ocmem, so for lack of understanding of the other use cases I just tried to add simply what the gpu needs..
Got it now, thanks.
On 10/01, Stanimir Varbanov wrote:
On 09/30/2015 02:45 PM, Rob Clark wrote:
On Wed, Sep 30, 2015 at 7:31 AM, Rob Clark robdclark@gmail.com wrote:
On Wed, Sep 30, 2015 at 3:51 AM, Stanimir Varbanov stanimir.varbanov@linaro.org wrote:
On 09/29/2015 10:48 PM, Rob Clark wrote:
was mandatory or just power optimization.. but yes, the plan was to move it somewhere else (not sure quite where, drivers/doc/qcom?) sometime.. Preferably when someone who understands all the other ocmem use-cases better could figure out what we really need to add to the driver.
In downstream driver there is a lot of complexity that appears to be in order to allow two clients to each allocate a portion of a macro within a region (ie. aggregate_macro_state(), apply_macro_vote(), etc), and I wanted to figure out if that is even a valid use-case before trying to make ocmem something that could actually support multiple clients.
There is also some complexity about ensuring that if clients aren't split up on region boundaries, that you don't have one client in region asking for wide-mode and other for narrow-mode.. (switch_region_mode()) but maybe we could handle that by just allocating wide from bottom and narrow from top. Also seems to be some craziness for allowing one client to pre-empt/evict another.. a dm engine, etc, etc..
All I know is gpu just statically allocates one big region aligned chunk of ocmem, so I ignored the rest of the crazy (maybe or maybe not hypothetical) use-cases for now...
OK, I will try to sort out ocmem use cases for vidc driver.
The simplest thing to do is to split the memory between GPU and vidc statically. The other use cases with preemption and eviction and DMA add a lot of complexity that we can explore at a later time if need be.
On Thu, Oct 1, 2015 at 2:00 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 10/01, Stanimir Varbanov wrote:
On 09/30/2015 02:45 PM, Rob Clark wrote:
On Wed, Sep 30, 2015 at 7:31 AM, Rob Clark robdclark@gmail.com wrote:
On Wed, Sep 30, 2015 at 3:51 AM, Stanimir Varbanov stanimir.varbanov@linaro.org wrote:
On 09/29/2015 10:48 PM, Rob Clark wrote:
was mandatory or just power optimization.. but yes, the plan was to move it somewhere else (not sure quite where, drivers/doc/qcom?) sometime.. Preferably when someone who understands all the other ocmem use-cases better could figure out what we really need to add to the driver.
In downstream driver there is a lot of complexity that appears to be in order to allow two clients to each allocate a portion of a macro within a region (ie. aggregate_macro_state(), apply_macro_vote(), etc), and I wanted to figure out if that is even a valid use-case before trying to make ocmem something that could actually support multiple clients.
There is also some complexity about ensuring that if clients aren't split up on region boundaries, that you don't have one client in region asking for wide-mode and other for narrow-mode.. (switch_region_mode()) but maybe we could handle that by just allocating wide from bottom and narrow from top. Also seems to be some craziness for allowing one client to pre-empt/evict another.. a dm engine, etc, etc..
All I know is gpu just statically allocates one big region aligned chunk of ocmem, so I ignored the rest of the crazy (maybe or maybe not hypothetical) use-cases for now...
OK, I will try to sort out ocmem use cases for vidc driver.
The simplest thing to do is to split the memory between GPU and vidc statically. The other use cases with preemption and eviction and DMA add a lot of complexity that we can explore at a later time if need be.
true, as long as one of the clients is the static gpu client, I guess we could reasonably easily support up to two clients reasonably easily...
BR, -R
-- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
On Thu, Oct 1, 2015 at 3:25 PM, Rob Clark robdclark@gmail.com wrote:
On Thu, Oct 1, 2015 at 2:00 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 10/01, Stanimir Varbanov wrote:
On 09/30/2015 02:45 PM, Rob Clark wrote:
On Wed, Sep 30, 2015 at 7:31 AM, Rob Clark robdclark@gmail.com wrote:
On Wed, Sep 30, 2015 at 3:51 AM, Stanimir Varbanov stanimir.varbanov@linaro.org wrote:
On 09/29/2015 10:48 PM, Rob Clark wrote:
was mandatory or just power optimization.. but yes, the plan was to move it somewhere else (not sure quite where, drivers/doc/qcom?) sometime.. Preferably when someone who understands all the other ocmem use-cases better could figure out what we really need to add to the driver.
In downstream driver there is a lot of complexity that appears to be in order to allow two clients to each allocate a portion of a macro within a region (ie. aggregate_macro_state(), apply_macro_vote(), etc), and I wanted to figure out if that is even a valid use-case before trying to make ocmem something that could actually support multiple clients.
There is also some complexity about ensuring that if clients aren't split up on region boundaries, that you don't have one client in region asking for wide-mode and other for narrow-mode.. (switch_region_mode()) but maybe we could handle that by just allocating wide from bottom and narrow from top. Also seems to be some craziness for allowing one client to pre-empt/evict another.. a dm engine, etc, etc..
All I know is gpu just statically allocates one big region aligned chunk of ocmem, so I ignored the rest of the crazy (maybe or maybe not hypothetical) use-cases for now...
OK, I will try to sort out ocmem use cases for vidc driver.
The simplest thing to do is to split the memory between GPU and vidc statically. The other use cases with preemption and eviction and DMA add a lot of complexity that we can explore at a later time if need be.
true, as long as one of the clients is the static gpu client, I guess we could reasonably easily support up to two clients reasonably easily...
btw, random thought.. drm_mm is a utility in drm that serves a similar function to genalloc for graphics drivers to manage their address space(s) (used for everything from mmap virtual address space of buffers allocated against device to managing vram and gart allocations, etc... when vram carveout is used w/ drm/msm (due to no iommu) I use it to manage allocations from the carveout). It has some potentially convenient twists, like supporting allocation from top of the "address space" instead of bottom. I'm thinking in particular of allocating "narrow mode" allocations from top and "wide mode" from bottom since wide vs narrow can only be set per region and not per macro within the region. (It can also search by first-fit or best-fit.. although not sure if that is useful to us, since OCMEM size is relatively constrained.)
Not that I really want to keep ocmem allocator in drm.. I'd really rather it be someone else's headache once it gets to implementing the crazy stuff for all the random use-cases of other OCMEM users, since gpu's use of OCMEM is rather simple/static..
The way downstream driver does this is with a bunch of extra bookkeeping on top of genalloc so it can do a dummy allocation to force "from the top" allocation (and then immediately freeing the dummy allocation).. Maybe it just makes sense to teach genalloc how to do from-top vs from-bottom allocations? Not really sure..
BR, -R
On 10/01, Rob Clark wrote:
On Thu, Oct 1, 2015 at 3:25 PM, Rob Clark robdclark@gmail.com wrote:
On Thu, Oct 1, 2015 at 2:00 PM, Stephen Boyd sboyd@codeaurora.org wrote:
The simplest thing to do is to split the memory between GPU and vidc statically. The other use cases with preemption and eviction and DMA add a lot of complexity that we can explore at a later time if need be.
true, as long as one of the clients is the static gpu client, I guess we could reasonably easily support up to two clients reasonably easily...
btw, random thought.. drm_mm is a utility in drm that serves a similar function to genalloc for graphics drivers to manage their address space(s) (used for everything from mmap virtual address space of buffers allocated against device to managing vram and gart allocations, etc... when vram carveout is used w/ drm/msm (due to no iommu) I use it to manage allocations from the carveout). It has some potentially convenient twists, like supporting allocation from top of the "address space" instead of bottom. I'm thinking in particular of allocating "narrow mode" allocations from top and "wide mode" from bottom since wide vs narrow can only be set per region and not per macro within the region. (It can also search by first-fit or best-fit.. although not sure if that is useful to us, since OCMEM size is relatively constrained.)
Not that I really want to keep ocmem allocator in drm.. I'd really rather it be someone else's headache once it gets to implementing the crazy stuff for all the random use-cases of other OCMEM users, since gpu's use of OCMEM is rather simple/static..
The way downstream driver does this is with a bunch of extra bookkeeping on top of genalloc so it can do a dummy allocation to force "from the top" allocation (and then immediately freeing the dummy allocation).. Maybe it just makes sense to teach genalloc how to do from-top vs from-bottom allocations? Not really sure..
It looks like video and GPU both use wide mode, if I'm reading the code correctly. So it seems that we don't need to do anything special for allocations, just hand the GPU and vidc a chunk of the memory in wide mode and then let the GPU and vidc drivers manage buffers within their chunk however they see fit.
One pitfall is going to be power management. ocmem is closely tied to the GPU power domains, so when video is using its chunk of memory we're going to need to keep ocmem powered up even if the GPU is off. I suppose for now we can just leave it always powered on once the driver probes, but if we ever want to turn it off we're going to need some tracking mechanism to make sure we don't turn it off when buffers are in use.
On Thu, Oct 1, 2015 at 8:59 PM, Stephen Boyd sboyd@codeaurora.org wrote:
On 10/01, Rob Clark wrote:
On Thu, Oct 1, 2015 at 3:25 PM, Rob Clark robdclark@gmail.com wrote:
On Thu, Oct 1, 2015 at 2:00 PM, Stephen Boyd sboyd@codeaurora.org wrote:
The simplest thing to do is to split the memory between GPU and vidc statically. The other use cases with preemption and eviction and DMA add a lot of complexity that we can explore at a later time if need be.
true, as long as one of the clients is the static gpu client, I guess we could reasonably easily support up to two clients reasonably easily...
btw, random thought.. drm_mm is a utility in drm that serves a similar function to genalloc for graphics drivers to manage their address space(s) (used for everything from mmap virtual address space of buffers allocated against device to managing vram and gart allocations, etc... when vram carveout is used w/ drm/msm (due to no iommu) I use it to manage allocations from the carveout). It has some potentially convenient twists, like supporting allocation from top of the "address space" instead of bottom. I'm thinking in particular of allocating "narrow mode" allocations from top and "wide mode" from bottom since wide vs narrow can only be set per region and not per macro within the region. (It can also search by first-fit or best-fit.. although not sure if that is useful to us, since OCMEM size is relatively constrained.)
Not that I really want to keep ocmem allocator in drm.. I'd really rather it be someone else's headache once it gets to implementing the crazy stuff for all the random use-cases of other OCMEM users, since gpu's use of OCMEM is rather simple/static..
The way downstream driver does this is with a bunch of extra bookkeeping on top of genalloc so it can do a dummy allocation to force "from the top" allocation (and then immediately freeing the dummy allocation).. Maybe it just makes sense to teach genalloc how to do from-top vs from-bottom allocations? Not really sure..
It looks like video and GPU both use wide mode, if I'm reading the code correctly. So it seems that we don't need to do anything special for allocations, just hand the GPU and vidc a chunk of the memory in wide mode and then let the GPU and vidc drivers manage buffers within their chunk however they see fit.
right, I think it is just audio that uses narrow-mode.. and at that point I think we need to use rpm for configuring things, since I guess audio wants to do some of that from dsp for low-power audio playback type use-cases?? Maybe we can ignore this for a while.. although when we get to the point of fixing it, spiffing out genalloc sounds more interesting than layering a bunch of bookkeeping on top of genalloc..
One pitfall is going to be power management. ocmem is closely tied to the GPU power domains, so when video is using its chunk of memory we're going to need to keep ocmem powered up even if the GPU is off. I suppose for now we can just leave it always powered on once the driver probes, but if we ever want to turn it off we're going to need some tracking mechanism to make sure we don't turn it off when buffers are in use.
part of the problem that right now drm/msm is going to hold onto it's allocation even when it clks down gpu. I suppose not terribly difficult to fix (although one reason why I didn't bother making things terribly dynamic w/ clk mgmt or macro mode state in current ocmem patch).. at this point I'm still more at the 'just try to make it work in the first place' stage, rather than worrying too much about optimizing for power..
BR, -R
dri-devel@lists.freedesktop.org