Merge "disp: msm: sde: add explicit sub-driver mappings for TVM"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
2bd58a2e46
@@ -107,6 +107,7 @@ int msm_dss_get_io_mem(struct platform_device *pdev,
|
|||||||
void msm_dss_clean_io_mem(struct list_head *mem_list);
|
void msm_dss_clean_io_mem(struct list_head *mem_list);
|
||||||
int msm_dss_get_pmic_io_mem(struct platform_device *pdev,
|
int msm_dss_get_pmic_io_mem(struct platform_device *pdev,
|
||||||
struct list_head *mem_list);
|
struct list_head *mem_list);
|
||||||
|
int msm_dss_get_gpio_io_mem(const int gpio_pin, struct list_head *mem_list);
|
||||||
int msm_dss_get_io_irq(struct platform_device *pdev,
|
int msm_dss_get_io_irq(struct platform_device *pdev,
|
||||||
struct list_head *irq_list, u32 label);
|
struct list_head *irq_list, u32 label);
|
||||||
void msm_dss_clean_io_irq(struct list_head *irq_list);
|
void msm_dss_clean_io_irq(struct list_head *irq_list);
|
||||||
|
@@ -1660,9 +1660,10 @@ static ssize_t debugfs_esd_trigger_check(struct file *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (display->esd_trigger) {
|
if (display->esd_trigger) {
|
||||||
|
struct dsi_panel *panel = display->panel;
|
||||||
|
|
||||||
DSI_INFO("ESD attack triggered by user\n");
|
DSI_INFO("ESD attack triggered by user\n");
|
||||||
rc = dsi_panel_trigger_esd_attack(display->panel,
|
rc = panel->panel_ops.trigger_esd_attack(panel);
|
||||||
display->trusted_vm_env);
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
DSI_ERR("Failed to trigger ESD attack\n");
|
DSI_ERR("Failed to trigger ESD attack\n");
|
||||||
goto error;
|
goto error;
|
||||||
@@ -5442,22 +5443,49 @@ static int dsi_display_get_io_resources(struct msm_io_res *io_res, void *data)
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct dsi_display *display;
|
struct dsi_display *display;
|
||||||
|
struct platform_device *pdev;
|
||||||
|
int te_gpio, avdd_gpio;
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
display = (struct dsi_display *)data;
|
||||||
|
|
||||||
|
pdev = display->pdev;
|
||||||
|
if (!pdev)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
rc = dsi_ctrl_get_io_resources(io_res);
|
rc = dsi_ctrl_get_io_resources(io_res);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto end;
|
return rc;
|
||||||
|
|
||||||
rc = dsi_phy_get_io_resources(io_res);
|
rc = dsi_phy_get_io_resources(io_res);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto end;
|
return rc;
|
||||||
|
|
||||||
display = (struct dsi_display *)data;
|
|
||||||
rc = dsi_panel_get_io_resources(display->panel, io_res);
|
rc = dsi_panel_get_io_resources(display->panel, io_res);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
te_gpio = of_get_named_gpio(pdev->dev.of_node, "qcom,platform-te-gpio", 0);
|
||||||
|
if (gpio_is_valid(te_gpio)) {
|
||||||
|
rc = msm_dss_get_gpio_io_mem(te_gpio, &io_res->mem);
|
||||||
|
if (rc) {
|
||||||
|
DSI_ERR("[%s] failed to retrieve the te gpio address\n",
|
||||||
|
display->panel->name);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
avdd_gpio = of_get_named_gpio(pdev->dev.of_node,
|
||||||
|
"qcom,avdd-regulator-gpio", 0);
|
||||||
|
if (gpio_is_valid(avdd_gpio)) {
|
||||||
|
rc = msm_dss_get_gpio_io_mem(avdd_gpio, &io_res->mem);
|
||||||
|
if (rc)
|
||||||
|
DSI_ERR("[%s] failed to retrieve the avdd gpio address\n",
|
||||||
|
display->panel->name);
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -193,47 +193,14 @@ static int dsi_panel_gpio_release(struct dsi_panel *panel)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dsi_panel_trigger_esd_attack(struct dsi_panel *panel, bool trusted_vm_env)
|
static int dsi_panel_trigger_esd_attack_sub(int reset_gpio)
|
||||||
{
|
{
|
||||||
if (!panel) {
|
if (!gpio_is_valid(reset_gpio)) {
|
||||||
DSI_ERR("Invalid panel param\n");
|
DSI_INFO("failed to pull down the reset gpio\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* toggle reset-gpio by writing directly to register in trusted-vm */
|
gpio_set_value(reset_gpio, 0);
|
||||||
if (trusted_vm_env) {
|
|
||||||
struct dsi_tlmm_gpio *gpio = NULL;
|
|
||||||
void __iomem *io;
|
|
||||||
u32 offset = 0x4;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < panel->tlmm_gpio_count; i++)
|
|
||||||
if (!strcmp(panel->tlmm_gpio[i].name, "reset-gpio"))
|
|
||||||
gpio = &panel->tlmm_gpio[i];
|
|
||||||
|
|
||||||
if (!gpio) {
|
|
||||||
DSI_ERR("reset gpio not found\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
io = ioremap(gpio->addr, gpio->size);
|
|
||||||
writel_relaxed(0, io + offset);
|
|
||||||
iounmap(io);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
struct dsi_panel_reset_config *r_config = &panel->reset_config;
|
|
||||||
|
|
||||||
if (!r_config) {
|
|
||||||
DSI_ERR("Invalid panel reset configuration\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gpio_is_valid(r_config->reset_gpio)) {
|
|
||||||
DSI_ERR("failed to pull down gpio\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
gpio_set_value(r_config->reset_gpio, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDE_EVT32(SDE_EVTLOG_FUNC_CASE1);
|
SDE_EVT32(SDE_EVTLOG_FUNC_CASE1);
|
||||||
DSI_INFO("GPIO pulled low to simulate ESD\n");
|
DSI_INFO("GPIO pulled low to simulate ESD\n");
|
||||||
@@ -241,6 +208,50 @@ int dsi_panel_trigger_esd_attack(struct dsi_panel *panel, bool trusted_vm_env)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dsi_panel_vm_trigger_esd_attack(struct dsi_panel *panel)
|
||||||
|
{
|
||||||
|
struct dsi_parser_utils *utils = &panel->utils;
|
||||||
|
int reset_gpio;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
reset_gpio = utils->get_named_gpio(utils->data,
|
||||||
|
"qcom,platform-reset-gpio", 0);
|
||||||
|
if (!gpio_is_valid(reset_gpio)) {
|
||||||
|
DSI_ERR("[%s] reset gpio not provided\n", panel->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = gpio_request(reset_gpio, "reset_gpio");
|
||||||
|
if (rc) {
|
||||||
|
DSI_ERR("request for reset_gpio failed, rc=%d\n", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = dsi_panel_trigger_esd_attack_sub(reset_gpio);
|
||||||
|
|
||||||
|
gpio_free(reset_gpio);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsi_panel_trigger_esd_attack(struct dsi_panel *panel)
|
||||||
|
{
|
||||||
|
struct dsi_panel_reset_config *r_config;
|
||||||
|
|
||||||
|
if (!panel) {
|
||||||
|
DSI_ERR("Invalid panel param\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
r_config = &panel->reset_config;
|
||||||
|
if (!r_config) {
|
||||||
|
DSI_ERR("Invalid panel reset configuration\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dsi_panel_trigger_esd_attack_sub(r_config->reset_gpio);
|
||||||
|
}
|
||||||
|
|
||||||
static int dsi_panel_reset(struct dsi_panel *panel)
|
static int dsi_panel_reset(struct dsi_panel *panel)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -2208,34 +2219,21 @@ error:
|
|||||||
int dsi_panel_get_io_resources(struct dsi_panel *panel,
|
int dsi_panel_get_io_resources(struct dsi_panel *panel,
|
||||||
struct msm_io_res *io_res)
|
struct msm_io_res *io_res)
|
||||||
{
|
{
|
||||||
struct list_head temp_head;
|
struct dsi_parser_utils *utils = &panel->utils;
|
||||||
struct msm_io_mem_entry *io_mem, *pos, *tmp;
|
|
||||||
struct list_head *mem_list = &io_res->mem;
|
struct list_head *mem_list = &io_res->mem;
|
||||||
int i, rc = 0;
|
int reset_gpio;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&temp_head);
|
reset_gpio = utils->get_named_gpio(utils->data,
|
||||||
|
"qcom,platform-reset-gpio", 0);
|
||||||
for (i = 0; i < panel->tlmm_gpio_count; i++) {
|
if (gpio_is_valid(reset_gpio)) {
|
||||||
io_mem = kzalloc(sizeof(*io_mem), GFP_KERNEL);
|
rc = msm_dss_get_gpio_io_mem(reset_gpio, mem_list);
|
||||||
if (!io_mem) {
|
if (rc) {
|
||||||
rc = -ENOMEM;
|
DSI_ERR("[%s] failed to retrieve the reset gpio address\n", panel->name);
|
||||||
goto parse_fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
io_mem->base = panel->tlmm_gpio[i].addr;
|
|
||||||
io_mem->size = panel->tlmm_gpio[i].size;
|
|
||||||
|
|
||||||
list_add(&io_mem->list, &temp_head);
|
|
||||||
}
|
|
||||||
|
|
||||||
list_splice(&temp_head, mem_list);
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
parse_fail:
|
|
||||||
list_for_each_entry_safe(pos, tmp, &temp_head, list) {
|
|
||||||
list_del(&pos->list);
|
|
||||||
kfree(pos);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2324,54 +2322,6 @@ error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsi_panel_parse_tlmm_gpio(struct dsi_panel *panel)
|
|
||||||
{
|
|
||||||
struct dsi_parser_utils *utils = &panel->utils;
|
|
||||||
u32 base, size, pin;
|
|
||||||
int pin_count, address_count, name_count, i;
|
|
||||||
|
|
||||||
address_count = utils->count_u32_elems(utils->data,
|
|
||||||
"qcom,dsi-panel-gpio-address");
|
|
||||||
if (address_count != 2) {
|
|
||||||
DSI_DEBUG("panel gpio address not defined\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
utils->read_u32_index(utils->data,
|
|
||||||
"qcom,dsi-panel-gpio-address", 0, &base);
|
|
||||||
utils->read_u32_index(utils->data,
|
|
||||||
"qcom,dsi-panel-gpio-address", 1, &size);
|
|
||||||
|
|
||||||
pin_count = utils->count_u32_elems(utils->data,
|
|
||||||
"qcom,dsi-panel-gpio-pins");
|
|
||||||
name_count = utils->count_strings(utils->data,
|
|
||||||
"qcom,dsi-panel-gpio-names");
|
|
||||||
if ((pin_count < 0) || (name_count < 0) || (pin_count != name_count)) {
|
|
||||||
DSI_ERR("invalid gpio pins/names\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
panel->tlmm_gpio = kcalloc(pin_count,
|
|
||||||
sizeof(struct dsi_tlmm_gpio), GFP_KERNEL);
|
|
||||||
if (!panel->tlmm_gpio)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
panel->tlmm_gpio_count = pin_count;
|
|
||||||
for (i = 0; i < pin_count; i++) {
|
|
||||||
utils->read_u32_index(utils->data,
|
|
||||||
"qcom,dsi-panel-gpio-pins", i, &pin);
|
|
||||||
panel->tlmm_gpio[i].num = pin;
|
|
||||||
panel->tlmm_gpio[i].addr = base + (pin * size);
|
|
||||||
panel->tlmm_gpio[i].size = size;
|
|
||||||
|
|
||||||
utils->read_string_index(utils->data,
|
|
||||||
"qcom,dsi-panel-gpio-names", i,
|
|
||||||
&(panel->tlmm_gpio[i].name));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dsi_panel_parse_bl_pwm_config(struct dsi_panel *panel)
|
static int dsi_panel_parse_bl_pwm_config(struct dsi_panel *panel)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
@@ -3487,6 +3437,7 @@ static void dsi_panel_setup_vm_ops(struct dsi_panel *panel, bool trusted_vm_env)
|
|||||||
panel->panel_ops.bl_unregister = dsi_panel_vm_stub;
|
panel->panel_ops.bl_unregister = dsi_panel_vm_stub;
|
||||||
panel->panel_ops.parse_gpios = dsi_panel_vm_stub;
|
panel->panel_ops.parse_gpios = dsi_panel_vm_stub;
|
||||||
panel->panel_ops.parse_power_cfg = dsi_panel_vm_stub;
|
panel->panel_ops.parse_power_cfg = dsi_panel_vm_stub;
|
||||||
|
panel->panel_ops.trigger_esd_attack = dsi_panel_vm_trigger_esd_attack;
|
||||||
} else {
|
} else {
|
||||||
panel->panel_ops.pinctrl_init = dsi_panel_pinctrl_init;
|
panel->panel_ops.pinctrl_init = dsi_panel_pinctrl_init;
|
||||||
panel->panel_ops.gpio_request = dsi_panel_gpio_request;
|
panel->panel_ops.gpio_request = dsi_panel_gpio_request;
|
||||||
@@ -3496,6 +3447,7 @@ static void dsi_panel_setup_vm_ops(struct dsi_panel *panel, bool trusted_vm_env)
|
|||||||
panel->panel_ops.bl_unregister = dsi_panel_bl_unregister;
|
panel->panel_ops.bl_unregister = dsi_panel_bl_unregister;
|
||||||
panel->panel_ops.parse_gpios = dsi_panel_parse_gpios;
|
panel->panel_ops.parse_gpios = dsi_panel_parse_gpios;
|
||||||
panel->panel_ops.parse_power_cfg = dsi_panel_parse_power_cfg;
|
panel->panel_ops.parse_power_cfg = dsi_panel_parse_power_cfg;
|
||||||
|
panel->panel_ops.trigger_esd_attack = dsi_panel_trigger_esd_attack;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3580,12 +3532,6 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = dsi_panel_parse_tlmm_gpio(panel);
|
|
||||||
if (rc) {
|
|
||||||
DSI_ERR("failed to parse panel tlmm gpios, rc=%d\n", rc);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = panel->panel_ops.parse_power_cfg(panel);
|
rc = panel->panel_ops.parse_power_cfg(panel);
|
||||||
if (rc)
|
if (rc)
|
||||||
DSI_ERR("failed to parse power config, rc=%d\n", rc);
|
DSI_ERR("failed to parse power config, rc=%d\n", rc);
|
||||||
@@ -3741,7 +3687,6 @@ int dsi_panel_drv_deinit(struct dsi_panel *panel)
|
|||||||
if (rc)
|
if (rc)
|
||||||
DSI_ERR("[%s] failed to put regs, rc=%d\n", panel->name, rc);
|
DSI_ERR("[%s] failed to put regs, rc=%d\n", panel->name, rc);
|
||||||
|
|
||||||
kfree(panel->tlmm_gpio);
|
|
||||||
panel->host = NULL;
|
panel->host = NULL;
|
||||||
memset(&panel->mipi_device, 0x0, sizeof(panel->mipi_device));
|
memset(&panel->mipi_device, 0x0, sizeof(panel->mipi_device));
|
||||||
|
|
||||||
|
@@ -191,13 +191,6 @@ struct dsi_panel_spr_info {
|
|||||||
enum msm_display_spr_pack_type pack_type;
|
enum msm_display_spr_pack_type pack_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dsi_tlmm_gpio {
|
|
||||||
u32 num;
|
|
||||||
u32 addr;
|
|
||||||
u32 size;
|
|
||||||
const char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dsi_panel;
|
struct dsi_panel;
|
||||||
|
|
||||||
struct dsi_panel_ops {
|
struct dsi_panel_ops {
|
||||||
@@ -209,6 +202,7 @@ struct dsi_panel_ops {
|
|||||||
int (*bl_unregister)(struct dsi_panel *panel);
|
int (*bl_unregister)(struct dsi_panel *panel);
|
||||||
int (*parse_gpios)(struct dsi_panel *panel);
|
int (*parse_gpios)(struct dsi_panel *panel);
|
||||||
int (*parse_power_cfg)(struct dsi_panel *panel);
|
int (*parse_power_cfg)(struct dsi_panel *panel);
|
||||||
|
int (*trigger_esd_attack)(struct dsi_panel *panel);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dsi_panel {
|
struct dsi_panel {
|
||||||
@@ -272,9 +266,6 @@ struct dsi_panel {
|
|||||||
int power_mode;
|
int power_mode;
|
||||||
enum dsi_panel_physical_type panel_type;
|
enum dsi_panel_physical_type panel_type;
|
||||||
|
|
||||||
struct dsi_tlmm_gpio *tlmm_gpio;
|
|
||||||
u32 tlmm_gpio_count;
|
|
||||||
|
|
||||||
struct dsi_panel_ops panel_ops;
|
struct dsi_panel_ops panel_ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -310,8 +301,6 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
|
|||||||
int topology_override,
|
int topology_override,
|
||||||
bool trusted_vm_env);
|
bool trusted_vm_env);
|
||||||
|
|
||||||
int dsi_panel_trigger_esd_attack(struct dsi_panel *panel, bool trusted_vm_env);
|
|
||||||
|
|
||||||
void dsi_panel_put(struct dsi_panel *panel);
|
void dsi_panel_put(struct dsi_panel *panel);
|
||||||
|
|
||||||
int dsi_panel_drv_init(struct dsi_panel *panel, struct mipi_dsi_host *host);
|
int dsi_panel_drv_init(struct dsi_panel *panel, struct mipi_dsi_host *host);
|
||||||
|
@@ -210,6 +210,7 @@ enum sde_prop {
|
|||||||
BASE_LAYER,
|
BASE_LAYER,
|
||||||
TRUSTED_VM_ENV,
|
TRUSTED_VM_ENV,
|
||||||
MAX_TRUSTED_VM_DISPLAYS,
|
MAX_TRUSTED_VM_DISPLAYS,
|
||||||
|
TVM_INCLUDE_REG,
|
||||||
SDE_PROP_MAX,
|
SDE_PROP_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -598,6 +599,7 @@ static struct sde_prop_type sde_prop[] = {
|
|||||||
{TRUSTED_VM_ENV, "qcom,sde-trusted-vm-env", false, PROP_TYPE_BOOL},
|
{TRUSTED_VM_ENV, "qcom,sde-trusted-vm-env", false, PROP_TYPE_BOOL},
|
||||||
{MAX_TRUSTED_VM_DISPLAYS, "qcom,sde-max-trusted-vm-displays", false,
|
{MAX_TRUSTED_VM_DISPLAYS, "qcom,sde-max-trusted-vm-displays", false,
|
||||||
PROP_TYPE_U32},
|
PROP_TYPE_U32},
|
||||||
|
{TVM_INCLUDE_REG, "qcom,tvm-include-reg", false, PROP_TYPE_U32_ARRAY},
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sde_prop_type sde_perf_prop[] = {
|
static struct sde_prop_type sde_perf_prop[] = {
|
||||||
@@ -3965,6 +3967,16 @@ static void _sde_top_parse_dt_helper(struct sde_mdss_cfg *cfg,
|
|||||||
0);
|
0);
|
||||||
cfg->max_trusted_vm_displays = PROP_VALUE_ACCESS(props->values,
|
cfg->max_trusted_vm_displays = PROP_VALUE_ACCESS(props->values,
|
||||||
MAX_TRUSTED_VM_DISPLAYS, 0);
|
MAX_TRUSTED_VM_DISPLAYS, 0);
|
||||||
|
if (props->exists[TVM_INCLUDE_REG]) {
|
||||||
|
cfg->tvm_reg_count = props->counts[TVM_INCLUDE_REG] / 2;
|
||||||
|
for (i = 0; i < cfg->tvm_reg_count; i++) {
|
||||||
|
cfg->tvm_reg[i].start = PROP_VALUE_ACCESS(props->values,
|
||||||
|
TVM_INCLUDE_REG, i * 2);
|
||||||
|
cfg->tvm_reg[i].end = cfg->tvm_reg[i].start +
|
||||||
|
PROP_VALUE_ACCESS(props->values, TVM_INCLUDE_REG,
|
||||||
|
i * 2 + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
|
static int sde_top_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg)
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
* based on current design
|
* based on current design
|
||||||
*/
|
*/
|
||||||
#define MAX_BLOCKS 12
|
#define MAX_BLOCKS 12
|
||||||
|
#define MAX_REG_SIZE_ENTRIES 14
|
||||||
|
|
||||||
#define SDE_HW_VER(MAJOR, MINOR, STEP) ((u32)((MAJOR & 0xF) << 28) |\
|
#define SDE_HW_VER(MAJOR, MINOR, STEP) ((u32)((MAJOR & 0xF) << 28) |\
|
||||||
((MINOR & 0xFFF) << 16) |\
|
((MINOR & 0xFFF) << 16) |\
|
||||||
@@ -1472,6 +1473,10 @@ struct sde_perf_cfg {
|
|||||||
* the trusted VM. false, otherwise.
|
* the trusted VM. false, otherwise.
|
||||||
* @max_trusted_vm_displays maximum number of concurrent trusted
|
* @max_trusted_vm_displays maximum number of concurrent trusted
|
||||||
* vm displays supported.
|
* vm displays supported.
|
||||||
|
* @tvm_reg_count number of sub-driver register ranges that need to be included
|
||||||
|
* for trusted vm for accepting the resources
|
||||||
|
* @tvm_reg array of sub-driver register ranges entries that need to be
|
||||||
|
* included
|
||||||
* @max_sspp_linewidth max source pipe line width support.
|
* @max_sspp_linewidth max source pipe line width support.
|
||||||
* @vig_sspp_linewidth max vig source pipe line width support.
|
* @vig_sspp_linewidth max vig source pipe line width support.
|
||||||
* @scaling_linewidth max vig source pipe linewidth for scaling usecases
|
* @scaling_linewidth max vig source pipe linewidth for scaling usecases
|
||||||
@@ -1561,6 +1566,8 @@ struct sde_mdss_cfg {
|
|||||||
u32 hwversion;
|
u32 hwversion;
|
||||||
bool trusted_vm_env;
|
bool trusted_vm_env;
|
||||||
u32 max_trusted_vm_displays;
|
u32 max_trusted_vm_displays;
|
||||||
|
u32 tvm_reg_count;
|
||||||
|
struct resource tvm_reg[MAX_REG_SIZE_ENTRIES];
|
||||||
|
|
||||||
u32 max_sspp_linewidth;
|
u32 max_sspp_linewidth;
|
||||||
u32 vig_sspp_linewidth;
|
u32 vig_sspp_linewidth;
|
||||||
|
@@ -4583,6 +4583,38 @@ power_error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _sde_kms_get_tvm_inclusion_mem(struct sde_mdss_cfg *catalog, struct list_head *mem_list)
|
||||||
|
{
|
||||||
|
struct list_head temp_head;
|
||||||
|
struct msm_io_mem_entry *io_mem;
|
||||||
|
int rc, i = 0;
|
||||||
|
|
||||||
|
INIT_LIST_HEAD(&temp_head);
|
||||||
|
|
||||||
|
for (i = 0; i < catalog->tvm_reg_count; i++) {
|
||||||
|
struct resource *res = &catalog->tvm_reg[i];
|
||||||
|
|
||||||
|
io_mem = kzalloc(sizeof(struct msm_io_mem_entry), GFP_KERNEL);
|
||||||
|
if (!io_mem) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto parse_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_mem->base = res->start;
|
||||||
|
io_mem->size = resource_size(res);
|
||||||
|
|
||||||
|
list_add(&io_mem->list, &temp_head);
|
||||||
|
}
|
||||||
|
|
||||||
|
list_splice(&temp_head, mem_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
parse_fail:
|
||||||
|
msm_dss_clean_io_mem(&temp_head);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
int sde_kms_get_io_resources(struct sde_kms *sde_kms, struct msm_io_res *io_res)
|
int sde_kms_get_io_resources(struct sde_kms *sde_kms, struct msm_io_res *io_res)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = to_platform_device(sde_kms->dev->dev);
|
struct platform_device *pdev = to_platform_device(sde_kms->dev->dev);
|
||||||
@@ -4606,6 +4638,12 @@ int sde_kms_get_io_resources(struct sde_kms *sde_kms, struct msm_io_res *io_res)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = _sde_kms_get_tvm_inclusion_mem(sde_kms->catalog, &io_res->mem);
|
||||||
|
if (rc) {
|
||||||
|
SDE_ERROR("failed to get tvm inclusion mem ranges");
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/soc/qcom/spmi-pmic-arb.h>
|
#include <linux/soc/qcom/spmi-pmic-arb.h>
|
||||||
|
#include <linux/pinctrl/qcom-pinctrl.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/sde_io_util.h>
|
#include <linux/sde_io_util.h>
|
||||||
#include <linux/sde_vm_event.h>
|
#include <linux/sde_vm_event.h>
|
||||||
@@ -133,6 +134,40 @@ void msm_dss_iounmap(struct dss_io_data *io_data)
|
|||||||
} /* msm_dss_iounmap */
|
} /* msm_dss_iounmap */
|
||||||
EXPORT_SYMBOL(msm_dss_iounmap);
|
EXPORT_SYMBOL(msm_dss_iounmap);
|
||||||
|
|
||||||
|
int msm_dss_get_gpio_io_mem(const int gpio_pin, struct list_head *mem_list)
|
||||||
|
{
|
||||||
|
struct msm_io_mem_entry *io_mem;
|
||||||
|
struct resource res;
|
||||||
|
bool gpio_pin_status = false;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!gpio_is_valid(gpio_pin))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
io_mem = kzalloc(sizeof(struct msm_io_mem_entry), GFP_KERNEL);
|
||||||
|
if (!io_mem)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
gpio_pin_status = msm_gpio_get_pin_address(gpio_pin, &res);
|
||||||
|
if (!gpio_pin_status) {
|
||||||
|
rc = -ENODEV;
|
||||||
|
goto parse_fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
io_mem->base = res.start;
|
||||||
|
io_mem->size = resource_size(&res);
|
||||||
|
|
||||||
|
list_add(&io_mem->list, mem_list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
parse_fail:
|
||||||
|
kfree(io_mem);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(msm_dss_get_gpio_io_mem);
|
||||||
|
|
||||||
int msm_dss_get_pmic_io_mem(struct platform_device *pdev,
|
int msm_dss_get_pmic_io_mem(struct platform_device *pdev,
|
||||||
struct list_head *mem_list)
|
struct list_head *mem_list)
|
||||||
{
|
{
|
||||||
|
@@ -1597,6 +1597,28 @@ static void sde_rsc_deinit(struct platform_device *pdev,
|
|||||||
kfree(rsc);
|
kfree(rsc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sde_rsc_get_io_resources - collect register ranges for the device to
|
||||||
|
* perform access control on TUI transition
|
||||||
|
* @io_res: io resource list
|
||||||
|
* @data: payload data provided during msm_register_vm_event
|
||||||
|
* Returns: zero on success
|
||||||
|
*/
|
||||||
|
static int sde_rsc_get_io_resources(struct msm_io_res *io_res, void *data)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct sde_rsc_priv *rsc = (struct sde_rsc_priv *)data;
|
||||||
|
struct platform_device *pdev = to_platform_device(rsc->dev);
|
||||||
|
|
||||||
|
rc = msm_dss_get_io_mem(pdev, &io_res->mem);
|
||||||
|
if (rc) {
|
||||||
|
pr_err("failed to get rsc io mem, rc = %d\n", rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* sde_rsc_bind - bind rsc device with controlling device
|
* sde_rsc_bind - bind rsc device with controlling device
|
||||||
* @dev: Pointer to base of platform device
|
* @dev: Pointer to base of platform device
|
||||||
@@ -1611,6 +1633,9 @@ static int sde_rsc_bind(struct device *dev,
|
|||||||
struct sde_rsc_priv *rsc;
|
struct sde_rsc_priv *rsc;
|
||||||
struct drm_device *drm;
|
struct drm_device *drm;
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
struct msm_vm_ops vm_event_ops = {
|
||||||
|
.vm_get_io_resources = sde_rsc_get_io_resources,
|
||||||
|
};
|
||||||
|
|
||||||
if (!dev || !pdev || !master) {
|
if (!dev || !pdev || !master) {
|
||||||
pr_err("invalid param(s), dev %pK, pdev %pK, master %pK\n",
|
pr_err("invalid param(s), dev %pK, pdev %pK, master %pK\n",
|
||||||
@@ -1630,6 +1655,9 @@ static int sde_rsc_bind(struct device *dev,
|
|||||||
rsc->drv_io.len, msm_get_phys_addr(pdev, "drv"), SDE_DBG_RSC);
|
rsc->drv_io.len, msm_get_phys_addr(pdev, "drv"), SDE_DBG_RSC);
|
||||||
sde_dbg_reg_register_base(SDE_RSC_WRAPPER_DBG_NAME, rsc->wrapper_io.base,
|
sde_dbg_reg_register_base(SDE_RSC_WRAPPER_DBG_NAME, rsc->wrapper_io.base,
|
||||||
rsc->wrapper_io.len, msm_get_phys_addr(pdev, "wrapper"), SDE_DBG_RSC);
|
rsc->wrapper_io.len, msm_get_phys_addr(pdev, "wrapper"), SDE_DBG_RSC);
|
||||||
|
|
||||||
|
msm_register_vm_event(master, dev, &vm_event_ops, (void *)rsc);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1655,6 +1683,8 @@ static void sde_rsc_unbind(struct device *dev,
|
|||||||
pr_err("invalid display rsc\n");
|
pr_err("invalid display rsc\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msm_unregister_vm_event(master, dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct component_ops sde_rsc_comp_ops = {
|
static const struct component_ops sde_rsc_comp_ops = {
|
||||||
|
Reference in New Issue
Block a user