mirror of
https://github.com/revyos/thead-kernel.git
synced 2026-06-21 09:12:26 +02:00
Linux_SDK_V1.5.4
Signed-off-by: thead_admin <occ_thead@service.alibaba.com>
This commit is contained in:
@@ -3403,6 +3403,16 @@ static void clk_debug_unregister(struct clk_core *core)
|
||||
core->dentry = NULL;
|
||||
mutex_unlock(&clk_debug_lock);
|
||||
}
|
||||
static bool noclk_debug_init = false;
|
||||
|
||||
/* noclkdebug bootargs: for option not init ftrace*/
|
||||
static int __init noclk_debug_setup(char *str)
|
||||
{
|
||||
noclk_debug_init = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("noclkdebug", noclk_debug_setup);
|
||||
|
||||
/**
|
||||
* clk_debug_init - lazily populate the debugfs clk directory
|
||||
@@ -3417,6 +3427,8 @@ static int __init clk_debug_init(void)
|
||||
{
|
||||
struct clk_core *core;
|
||||
|
||||
if(noclk_debug_init)
|
||||
return 0;
|
||||
#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
|
||||
pr_warn("\n");
|
||||
pr_warn("********************************************************************\n");
|
||||
|
||||
@@ -430,7 +430,7 @@ static int light_clocks_probe(struct platform_device *pdev)
|
||||
clks[VISYS_AHB_HCLK] = thead_clk_light_divider("visys_ahb_hclk", "video_pll_foutvco", ap_base + 0x1d0, 0, 4, 4, MUX_TYPE_DIV, 6, 15);
|
||||
clks[VPSYS_APB_PCLK] = thead_clk_light_divider("vpsys_apb_pclk", "gmac_pll_fout1ph0", ap_base + 0x1e0, 0, 3, 4, MUX_TYPE_DIV, 2, 7);
|
||||
clks[VPSYS_AXI_ACLK] = thead_clk_light_divider("vpsys_axi_aclk", "video_pll_foutvco", ap_base + 0x1e0, 8, 4, 12, MUX_TYPE_DIV, 3, 15);
|
||||
clks[VENC_CCLK] = thead_clk_light_divider("venc_cclk", "gmac_pll_foutpostdiv", ap_base + 0x1e4, 0, 3, 4, MUX_TYPE_DIV, 2, 7);
|
||||
clks[VENC_CCLK] = thead_clk_light_divider_closest("venc_cclk", "gmac_pll_foutpostdiv", ap_base + 0x1e4, 0, 3, 4, MUX_TYPE_DIV, 2, 7);
|
||||
clks[DPU0_PLL_DIV_CLK] = thead_clk_light_divider("dpu0_pll_div_clk", "dpu0_pll_foutpostdiv", ap_base + 0x1e8, 0, 8, 8, MUX_TYPE_DIV, 2, 214);
|
||||
clks[DPU1_PLL_DIV_CLK] = thead_clk_light_divider("dpu1_pll_div_clk", "dpu1_pll_foutpostdiv", ap_base + 0x1ec, 0, 8, 8, MUX_TYPE_DIV, 2, 214);
|
||||
|
||||
|
||||
@@ -550,7 +550,12 @@ static int clk_lightdiv_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long flags = 0;
|
||||
u32 val;
|
||||
|
||||
divider = parent_rate / rate;
|
||||
/**
|
||||
* The clk-divider will calculate the node frequency by rounding up
|
||||
* based on the parent frequency and the target divider.
|
||||
* This calculation is to restore accurate frequency divider.
|
||||
*/
|
||||
divider = DIV64_U64_ROUND_CLOSEST(parent_rate, rate);
|
||||
|
||||
/* DIV is zero based divider, but CDE is not */
|
||||
if (light_div->div_type == MUX_TYPE_DIV)
|
||||
@@ -592,10 +597,10 @@ static const struct clk_ops clk_lightdiv_ops = {
|
||||
.set_rate = clk_lightdiv_set_rate,
|
||||
};
|
||||
|
||||
struct clk *thead_clk_light_divider(const char *name, const char *parent,
|
||||
static struct clk *thead_clk_light_divider_internal(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 sync, enum light_div_type div_type,
|
||||
u16 min, u16 max)
|
||||
u16 min, u16 max, bool closest)
|
||||
{
|
||||
struct clk_lightdiv *light_div;
|
||||
struct clk_hw *hw;
|
||||
@@ -622,6 +627,10 @@ struct clk *thead_clk_light_divider(const char *name, const char *parent,
|
||||
light_div->div_type = div_type;
|
||||
if (light_div->div_type == MUX_TYPE_DIV)
|
||||
light_div->divider.flags = CLK_DIVIDER_ONE_BASED;
|
||||
|
||||
if (closest)
|
||||
light_div->divider.flags |= CLK_DIVIDER_ROUND_CLOSEST;
|
||||
|
||||
light_div->min_div = min > ((1 << width) - 1) ?
|
||||
((1 << width) - 1) : min;
|
||||
light_div->max_div = max > ((1 << width) - 1) ?
|
||||
@@ -638,6 +647,24 @@ struct clk *thead_clk_light_divider(const char *name, const char *parent,
|
||||
return hw->clk;
|
||||
}
|
||||
|
||||
struct clk *thead_clk_light_divider(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 sync, enum light_div_type div_type,
|
||||
u16 min, u16 max)
|
||||
{
|
||||
return thead_clk_light_divider_internal(name, parent, reg, shift, width,
|
||||
sync, div_type, min, max, false);
|
||||
}
|
||||
|
||||
struct clk *thead_clk_light_divider_closest(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 sync, enum light_div_type div_type,
|
||||
u16 min, u16 max)
|
||||
{
|
||||
return thead_clk_light_divider_internal(name, parent, reg, shift, width,
|
||||
sync, div_type, min, max, true);
|
||||
}
|
||||
|
||||
static inline struct clk_lightgate *to_clk_lightgate(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gate *gate = to_clk_gate(hw);
|
||||
|
||||
@@ -90,6 +90,15 @@ struct clk *thead_clk_light_divider(const char *name, const char *parent,
|
||||
u8 sync, enum light_div_type div_type,
|
||||
u16 min, u16 max);
|
||||
|
||||
/**
|
||||
* By default, the clk framework calculates frequency by rounding downwards.
|
||||
* This function is to achieve closest frequency.
|
||||
*/
|
||||
struct clk *thead_clk_light_divider_closest(const char *name, const char *parent,
|
||||
void __iomem *reg, u8 shift, u8 width,
|
||||
u8 sync, enum light_div_type div_type,
|
||||
u16 min, u16 max);
|
||||
|
||||
void thead_unregister_clocks(struct clk *clks[], unsigned int count);
|
||||
|
||||
static inline struct clk *thead_clk_fixed(const char *name, unsigned long rate)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-$(CONFIG_LIGHT_AON) += light_aon.o light_aon_misc.o light_aon_test.o
|
||||
obj-$(CONFIG_LIGHT_AON_PD) += light_aon_pd.o
|
||||
obj-y += light_proc_debug.o
|
||||
|
||||
@@ -12,7 +12,12 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/light_proc_debug.h>
|
||||
#include <linux/firmware/thead/ipc.h>
|
||||
|
||||
/* wait for response for 3000ms instead of 300ms (fix me pls)*/
|
||||
#define MAX_RX_TIMEOUT (msecs_to_jiffies(3000))
|
||||
@@ -24,6 +29,12 @@ struct light_aon_chan {
|
||||
struct mbox_client cl;
|
||||
struct mbox_chan *ch;
|
||||
struct completion tx_done;
|
||||
/*for log proc*/
|
||||
phys_addr_t log_phy;
|
||||
size_t log_size;
|
||||
void __iomem *log_mem;
|
||||
void *log_ctrl;
|
||||
struct proc_dir_entry *proc_dir;
|
||||
};
|
||||
|
||||
struct light_aon_ipc {
|
||||
@@ -101,9 +112,11 @@ static void light_aon_rx_callback(struct mbox_client *c, void *msg)
|
||||
{
|
||||
struct light_aon_chan *aon_chan = container_of(c, struct light_aon_chan, cl);
|
||||
struct light_aon_ipc *aon_ipc = aon_chan->aon_ipc;
|
||||
struct light_aon_rpc_msg_hdr* hdr = (struct light_aon_rpc_msg_hdr*)msg;
|
||||
uint8_t recv_size = sizeof(struct light_aon_rpc_msg_hdr) + hdr->size;
|
||||
|
||||
memcpy(aon_ipc->msg, msg, LIGHT_AON_RPC_MSG_NUM * sizeof(u32));
|
||||
dev_dbg(aon_ipc->dev, "msg head: 0x%x\n", *((u32 *)msg));
|
||||
memcpy(aon_ipc->msg, msg, recv_size);
|
||||
dev_dbg(aon_ipc->dev, "msg head: 0x%x, size:%d\n", *((u32 *)msg), recv_size);
|
||||
complete(&aon_ipc->done);
|
||||
}
|
||||
|
||||
@@ -140,19 +153,29 @@ static int light_aon_ipc_write(struct light_aon_ipc *aon_ipc, void *msg)
|
||||
/*
|
||||
* RPC command/response
|
||||
*/
|
||||
int light_aon_call_rpc(struct light_aon_ipc *aon_ipc, void *msg, bool have_resp)
|
||||
int light_aon_call_rpc(struct light_aon_ipc *aon_ipc, void *msg, void *ack_msg, bool have_resp)
|
||||
{
|
||||
struct light_aon_rpc_msg_hdr *hdr;
|
||||
int ret;
|
||||
struct light_aon_rpc_msg_hdr *hdr = msg;
|
||||
int ret = 0;
|
||||
|
||||
if (WARN_ON(!aon_ipc || !msg))
|
||||
return -EINVAL;
|
||||
|
||||
if(have_resp && WARN_ON(!ack_msg))
|
||||
return -EINVAL;
|
||||
mutex_lock(&aon_ipc->lock);
|
||||
reinit_completion(&aon_ipc->done);
|
||||
|
||||
if (have_resp)
|
||||
aon_ipc->msg = msg;
|
||||
RPC_SET_VER(hdr, LIGHT_AON_RPC_VERSION);
|
||||
/*svc id use 6bit for version 2*/
|
||||
RPC_SET_SVC_ID(hdr, hdr->svc);
|
||||
RPC_SET_SVC_FLAG_MSG_TYPE(hdr, RPC_SVC_MSG_TYPE_DATA);
|
||||
|
||||
if (have_resp){
|
||||
aon_ipc->msg = ack_msg;
|
||||
RPC_SET_SVC_FLAG_ACK_TYPE(hdr, RPC_SVC_MSG_NEED_ACK);
|
||||
} else {
|
||||
RPC_SET_SVC_FLAG_ACK_TYPE(hdr, RPC_SVC_MSG_NO_NEED_ACK);
|
||||
}
|
||||
|
||||
ret = light_aon_ipc_write(aon_ipc, msg);
|
||||
if (ret < 0) {
|
||||
@@ -168,9 +191,9 @@ int light_aon_call_rpc(struct light_aon_ipc *aon_ipc, void *msg, bool have_resp)
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* response status is stored in hdr->func field */
|
||||
hdr = msg;
|
||||
ret = hdr->func;
|
||||
/* response status is stored in msg data[0] field */
|
||||
struct light_aon_rpc_ack_common* ack = ack_msg;
|
||||
ret = ack->err_code;
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -182,12 +205,41 @@ out:
|
||||
}
|
||||
EXPORT_SYMBOL(light_aon_call_rpc);
|
||||
|
||||
int get_aon_log_mem(struct device *dev, phys_addr_t* mem, size_t* mem_size)
|
||||
{
|
||||
struct resource r;
|
||||
ssize_t fw_size;
|
||||
void *mem_va;
|
||||
struct device_node *node;
|
||||
int ret;
|
||||
|
||||
*mem = 0;
|
||||
*mem_size = 0;
|
||||
|
||||
node = of_parse_phandle(dev->of_node, "log-memory-region", 0);
|
||||
if (!node) {
|
||||
dev_err(dev, "no memory-region specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(node, 0, &r);
|
||||
if (ret) {
|
||||
dev_err(dev, "memory-region get resource faild\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*mem = r.start;
|
||||
*mem_size = resource_size(&r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_aon_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct light_aon_ipc *aon_ipc;
|
||||
struct light_aon_chan *aon_chan;
|
||||
struct mbox_client *cl;
|
||||
char dir_name[32] = {0x0};
|
||||
int ret;
|
||||
|
||||
aon_ipc = devm_kzalloc(dev, sizeof(*aon_ipc), GFP_KERNEL);
|
||||
@@ -220,7 +272,33 @@ static int light_aon_probe(struct platform_device *pdev)
|
||||
aon_ipc->dev = dev;
|
||||
mutex_init(&aon_ipc->lock);
|
||||
init_completion(&aon_ipc->done);
|
||||
aon_chan->log_ctrl = NULL;
|
||||
|
||||
ret = get_aon_log_mem(dev, &aon_chan->log_phy, &aon_chan->log_size);
|
||||
if(ret) {
|
||||
return ret;
|
||||
}
|
||||
aon_chan->log_mem = ioremap(aon_chan->log_phy, aon_chan->log_size);
|
||||
if (!IS_ERR(aon_chan->log_mem)) {
|
||||
printk("%s:virtual_log_mem=0x%p, phy base=0x%llx,size:%d\n",
|
||||
__func__, aon_chan->log_mem, aon_chan->log_phy,
|
||||
aon_chan->log_size);
|
||||
} else {
|
||||
aon_chan->log_mem = NULL;
|
||||
dev_err(dev, "%s:get aon log region fail\n",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(dir_name, "aon_proc");
|
||||
aon_chan->proc_dir = proc_mkdir(dir_name, NULL);
|
||||
if (NULL != aon_chan->proc_dir) {
|
||||
aon_chan->log_ctrl = light_create_panic_log_proc(aon_chan->log_phy,
|
||||
aon_chan->proc_dir, aon_chan->log_mem, aon_chan->log_size);
|
||||
} else {
|
||||
dev_err(dev, "create %s fail\n", dir_name);
|
||||
return ret;
|
||||
}
|
||||
light_aon_ipc_handle = aon_ipc;
|
||||
|
||||
return devm_of_platform_populate(dev);
|
||||
|
||||
@@ -11,37 +11,37 @@ struct light_aon_msg_req_misc_set_ctrl {
|
||||
u32 val;
|
||||
u16 resource;
|
||||
u16 reserved[7];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_msg_req_misc_get_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
u32 ctrl;
|
||||
u16 resource;
|
||||
u16 reserved[9];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_msg_resp_misc_get_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
struct light_aon_rpc_ack_common ack_hdr;
|
||||
u32 val;
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
int light_aon_misc_set_control(struct light_aon_ipc *ipc, u16 resource,
|
||||
u32 ctrl, u32 val)
|
||||
{
|
||||
struct light_aon_msg_req_misc_set_ctrl msg;
|
||||
struct light_aon_rpc_ack_common ack_msg;
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg.hdr;
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_MISC;
|
||||
hdr->func = (uint8_t)LIGHT_AON_MISC_FUNC_SET_CONTROL;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
|
||||
msg.ctrl = ctrl;
|
||||
msg.val = val;
|
||||
msg.resource = resource;
|
||||
RPC_SET_BE32(&msg.ctrl, 0, ctrl);
|
||||
RPC_SET_BE32(&msg.ctrl, 4, val);
|
||||
RPC_SET_BE16(&msg.ctrl, 8, resource);
|
||||
|
||||
return light_aon_call_rpc(ipc, &msg, true);
|
||||
return light_aon_call_rpc(ipc, &msg, &ack_msg, true);
|
||||
}
|
||||
EXPORT_SYMBOL(light_aon_misc_set_control);
|
||||
|
||||
@@ -49,25 +49,23 @@ int light_aon_misc_get_control(struct light_aon_ipc *ipc, u16 resource,
|
||||
u32 ctrl, u32 *val)
|
||||
{
|
||||
struct light_aon_msg_req_misc_get_ctrl msg;
|
||||
struct light_aon_msg_resp_misc_get_ctrl *resp;
|
||||
struct light_aon_msg_resp_misc_get_ctrl resp;
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg.hdr;
|
||||
int ret;
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_MISC;
|
||||
hdr->func = (uint8_t)LIGHT_AON_MISC_FUNC_GET_CONTROL;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
|
||||
msg.ctrl = ctrl;
|
||||
msg.resource = resource;
|
||||
RPC_SET_BE32(&msg.ctrl, 0, ctrl);
|
||||
RPC_SET_BE16(&msg.ctrl, 4, resource);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &msg, true);
|
||||
ret = light_aon_call_rpc(ipc, &msg, &resp, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
resp = (struct light_aon_msg_resp_misc_get_ctrl *)&msg;
|
||||
if (val != NULL)
|
||||
*val = resp->val;
|
||||
RPC_GET_BE32(&resp.val, 0, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ struct light_aon_msg_req_set_resource_power_mode {
|
||||
u16 resource;
|
||||
u16 mode;
|
||||
u16 reserved[10];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
#define LIGHT_AONU_PD_NAME_SIZE 20
|
||||
#define LIGHT_AONU_PD_STATE_NAME_SIZE 10
|
||||
@@ -79,21 +79,21 @@ static inline struct light_aon_pm_domain *to_light_aon_pd(struct generic_pm_doma
|
||||
static int light_aon_pd_power(struct generic_pm_domain *domain, bool power_on)
|
||||
{
|
||||
struct light_aon_msg_req_set_resource_power_mode msg;
|
||||
struct light_aon_rpc_ack_common ack_msg;
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg.hdr;
|
||||
struct light_aon_pm_domain *pd;
|
||||
int ret;
|
||||
|
||||
pd = to_light_aon_pd(domain);
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = LIGHT_AON_RPC_SVC_PM;
|
||||
hdr->func = LIGHT_AON_PM_FUNC_SET_RESOURCE_POWER_MODE;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
|
||||
msg.resource = pd->rsrc;
|
||||
msg.mode = power_on ? LIGHT_AON_PM_PW_MODE_ON : LIGHT_AON_PM_PW_MODE_OFF;
|
||||
RPC_SET_BE16(&msg.resource, 0, pd->rsrc);
|
||||
RPC_SET_BE16(&msg.resource, 2, (power_on ? LIGHT_AON_PM_PW_MODE_ON : LIGHT_AON_PM_PW_MODE_OFF));
|
||||
|
||||
ret = light_aon_call_rpc(pm_ipc_handle, &msg, true);
|
||||
ret = light_aon_call_rpc(pm_ipc_handle, &msg, &ack_msg, true);
|
||||
if (ret)
|
||||
dev_err(&domain->dev, "failed to power %s resource %d ret %d\n",
|
||||
power_on ? "up" : "off", pd->rsrc, ret);
|
||||
|
||||
@@ -25,20 +25,20 @@ struct light_aon_msg_req_misc_set_ctrl {
|
||||
u32 val;
|
||||
u16 resource;
|
||||
u16 reserved[7];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_msg_req_misc_get_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
u32 ctrl;
|
||||
u16 resource;
|
||||
u16 reserved[9];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_msg_resp_misc_get_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
u32 val;
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_device {
|
||||
struct device *dev;
|
||||
|
||||
171
drivers/firmware/thead/light_proc_debug.c
Normal file
171
drivers/firmware/thead/light_proc_debug.c
Normal file
@@ -0,0 +1,171 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* sys log sys for light c906 and e902
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
#include <asm/cacheflush.h>
|
||||
|
||||
#define GET_PAGE_NUM(size, offset) \
|
||||
((((size) + ((offset) & ~PAGE_MASK)) + PAGE_SIZE - 1) >> PAGE_SHIFT)
|
||||
|
||||
struct light_log_ring_buffer {
|
||||
__u32 read;
|
||||
__u32 write;
|
||||
__u32 size;
|
||||
__u32 reserved[1];
|
||||
__u8 data[0];
|
||||
};
|
||||
|
||||
struct light_hw_log {
|
||||
__u32 panic;
|
||||
__u32 reserved[2];
|
||||
struct light_log_ring_buffer rb;
|
||||
};
|
||||
|
||||
struct light_proc_log_ctrl {
|
||||
struct light_hw_log __iomem *log;
|
||||
struct proc_dir_entry *log_proc_file;
|
||||
phys_addr_t log_phy;
|
||||
};
|
||||
|
||||
static void memset_hw(void __iomem *dst, int c, size_t sz)
|
||||
{
|
||||
int i;
|
||||
volatile u32 *d_ptr = dst;
|
||||
for (i = 0; i < sz / 4; i++) {
|
||||
__raw_writel(c, d_ptr++);
|
||||
}
|
||||
}
|
||||
static void dump_regs(const char *fn, void *hw_arg)
|
||||
{
|
||||
struct light_proc_log_ctrl *log_ctrl = hw_arg;
|
||||
|
||||
if (!log_ctrl->log)
|
||||
return;
|
||||
|
||||
pr_debug("%s: panic = 0x%08x\n", fn,
|
||||
__raw_readl(&log_ctrl->log->panic));
|
||||
pr_debug("%s: read = 0x%08x, write = 0x%08x, size = 0x%08x\n", fn,
|
||||
__raw_readl(&log_ctrl->log->rb.read),
|
||||
__raw_readl(&log_ctrl->log->rb.write),
|
||||
__raw_readl(&log_ctrl->log->rb.size));
|
||||
}
|
||||
|
||||
static int log_proc_show(struct seq_file *file, void *v)
|
||||
{
|
||||
struct light_proc_log_ctrl *log_ctrl = file->private;
|
||||
char *buf;
|
||||
size_t i;
|
||||
/*dcache clean and invalid*/
|
||||
dma_wbinv_range(log_ctrl->log_phy, ((char*)log_ctrl->log_phy + sizeof(struct light_hw_log)));
|
||||
|
||||
uint32_t write = __raw_readl(&log_ctrl->log->rb.write);
|
||||
uint32_t read = __raw_readl(&log_ctrl->log->rb.read);
|
||||
uint32_t size = __raw_readl(&log_ctrl->log->rb.size);
|
||||
size_t log_size = write >= read ? write - read : size + write - read;
|
||||
|
||||
seq_printf(file,"****************** device log >>>>>>>>>>>>>>>>>\n");
|
||||
dump_regs(__func__, log_ctrl);
|
||||
if(!log_size) {
|
||||
seq_printf(file,"****************** end device log <<<<<<<<<<<<<<<<<\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int page_num = GET_PAGE_NUM(log_size, 0);
|
||||
|
||||
int log_patch_1 = -1, log_patch_2 = -1;
|
||||
|
||||
buf = kmalloc(PAGE_SIZE * page_num, GFP_KERNEL);
|
||||
if (buf) {
|
||||
if(read + log_size >= size) {
|
||||
log_patch_2 = read + log_size - size + 1;
|
||||
log_patch_1 = log_size - log_patch_2;
|
||||
|
||||
} else {
|
||||
log_patch_1 = log_size;
|
||||
}
|
||||
|
||||
memcpy_fromio(buf, &log_ctrl->log->rb.data[read], log_patch_1);
|
||||
if(log_patch_2 > 0) {
|
||||
memcpy_fromio(buf, &log_ctrl->log->rb.data[0], log_patch_2);
|
||||
}
|
||||
|
||||
uint8_t last_fame_size = log_size % 64;
|
||||
|
||||
for (i = 0; i < log_size - last_fame_size; i += 64) {
|
||||
seq_printf(file, " %*pEp", 64, buf + i);
|
||||
}
|
||||
if(last_fame_size) {
|
||||
seq_printf(file, " %*pEp", last_fame_size, buf + log_size - last_fame_size);
|
||||
}
|
||||
|
||||
__raw_writel(write, &log_ctrl->log->rb.read);
|
||||
kfree(buf);
|
||||
/*dcahce clean*/
|
||||
dma_wb_range(log_ctrl->log_phy, ((char*)log_ctrl->log_phy + sizeof(struct light_hw_log)));
|
||||
//seq_printf(file,"\n%d %d %d %d %d\n",log_patch_1, log_patch_2, log_size ,last_fame_size, read);
|
||||
seq_printf(file,"\n****************** end device log <<<<<<<<<<<<<<<<<\n");
|
||||
return 0;
|
||||
} else {
|
||||
pr_debug("Fail to alloc buf\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool light_panic_init(struct light_hw_log *hw_log, size_t size)
|
||||
{
|
||||
if (size < sizeof(struct light_hw_log)) {
|
||||
return false;
|
||||
}
|
||||
hw_log->rb.read = 0;
|
||||
hw_log->rb.size = size - sizeof(struct light_hw_log);
|
||||
return true;
|
||||
}
|
||||
|
||||
void *light_create_panic_log_proc(phys_addr_t log_phy, void *dir, void *log_info_addr, size_t size)
|
||||
{
|
||||
struct light_proc_log_ctrl *log_ctrl =
|
||||
kmalloc(sizeof(struct light_proc_log_ctrl), GFP_KERNEL);
|
||||
|
||||
if (log_ctrl == NULL)
|
||||
return NULL;
|
||||
|
||||
log_ctrl->log = log_info_addr;
|
||||
|
||||
light_panic_init(log_ctrl->log, size);
|
||||
|
||||
log_ctrl->log_proc_file = proc_create_single_data(
|
||||
"proc_log", 0644, dir, &log_proc_show, log_ctrl);
|
||||
if (log_ctrl->log_proc_file == NULL) {
|
||||
pr_debug("Error: Could not initialize %s\n", "dsp_log");
|
||||
kfree(log_ctrl);
|
||||
log_ctrl = NULL;
|
||||
} else {
|
||||
pr_debug("%s create Success!\n", "dsp_log");
|
||||
}
|
||||
log_ctrl->log_phy = log_phy;
|
||||
return log_ctrl;
|
||||
}
|
||||
|
||||
void light_remove_panic_log_proc(void *arg)
|
||||
{
|
||||
struct light_proc_log_ctrl *log_ctrl = (struct light_proc_log_ctrl *)arg;
|
||||
|
||||
proc_remove(log_ctrl->log_proc_file);
|
||||
kfree(log_ctrl);
|
||||
pr_debug("light proc log removed\n");
|
||||
}
|
||||
@@ -58,7 +58,7 @@ SDK_DIR ?= $(AQROOT)/build/sdk
|
||||
VIVANTE_ENABLE_3D ?= 0
|
||||
VIVANTE_ENABLE_2D ?= 1
|
||||
VIVANTE_ENABLE_VG ?= 0
|
||||
VIVANTE_ENABLE_DRM ?= 1
|
||||
VIVANTE_ENABLE_DRM ?= 0
|
||||
NO_DMA_COHERENT ?= 0
|
||||
USE_PLATFORM_DRIVER ?= 1
|
||||
ENABLE_GPU_CLOCK_BY_DRIVER ?= 1
|
||||
|
||||
@@ -59,6 +59,10 @@
|
||||
|
||||
#include "gc_feature_database.h"
|
||||
#include <gc_hal_kernel_debug.h>
|
||||
#include <linux/printk.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/g2d.h>
|
||||
|
||||
#define _GC_OBJ_ZONE gcvZONE_HARDWARE
|
||||
|
||||
@@ -298,7 +302,7 @@ _IdentifyHardwareByDatabase(
|
||||
|
||||
if (database == gcvNULL)
|
||||
{
|
||||
gcmkPRINT("[galcore]: Feature database is not found,"
|
||||
pr_err("[galcore]: Feature database is not found,"
|
||||
"chipModel=0x%0x, chipRevision=0x%x, productID=0x%x, ecoID=0x%x, customerID=0x%x",
|
||||
Hardware->identity.chipModel,
|
||||
Hardware->identity.chipRevision,
|
||||
@@ -309,7 +313,7 @@ _IdentifyHardwareByDatabase(
|
||||
}
|
||||
else if (database->chipVersion != Hardware->identity.chipRevision)
|
||||
{
|
||||
gcmkPRINT("[galcore]: Warning: chipRevision mismatch, database chipRevision=0x%x register read chipRevision=0x%x\n",
|
||||
pr_warn("[galcore]: Warning: chipRevision mismatch, database chipRevision=0x%x register read chipRevision=0x%x\n",
|
||||
database->chipVersion, Hardware->identity.chipRevision);
|
||||
}
|
||||
|
||||
@@ -1184,7 +1188,7 @@ _IsGPUPresent(
|
||||
|| (Hardware->signature.chipMinorFeatures2 != signature.chipMinorFeatures2)
|
||||
)
|
||||
{
|
||||
gcmkPRINT("[galcore]: GPU is not present.");
|
||||
pr_err("[galcore]: GPU is not present.");
|
||||
gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
|
||||
}
|
||||
|
||||
@@ -1747,7 +1751,7 @@ _ConfigurePolicyID(
|
||||
/* Check whether this bit changes. */
|
||||
if (auxBit != ((policyID >> 4) & 0x1))
|
||||
{
|
||||
gcmkPRINT("[galcore]: AUX_BIT changes");
|
||||
pr_warn("[galcore]: AUX_BIT changes");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1830,7 +1834,7 @@ _QueryNNClusters(
|
||||
/* We only support maximum 8 clusters by current. */
|
||||
if (enableNN > 0x7)
|
||||
{
|
||||
gcmkPRINT("[Galcore warning]: Invalid enableNN value is configured.");
|
||||
pr_warn("[Galcore warning]: Invalid enableNN value is configured.");
|
||||
|
||||
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
@@ -1843,7 +1847,7 @@ _QueryNNClusters(
|
||||
|
||||
if (value && Hardware->identity.customerID != 0x85)
|
||||
{
|
||||
gcmkPRINT("Galcore warning: Don't set enableNN as this chip not support NN cluster power control!\n");
|
||||
pr_warn("Galcore warning: Don't set enableNN as this chip not support NN cluster power control!\n");
|
||||
}
|
||||
|
||||
Hardware->options.configNNPowerControl = value;
|
||||
@@ -1901,7 +1905,7 @@ _SetHardwareOptions(
|
||||
|
||||
if (options->enableMMU == gcvFALSE)
|
||||
{
|
||||
gcmkPRINT("Galcore warning: MMU is disabled!\n");
|
||||
pr_err("Galcore warning: MMU is disabled!\n");
|
||||
}
|
||||
|
||||
/* Query enabled NN clusters. */
|
||||
@@ -1935,7 +1939,7 @@ _SetHardwareOptions(
|
||||
}
|
||||
else if (options->userClusterMask & (~Hardware->identity.clusterAvailMask))
|
||||
{
|
||||
gcmkPRINT("%s(%d): user cluster mask(0x%x) must be a subset of available clusters(0x%x),ignored it!",
|
||||
pr_warn("%s(%d): user cluster mask(0x%x) must be a subset of available clusters(0x%x),ignored it!",
|
||||
__FUNCTION__, __LINE__, options->userClusterMask, Hardware->identity.clusterAvailMask);
|
||||
options->userClusterMasks[Hardware->core] = options->userClusterMask = Hardware->identity.clusterAvailMask;
|
||||
}
|
||||
@@ -3064,7 +3068,7 @@ gckHARDWARE_InitializeHardware(
|
||||
|
||||
gcmkSAFECASTPHYSADDRT(offset, Hardware->identity.registerAPB);
|
||||
|
||||
gcmkPRINT("Initailize APB1 registers, APB offset is 0x%x.\n", offset);
|
||||
pr_warn("Initailize APB1 registers, APB offset is 0x%x.\n", offset);
|
||||
|
||||
/* APB FE ctrl. */
|
||||
gcmkONERROR(gckOS_WriteRegisterEx(
|
||||
@@ -4621,7 +4625,7 @@ OnError:
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
_ResumeWaitLinkFE(
|
||||
gckHARDWARE Hardware
|
||||
)
|
||||
@@ -4632,14 +4636,18 @@ _ResumeWaitLinkFE(
|
||||
gctUINT32 idle;
|
||||
|
||||
/* Make sure FE is idle. */
|
||||
do
|
||||
{
|
||||
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
|
||||
|
||||
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
|
||||
Hardware->core,
|
||||
0x00004,
|
||||
&idle));
|
||||
}
|
||||
while (idle != 0x7FFFFFFF);
|
||||
|
||||
gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
|
||||
Hardware->core,
|
||||
0x00004,
|
||||
&idle));
|
||||
if(idle != 0x7FFFFFFF)
|
||||
return;
|
||||
|
||||
gcmkDUMP(Hardware->os, "@[register.wait 0x%05X 0x%08X 0x%08X]",
|
||||
0x00004,
|
||||
@@ -4712,6 +4720,7 @@ gckHARDWARE_Interrupt(
|
||||
Hardware->core,
|
||||
0x00010,
|
||||
&data);
|
||||
trace_g2d_irq_reg(0x00010,data);
|
||||
|
||||
if (gcmIS_ERROR(status))
|
||||
{
|
||||
@@ -4746,7 +4755,7 @@ gckHARDWARE_Interrupt(
|
||||
0x000D4,
|
||||
&dataEx
|
||||
);
|
||||
|
||||
trace_g2d_irq_reg(0x000D4,dataEx);
|
||||
if (gcmIS_ERROR(statusEx))
|
||||
{
|
||||
/*
|
||||
@@ -4815,13 +4824,6 @@ gckHARDWARE_Notify(
|
||||
|
||||
gckOS_AtomGet(Hardware->os, Hardware->kernel->eventObj->pending, (gctINT32_PTR)&pending);
|
||||
|
||||
if (pending & (1 << 29))
|
||||
{
|
||||
/* Event ID 29 is not a normal event, but for invalidating pipe. */
|
||||
_ResumeWaitLinkFE(Hardware);
|
||||
pending &= ~(1 << 29);
|
||||
}
|
||||
|
||||
gckOS_AtomSetMask(Hardware->kernel->eventObj->pending, pending);
|
||||
|
||||
/* Handle events. */
|
||||
@@ -7883,7 +7885,7 @@ gckHARDWARE_PowerControlClusters(
|
||||
#if gcdGPU_TIMEOUT
|
||||
if (timer >= Hardware->kernel->timeOut)
|
||||
{
|
||||
gcmkPRINT("%s %d Galcore timeout...\n", __FUNCTION__, __LINE__);
|
||||
pr_err("%s %d Galcore timeout...\n", __FUNCTION__, __LINE__);
|
||||
|
||||
gcmkONERROR(gcvSTATUS_DEVICE);
|
||||
}
|
||||
@@ -9219,7 +9221,7 @@ gckHARDWARE_SetPowerState(
|
||||
status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
|
||||
if (status != gcvSTATUS_TIMEOUT && Hardware->isLastPowerGlobal)
|
||||
{
|
||||
gcmkPRINT("%s: global state error", __FUNCTION__);
|
||||
pr_err("%s: global state error", __FUNCTION__);
|
||||
}
|
||||
|
||||
/* Switched to global ON, now release the global semaphore. */
|
||||
@@ -12621,14 +12623,14 @@ gckHARDWARE_Reset(
|
||||
Hardware, state
|
||||
));
|
||||
|
||||
gcmkPRINT("[galcore]: recovery done");
|
||||
pr_warn("[galcore]: recovery done");
|
||||
|
||||
/* Success. */
|
||||
gcmkFOOTER_NO();
|
||||
return gcvSTATUS_OK;
|
||||
|
||||
OnError:
|
||||
gcmkPRINT("[galcore]: Hardware not reset successfully, give up");
|
||||
pr_err("[galcore]: Hardware not reset successfully, give up");
|
||||
|
||||
if (globalAcquired)
|
||||
{
|
||||
|
||||
@@ -2436,39 +2436,39 @@ _FuncExecute_FLOPRESET(IN gcsFUNCTION_EXECUTION_PTR Execution)
|
||||
#if gcdENABLE_FLOP_RESET_DEBUG
|
||||
for (i = 0; i < Execution->funcCmdCount - minus_flag; i++)
|
||||
{
|
||||
gcmkPRINT("outSizeBytes is : %d", Execution->funcCmd[i].outSize);
|
||||
gcmkPRINT("outAddress is %x", Execution->funcCmd[i].data[2].address);
|
||||
pr_warn("outSizeBytes is : %d", Execution->funcCmd[i].outSize);
|
||||
pr_warn("outAddress is %x", Execution->funcCmd[i].data[2].address);
|
||||
for(j = 0; j < Execution->funcCmd[i].outSize; j++ )
|
||||
{
|
||||
if(((gctUINT8_PTR)(Execution->funcCmd[i].golden))[j] != ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[j])
|
||||
{
|
||||
if(i == 0)
|
||||
{
|
||||
gcmkPRINT("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
gcmkPRINT("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
gcmkPRINT("NN workaround verify failed!");
|
||||
pr_warn("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
pr_warn("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
pr_warn("NN workaround verify failed!");
|
||||
return status;
|
||||
}
|
||||
else if(i == 1)
|
||||
{
|
||||
gcmkPRINT("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
gcmkPRINT("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
gcmkPRINT("TP workaround verify failed!");
|
||||
pr_warn("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
pr_warn("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
pr_warn("TP workaround verify failed!");
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(i == 0)
|
||||
{
|
||||
gcmkPRINT("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
gcmkPRINT("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
gcmkPRINT("NN workaround verify success!");
|
||||
pr_warn("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
pr_warn("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
pr_warn("NN workaround verify success!");
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
gcmkPRINT("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
gcmkPRINT("TP workaround verify success!");
|
||||
pr_warn("top 2 outputBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].outlogical))[1]);
|
||||
pr_warn("top 2 goldenBytes: %x, %x",((gctUINT8_PTR)(Execution->funcCmd[i].golden))[0], ((gctUINT8_PTR)(Execution->funcCmd[i].golden))[1]);
|
||||
pr_warn("TP workaround verify success!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -2576,7 +2576,7 @@ _ProgramMMUStates(
|
||||
case gcvSECURE_IN_TA:
|
||||
default:
|
||||
gcmkASSERT(gcvFALSE);
|
||||
gcmkPRINT("%s(%d): secureMode is wrong", __FUNCTION__, __LINE__);
|
||||
pr_err("%s(%d): secureMode is wrong", __FUNCTION__, __LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3467,7 +3467,7 @@ _ProgramMMUStatesMCFE(
|
||||
case gcvSECURE_IN_TA:
|
||||
default:
|
||||
gcmkASSERT(gcvFALSE);
|
||||
gcmkPRINT("%s(%d): secureMode is wrong", __FUNCTION__, __LINE__);
|
||||
pr_err("%s(%d): secureMode is wrong", __FUNCTION__, __LINE__);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4792,10 +4792,10 @@ _FuncRelease_PPU(IN gcsFUNCTION_EXECUTION_PTR Execution)
|
||||
if (((gctUINT32_PTR)(Execution->funcCmd[0].data[OUTPUT_PPU_IDX].logical))[i] != 0x02020202)
|
||||
{
|
||||
pass = gcvFALSE;
|
||||
gcmkPRINT("Incorrect Result:[%d] 0x%08x\n", i, ((gctUINT32_PTR)(Execution->funcCmd[0].data[OUTPUT_PPU_IDX].logical))[i]);
|
||||
pr_warn("Incorrect Result:[%d] 0x%08x\n", i, ((gctUINT32_PTR)(Execution->funcCmd[0].data[OUTPUT_PPU_IDX].logical))[i]);
|
||||
}
|
||||
}
|
||||
gcmkPRINT("PPU %s!\n", pass?"PASS":"FAIL");
|
||||
pr_warn("PPU %s!\n", pass?"PASS":"FAIL");
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9831,7 +9831,7 @@ _FuncRelease_USC(IN gcsFUNCTION_EXECUTION_PTR Execution)
|
||||
|| *((gctUINT32_PTR)(Execution->funcCmd[0].data[3].logical)) == 0x44004400 /*FP16*/
|
||||
)
|
||||
{
|
||||
gcmkPRINT("USC PASS! ");
|
||||
pr_warn("USC PASS! ");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -176,7 +176,7 @@ _AllocateDescRingBuf(
|
||||
|
||||
if (Channel->physical > 0xffffffffull)
|
||||
{
|
||||
gcmkPRINT("%s(%d): MCFE ring buffer physical over 4G: 0x%llx",
|
||||
pr_err("%s(%d): MCFE ring buffer physical over 4G: 0x%llx",
|
||||
__FUNCTION__, __LINE__, (unsigned long long)Channel->physical);
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ gckMCFE_Execute(
|
||||
|
||||
if (_NextPtr(ringBuf->writePtr) == ringBuf->readPtr)
|
||||
{
|
||||
gcmkPRINT("%s: MCFE channel %s-%d ringBuf is full!",
|
||||
pr_warn("%s: MCFE channel %s-%d ringBuf is full!",
|
||||
__FUNCTION__,
|
||||
Priority ? "Pri" : "Std",
|
||||
ChannelId);
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
|
||||
|
||||
#include "gc_hal_kernel_precomp.h"
|
||||
#include <linux/module.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
#if gcdDEC_ENABLE_AHB
|
||||
#include "viv_dec300_main.h"
|
||||
@@ -65,9 +67,11 @@
|
||||
|
||||
#define _GC_OBJ_ZONE gcvZONE_KERNEL
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
***** Version Signature *******************************************************/
|
||||
|
||||
#define MAX_THREADS 10
|
||||
#define MAX_TIMESTAMPS 10
|
||||
#define _gcmTXT2STR(t) #t
|
||||
#define gcmTXT2STR(t) _gcmTXT2STR(t)
|
||||
const char * _VERSION = "\n\0$VERSION$"
|
||||
@@ -80,6 +84,7 @@ const char * _VERSION = "\n\0$VERSION$"
|
||||
******************************* gckKERNEL API Code ******************************
|
||||
\******************************************************************************/
|
||||
|
||||
|
||||
#if gcmIS_DEBUG(gcdDEBUG_TRACE)
|
||||
#define gcmDEFINE2TEXT(d) #d
|
||||
gctCONST_STRING _DispatchText[] =
|
||||
@@ -1251,7 +1256,7 @@ AllocateMemory:
|
||||
#if gcdCAPTURE_ONLY_MODE
|
||||
else
|
||||
{
|
||||
gcmkPRINT("Capture only mode: Out of Memory");
|
||||
pr_err("Capture only mode: Out of Memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2337,7 +2342,7 @@ gckKERNEL_CacheOperation(
|
||||
if (!printed)
|
||||
{
|
||||
printed = gcvTRUE;
|
||||
gcmkPRINT("[galcore]: %s: Flush Video Memory", __FUNCTION__);
|
||||
pr_warn("[galcore]: %s: Flush Video Memory", __FUNCTION__);
|
||||
}
|
||||
|
||||
gcmkFOOTER_NO();
|
||||
@@ -2907,6 +2912,8 @@ gckKERNEL_Dispatch(
|
||||
gckCONTEXT context = gcvNULL;
|
||||
gckKERNEL kernel = Kernel;
|
||||
gctUINT32 processID;
|
||||
gcsDATABASE_PTR database;
|
||||
gctUINT i;
|
||||
#if !USE_NEW_LINUX_SIGNAL
|
||||
gctSIGNAL signal;
|
||||
#endif
|
||||
@@ -3232,9 +3239,35 @@ gckKERNEL_Dispatch(
|
||||
|
||||
case gcvUSER_SIGNAL_WAIT:
|
||||
/* Wait on the signal. */
|
||||
gcmkVERIFY_OK(gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
|
||||
for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
|
||||
{
|
||||
for (database = kernel->db->db[i];
|
||||
database != gcvNULL;
|
||||
database = database->next)
|
||||
{
|
||||
database->st = database->st % 10;
|
||||
database->start_times[database->st] = ktime_get();
|
||||
}
|
||||
}
|
||||
gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
|
||||
|
||||
status = gckOS_WaitUserSignal(Kernel->os,
|
||||
Interface->u.UserSignal.id,
|
||||
Interface->u.UserSignal.wait);
|
||||
gcmkVERIFY_OK(gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
|
||||
for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
|
||||
{
|
||||
for (database = kernel->db->db[i];
|
||||
database != gcvNULL;
|
||||
database = database->next)
|
||||
{
|
||||
database->st = database->st % 9;
|
||||
database->end_times[database->st++] = ktime_get();
|
||||
}
|
||||
}
|
||||
gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
|
||||
|
||||
break;
|
||||
|
||||
case gcvUSER_SIGNAL_MAP:
|
||||
@@ -3472,7 +3505,7 @@ gckKERNEL_Dispatch(
|
||||
Interface->u.ReadRegisterData.data = 0;
|
||||
status = gcvSTATUS_CHIP_NOT_READY;
|
||||
|
||||
gcmkPRINT("[galcore]: Can't dump state if GPU isn't POWER ON.");
|
||||
pr_err("[galcore]: Can't dump state if GPU isn't POWER ON.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -4199,7 +4232,7 @@ gckKERNEL_Recovery(
|
||||
|
||||
if (Kernel->stuckDump == gcvSTUCK_DUMP_NONE)
|
||||
{
|
||||
gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
|
||||
pr_err("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
|
||||
}
|
||||
else if (Kernel->stuckDump == gcvSTUCK_DUMP_ALL_CORE)
|
||||
{
|
||||
@@ -4233,7 +4266,7 @@ gckKERNEL_Recovery(
|
||||
|
||||
if (Kernel->recovery == gcvFALSE)
|
||||
{
|
||||
gcmkPRINT("[galcore]: Stop driver to keep scene.");
|
||||
pr_err("[galcore]: Stop driver to keep scene.");
|
||||
|
||||
/* Stop monitor timer. */
|
||||
Kernel->monitorTimerStop = gcvTRUE;
|
||||
@@ -6013,7 +6046,7 @@ gckDEVICE_Profiler_Dispatch(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("unknown profileMode argument");
|
||||
pr_err("unknown profileMode argument");
|
||||
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "gc_hal_driver.h"
|
||||
#include "gc_hal_kernel_mutex.h"
|
||||
#include "gc_hal_metadata.h"
|
||||
#include <linux/ktime.h>
|
||||
|
||||
#if gcdENABLE_SW_PREEMPTION
|
||||
#include "gc_hal_kernel_preemption.h"
|
||||
@@ -291,6 +292,13 @@ typedef struct _gcsDATABASE
|
||||
/* Process ID. */
|
||||
gctUINT32 processID;
|
||||
|
||||
/* Process time. */
|
||||
ktime_t start_times[10];
|
||||
ktime_t end_times[10];
|
||||
gctUINT32 st;
|
||||
ktime_t max_hw_time;
|
||||
|
||||
|
||||
/* Open-Close ref count */
|
||||
gctPOINTER refs;
|
||||
|
||||
|
||||
@@ -4532,7 +4532,7 @@ gckCOMMAND_DumpExecutingBuffer(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("Can not find command buffer around 0x%08X.\n", gpuAddress);
|
||||
pr_err("Can not find command buffer around 0x%08X.\n", gpuAddress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4616,7 +4616,7 @@ gckCOMMAND_DumpExecutingBuffer(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("Not found");
|
||||
pr_err("Not found");
|
||||
}
|
||||
|
||||
/* new line. */
|
||||
@@ -4662,7 +4662,7 @@ gckCOMMAND_DumpExecutingBuffer(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("%08X sub command not found", node->address);
|
||||
pr_err("%08X sub command not found", node->address);
|
||||
}
|
||||
|
||||
/* new line */
|
||||
@@ -4842,7 +4842,7 @@ gckCOMMAND_PreemptCommit(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("Don't enable SW preemption for aysnc FE.\n");
|
||||
pr_err("Don't enable SW preemption for aysnc FE.\n");
|
||||
|
||||
gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
@@ -1159,7 +1159,7 @@ gckKERNEL_DestroyProcessDB(
|
||||
}
|
||||
|
||||
#if gcdCAPTURE_ONLY_MODE
|
||||
gcmkPRINT("Capture only mode: The max allocation from System Pool is %llu bytes", database->vidMemPool[gcvPOOL_SYSTEM].maxBytes);
|
||||
pr_warn("Capture only mode: The max allocation from System Pool is %llu bytes", database->vidMemPool[gcvPOOL_SYSTEM].maxBytes);
|
||||
#endif
|
||||
|
||||
/* Cannot remove the database from the hash list
|
||||
@@ -1344,7 +1344,7 @@ gckKERNEL_DestroyProcessDB(
|
||||
|
||||
if (priorityID >= gcdMAX_PRIORITY_QUEUE_NUM)
|
||||
{
|
||||
gcmkPRINT("Galcore Info: get an error priority.");
|
||||
pr_err("Galcore Info: get an error priority.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
#define gcdEVENT_ALLOCATION_COUNT (4096 / gcmSIZEOF(gcsHAL_INTERFACE))
|
||||
#define gcdEVENT_MIN_THRESHOLD 4
|
||||
|
||||
extern void _ResumeWaitLinkFE(gckHARDWARE Hardware);
|
||||
/******************************************************************************\
|
||||
********************************* Support Code *********************************
|
||||
\******************************************************************************/
|
||||
@@ -1870,6 +1871,12 @@ gckEVENT_Interrupt(
|
||||
)
|
||||
{
|
||||
/* Combine current interrupt status with pending flags. */
|
||||
if (Data & (1 << 29))
|
||||
{
|
||||
/* Event ID 29 is not a normal event, but for invalidating pipe. */
|
||||
_ResumeWaitLinkFE(Event->kernel->hardware);
|
||||
Data &= ~(1 << 29);
|
||||
}
|
||||
gckOS_AtomSetMask(Event->pending, Data);
|
||||
|
||||
#if gcdINTERRUPT_STATISTIC
|
||||
@@ -1978,7 +1985,7 @@ gckEVENT_Notify(
|
||||
|
||||
if (pending & 0x80000000)
|
||||
{
|
||||
gcmkPRINT("AXI BUS ERROR");
|
||||
pr_err("AXI BUS ERROR");
|
||||
pending &= 0x7FFFFFFF;
|
||||
|
||||
fault |= gcvEVENT_BUS_ERROR_FAULT;
|
||||
@@ -2484,29 +2491,29 @@ _PrintRecord(
|
||||
switch (record->info.command)
|
||||
{
|
||||
case gcvHAL_WRITE_DATA:
|
||||
gcmkPRINT(" gcvHAL_WRITE_DATA");
|
||||
pr_warn(" gcvHAL_WRITE_DATA");
|
||||
break;
|
||||
|
||||
case gcvHAL_UNLOCK_VIDEO_MEMORY:
|
||||
gcmkPRINT(" gcvHAL_UNLOCK_VIDEO_MEMORY");
|
||||
pr_warn(" gcvHAL_UNLOCK_VIDEO_MEMORY");
|
||||
break;
|
||||
|
||||
case gcvHAL_SIGNAL:
|
||||
gcmkPRINT(" gcvHAL_SIGNAL process=%lld signal=0x%llx",
|
||||
pr_warn(" gcvHAL_SIGNAL process=%lld signal=0x%llx",
|
||||
record->info.u.Signal.process,
|
||||
record->info.u.Signal.signal);
|
||||
break;
|
||||
|
||||
case gcvHAL_TIMESTAMP:
|
||||
gcmkPRINT(" gcvHAL_TIMESTAMP");
|
||||
pr_warn(" gcvHAL_TIMESTAMP");
|
||||
break;
|
||||
|
||||
case gcvHAL_COMMIT_DONE:
|
||||
gcmkPRINT(" gcvHAL_COMMIT_DONE");
|
||||
pr_warn(" gcvHAL_COMMIT_DONE");
|
||||
break;
|
||||
|
||||
case gcvHAL_DESTROY_MMU:
|
||||
gcmkPRINT(" gcvHAL_DESTORY_MMU mmu=%p",
|
||||
pr_warn(" gcvHAL_DESTORY_MMU mmu=%p",
|
||||
gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu));
|
||||
|
||||
break;
|
||||
@@ -2596,7 +2603,7 @@ gckEVENT_Dump(
|
||||
);
|
||||
if (gcmIS_ERROR(status))
|
||||
{
|
||||
gcmkPRINT(" READ INTR_ACKNOWLEDGE ERROR!");
|
||||
pr_err(" READ INTR_ACKNOWLEDGE ERROR!");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -868,17 +868,17 @@ gckHEAP_ProfileEnd(
|
||||
gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
|
||||
gcmkVERIFY_ARGUMENT(Title != gcvNULL);
|
||||
|
||||
gcmkPRINT("\n");
|
||||
gcmkPRINT("=====[ HEAP - %s ]=====", Title);
|
||||
gcmkPRINT("Number of allocations : %12u", Heap->allocCount);
|
||||
gcmkPRINT("Number of bytes allocated : %12llu", Heap->allocBytes);
|
||||
gcmkPRINT("Maximum allocation size : %12llu", Heap->allocBytesMax);
|
||||
gcmkPRINT("Total number of bytes allocated : %12llu", Heap->allocBytesTotal);
|
||||
gcmkPRINT("Number of heaps : %12u", Heap->heapCount);
|
||||
gcmkPRINT("Heap memory in bytes : %12llu", Heap->heapMemory);
|
||||
gcmkPRINT("Maximum number of heaps : %12u", Heap->heapCountMax);
|
||||
gcmkPRINT("Maximum heap memory in bytes : %12llu", Heap->heapMemoryMax);
|
||||
gcmkPRINT("==============================================");
|
||||
pr_debug("\n");
|
||||
pr_debug("=====[ HEAP - %s ]=====", Title);
|
||||
pr_debug("Number of allocations : %12u", Heap->allocCount);
|
||||
pr_debug("Number of bytes allocated : %12llu", Heap->allocBytes);
|
||||
pr_debug("Maximum allocation size : %12llu", Heap->allocBytesMax);
|
||||
pr_debug("Total number of bytes allocated : %12llu", Heap->allocBytesTotal);
|
||||
pr_debug("Number of heaps : %12u", Heap->heapCount);
|
||||
pr_debug("Heap memory in bytes : %12llu", Heap->heapMemory);
|
||||
pr_debug("Maximum number of heaps : %12u", Heap->heapCountMax);
|
||||
pr_debug("Maximum heap memory in bytes : %12llu", Heap->heapMemoryMax);
|
||||
pr_debug("==============================================");
|
||||
|
||||
/* Success. */
|
||||
gcmkFOOTER_NO();
|
||||
|
||||
@@ -568,7 +568,7 @@ _CollectFreeSpace(
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
gckOS_Print("%s(%d): [%d]: start=%d, entries=%d.\n",
|
||||
gcmkPRINT("%s(%d): [%d]: start=%d, entries=%d.\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
i,
|
||||
array[i].start,
|
||||
@@ -775,7 +775,7 @@ gckMMU_FillFlatMappingWithPage16M(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_err("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ gckMMU_FillFlatMappingWithPage16M(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_err("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -915,12 +915,12 @@ gckMMU_FillFlatMappingWithPage16M(
|
||||
_WritePageEntry(Mmu->mtlbLogical + mCursor, mtlbEntry);
|
||||
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
mStart,
|
||||
_ReadPageEntry(Mmu->mtlbLogical + mCursor));
|
||||
|
||||
gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
pr_warn("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
stlbLogical,
|
||||
stlbPhyBase);
|
||||
@@ -952,7 +952,7 @@ gckMMU_FillFlatMappingWithPage16M(
|
||||
_WritePageEntry(stlbLogical + sStart, _SetPage(start, physBaseExt, gcvTRUE));
|
||||
}
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert STLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
sStart,
|
||||
_ReadPageEntry(stlbLogical + sStart));
|
||||
@@ -1123,7 +1123,7 @@ gckMMU_FillFlatMappingWithPage1M(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_err("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1144,7 +1144,7 @@ gckMMU_FillFlatMappingWithPage1M(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_err("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1241,12 +1241,12 @@ gckMMU_FillFlatMappingWithPage1M(
|
||||
_WritePageEntry(Mmu->mtlbLogical + mStart, mtlbEntry);
|
||||
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
mStart,
|
||||
_ReadPageEntry(Mmu->mtlbLogical + mStart));
|
||||
|
||||
gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
pr_warn("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
stlbLogical,
|
||||
stlbPhyBase);
|
||||
@@ -1298,7 +1298,7 @@ gckMMU_FillFlatMappingWithPage1M(
|
||||
_WritePageEntry(stlbLogical + sStart, _SetPage(start, physBaseExt, gcvTRUE));
|
||||
}
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert STLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
sStart,
|
||||
_ReadPageEntry(stlbLogical + sStart));
|
||||
@@ -1481,7 +1481,7 @@ gckMMU_FillFlatMappingWithPage64K(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_err("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1502,7 +1502,7 @@ gckMMU_FillFlatMappingWithPage64K(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_err("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1599,12 +1599,12 @@ gckMMU_FillFlatMappingWithPage64K(
|
||||
_WritePageEntry(Mmu->mtlbLogical + mStart, mtlbEntry);
|
||||
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
mStart,
|
||||
_ReadPageEntry(Mmu->mtlbLogical + mStart));
|
||||
|
||||
gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
pr_warn("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
stlbLogical,
|
||||
stlbPhyBase);
|
||||
@@ -1656,7 +1656,7 @@ gckMMU_FillFlatMappingWithPage64K(
|
||||
_WritePageEntry(stlbLogical + sStart, _SetPage(start, physBaseExt, gcvTRUE));
|
||||
}
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert STLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
sStart,
|
||||
_ReadPageEntry(stlbLogical + sStart));
|
||||
@@ -1839,7 +1839,7 @@ gckMMU_FillFlatMappingWithPage4K(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_err("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1860,7 +1860,7 @@ gckMMU_FillFlatMappingWithPage4K(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
|
||||
pr_warn("There is a hole in new flat mapping range, which is not correct");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1957,12 +1957,12 @@ gckMMU_FillFlatMappingWithPage4K(
|
||||
_WritePageEntry(Mmu->mtlbLogical + mStart, mtlbEntry);
|
||||
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
mStart,
|
||||
_ReadPageEntry(Mmu->mtlbLogical + mStart));
|
||||
|
||||
gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
pr_warn("%s(%d): STLB: logical:%08x -> physical:%08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
stlbLogical,
|
||||
stlbPhyBase);
|
||||
@@ -2016,7 +2016,7 @@ gckMMU_FillFlatMappingWithPage4K(
|
||||
_WritePageEntry(stlbLogical + sStart, _SetPage(start, physBaseExt, gcvTRUE));
|
||||
}
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert STLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
sStart,
|
||||
_ReadPageEntry(stlbLogical + sStart));
|
||||
@@ -2262,7 +2262,7 @@ _ConstructDynamicStlb(
|
||||
_WritePageEntry(Mmu->mtlbLogical + i, mtlbEntry);
|
||||
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert MTLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
i,
|
||||
_ReadPageEntry(Mmu->mtlbLogical + i));
|
||||
@@ -2726,7 +2726,7 @@ _Construct(
|
||||
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
gcmkPRINT("Galcore warning: pre-flat mapping base address can't be lower than 0x1000000, adjust it to 0x1000000. ");
|
||||
pr_warn("Galcore warning: pre-flat mapping base address can't be lower than 0x1000000, adjust it to 0x1000000. ");
|
||||
|
||||
physSize = gpuAddress + physSize - gcdMTLB_RESERVED_SIZE;
|
||||
|
||||
@@ -3049,7 +3049,7 @@ _Destroy(
|
||||
{
|
||||
_WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex + i, 0);
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): clean MTLB[%d]\n",
|
||||
pr_warn("%s(%d): clean MTLB[%d]\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
pre->mtlbIndex + i);
|
||||
#endif
|
||||
@@ -3697,7 +3697,7 @@ gckMMU_AllocatePagesEx(
|
||||
)
|
||||
{
|
||||
#if gcdDISABLE_GPU_VIRTUAL_ADDRESS
|
||||
gcmkPRINT("GPU virtual address is disabled.");
|
||||
pr_warn("GPU virtual address is disabled.");
|
||||
return gcvSTATUS_NOT_SUPPORTED;
|
||||
#else
|
||||
return _AllocatePages(Mmu, PageCount, Type, PageType, Secure, PageTable, Address);
|
||||
@@ -3883,7 +3883,7 @@ gckMMU_DumpPageTableEntry(
|
||||
* stlbEntryNum
|
||||
+ stlb;
|
||||
|
||||
gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
|
||||
pr_warn(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3905,7 +3905,7 @@ gckMMU_DumpPageTableEntry(
|
||||
(gctUINT32_PTR)((gctUINT8_PTR)stlbChunkObj->logical + (i * gcdMMU_STLB_1M_SIZE));
|
||||
if (entry == stlbPhysBase)
|
||||
{
|
||||
gcmkPRINT(" Page table entry = 0x%08X", stlbLogical[stlb]);
|
||||
pr_warn(" Page table entry = 0x%08X", stlbLogical[stlb]);
|
||||
found = gcvTRUE;
|
||||
break;
|
||||
}
|
||||
@@ -3941,7 +3941,7 @@ gckMMU_CheckSaftPage(
|
||||
{
|
||||
if (safeLogical[offsets[i]] != 0)
|
||||
{
|
||||
gcmkPRINT("%s(%d) safe page is over written [%d] = %x",
|
||||
pr_warn("%s(%d) safe page is over written [%d] = %x",
|
||||
__FUNCTION__, __LINE__, i, safeLogical[offsets[i]]);
|
||||
}
|
||||
}
|
||||
@@ -3992,7 +3992,7 @@ gckMMU_DumpAddressSpace(
|
||||
|
||||
if (!used)
|
||||
{
|
||||
gcmkPRINT("Available Range [%d - %d)", i, i + numPages);
|
||||
pr_warn("Available Range [%d - %d)", i, i + numPages);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4012,13 +4012,13 @@ gckMMU_DumpRecentFreedAddress(
|
||||
|
||||
if (queue->count)
|
||||
{
|
||||
gcmkPRINT(" Recent %d freed GPU address ranges:", queue->count);
|
||||
pr_warn(" Recent %d freed GPU address ranges:", queue->count);
|
||||
|
||||
for (i = 0; i < queue->count; i++)
|
||||
{
|
||||
gckQUEUE_GetData(queue, i, &data);
|
||||
|
||||
gcmkPRINT(" [%08X - %08X]", data->addressData.start, data->addressData.end);
|
||||
pr_warn(" [%08X - %08X]", data->addressData.start, data->addressData.end);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4190,7 +4190,7 @@ gckMMU_FillFlatMapping(
|
||||
/* Flat mapping in page table. */
|
||||
_WritePageEntry(stlbEntry, _SetPage(physBase + i * gcdMMU_PAGE_4K_SIZE, 0, gcvTRUE));
|
||||
#if gcdMMU_TABLE_DUMP
|
||||
gckOS_Print("%s(%d): insert MTLB[%d] STLB[%d]: %08x\n",
|
||||
pr_warn("%s(%d): insert MTLB[%d] STLB[%d]: %08x\n",
|
||||
__FUNCTION__, __LINE__,
|
||||
(physBase & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT,
|
||||
((physBase & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT) + i,
|
||||
@@ -4407,7 +4407,7 @@ gckMMU_SetupSRAM(
|
||||
{
|
||||
if (Device->showSRAMMapInfo)
|
||||
{
|
||||
gcmkPRINT("Galcore Info: MMU mapped core%d SRAM base=0x%llx size=0x%x",
|
||||
pr_warn("Galcore Info: MMU mapped core%d SRAM base=0x%llx size=0x%x",
|
||||
i,
|
||||
reservedBase,
|
||||
reservedSize
|
||||
@@ -4547,7 +4547,7 @@ gckMMU_SetupSRAM(
|
||||
|
||||
if (Device->showSRAMMapInfo)
|
||||
{
|
||||
gcmkPRINT("Galcore Info: MMU mapped core %d SRAM[%d] hardware virtual address=0x%x size=0x%x",
|
||||
pr_warn("Galcore Info: MMU mapped core %d SRAM[%d] hardware virtual address=0x%x size=0x%x",
|
||||
Hardware->core,
|
||||
i,
|
||||
kernel->sRAMBaseAddresses[i],
|
||||
@@ -4577,7 +4577,7 @@ gckMMU_SetupSRAM(
|
||||
|
||||
if (Device->showSRAMMapInfo)
|
||||
{
|
||||
gcmkPRINT("Galcore Info: MMU mapped external shared SRAM[%d] CPU view base=0x%llx GPU view base=0x%llx GPU virtual address=0x%x size=0x%x",
|
||||
pr_warn("Galcore Info: MMU mapped external shared SRAM[%d] CPU view base=0x%llx GPU view base=0x%llx GPU virtual address=0x%x size=0x%x",
|
||||
i,
|
||||
Device->extSRAMBases[i],
|
||||
Device->extSRAMGPUBases[i],
|
||||
|
||||
@@ -189,10 +189,10 @@ _Policy(
|
||||
|
||||
if (Dvfs->totalConfig % 100 == 0)
|
||||
{
|
||||
gcmkPRINT("=======================================================");
|
||||
gcmkPRINT("GPU Load: %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
|
||||
pr_warn("=======================================================");
|
||||
pr_warn("GPU Load: %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
|
||||
8, 16, 24, 32, 40, 48, 56, 64);
|
||||
gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
|
||||
pr_warn(" %-8d %-8d %-8d %-8d %-8d %-8d %-8d %-8d",
|
||||
_GetLoadHistory(Dvfs,2, 0),
|
||||
_GetLoadHistory(Dvfs,2, 1),
|
||||
_GetLoadHistory(Dvfs,2, 2),
|
||||
@@ -203,9 +203,9 @@ _Policy(
|
||||
_GetLoadHistory(Dvfs,2, 7)
|
||||
);
|
||||
|
||||
gcmkPRINT("Frequency(MHz) %-8d %-8d %-8d %-8d %-8d",
|
||||
pr_warn("Frequency(MHz) %-8d %-8d %-8d %-8d %-8d",
|
||||
58, 120, 240, 360, 480);
|
||||
gcmkPRINT(" %-8d %-8d %-8d %-8d %-8d",
|
||||
pr_warn(" %-8d %-8d %-8d %-8d %-8d",
|
||||
_GetFrequencyHistory(Dvfs, 58),
|
||||
_GetFrequencyHistory(Dvfs,120),
|
||||
_GetFrequencyHistory(Dvfs,240),
|
||||
|
||||
@@ -4552,7 +4552,7 @@ gckVIDMEM_NODE_WrapUserMemory(
|
||||
|
||||
if (IS_ERR(gcmUINT64_TO_PTR(Desc->dmabuf)))
|
||||
{
|
||||
gcmkPRINT("Wrap memory: invalid dmabuf from kernel.\n");
|
||||
pr_err("Wrap memory: invalid dmabuf from kernel.\n");
|
||||
|
||||
gcmkFOOTER();
|
||||
return gcvSTATUS_INVALID_ARGUMENT;
|
||||
@@ -4562,7 +4562,7 @@ gckVIDMEM_NODE_WrapUserMemory(
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkPRINT("Wrap memory: invalid dmabuf fd.\n");
|
||||
pr_err("Wrap memory: invalid dmabuf fd.\n");
|
||||
|
||||
gcmkFOOTER();
|
||||
return gcvSTATUS_INVALID_ARGUMENT;
|
||||
|
||||
@@ -197,12 +197,12 @@ _DmaAlloc(
|
||||
#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
|
||||
if (set_memory_wc((unsigned long)(mdlPriv->kvaddr), NumPages) != 0)
|
||||
{
|
||||
printk("%s(%d): failed to set_memory_wc\n", __func__, __LINE__);
|
||||
pr_debug("%s(%d): failed to set_memory_wc\n", __func__, __LINE__);
|
||||
}
|
||||
#else
|
||||
if (set_memory_uc((unsigned long)(mdlPriv->kvaddr), NumPages) != 0)
|
||||
{
|
||||
printk("%s(%d): failed to set_memory_uc\n", __func__, __LINE__);
|
||||
pr_debug("%s(%d): failed to set_memory_uc\n", __func__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -591,12 +591,12 @@ _GFPAlloc(
|
||||
#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
|
||||
if (set_memory_wc((unsigned long)page_address(mdlPriv->contiguousPages), NumPages) != 0)
|
||||
{
|
||||
printk("%s(%d): failed to set_memory_wc\n", __func__, __LINE__);
|
||||
pr_debug("%s(%d): failed to set_memory_wc\n", __func__, __LINE__);
|
||||
}
|
||||
#else
|
||||
if (set_memory_uc((unsigned long)page_address(mdlPriv->contiguousPages), NumPages) != 0)
|
||||
{
|
||||
printk("%s(%d): failed to set_memory_uc\n", __func__, __LINE__);
|
||||
pr_debug("%s(%d): failed to set_memory_uc\n", __func__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -665,12 +665,12 @@ _GFPAlloc(
|
||||
#if gcdENABLE_BUFFERABLE_VIDEO_MEMORY
|
||||
if (set_pages_array_wc(mdlPriv->nonContiguousPages, NumPages))
|
||||
{
|
||||
printk("%s(%d): failed to set_pages_array_wc\n", __func__, __LINE__);
|
||||
pr_debug("%s(%d): failed to set_pages_array_wc\n", __func__, __LINE__);
|
||||
}
|
||||
#else
|
||||
if (set_pages_array_uc(mdlPriv->nonContiguousPages, NumPages))
|
||||
{
|
||||
printk("%s(%d): failed to set_pages_array_uc\n", __func__, __LINE__);
|
||||
pr_debug("%s(%d): failed to set_pages_array_uc\n", __func__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -195,7 +195,7 @@ reserved_mem_attach(
|
||||
|
||||
if (!region)
|
||||
{
|
||||
printk("request mem %s(0x%lx - 0x%lx) failed\n",
|
||||
pr_debug("request mem %s(0x%lx - 0x%lx) failed\n",
|
||||
res->name, res->start, res->start + res->size - 1);
|
||||
|
||||
kfree(res);
|
||||
@@ -314,13 +314,13 @@ reserved_mem_unmap_user(
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
|
||||
if (vm_munmap((unsigned long)MdlMap->vmaAddr - res->offset_in_page, res->size) < 0)
|
||||
{
|
||||
printk("%s: vm_munmap failed\n", __func__);
|
||||
pr_debug("%s: vm_munmap failed\n", __func__);
|
||||
}
|
||||
#else
|
||||
down_write(¤t_mm_mmap_sem);
|
||||
if (do_munmap(current->mm, (unsigned long)MdlMap->vmaAddr - res->offset_in_page, res->size) < 0)
|
||||
{
|
||||
printk("%s: do_munmap failed\n", __func__);
|
||||
pr_debug("%s: do_munmap failed\n", __func__);
|
||||
}
|
||||
up_write(¤t_mm_mmap_sem);
|
||||
#endif
|
||||
|
||||
@@ -225,14 +225,14 @@ static int import_page_map(gckOS Os, struct um_desc *um,
|
||||
#endif
|
||||
if (unlikely(result < 0))
|
||||
{
|
||||
printk("[galcore]: %s: sg_alloc_table_from_pages failed\n", __FUNCTION__);
|
||||
pr_debug("[galcore]: %s: sg_alloc_table_from_pages failed\n", __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
result = dma_map_sg(galcore_device, um->sgt.sgl, um->sgt.nents, DMA_TO_DEVICE);
|
||||
if (unlikely(result != um->sgt.nents))
|
||||
{
|
||||
printk("[galcore]: %s: dma_map_sg failed\n", __FUNCTION__);
|
||||
pr_debug("[galcore]: %s: dma_map_sg failed\n", __FUNCTION__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -393,7 +393,7 @@ static int import_pfn_map(gckOS Os, struct um_desc *um,
|
||||
#endif
|
||||
if (unlikely(result < 0))
|
||||
{
|
||||
printk("[galcore]: %s: sg_alloc_table_from_pages failed\n", __FUNCTION__);
|
||||
pr_debug("[galcore]: %s: sg_alloc_table_from_pages failed\n", __FUNCTION__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ static int import_pfn_map(gckOS Os, struct um_desc *um,
|
||||
#else
|
||||
kfree(um->sgt.sgl);
|
||||
#endif
|
||||
printk("[galcore]: %s: dma_map_sg failed\n", __FUNCTION__);
|
||||
pr_debug("[galcore]: %s: dma_map_sg failed\n", __FUNCTION__);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ gckOS_ImportAllocators(
|
||||
|
||||
if (gcmIS_ERROR(status))
|
||||
{
|
||||
gcmkPRINT("["DEVICE_NAME"]: Can't construct allocator(%s)",
|
||||
pr_err("["DEVICE_NAME"]: Can't construct allocator(%s)",
|
||||
allocatorArray[i].name);
|
||||
|
||||
continue;
|
||||
|
||||
@@ -1288,7 +1288,7 @@ gckOS_DumpBuffer(
|
||||
/* memory dump below. */
|
||||
if (Type >= gcvDUMP_BUFFER_TYPE_COUNT)
|
||||
{
|
||||
gcmkPRINT("#[ERROR: invalid buffer type]\n");
|
||||
pr_err("#[ERROR: invalid buffer type]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,13 +72,24 @@
|
||||
#include <linux/export.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
#define _GC_OBJ_ZONE gcvZONE_DEVICE
|
||||
|
||||
#define MAX_TIMESTAMPS 10
|
||||
#define MAX_HW_PROCESS_TIME 90000000
|
||||
|
||||
static struct timer_list my_timer;
|
||||
static struct workqueue_struct *my_workqueue;
|
||||
static struct work_struct my_work;
|
||||
|
||||
static gckGALDEVICE galDevice;
|
||||
|
||||
extern gcTA globalTA[gcdMAX_GPU_COUNT];
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#if defined(CONFIG_CPU_CSKYV2) && LINUX_VERSION_CODE <= KERNEL_VERSION(3,0,8)
|
||||
static void
|
||||
@@ -323,9 +334,9 @@ int gc_load_show(void* m, void* data)
|
||||
{
|
||||
int len = 0;
|
||||
gctUINT32 i = 0;
|
||||
|
||||
|
||||
gckGALDEVICE device = galDevice;
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void* ptr = m;
|
||||
#else
|
||||
@@ -335,8 +346,8 @@ int gc_load_show(void* m, void* data)
|
||||
if (!device) {
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
for (i = 0; i <= gcvCORE_2D_MAX; i++)
|
||||
{
|
||||
@@ -1251,7 +1262,7 @@ static int set_clk(const char* buf)
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("Error: command format must be this: echo \"0 32 32\" > /sys/kernel/debug/gc/clk\n");
|
||||
pr_err("Error: command format must be this: echo \"0 32 32\" > /sys/kernel/debug/gc/clk\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1264,10 +1275,10 @@ static int set_clk(const char* buf)
|
||||
}
|
||||
|
||||
if (3 == sscanf(data, "%d %d %d", &dumpCore, &clkScale[0], &clkScale[1])) {
|
||||
printk("Change core:%d MC scale:%d SH scale:%d\n",
|
||||
pr_err("Change core:%d MC scale:%d SH scale:%d\n",
|
||||
dumpCore, clkScale[0], clkScale[1]);
|
||||
} else {
|
||||
printk("usage: echo \"0 32 32\" > clk\n");
|
||||
pr_err("usage: echo \"0 32 32\" > clk\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1279,7 +1290,7 @@ static int set_clk(const char* buf)
|
||||
}
|
||||
else
|
||||
{
|
||||
printk("Error: invalid core\n");
|
||||
pr_err("Error: invalid core\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1354,7 +1365,7 @@ static int debugfs_copy_from_user(char *k_buf, const char __user *buf, size_t co
|
||||
ret = copy_from_user(k_buf, buf, count);
|
||||
if (ret != 0)
|
||||
{
|
||||
printk("Error: lost data: %d\n", (int)ret);
|
||||
pr_err("Error: lost data: %d\n", (int)ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1844,7 +1855,7 @@ _SetupContiguousVidMem(
|
||||
|
||||
if (Args->showArgs)
|
||||
{
|
||||
gcmkPRINT("Galcore Info: ContiguousBase=0x%llx ContiguousSize=0x%zx\n", device->contiguousBase, device->contiguousSize);
|
||||
pr_warn("Galcore Info: ContiguousBase=0x%llx ContiguousSize=0x%zx\n", device->contiguousBase, device->contiguousSize);
|
||||
}
|
||||
|
||||
OnError:
|
||||
@@ -2068,7 +2079,7 @@ _SetupIsr(
|
||||
gcmkONERROR(gcvSTATUS_GENERIC_IO);
|
||||
}
|
||||
|
||||
gcmkPRINT("galcore: polling core%d int state\n", Core);
|
||||
pr_err("galcore: polling core%d int state\n", Core);
|
||||
|
||||
Device->isrThread[Core] = task;
|
||||
Device->isrInitializeds[Core] = gcvTRUE;
|
||||
@@ -2332,7 +2343,7 @@ _StopPreemptThread(
|
||||
/******************************************************************************\
|
||||
******************************* G2D Devfreq support START***********************
|
||||
\******************************************************************************/
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
static int gc_df_target(struct device * dev, unsigned long *freq, u32 flags) {
|
||||
|
||||
int i = 0;
|
||||
@@ -2369,7 +2380,7 @@ static int gc_df_target(struct device * dev, unsigned long *freq, u32 flags) {
|
||||
for(i = 0; i < gcvCORE_2D_MAX; i++) {
|
||||
if(device->kernels[i]) {
|
||||
hardware = device->kernels[i]->hardware;
|
||||
if(hardware->clockState) {
|
||||
if(hardware->os->clockStates[i]) {
|
||||
gckHARDWARE_SetClock(hardware, i, _freq, _freq);
|
||||
device->kernels[i]->cur_freq = *freq;
|
||||
}
|
||||
@@ -2425,7 +2436,7 @@ static int gc_df_get_cur_freq(struct device *dev, unsigned long *freq) {
|
||||
struct devfreq_simple_ondemand_data galcore_gov_data;
|
||||
|
||||
static struct devfreq_dev_profile gc_df_profile = {
|
||||
.polling_ms = 500,
|
||||
.polling_ms = 50,
|
||||
.target = gc_df_target,
|
||||
.get_dev_status = gc_df_status,
|
||||
.get_cur_freq = gc_df_get_cur_freq,
|
||||
@@ -2441,7 +2452,7 @@ g2d_EnableDevfreq(void) {
|
||||
|
||||
ret = dev_pm_opp_of_add_table(galcore_device);
|
||||
if(ret) {
|
||||
gcmkPRINT("add table failed \n");
|
||||
pr_err("add table failed \n");
|
||||
}
|
||||
|
||||
new_clk = devm_clk_get(galcore_device, "cclk");
|
||||
@@ -2465,17 +2476,255 @@ g2d_EnableDevfreq(void) {
|
||||
galDevice->g2d_devfreq = devm_devfreq_add_device(galcore_device, &gc_df_profile, DEVFREQ_GOV_SIMPLE_ONDEMAND, &galcore_gov_data);
|
||||
|
||||
if(IS_ERR(galDevice->g2d_devfreq)) {
|
||||
gcmkPRINT("Errot: init devgreq %lx\n", (unsigned long)galcore_device);
|
||||
pr_err("Errot: init devgreq %lx\n", (unsigned long)galcore_device);
|
||||
status = gcvSTATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/******************************************************************************\
|
||||
******************************* G2D Devfreq support END ************************
|
||||
******************************* Driver status query ****************************
|
||||
\******************************************************************************/
|
||||
|
||||
gctUINT64 cur_on = 0, cur_idle = 0, cur_suspend = 0, cur_off = 0,
|
||||
busy_time = 0, total_time = 0, freq = 396000000;
|
||||
gctUINT64 on = 0;
|
||||
gctUINT64 off = 0;
|
||||
gctUINT64 idle = 0;
|
||||
gctUINT64 suspend = 0;
|
||||
int dev_loading_percent;
|
||||
int dev_loading_max_percent;
|
||||
int updatePeriod_ms = 50;
|
||||
|
||||
static ssize_t log_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
ssize_t len = 0;
|
||||
gctINT i, j,ct, pid, id = 0;
|
||||
gctINT devIncenum = 0;
|
||||
char name[24];
|
||||
gceSTATUS status;
|
||||
gckVIDMEM memory;
|
||||
gctUINT32 free = 0, used = 0, total = 0, minFree = 0, maxUsed = 0;
|
||||
gckGALDEVICE device = galDevice;
|
||||
gcsDATABASE_PTR database;
|
||||
gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
|
||||
gckKERNEL kernel = _GetValidKernel(device);
|
||||
ktime_t result;
|
||||
|
||||
status = gckKERNEL_GetVideoMemoryPool(kernel, gcvPOOL_SYSTEM, &memory);
|
||||
|
||||
if (gcmIS_SUCCESS(status))
|
||||
{
|
||||
gcmkVERIFY_OK(
|
||||
gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
|
||||
|
||||
free = memory->freeBytes;
|
||||
minFree = memory->minFreeBytes;
|
||||
used = memory->bytes - memory->freeBytes;
|
||||
maxUsed = memory->bytes - memory->minFreeBytes;
|
||||
total = memory->bytes;
|
||||
|
||||
gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
|
||||
}
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"[G2D] Version: %s\n"
|
||||
"Build Time【%s,%s,%s,%s】\n"
|
||||
"-------------------------------------------MODULE PARAM----------------------------------\n"
|
||||
"updatePeriod_ms\n"
|
||||
" %d\n",
|
||||
gcvVERSION_STRING, utsname()->sysname, utsname()->release, utsname()->version, utsname()->machine,
|
||||
updatePeriod_ms
|
||||
);
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"-------------------------------------------INSTANCE INFO---------------------------------\n");
|
||||
|
||||
if (!kernel)
|
||||
return -ENXIO;
|
||||
|
||||
gcmkVERIFY_OK(gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
|
||||
if (kernel->db->idleTime)
|
||||
{
|
||||
/* Record idle time if DB upated. */
|
||||
kernel->db->idleTime = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
|
||||
{
|
||||
for (database = kernel->db->db[i];
|
||||
database != gcvNULL;
|
||||
database = database->next)
|
||||
{
|
||||
static const char * otherCounterNames[] = {
|
||||
"AllocContiguous",
|
||||
"MapMemory",
|
||||
};
|
||||
gcsDATABASE_COUNTERS * otherCounters[] = {
|
||||
&database->contiguous,
|
||||
&database->mapMemory,
|
||||
};
|
||||
gcsDATABASE_COUNTERS * counter;
|
||||
pid = database->processID;
|
||||
|
||||
|
||||
for(j = 0; j < MAX_TIMESTAMPS; j++) {
|
||||
if(database->start_times[j] == 0) continue;
|
||||
if(database->end_times[j] - database->start_times[j] > result &&
|
||||
database->end_times[j] - database->start_times[j] < MAX_HW_PROCESS_TIME) {
|
||||
result = database->end_times[j] - database->start_times[j];
|
||||
if(result > database->max_hw_time) {
|
||||
database->max_hw_time = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gcmkVERIFY_OK(gckOS_GetProcessNameByPid(pid, gcmSIZEOF(name), name));
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"ID: %d ProId: %-8d NAME: %s\n"
|
||||
"\n",
|
||||
id, pid, name
|
||||
);
|
||||
id++;
|
||||
devIncenum++;
|
||||
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
" Current Maximum Total\n");
|
||||
for (ct = 0; ct < gcmCOUNTOF(otherCounterNames); ct++)
|
||||
{
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"%-16s %16lld %16lld %16lld\n",
|
||||
otherCounterNames[ct],
|
||||
otherCounters[ct]->bytes,
|
||||
otherCounters[ct]->maxBytes,
|
||||
otherCounters[ct]->totalBytes);
|
||||
|
||||
}
|
||||
counter = &database->vidMemPool[gcvPOOL_VIRTUAL];
|
||||
virtualCounter.bytes += counter->bytes;
|
||||
virtualCounter.maxBytes += counter->maxBytes;
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"HwProcNs %lld %lld \n",
|
||||
result,database->max_hw_time);
|
||||
result = 0;
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"\n");
|
||||
|
||||
memset(database->start_times, 0, sizeof(database->start_times));
|
||||
memset(database->end_times, 0, sizeof(database->end_times));
|
||||
database->st = 0;
|
||||
|
||||
}
|
||||
}
|
||||
gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"-------------------------------------------MODULE STATUS---------------------------------\n"
|
||||
"DevInstanceNum DevLoading_%% DevLoadingMax_%%\n"
|
||||
"%d %d %d\n",
|
||||
devIncenum, dev_loading_percent, dev_loading_max_percent
|
||||
);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"-----------------------------------------VIDEO MEMORY INFO-------------------------------\n"
|
||||
" POOL SYSTEM:\n"
|
||||
" Free Minfree Used MaxUsed Total\n"
|
||||
"%10u B %10u B %10u B %10u B %10u B\n"
|
||||
"\n"
|
||||
" POOL VIRTUAL:\n"
|
||||
" Used MaxUsed\n"
|
||||
"%10llu B %10llu B\n",
|
||||
free, minFree, used, maxUsed,total,
|
||||
virtualCounter.bytes, virtualCounter.maxBytes);
|
||||
|
||||
gckHARDWARE_QueryStateTimer(kernel->hardware, &on, &off, &idle, &suspend);
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"--------------------------------------------IDLE INFO------------------------------------\n"
|
||||
" On Off Suspend\n"
|
||||
"%lld ns %lld ns %lld ns",
|
||||
on, off, suspend);
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"\n\n");
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t log_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
dev_loading_max_percent = 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t updatePeriod_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf,"%u\n",updatePeriod_ms);
|
||||
}
|
||||
|
||||
static void timer_callback(struct timer_list *t) {
|
||||
queue_work(my_workqueue, &my_work);
|
||||
mod_timer(t, jiffies + msecs_to_jiffies(updatePeriod_ms));
|
||||
}
|
||||
|
||||
static void my_work_func(struct work_struct *work)
|
||||
{
|
||||
gckGALDEVICE device = galDevice;
|
||||
gckKERNEL kernel = _GetValidKernel(device);
|
||||
int i;
|
||||
|
||||
gckHARDWARE_QueryStateTimer(kernel->hardware, &on, &off, &idle, &suspend);
|
||||
|
||||
for(i = 0; i < gcvCORE_2D_MAX; i++) {
|
||||
if(device->kernels[i]) {
|
||||
freq = device->kernels[i]->cur_freq;
|
||||
}
|
||||
}
|
||||
|
||||
busy_time = on - cur_on;
|
||||
total_time = on - cur_on + idle - cur_idle + suspend - cur_suspend + off - cur_off;
|
||||
dev_loading_percent = busy_time * 100 / total_time / (396000000 / freq);
|
||||
if(dev_loading_max_percent < dev_loading_percent) {
|
||||
dev_loading_max_percent = dev_loading_percent;
|
||||
}
|
||||
cur_on = on;
|
||||
cur_idle = idle;
|
||||
cur_suspend = suspend;
|
||||
cur_off = off;
|
||||
}
|
||||
|
||||
static ssize_t updatePeriod_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
char *start = (char *)buf;
|
||||
updatePeriod_ms = simple_strtoul(start, &start, 0);
|
||||
if(updatePeriod_ms <= 0) {
|
||||
del_timer(&my_timer);
|
||||
if (my_workqueue)
|
||||
destroy_workqueue(my_workqueue);
|
||||
} else {
|
||||
my_workqueue = create_workqueue("my_workqueue");
|
||||
INIT_WORK(&my_work, my_work_func);
|
||||
timer_setup(&my_timer, timer_callback, 0);
|
||||
mod_timer(&my_timer, jiffies + msecs_to_jiffies(updatePeriod_ms));
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute log_attr = __ATTR(log, 0664, log_show, log_store);
|
||||
|
||||
static struct kobj_attribute updatePeriod_attr = __ATTR(updatePeriod_ms, 0664, updatePeriod_show, updatePeriod_store);
|
||||
|
||||
static struct attribute *attrs[] = {
|
||||
&log_attr.attr,
|
||||
&updatePeriod_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group xrp_dev_attr_group = {
|
||||
.name = "info",
|
||||
.attrs = attrs,
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -2502,7 +2751,7 @@ gckGALDEVICE_Construct(
|
||||
gckGALDEVICE device;
|
||||
gceSTATUS status = gcvSTATUS_OK;
|
||||
gctUINT64 isrPolling = -1;
|
||||
gctINT32 i;
|
||||
gctINT32 i, ret;
|
||||
|
||||
gcmkHEADER_ARG("Platform=%p Args=%p", Platform, Args);
|
||||
|
||||
@@ -2553,7 +2802,7 @@ gckGALDEVICE_Construct(
|
||||
else
|
||||
{
|
||||
#if USE_LINUX_PCIE
|
||||
gcmkPRINT("register should be mapped in platform layer");
|
||||
pr_warn("register should be mapped in platform layer");
|
||||
#endif
|
||||
if (!request_mem_region(physical,
|
||||
device->requestedRegisterMemSizes[i],
|
||||
@@ -2846,8 +3095,21 @@ gckGALDEVICE_Construct(
|
||||
|
||||
/* Return pointer to the device. */
|
||||
*Device = galDevice = device;
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
g2d_EnableDevfreq();
|
||||
devfreq_suspend_device(galDevice->g2d_devfreq);
|
||||
#endif
|
||||
ret = sysfs_create_group(&galcore_device->kobj, &xrp_dev_attr_group);
|
||||
if (ret) {
|
||||
dev_err(galcore_device, "Failed to create xrp dev sysfs.\n");
|
||||
goto OnError;
|
||||
}
|
||||
my_workqueue = create_workqueue("my_workqueue");
|
||||
|
||||
INIT_WORK(&my_work, my_work_func);
|
||||
timer_setup(&my_timer, timer_callback, 0);
|
||||
|
||||
mod_timer(&my_timer, jiffies + msecs_to_jiffies(100));
|
||||
|
||||
OnError:
|
||||
if (gcmIS_ERROR(status))
|
||||
@@ -2886,7 +3148,12 @@ gckGALDEVICE_Destroy(
|
||||
gckKERNEL kernel = gcvNULL;
|
||||
|
||||
gcmkHEADER_ARG("Device=%p", Device);
|
||||
|
||||
|
||||
sysfs_remove_group(&galcore_device->kobj, &xrp_dev_attr_group);
|
||||
del_timer(&my_timer);
|
||||
if (my_workqueue) {
|
||||
destroy_workqueue(my_workqueue);
|
||||
}
|
||||
if (Device != gcvNULL)
|
||||
{
|
||||
/* Grab the first available kernel */
|
||||
|
||||
@@ -150,11 +150,12 @@ typedef struct _gckGALDEVICE
|
||||
/* gctsOs object for trust application. */
|
||||
gctaOS taos;
|
||||
|
||||
/*Number of devices opened*/
|
||||
/*Number of devices opened*/
|
||||
atomic_t openNum;
|
||||
/*object of devfreq add device*/
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
struct devfreq *g2d_devfreq;
|
||||
|
||||
#endif
|
||||
#if gcdENABLE_DRM
|
||||
void * drm;
|
||||
#endif
|
||||
|
||||
@@ -644,7 +644,7 @@ gckOS_DumpParam(
|
||||
{
|
||||
gctINT i;
|
||||
|
||||
printk("Galcore options:\n");
|
||||
gcmkPRINT("Galcore options:\n");
|
||||
|
||||
#if USE_LINUX_PCIE
|
||||
if (bar != -1)
|
||||
@@ -821,8 +821,10 @@ static int drv_open(
|
||||
filp->private_data = data;
|
||||
|
||||
/* Success. */
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
atomic_inc_return(&galDevice->openNum);
|
||||
devfreq_resume_device(galDevice->g2d_devfreq);
|
||||
#endif
|
||||
gcmkFOOTER_NO();
|
||||
return 0;
|
||||
}
|
||||
@@ -888,10 +890,12 @@ static int drv_release(
|
||||
|
||||
kfree(data);
|
||||
filp->private_data = NULL;
|
||||
|
||||
#ifdef CONFIG_PM_DEVFREQ
|
||||
if(atomic_dec_return(&galDevice->openNum) == 0) {
|
||||
devfreq_suspend_device(galDevice->g2d_devfreq);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Success. */
|
||||
ret = 0;
|
||||
|
||||
@@ -1159,7 +1163,7 @@ static int drv_init(void)
|
||||
|
||||
gcmkHEADER();
|
||||
|
||||
printk(KERN_INFO "Galcore version %s\n", gcvVERSION_STRING);
|
||||
pr_info("Galcore version %s\n", gcvVERSION_STRING);
|
||||
|
||||
if (showArgs)
|
||||
{
|
||||
@@ -1384,11 +1388,11 @@ static int __devinit gpu_probe(struct platform_device *pdev)
|
||||
contiguousBaseCap = platform->params.contiguousBase;
|
||||
contiguousSizeCap = platform->params.contiguousSize;
|
||||
|
||||
gcmkPRINT("Capture only mode is enabled in Hal Kernel.");
|
||||
pr_warn("Capture only mode is enabled in Hal Kernel.");
|
||||
|
||||
if ((contiguousBaseCap + contiguousSizeCap) > 0x80000000)
|
||||
{
|
||||
gcmkPRINT("Capture only mode: contiguousBase + contiguousSize > 2G, there is error in CModel and old MMU version RTL simulation.");
|
||||
pr_err("Capture only mode: contiguousBase + contiguousSize > 2G, there is error in CModel and old MMU version RTL simulation.");
|
||||
}
|
||||
|
||||
for (i = 0; i < gcvCORE_COUNT; i++)
|
||||
@@ -1437,7 +1441,7 @@ static int __devinit gpu_probe(struct platform_device *pdev)
|
||||
|
||||
if (powerManagement == 0)
|
||||
{
|
||||
gcmkPRINT("[galcore warning]: power saveing is disabled.");
|
||||
pr_err("[galcore warning]: power saveing is disabled.");
|
||||
}
|
||||
|
||||
ret = drv_init();
|
||||
@@ -1461,14 +1465,14 @@ static int __devinit gpu_probe(struct platform_device *pdev)
|
||||
}
|
||||
}
|
||||
|
||||
gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
|
||||
pr_info("Failed to register gpu driver: %d\n", ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcmkFOOTER_NO();
|
||||
}
|
||||
|
||||
gcmkFOOTER_ARG(KERN_INFO "Success ret=%d", ret);
|
||||
pr_info("Success ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1649,7 +1653,7 @@ static int __init gpu_init(void)
|
||||
|
||||
if (ret || !platform)
|
||||
{
|
||||
printk(KERN_ERR "galcore: Soc platform init failed.\n");
|
||||
pr_err("galcore: Soc platform init failed.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@@ -1657,7 +1661,7 @@ static int __init gpu_init(void)
|
||||
|
||||
if (ret)
|
||||
{
|
||||
printk(KERN_ERR "galcore: gpu_init() failed to register driver!\n");
|
||||
pr_err("galcore: gpu_init() failed to register driver!\n");
|
||||
gckPLATFORM_Terminate(platform);
|
||||
platform = NULL;
|
||||
return -ENODEV;
|
||||
|
||||
@@ -905,7 +905,7 @@ OnError:
|
||||
{
|
||||
drm_dev_unref(drm);
|
||||
}
|
||||
printk(KERN_ERR "galcore: Failed to setup drm device.\n");
|
||||
pr_err("galcore: Failed to setup drm device.\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ gckIOMMU_Construct(
|
||||
|
||||
*Iommu = iommu;
|
||||
|
||||
gcmkPRINT("[galcore]: Enable IOMMU\n");
|
||||
pr_debug("[galcore]: Enable IOMMU\n");
|
||||
OnError:
|
||||
if (gcmIS_ERROR(status))
|
||||
{
|
||||
|
||||
@@ -1664,7 +1664,7 @@ gckOS_RequestReservedMemory(
|
||||
allocator = _FindAllocator(Os, gcvALLOC_FLAG_LINUX_RESERVED_MEM);
|
||||
if (!allocator)
|
||||
{
|
||||
gcmkPRINT("reserved-mem allocator not integrated!");
|
||||
pr_err("reserved-mem allocator not integrated!");
|
||||
gcmkONERROR(gcvSTATUS_GENERIC_IO);
|
||||
}
|
||||
|
||||
@@ -1913,7 +1913,7 @@ gckOS_ReadRegisterEx(
|
||||
* 2. In non-irq context, register access should not be called,
|
||||
* otherwise it's driver bug.
|
||||
*/
|
||||
printk(KERN_ERR "[galcore]: %s(%d) GPU[%d] external clock off",
|
||||
pr_err("[galcore]: %s(%d) GPU[%d] external clock off",
|
||||
__func__, __LINE__, Core);
|
||||
gcmkBUG_ON(1);
|
||||
return gcvSTATUS_GENERIC_IO;
|
||||
@@ -1924,7 +1924,7 @@ gckOS_ReadRegisterEx(
|
||||
|
||||
#if gcdDUMP_AHB_ACCESS
|
||||
/* Dangerous to print in interrupt context, skip. */
|
||||
gcmkPRINT("@[RD %d] %08x %08x", Core, Address, *Data);
|
||||
pr_warn("@[RD %d] %08x %08x", Core, Address, *Data);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1954,7 +1954,7 @@ _WriteRegisterEx(
|
||||
{
|
||||
spin_unlock(&Os->registerAccessLock);
|
||||
|
||||
printk(KERN_ERR "[galcore]: %s(%d) GPU[%d] external clock off",
|
||||
pr_err("[galcore]: %s(%d) GPU[%d] external clock off",
|
||||
__func__, __LINE__, Core);
|
||||
|
||||
/* Driver bug: register write when clock off. */
|
||||
@@ -1980,7 +1980,7 @@ _WriteRegisterEx(
|
||||
{
|
||||
spin_unlock_irqrestore(&Os->registerAccessLock, flags);
|
||||
|
||||
printk(KERN_ERR "[galcore]: %s(%d) GPU[%d] external clock off",
|
||||
pr_err("[galcore]: %s(%d) GPU[%d] external clock off",
|
||||
__func__, __LINE__, Core);
|
||||
|
||||
/* Driver bug: register write when clock off. */
|
||||
@@ -1993,7 +1993,7 @@ _WriteRegisterEx(
|
||||
|
||||
#if gcdDUMP_AHB_ACCESS
|
||||
/* Dangerous to print in interrupt context, skip. */
|
||||
gcmkPRINT("@[WR %d] %08x %08x", Core, Address, Data);
|
||||
pr_warn("@[WR %d] %08x %08x", Core, Address, Data);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4462,7 +4462,7 @@ _CacheOperation(
|
||||
|
||||
if (!mdl || !mdl->allocator)
|
||||
{
|
||||
gcmkPRINT("[galcore]: %s: Logical=%p no mdl", __FUNCTION__, Logical);
|
||||
pr_err("[galcore]: %s: Logical=%p no mdl", __FUNCTION__, Logical);
|
||||
return gcvSTATUS_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
@@ -7600,7 +7600,7 @@ gckOS_WrapMemory(
|
||||
{
|
||||
/* Won't enter here currently, the caller confirms the dmabuf is valid. */
|
||||
|
||||
gcmkPRINT("Wrap memory: invalid dmabuf.\n");
|
||||
pr_err("Wrap memory: invalid dmabuf.\n");
|
||||
gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
|
||||
}
|
||||
|
||||
|
||||
@@ -584,7 +584,7 @@ _QueryBarInfo(
|
||||
return;
|
||||
}
|
||||
|
||||
gcmkPRINT("Bar%d addr=0x%x size=0x%x", BarNum, addr, size);
|
||||
pr_warn("Bar%d addr=0x%x size=0x%x", BarNum, addr, size);
|
||||
|
||||
*BarAddr = addr;
|
||||
*BarSize = size;
|
||||
@@ -613,31 +613,31 @@ static int gpu_sub_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
static u64 dma_mask = DMA_40BIT_MASK;
|
||||
#endif
|
||||
|
||||
gcmkPRINT("PCIE DRIVER PROBED");
|
||||
pr_debug("PCIE DRIVER PROBED");
|
||||
if (pci_enable_device(pdev)) {
|
||||
printk(KERN_ERR "galcore: pci_enable_device() failed.\n");
|
||||
pr_err("galcore: pci_enable_device() failed.\n");
|
||||
}
|
||||
|
||||
if (pci_set_dma_mask(pdev, dma_mask)) {
|
||||
printk(KERN_ERR "galcore: Failed to set DMA mask.\n");
|
||||
pr_err("galcore: Failed to set DMA mask.\n");
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (pci_request_regions(pdev, "galcore")) {
|
||||
printk(KERN_ERR "galcore: Failed to get ownership of BAR region.\n");
|
||||
pr_err("galcore: Failed to get ownership of BAR region.\n");
|
||||
}
|
||||
|
||||
#if USE_MSI
|
||||
if (pci_enable_msi(pdev)) {
|
||||
printk(KERN_ERR "galcore: Failed to enable MSI.\n");
|
||||
pr_err("galcore: Failed to enable MSI.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PPC)
|
||||
/* On PPC platform, enable bus master, enable irq. */
|
||||
if (pci_write_config_word(pdev, 0x4, 0x0006) < 0) {
|
||||
printk(KERN_ERR "galcore: Failed to enable bus master on PPC.\n");
|
||||
pr_err("galcore: Failed to enable bus master on PPC.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -824,14 +824,14 @@ int gckPLATFORM_Init(struct platform_driver *pdrv,
|
||||
struct platform_device *default_dev = platform_device_alloc(pdrv->driver.name, -1);
|
||||
|
||||
if (!default_dev) {
|
||||
printk(KERN_ERR "galcore: platform_device_alloc failed.\n");
|
||||
pr_err("galcore: platform_device_alloc failed.\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Add device */
|
||||
ret = platform_device_add(default_dev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "galcore: platform_device_add failed.\n");
|
||||
pr_err("galcore: platform_device_add failed.\n");
|
||||
platform_device_put(default_dev);
|
||||
return ret;
|
||||
}
|
||||
@@ -848,7 +848,7 @@ int gckPLATFORM_Init(struct platform_driver *pdrv,
|
||||
pdrv->driver.of_match_table = gpu_dt_ids;
|
||||
ret = gpu_power_domain_init();
|
||||
if (ret) {
|
||||
printk(KERN_ERR "galcore: gpu_gpc_init failed.\n");
|
||||
pr_err("galcore: gpu_gpc_init failed.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "gc_hal_ta_hardware.h"
|
||||
#include "gc_hal.h"
|
||||
#include "gc_feature_database.h"
|
||||
#include <linux/printk.h>
|
||||
|
||||
|
||||
#define _GC_OBJ_ZONE 1
|
||||
@@ -187,7 +188,7 @@ _IdentifyHardwareByDatabase(
|
||||
|
||||
if (database == gcvNULL)
|
||||
{
|
||||
gcmkPRINT("[galcore]: Feature database is not found,"
|
||||
pr_warn("[galcore]: Feature database is not found,"
|
||||
"chipModel=0x%0x, chipRevision=0x%x, productID=0x%x, ecoID=0x%x, customerID=0x%x",
|
||||
Hardware->chipModel,
|
||||
Hardware->chipRevision,
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "gc_hal_security_interface.h"
|
||||
#include "gc_hal_ta.h"
|
||||
#include "gc_hal.h"
|
||||
#include <linux/printk.h>
|
||||
|
||||
#define _GC_OBJ_ZONE 2
|
||||
/*******************************************************************************
|
||||
@@ -560,11 +561,11 @@ gctaMMU_DumpPagetableEntry(
|
||||
|
||||
stlb = stlbs[mtlb];
|
||||
|
||||
gcmkPRINT(" MTLB entry = %d\n", mtlb);
|
||||
pr_warn(" MTLB entry = %d\n", mtlb);
|
||||
|
||||
gcmkPRINT(" STLB entry = %d\n", stlbOffset);
|
||||
pr_warn(" STLB entry = %d\n", stlbOffset);
|
||||
|
||||
gcmkPRINT(" Offset = 0x%08X (%d)\n", offsetInPage, offsetInPage);
|
||||
pr_warn(" Offset = 0x%08X (%d)\n", offsetInPage, offsetInPage);
|
||||
|
||||
|
||||
if (stlb == gcvNULL)
|
||||
@@ -572,13 +573,13 @@ gctaMMU_DumpPagetableEntry(
|
||||
/* Dmp mtlb entry. */
|
||||
entry = mtlbLogical[mtlb];
|
||||
|
||||
gcmkPRINT(" mtlb entry [%d] = %x", mtlb, entry);
|
||||
pr_warn(" mtlb entry [%d] = %x", mtlb, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
stlbLogical = stlb->logical;
|
||||
|
||||
gcmkPRINT(" stlb entry = 0x%08X", stlbLogical[stlbOffset]);
|
||||
pr_warn(" stlb entry = 0x%08X", stlbLogical[stlbOffset]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2059,6 +2059,12 @@ static void hdmi_av_composer(struct dw_hdmi *hdmi,
|
||||
drm_scdc_set_scrambling(hdmi->ddc, 0);
|
||||
}
|
||||
}
|
||||
else{
|
||||
hdmi_writeb(hdmi, 0, HDMI_FC_SCRAMBLER_CTRL);
|
||||
hdmi_writeb(hdmi, (u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ,
|
||||
HDMI_MC_SWRSTZ);
|
||||
drm_scdc_set_scrambling(hdmi->ddc, 0);
|
||||
}
|
||||
|
||||
/* Set up horizontal active pixel width */
|
||||
hdmi_writeb(hdmi, hdisplay >> 8, HDMI_FC_INHACTV1);
|
||||
|
||||
@@ -135,17 +135,17 @@ static int hx8279_panel_enable(struct drm_panel *panel)
|
||||
if (pinfo->enabled)
|
||||
return 0;
|
||||
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(pinfo->link);
|
||||
ret = mipi_dsi_dcs_set_display_on(pinfo->link);
|
||||
if (ret < 0) {
|
||||
dev_err(panel->dev, "failed to exit sleep mode: %d\n", ret);
|
||||
dev_err(panel->dev, "failed to set display on: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
msleep(120);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(pinfo->link);
|
||||
ret = mipi_dsi_dcs_exit_sleep_mode(pinfo->link);
|
||||
if (ret < 0) {
|
||||
dev_err(panel->dev, "failed to set display on: %d\n", ret);
|
||||
dev_err(panel->dev, "failed to exit sleep mode: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,10 +136,10 @@ static int jadard_prepare(struct drm_panel *panel)
|
||||
dev_err(pinfo->base.dev, "Failed to enable vspn3v3 supply: %d\n", ret);
|
||||
goto fail;
|
||||
}
|
||||
usleep_range(5000, 6000);
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
gpiod_set_value(pinfo->reset, 1);
|
||||
msleep(180);
|
||||
msleep(10);
|
||||
|
||||
pinfo->prepared = true;
|
||||
|
||||
@@ -165,7 +165,7 @@ static int jadard_enable(struct drm_panel *panel)
|
||||
return ret;
|
||||
}
|
||||
|
||||
msleep(120);
|
||||
msleep(10);
|
||||
|
||||
ret = mipi_dsi_dcs_set_display_on(pinfo->link);
|
||||
if (ret < 0) {
|
||||
@@ -225,7 +225,7 @@ static const struct drm_display_mode jadard_default_mode = {
|
||||
|
||||
.width_mm = 62,
|
||||
.height_mm = 110,
|
||||
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
|
||||
.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -29,6 +29,8 @@ static void vs_crtc_reset(struct drm_crtc *crtc)
|
||||
{
|
||||
struct vs_crtc_state *state;
|
||||
|
||||
vs_crtc_reset_count ++;
|
||||
|
||||
if (crtc->state) {
|
||||
__drm_atomic_helper_crtc_destroy_state(crtc->state);
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "vs_type.h"
|
||||
|
||||
extern int vs_crtc_reset_count;
|
||||
|
||||
struct vs_crtc_funcs {
|
||||
void (*enable)(struct device *dev, struct drm_crtc *crtc);
|
||||
void (*disable)(struct device *dev, struct drm_crtc *crtc);
|
||||
|
||||
@@ -1345,6 +1345,8 @@ static int dc_suspend(struct device *dev)
|
||||
clk_set_rate(dc->pixclk[i], dc->pix_clk_rate[i] * 1000);
|
||||
}
|
||||
|
||||
dc_runtime_suspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1353,10 +1355,14 @@ static int dc_resume(struct device *dev)
|
||||
int i, ret;
|
||||
struct vs_dc *dc = dev_get_drvdata(dev);
|
||||
dev_info(dev,"dc resume\n");
|
||||
|
||||
dc_runtime_suspend(dev);
|
||||
dc_runtime_resume(dev);
|
||||
|
||||
regmap_write(dc->hw.vosys_regmap,0x4,0x7); //release dpu reset
|
||||
|
||||
ret = dc_hw_init(&dc->hw);
|
||||
if (ret)
|
||||
if (ret)
|
||||
dev_err(dev, "failed to init DC HW\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -34,12 +34,22 @@
|
||||
#include "dw_mipi_dsi.h"
|
||||
#include "dw_hdmi_light.h"
|
||||
|
||||
/* debug sysfs */
|
||||
#include <drm/drm_auth.h>
|
||||
#include "../drm_crtc_internal.h"
|
||||
|
||||
|
||||
|
||||
#define DRV_NAME "vs-drm"
|
||||
#define DRV_DESC "VeriSilicon DRM driver"
|
||||
#define DRV_DATE "20191101"
|
||||
#define DRV_MAJOR 1
|
||||
#define DRV_MINOR 0
|
||||
|
||||
/* extern exception info */
|
||||
int vs_crtc_reset_count = 0;
|
||||
int TotalFailures = 0;
|
||||
|
||||
static bool has_iommu = true;
|
||||
static struct platform_driver vs_drm_platform_driver;
|
||||
|
||||
@@ -54,6 +64,225 @@ static const struct file_operations fops = {
|
||||
.mmap = vs_gem_mmap,
|
||||
};
|
||||
|
||||
static ssize_t log_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
|
||||
// struct device *dev = kobj_to_dev(kobj);
|
||||
// struct drm_device *drm_dev = dev_get_drvdata(dev);
|
||||
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct drm_minor *dminor = dev_get_drvdata(dev);
|
||||
struct drm_device *drm_dev = dminor -> dev;
|
||||
|
||||
|
||||
struct drm_framebuffer *fb;
|
||||
struct drm_plane *plane;
|
||||
struct drm_crtc * drm_crtc;
|
||||
|
||||
ssize_t len = 0;
|
||||
|
||||
/* module version */
|
||||
const char *module_version = "1.0.0";
|
||||
const char *build_time = "20230101";
|
||||
|
||||
/* module info */
|
||||
int crtc_count = 0;
|
||||
|
||||
unsigned int plane_count = 0;
|
||||
unsigned int plane_used = 0;
|
||||
unsigned int plane_free = 0;
|
||||
|
||||
unsigned int fb_count = 0;
|
||||
|
||||
list_for_each_entry(drm_crtc, &drm_dev->mode_config.crtc_list, head) {
|
||||
crtc_count++;
|
||||
}
|
||||
|
||||
list_for_each_entry(plane, &drm_dev->mode_config.plane_list, head) {
|
||||
plane_count++;
|
||||
if (plane->state && plane->state->fb) {
|
||||
plane_used++;
|
||||
}
|
||||
}
|
||||
plane_free = plane_count - plane_used;
|
||||
|
||||
list_for_each_entry(fb, &drm_dev->mode_config.fb_list, head) {
|
||||
fb_count++;
|
||||
}
|
||||
|
||||
struct drm_connector *connector;
|
||||
enum drm_connector_status status;
|
||||
bool hdmi_on = false;
|
||||
bool dsi_on = false;
|
||||
|
||||
list_for_each_entry(connector, &drm_dev->mode_config.connector_list, head) {
|
||||
status = connector->status;
|
||||
if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
|
||||
hdmi_on = (status == connector_status_connected);
|
||||
} else if (connector->connector_type == DRM_MODE_CONNECTOR_DSI) {
|
||||
dsi_on = (status == connector_status_connected);
|
||||
}
|
||||
}
|
||||
|
||||
struct drm_file *priv;
|
||||
kuid_t uid;
|
||||
int client_count = 0;
|
||||
list_for_each_entry_reverse(priv, &drm_dev->filelist, lhead) {
|
||||
client_count++;
|
||||
}
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"----------------------------------------MODULE VERSION----------------------------------------\n"
|
||||
"[Video Sub System] Version: %s, Build Time【%s】\n"
|
||||
"----------------------------------------MODULE STATUS-----------------------------------------\n"
|
||||
"CrtcCount PlaneCount PlaneUsed PlaneFree FrameBufferCount ClientCount HDMI DSI\n"
|
||||
" %d %u %u %u %u %u %s %s\n"
|
||||
"----------------------------------------EXCEPTION INFO----------------------------------------\n"
|
||||
"TotalFailures Reset\n"
|
||||
" %d %d\n",
|
||||
|
||||
module_version, build_time,
|
||||
crtc_count, plane_count, plane_used, plane_count - plane_used , fb_count, client_count, hdmi_on?"on":"off", dsi_on?"on":"off",
|
||||
TotalFailures, vs_crtc_reset_count
|
||||
);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"-----------------------------------------Client Info-----------------------------------------\n"
|
||||
"%20s %5s %3s master a %5s %10s\n",
|
||||
"command","pid","dev","uid","magic");
|
||||
list_for_each_entry_reverse(priv, &drm_dev->filelist, lhead) {
|
||||
struct task_struct *task;
|
||||
bool is_current_master = drm_is_current_master(priv);
|
||||
|
||||
rcu_read_lock(); /* locks pid_task()->comm */
|
||||
task = pid_task(priv->pid, PIDTYPE_PID);
|
||||
uid = task ? __task_cred(task)->euid : GLOBAL_ROOT_UID;
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len, "%20s %5d %3d %c %c %5u %10u\n",
|
||||
task ? task->comm : "<unknown>",
|
||||
pid_vnr(priv->pid),
|
||||
priv->minor->index,
|
||||
is_current_master ? 'y' : 'n',
|
||||
priv->authenticated ? 'y' : 'n',
|
||||
// from_kuid_munged(seq_user_ns(m), uid)
|
||||
uid,
|
||||
priv->magic);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (drm_dev) {
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"-----------------------------------------MODULE INFO-----------------------------------------\n");
|
||||
list_for_each_entry(fb, &drm_dev->mode_config.fb_list, head) {
|
||||
struct drm_format_name_buf format_name;
|
||||
unsigned int i;
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"framebuffer[%u]:\n"
|
||||
"\tallocated by = %s\n"
|
||||
"\tformat=%s\n"
|
||||
"\tsize=%ux%u\n",
|
||||
fb->base.id,
|
||||
fb->comm,
|
||||
drm_get_format_name(fb->format->format, &format_name),
|
||||
fb->width, fb->height
|
||||
);
|
||||
for (i = 0; i < fb->format->num_planes; i++) {
|
||||
len+= scnprintf(buf + len, PAGE_SIZE - len,"\t\tpitch[%u]=%u\n",i, fb->pitches[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(drm_crtc, &drm_dev->mode_config.crtc_list, head) {
|
||||
// struct vs_crtc *crtc = to_vs_crtc(drm_crtc);
|
||||
struct drm_crtc *crtc = drm_crtc->state->crtc;
|
||||
struct vs_crtc_state *crtc_state = to_vs_crtc_state(drm_crtc->state);
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"crtc[%u]: %s\n"
|
||||
"\tenable= %d\n"
|
||||
"\tplane_mask=%x\n"
|
||||
"\tconnector_mask=%x\n"
|
||||
"\tencoder_mask=%x\n"
|
||||
"\tmode: " DRM_MODE_FMT "\n",
|
||||
crtc->base.id, crtc->name,
|
||||
drm_crtc->state->enable,
|
||||
drm_crtc->state->plane_mask,
|
||||
drm_crtc->state->connector_mask,
|
||||
drm_crtc->state->encoder_mask,
|
||||
DRM_MODE_ARG(&(drm_crtc->state->mode))
|
||||
);
|
||||
}
|
||||
|
||||
list_for_each_entry(plane, &drm_dev->mode_config.plane_list, head) {
|
||||
struct drm_plane_state *state = plane->state;
|
||||
struct vs_plane_state *plane_state = to_vs_plane_state(state);
|
||||
struct drm_rect src = drm_plane_state_src(state);
|
||||
struct drm_rect dest = drm_plane_state_dest(state);
|
||||
|
||||
len += scnprintf(buf + len, PAGE_SIZE - len,
|
||||
"plane[%u]: %s\n"
|
||||
"\tcrtc=%s\n"
|
||||
"\tcrtc-pos=" DRM_RECT_FMT "\n"
|
||||
"\tsrc-pos=" DRM_RECT_FP_FMT "\n"
|
||||
"\trotation=%x\n"
|
||||
"\tcolor-encoding=%s\n"
|
||||
"\tcolor-range=%s\n",
|
||||
plane->base.id, plane->name,
|
||||
state->crtc ? state->crtc->name : "(null)",
|
||||
DRM_RECT_ARG(&dest),
|
||||
DRM_RECT_FP_ARG(&src),
|
||||
state->rotation,
|
||||
drm_get_color_encoding_name(state->color_encoding),
|
||||
drm_get_color_range_name(state->color_range)
|
||||
);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t log_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
TotalFailures = 0;
|
||||
vs_crtc_reset_count = 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int period_ms =0;
|
||||
|
||||
static ssize_t updatePeriod_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
return sprintf(buf,"%u\n",period_ms);
|
||||
}
|
||||
|
||||
static ssize_t updatePeriod_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
char *start = (char *)buf;
|
||||
period_ms = simple_strtoul(start, &start, 0);
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct kobj_attribute log_attr = __ATTR(log, 0664, log_show, log_store);
|
||||
|
||||
static struct kobj_attribute updatePeriod_attr = __ATTR(updatePeriod_ms, 0664, updatePeriod_show, updatePeriod_store);
|
||||
|
||||
|
||||
static struct attribute *attrs[] = {
|
||||
&log_attr.attr,
|
||||
&updatePeriod_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
static umode_t always_visible(struct kobject *kobj, struct attribute *attr, int index)
|
||||
{
|
||||
return 0644;
|
||||
}
|
||||
|
||||
|
||||
static struct attribute_group vs_dev_attr_group = {
|
||||
.name = "info",
|
||||
.is_visible = always_visible,
|
||||
.attrs = attrs,
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int vs_debugfs_planes_show(struct seq_file *s, void *data)
|
||||
{
|
||||
@@ -239,10 +468,19 @@ static int vs_drm_bind(struct device *dev)
|
||||
if (ret)
|
||||
goto err_helper;
|
||||
|
||||
|
||||
ret = sysfs_create_group(&drm_dev->primary->kdev->kobj, &vs_dev_attr_group);
|
||||
if (ret) {
|
||||
dev_err(drm_dev->dev, "Failed to create drm dev sysfs.\n");
|
||||
goto err_drm_dev_register;
|
||||
}
|
||||
|
||||
drm_fbdev_generic_setup(drm_dev, 32);
|
||||
|
||||
return 0;
|
||||
|
||||
err_drm_dev_register:
|
||||
drm_dev_unregister(drm_dev);
|
||||
err_helper:
|
||||
drm_kms_helper_poll_fini(drm_dev);
|
||||
err_bind:
|
||||
@@ -265,6 +503,8 @@ static void vs_drm_unbind(struct device *dev)
|
||||
|
||||
drm_dev_unregister(drm_dev);
|
||||
|
||||
sysfs_remove_group(&drm_dev->primary->kdev->kobj, &vs_dev_attr_group);
|
||||
|
||||
drm_kms_helper_poll_fini(drm_dev);
|
||||
|
||||
component_unbind_all(drm_dev->dev, drm_dev);
|
||||
|
||||
@@ -281,10 +281,19 @@ int i2c_dw_xfer_dma_init(struct dw_i2c_dev *dev)
|
||||
if (dma->dma_chan == NULL) {
|
||||
//Alloc i2c dma channel.
|
||||
//The function is to configure the handshake number in i2c dts into the channel
|
||||
dma->dma_chan = dma_request_slave_channel(dev->dev, "tx");
|
||||
if (!dma->dma_chan) {
|
||||
dev_err(dev->dev, "Failed to request dma channel");
|
||||
return -EIO;
|
||||
//Try to obtain the dma channel within 10 seconds
|
||||
int i = 2000;
|
||||
while(i--) {
|
||||
dma->dma_chan = dma_request_slave_channel(dev->dev, "tx");
|
||||
if (dma->dma_chan) {
|
||||
break;
|
||||
}
|
||||
msleep(5);
|
||||
}
|
||||
|
||||
if (!dma->dma_chan) {
|
||||
dev_err(dev->dev, "Failed to request dma channel");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
__dev_vdgb(dev->dev,"i2c request dma_ch %d\n", dma->dma_chan->chan_id);
|
||||
|
||||
@@ -871,8 +871,10 @@ static int __maybe_unused thead_dwmac_resume(struct device *dev)
|
||||
if (!netif_running(ndev))
|
||||
return 0;
|
||||
|
||||
pm_runtime_get_sync(dev);
|
||||
if (priv->plat->init)
|
||||
priv->plat->init(pdev, priv->plat->bsp_priv);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return stmmac_resume(dev);
|
||||
}
|
||||
@@ -901,6 +903,7 @@ static int __maybe_unused thead_dwmac_runtime_resume(struct device *dev)
|
||||
ret = thead_dwmac_clk_enable(pdev, priv->plat->bsp_priv);
|
||||
if(ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2239,6 +2239,7 @@ EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
|
||||
EXTRA_CFLAGS += -DCONFIG_IOCTL_CFG80211 -DRTW_USE_CFG80211_STA_EVENT
|
||||
#EXTRA_CFLAGS += -DCONFIG_FULL_CH_IN_P2P_HANDSHAKE
|
||||
#EXTRA_CFLAGS += -DCONFIG_SEL_P2P_IFACE
|
||||
EXTRA_CFLAGS += -DCONFIG_RESUME_IN_WORKQUEUE
|
||||
ARCH := riscv
|
||||
MODULE_NAME := rtl8723ds
|
||||
endif
|
||||
|
||||
@@ -2287,7 +2287,7 @@ void rtw_init_pwrctrl_priv(PADAPTER padapter)
|
||||
|
||||
#ifdef CONFIG_RESUME_IN_WORKQUEUE
|
||||
_init_workitem(&pwrctrlpriv->resume_work, resume_workitem_callback, NULL);
|
||||
pwrctrlpriv->rtw_workqueue = create_singlethread_workqueue("rtw_workqueue");
|
||||
pwrctrlpriv->rtw_workqueue = create_freezable_workqueue("rtw_workqueue");
|
||||
#endif /* CONFIG_RESUME_IN_WORKQUEUE */
|
||||
|
||||
#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_ANDROID_POWER)
|
||||
|
||||
@@ -175,12 +175,12 @@
|
||||
#endif
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_RESUME_IN_WORKQUEUE /* this can be removed, because there is no case for this... */
|
||||
#if !defined(CONFIG_WAKELOCK) && !defined(CONFIG_ANDROID_POWER)
|
||||
#error "enable CONFIG_RESUME_IN_WORKQUEUE without CONFIG_WAKELOCK or CONFIG_ANDROID_POWER will suffer from the danger of wifi's unfunctionality..."
|
||||
#error "If you still want to enable CONFIG_RESUME_IN_WORKQUEUE in this case, mask this preprossor checking and GOOD LUCK..."
|
||||
#endif
|
||||
#endif
|
||||
// #ifdef CONFIG_RESUME_IN_WORKQUEUE /* this can be removed, because there is no case for this... */
|
||||
// #if !defined(CONFIG_WAKELOCK) && !defined(CONFIG_ANDROID_POWER)
|
||||
// #error "enable CONFIG_RESUME_IN_WORKQUEUE without CONFIG_WAKELOCK or CONFIG_ANDROID_POWER will suffer from the danger of wifi's unfunctionality..."
|
||||
// #error "If you still want to enable CONFIG_RESUME_IN_WORKQUEUE in this case, mask this preprossor checking and GOOD LUCK..."
|
||||
// #endif
|
||||
// #endif
|
||||
|
||||
/* About USB VENDOR REQ */
|
||||
#if defined(CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC) && !defined(CONFIG_USB_VENDOR_REQ_MUTEX)
|
||||
|
||||
@@ -751,15 +751,50 @@ static int dw_dphy_runtime_resume(struct device *dev)
|
||||
|
||||
static int dw_dphy_resume(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
struct dw_dphy *dphy = dev_get_drvdata(dev);
|
||||
|
||||
dw_dphy_init(dphy->phy);
|
||||
clk_disable_unprepare(dphy->refclk);
|
||||
clk_disable_unprepare(dphy->cfgclk);
|
||||
clk_disable_unprepare(dphy->pclk);
|
||||
|
||||
ret = clk_prepare_enable(dphy->pclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "dphy resume failed to prepare/enable pclk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dphy->cfgclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "dphy resume failed to prepare/enable cfgclk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(dphy->refclk);
|
||||
if (ret) {
|
||||
dev_err(dev, "dphy resume failed to prepare/enable refclk\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dw_dphy_config_testclr(dphy, 1);
|
||||
dw_dphy_config_testclr(dphy, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dw_dphy_suspend(struct device *dev)
|
||||
{
|
||||
struct dw_dphy *dphy = dev_get_drvdata(dev);
|
||||
|
||||
clk_disable_unprepare(dphy->refclk);
|
||||
clk_disable_unprepare(dphy->cfgclk);
|
||||
clk_disable_unprepare(dphy->pclk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops dw_dphy_pm_ops = {
|
||||
SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL,
|
||||
SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_dphy_suspend,
|
||||
dw_dphy_resume)
|
||||
SET_RUNTIME_PM_OPS(dw_dphy_runtime_suspend, dw_dphy_runtime_resume, NULL)
|
||||
};
|
||||
|
||||
@@ -75,6 +75,8 @@ struct light_pinctrl_soc_info {
|
||||
#define LIGHT_PADCTRL0_MUX_REG_NUMS 7
|
||||
#define LIGHT_PADCTRL1_CFG_REG_NUMS 32
|
||||
#define LIGHT_PADCTRL1_MUX_REG_NUMS 8
|
||||
#define LIGHT_AON_CFG_REG_NUMS 24
|
||||
#define LIGHT_AON_MUX_REG_NUMS 6
|
||||
#define LIGHT_AUDIO_CFG_REG_NUMS 16
|
||||
#define LIGHT_AUDIO_MUX_REG_NUMS 2
|
||||
#define LIGHT_AUDIO_IO_SEL_IDX 2
|
||||
@@ -687,6 +689,7 @@ static int light_pinctrl_suspend(struct device *dev)
|
||||
clk_disable_unprepare(priv->clk);
|
||||
break;
|
||||
case LIGHT_FM_AON:
|
||||
ret = light_pinctrl_backup_regs(priv, LIGHT_AON_CFG_REG_NUMS, LIGHT_AON_MUX_REG_NUMS);
|
||||
break;
|
||||
case LIGHT_FM_AUDIO:
|
||||
ret = light_pinctrl_backup_regs(priv, LIGHT_AUDIO_CFG_REG_NUMS, LIGHT_AUDIO_MUX_REG_NUMS);
|
||||
@@ -723,6 +726,7 @@ static int light_pinctrl_resume(struct device *dev)
|
||||
ret = light_pinctrl_restore_regs(priv, LIGHT_PADCTRL1_CFG_REG_NUMS, LIGHT_PADCTRL1_MUX_REG_NUMS);
|
||||
break;
|
||||
case LIGHT_FM_AON:
|
||||
ret = light_pinctrl_restore_regs(priv, LIGHT_AON_CFG_REG_NUMS, LIGHT_AON_MUX_REG_NUMS);
|
||||
break;
|
||||
case LIGHT_FM_AUDIO:
|
||||
ret = light_pinctrl_restore_regs(priv, LIGHT_AUDIO_CFG_REG_NUMS, LIGHT_AUDIO_MUX_REG_NUMS);
|
||||
|
||||
@@ -29,7 +29,7 @@ struct rpc_msg_regu_vol_set {
|
||||
u32 dc1; ///< voltage uinit in uv for single rail or first rail of dual rail
|
||||
u32 dc2; ///< voltage uinit in uv for second rail of dual rail,ignore it if "is_dual_rail" is false
|
||||
u16 reserved[6];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct rpc_msg_regu_vol_get {
|
||||
u16 regu_id; ///< virtual regu id
|
||||
@@ -38,20 +38,35 @@ struct rpc_msg_regu_vol_get {
|
||||
u32 dc2; ///< voltage uinit in uv for second rail of dual rail,ignore it if "is_dual_rail" is false
|
||||
u16 reserved[6];
|
||||
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct rpc_msg_regu_vol_get_ack {
|
||||
struct light_aon_rpc_ack_common ack_hdr; ///< ack_hdr
|
||||
u16 regu_id; ///< virtual regu id
|
||||
u16 is_dual_rail; ///< whether this regu has dual rails
|
||||
u32 dc1; ///< voltage uinit in uv for single rail or first rail of dual rail
|
||||
u32 dc2; ///< voltage uinit in uv for second rail of dual rail,ignore it if "is_dual_rail" is false
|
||||
u16 reserved[6];
|
||||
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct rpc_msg_regu_pwr_set {
|
||||
u16 regu_id; ///< virtual regu id
|
||||
u16 status; ///< 0: power off; 1: powr on
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct rpc_msg_regu_pwr_get {
|
||||
u16 regu_id; ///< virtual regu id
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct rpc_msg_regu_pwr_get_ack {
|
||||
struct light_aon_rpc_ack_common ack_hdr; ///< ack_hdr
|
||||
u16 regu_id; ///< virtual regu id
|
||||
u16 status; ///< 0: power off; 1: powr on
|
||||
u32 reserved[5];
|
||||
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_msg_regulator_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
@@ -60,8 +75,8 @@ struct light_aon_msg_regulator_ctrl {
|
||||
struct rpc_msg_regu_vol_get regu_vol_get;
|
||||
struct rpc_msg_regu_pwr_set regu_pwr_set;
|
||||
struct rpc_msg_regu_pwr_get regu_pwr_get;
|
||||
} __packed __aligned(4) rpc;
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1) rpc;
|
||||
} __packed __aligned(1);
|
||||
|
||||
enum pm_resource {
|
||||
SOC_DVDD18_AON, /*da9063: ldo-3 */
|
||||
@@ -110,6 +125,8 @@ struct aon_regu_info {
|
||||
struct device *dev;
|
||||
const struct apcpu_vol_set *cpu_vol; ///< signed-off voltage of cpu
|
||||
u32 vddm; ///< cpu-mem voltage
|
||||
uint8_t cpu_dual_rail_flag; ///< cpu dual rail flag
|
||||
uint8_t vddm_dual_rail_flag; ///< cpu-mem dual rail flag
|
||||
struct aon_regu_desc *regu_desc; ///< regu-desc set
|
||||
struct light_aon_ipc *ipc_handle; ///< handle of mail-box
|
||||
};
|
||||
@@ -143,22 +160,31 @@ static const struct apcpu_vol_set apcpu_volts[] = {
|
||||
* dual-rail regulator means that a virtual regulator involes two hw-regulators
|
||||
*/
|
||||
static int aon_set_regulator(struct light_aon_ipc *ipc, u16 regu_id,
|
||||
u32 dc1, u32 dc2, u16 is_dual_rail)
|
||||
u32 dc1, u32 dc2, u8 dc1_is_dual_rail, u8 dc2_is_dual_rail)
|
||||
{
|
||||
uint16_t is_dual_rail = 0;
|
||||
struct light_aon_msg_regulator_ctrl msg = {0};
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg.hdr;
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_PM;
|
||||
hdr->func = (uint8_t)LIGHT_AON_PM_FUNC_SET_RESOURCE_REGULATOR;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
|
||||
msg.rpc.regu_vol_set.regu_id = regu_id;
|
||||
msg.rpc.regu_vol_set.is_dual_rail = is_dual_rail;
|
||||
msg.rpc.regu_vol_set.dc1 = dc1;
|
||||
msg.rpc.regu_vol_set.dc2 = dc2;
|
||||
if(dc1_is_dual_rail) {
|
||||
is_dual_rail |= 1 << 0;
|
||||
}
|
||||
|
||||
return light_aon_call_rpc(ipc, &msg, true);
|
||||
if(dc2_is_dual_rail) {
|
||||
is_dual_rail |= 1 << 1;
|
||||
}
|
||||
|
||||
RPC_SET_BE16(&msg.rpc.regu_vol_set.regu_id, 0, regu_id);
|
||||
RPC_SET_BE16(&msg.rpc.regu_vol_set.regu_id, 2, is_dual_rail);
|
||||
RPC_SET_BE32(&msg.rpc.regu_vol_set.regu_id, 4, dc1);
|
||||
RPC_SET_BE32(&msg.rpc.regu_vol_set.regu_id, 8, dc2);
|
||||
|
||||
return light_aon_call_rpc(ipc, &msg, &ack_msg, true);
|
||||
}
|
||||
|
||||
/* dc2 is valid when is_dual_rail is true
|
||||
@@ -169,25 +195,33 @@ static int aon_get_regulator(struct light_aon_ipc *ipc, u16 regu_id,
|
||||
u32 *dc1, u32 *dc2, u16 is_dual_rail)
|
||||
{
|
||||
struct light_aon_msg_regulator_ctrl msg = {0};
|
||||
struct rpc_msg_regu_vol_get_ack ack_msg = {0};
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg.hdr;
|
||||
int ret;
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_PM;
|
||||
hdr->func = (uint8_t)LIGHT_AON_PM_FUNC_GET_RESOURCE_REGULATOR;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
msg.rpc.regu_vol_get.regu_id = regu_id;
|
||||
msg.rpc.regu_vol_get.is_dual_rail = is_dual_rail;
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &msg, true);
|
||||
RPC_SET_BE16(&msg.rpc.regu_vol_get.regu_id, 0, regu_id);
|
||||
RPC_SET_BE16(&msg.rpc.regu_vol_get.regu_id, 2, is_dual_rail);
|
||||
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &msg, &ack_msg, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*fix me:set local */
|
||||
ack_msg.regu_id = regu_id;
|
||||
ack_msg.is_dual_rail = is_dual_rail;
|
||||
|
||||
RPC_GET_BE32(&ack_msg.regu_id, 4, &ack_msg.dc1);
|
||||
RPC_GET_BE32(&ack_msg.regu_id, 8, &ack_msg.dc2);
|
||||
|
||||
if (dc1 != NULL)
|
||||
*dc1 = msg.rpc.regu_vol_get.dc1;
|
||||
*dc1 = ack_msg.dc1;
|
||||
|
||||
if (dc2 != NULL)
|
||||
*dc2 = msg.rpc.regu_vol_get.dc2;
|
||||
*dc2 = ack_msg.dc2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -195,16 +229,17 @@ static int aon_get_regulator(struct light_aon_ipc *ipc, u16 regu_id,
|
||||
static int aon_regu_power_ctrl(struct light_aon_ipc *ipc,u32 regu_id,u16 pwr_on)
|
||||
{
|
||||
struct light_aon_msg_regulator_ctrl msg = {0};
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg.hdr;
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_PM;
|
||||
hdr->func = (uint8_t)LIGHT_AON_PM_FUNC_PWR_SET;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
|
||||
msg.rpc.regu_pwr_set.regu_id = regu_id;
|
||||
msg.rpc.regu_pwr_set.status = pwr_on;
|
||||
return light_aon_call_rpc(ipc, &msg, true);
|
||||
RPC_SET_BE16(&msg.rpc.regu_pwr_set.regu_id, 0, regu_id);
|
||||
RPC_SET_BE16(&msg.rpc.regu_pwr_set.regu_id, 2, pwr_on);
|
||||
|
||||
return light_aon_call_rpc(ipc, &msg, &ack_msg, true);
|
||||
}
|
||||
static int aon_regu_dummy_enable(struct regulator_dev *reg)
|
||||
{
|
||||
@@ -233,22 +268,23 @@ static int aon_regu_disable(struct regulator_dev *reg)
|
||||
static int aon_regu_is_enabled(struct regulator_dev *reg)
|
||||
{
|
||||
struct light_aon_msg_regulator_ctrl msg = {0};
|
||||
struct rpc_msg_regu_pwr_get_ack ack_msg = {0};
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg.hdr;
|
||||
int ret;
|
||||
u16 regu_id =(u16) rdev_get_id(reg);
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_PM;
|
||||
hdr->func = (uint8_t)LIGHT_AON_PM_FUNC_PWR_GET;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
|
||||
msg.rpc.regu_pwr_get.regu_id = regu_id;
|
||||
ret = light_aon_call_rpc(light_aon_pmic_info.ipc_handle, &msg, true);
|
||||
RPC_SET_BE16(&msg.rpc.regu_pwr_get.regu_id, 0, regu_id);
|
||||
|
||||
ret = light_aon_call_rpc(light_aon_pmic_info.ipc_handle, &msg, &ack_msg, true);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return (int) msg.rpc.regu_pwr_get.status;
|
||||
RPC_GET_BE16(&ack_msg.regu_id, 2, &ack_msg.status);
|
||||
return (int) ack_msg.status;
|
||||
}
|
||||
|
||||
static int aon_regu_set_voltage(struct regulator_dev *reg,
|
||||
@@ -261,7 +297,7 @@ static int aon_regu_set_voltage(struct regulator_dev *reg,
|
||||
pr_debug("[%s,%d]minuV = %d, uV = %d\n", __func__, __LINE__, minuV, uV);
|
||||
|
||||
err = aon_set_regulator(light_aon_pmic_info.ipc_handle, regu_id,
|
||||
voltage, 0, 0);
|
||||
voltage, 0, 0, 0);
|
||||
if (err) {
|
||||
pr_err("failed to set Voltages to %d!\n", minuV);
|
||||
return -EINVAL;
|
||||
@@ -327,7 +363,7 @@ static int apcpu_set_vdd_vddm_voltage(struct regulator_dev *reg,
|
||||
info->vddm = cpu_vol->vddm;
|
||||
|
||||
err = aon_set_regulator(light_aon_pmic_info.ipc_handle, (u16)SOC_APCPU_DVDD_DVDDM,
|
||||
dc1, dc2, 1);
|
||||
dc1, dc2, info->cpu_dual_rail_flag, info->vddm_dual_rail_flag);
|
||||
if (err) {
|
||||
dev_err(info->dev, "failed to set Voltages to %d!\n", uV);
|
||||
return -EINVAL;
|
||||
@@ -402,6 +438,14 @@ static const struct regulator_ops regu_common_ops = {
|
||||
.set_voltage = aon_regu_set_voltage,
|
||||
.get_voltage = aon_regu_get_voltage,
|
||||
};
|
||||
|
||||
static const struct regulator_ops regu_gpio_ops = {
|
||||
.enable = aon_regu_enable,
|
||||
.disable = aon_regu_disable,
|
||||
.is_enabled = aon_regu_is_enabled,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static const struct regulator_ops apcpu_dvdd_ops = {
|
||||
.enable = aon_regu_dummy_enable,
|
||||
.disable = aon_regu_dummy_disable,
|
||||
@@ -423,15 +467,14 @@ static const struct regulator_ops apcpu_dvddm_ops = {
|
||||
/* Macros for voltage DC/DC converters (BUCKs) for cpu */
|
||||
#define REGU_DSC_DEF(regu_id, of_math_name) \
|
||||
.id = regu_id, \
|
||||
.name = #regu_id, \
|
||||
.name = of_match_ptr(__stringify(of_math_name)), \
|
||||
.of_match = of_match_ptr(__stringify(of_math_name)), \
|
||||
.ops = ®u_common_ops, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE
|
||||
|
||||
#define BUCK_APCPU_DVDD(regu_id,min_mV, step_mV, max_mV) \
|
||||
.id = regu_id, \
|
||||
.name = "APCPU_DVDD", \
|
||||
.name = of_match_ptr("appcpu_dvdd"), \
|
||||
.of_match = of_match_ptr("appcpu_dvdd"), \
|
||||
.ops = &apcpu_dvdd_ops, \
|
||||
.min_uV = (min_mV), \
|
||||
@@ -442,7 +485,7 @@ static const struct regulator_ops apcpu_dvddm_ops = {
|
||||
|
||||
#define BUCK_APCPU_DVDDM(regu_id, min_mV, step_mV, max_mV) \
|
||||
.id = regu_id, \
|
||||
.name = "APCPU_DVDDM", \
|
||||
.name = of_match_ptr("appcpu_dvddm"),\
|
||||
.of_match = of_match_ptr("appcpu_dvddm"), \
|
||||
.ops = &apcpu_dvddm_ops, \
|
||||
.min_uV = (min_mV) , \
|
||||
@@ -451,67 +494,6 @@ static const struct regulator_ops apcpu_dvddm_ops = {
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.owner = THIS_MODULE
|
||||
|
||||
/* regulator desc for dialog */
|
||||
static struct regulator_desc light_dialog_ant_regu_desc[] = {
|
||||
/*cpu vdd vddm regulators, used to adjust vol dynamicaly */
|
||||
{
|
||||
BUCK_APCPU_DVDD(SOC_APCPU_DVDD_DVDDM, 300000, 10000, 1570000),
|
||||
},
|
||||
{
|
||||
BUCK_APCPU_DVDDM(SOC_APCPU_DVDD_DVDDM, 300000, 10000, 1570000),
|
||||
},
|
||||
|
||||
/*common regu ,no need to adjust vol dynamicaly */
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD18_AON,soc_dvdd18_aon),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_AVDD33_USB3,soc_avdd33_usb3),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD08_AON,soc_dvdd08_aon),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD08_DDR,soc_dvdd08_ddr),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_VDD_DDR_1V8,soc_vdd_ddr_1v8),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_VDD_DDR_1V1,soc_vdd_ddr_1v1),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_VDD_DDR_0V6,soc_vdd_ddr_0v6),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD18_AP,soc_dvdd18_ap),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD08_AP,soc_dvdd08_ap),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_AVDD08_MIPI_HDMI,soc_avdd08_mipi_hdmi),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_AVDD18_MIPI_HDMI,soc_avdd18_mipi_hdmi),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD33_EMMC,soc_dvdd33_emmc),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD18_EMMC,soc_dvdd18_emmc),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DOVDD18_SCAN,soc_dovdd18_scan),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD12_SCAN,soc_dvdd12_scan),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_AVDD28_SCAN_EN,soc_avdd28_scan_en),
|
||||
},
|
||||
};
|
||||
|
||||
static struct regulator_desc light_dialog_regu_desc[] = {
|
||||
/*cpu vdd vddm regulators, used to adjust vol dynamicaly */
|
||||
{
|
||||
@@ -591,58 +573,6 @@ static struct regulator_desc light_dialog_regu_desc[] = {
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD12_IR,soc_dvdd12_ir),
|
||||
},
|
||||
};
|
||||
|
||||
/* regulator desc for ricoh */
|
||||
static struct regulator_desc light_ricoh_regu_desc[] = {
|
||||
/*cpu vdd vddm regulators, used to adjust vol dynamicaly */
|
||||
{
|
||||
BUCK_APCPU_DVDD(SOC_APCPU_DVDD_DVDDM, 600000, 12500, 1500000),
|
||||
},
|
||||
{
|
||||
BUCK_APCPU_DVDDM(SOC_APCPU_DVDD_DVDDM, 600000, 12500, 1500000),
|
||||
},
|
||||
|
||||
/*common regu ,no need to adjust vol dynamicaly */
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD18_AON,soc_dvdd18_aon),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_AVDD33_USB3,soc_avdd33_usb3),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD08_AON,soc_dvdd08_aon),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD08_DDR,soc_dvdd08_ddr),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_VDD_DDR_1V8,soc_vdd_ddr_1v8),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_VDD_DDR_1V1,soc_vdd_ddr_1v1),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_VDD_DDR_0V6,soc_vdd_ddr_0v6),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD18_AP,soc_dvdd18_ap),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD08_AP,soc_dvdd08_ap),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_AVDD08_MIPI_HDMI,soc_avdd08_mipi_hdmi),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_AVDD18_MIPI_HDMI,soc_avdd18_mipi_hdmi),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD33_EMMC,soc_dvdd33_emmc),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_DVDD18_EMMC,soc_dvdd18_emmc),
|
||||
},
|
||||
{
|
||||
REGU_DSC_DEF(SOC_LCD0_EN,soc_lcd0_en),
|
||||
},
|
||||
@@ -651,169 +581,39 @@ static struct regulator_desc light_ricoh_regu_desc[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#define GEN_REGISTER_SHOW(x, y) \
|
||||
static ssize_t x##_registers_show(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
char *buf) \
|
||||
{ \
|
||||
struct platform_device *pdev = to_platform_device(dev); \
|
||||
struct aon_regu_info *info = platform_get_drvdata(pdev); \
|
||||
u32 dc1, dc2; \
|
||||
ssize_t ret; \
|
||||
\
|
||||
ret = aon_get_regulator(light_aon_pmic_info.ipc_handle, y, \
|
||||
&dc1, &dc2, 0); \
|
||||
if (ret) { \
|
||||
dev_err(info->dev, "failed to get Voltages!\n"); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
\
|
||||
ret = sprintf(buf, "%u\n", dc1); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
#define GEN_REGISTER_STORE(x, y) \
|
||||
static ssize_t x##_register_store(struct device *dev, \
|
||||
struct device_attribute *attr, \
|
||||
const char *buf, size_t count) \
|
||||
{ \
|
||||
struct platform_device *pdev = to_platform_device(dev); \
|
||||
struct aon_regu_info *info = platform_get_drvdata(pdev); \
|
||||
unsigned long dc1, dc2 = 0; \
|
||||
int err; \
|
||||
\
|
||||
if (kstrtoul(buf, 0, &dc1)) \
|
||||
return -EINVAL; \
|
||||
\
|
||||
err = aon_set_regulator(light_aon_pmic_info.ipc_handle, y, \
|
||||
dc1, dc2, 0); \
|
||||
if (err) { \
|
||||
dev_err(info->dev, "failed to set Voltages to [%lu]!\n", dc1); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
\
|
||||
return count; \
|
||||
}
|
||||
|
||||
static ssize_t soc_apcpu_dvdd_dvddm_registers_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct aon_regu_info *info = platform_get_drvdata(pdev);
|
||||
size_t bufpos = 0, count = 26;
|
||||
const struct apcpu_vol_set *cpu_vol;
|
||||
u32 dc1, dc2;
|
||||
int i = 0;
|
||||
int err;
|
||||
err = aon_get_regulator(light_aon_pmic_info.ipc_handle, SOC_APCPU_DVDD_DVDDM,
|
||||
&dc1, &dc2, 1);
|
||||
if (err) {
|
||||
dev_err(info->dev, "failed to get Voltages!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
cpu_vol = apcpu_get_matched_signed_off_voltage(dc1, dc2);
|
||||
if (!cpu_vol)
|
||||
dev_err(info->dev, "Read [%d:%d] is not existing in matching table\n", dc1, dc2);
|
||||
snprintf(buf + bufpos, count - bufpos, "%.*x: ", 2, i);
|
||||
bufpos += 4;
|
||||
snprintf(buf + bufpos, count - bufpos, "%u", dc1);
|
||||
bufpos += 8;
|
||||
buf[bufpos++] = '\n';
|
||||
i++;
|
||||
snprintf(buf + bufpos, count - bufpos, "%.*x: ", 2, i);
|
||||
bufpos += 4;
|
||||
snprintf(buf + bufpos, count - bufpos, "%u", dc2);
|
||||
bufpos += 8;
|
||||
buf[bufpos++] = '\n';
|
||||
return bufpos;
|
||||
}
|
||||
static ssize_t soc_apcpu_dvdd_dvddm_register_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct aon_regu_info *info = platform_get_drvdata(pdev);
|
||||
const struct apcpu_vol_set *cpu_vol;
|
||||
char *start = (char *)buf;
|
||||
unsigned long dc1, dc2;
|
||||
int err;
|
||||
while (*start == ' ')
|
||||
start++;
|
||||
dc1 = simple_strtoul(start, &start, 0);
|
||||
while (*start == ' ')
|
||||
start++;
|
||||
if (kstrtoul(start, 0, &dc2))
|
||||
return -EINVAL;
|
||||
cpu_vol = apcpu_get_matched_signed_off_voltage(dc1, dc2);
|
||||
if (!cpu_vol) {
|
||||
dev_err(info->dev, "failed to find bcore1/bcore2 matching table\n");
|
||||
#ifndef CONFIG_AON_REG_DEBUG
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
info->cpu_vol = cpu_vol;
|
||||
info->vddm = cpu_vol->vddm;
|
||||
err = aon_set_regulator(light_aon_pmic_info.ipc_handle, SOC_APCPU_DVDD_DVDDM,
|
||||
dc1, dc2, 1);
|
||||
if (err) {
|
||||
dev_err(info->dev, "failed to set Voltages to [%lu,%lu]!\n", dc1, dc2);
|
||||
#ifndef CONFIG_AON_REG_DEBUG
|
||||
return -EINVAL;
|
||||
#endif
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
GEN_REGISTER_SHOW(soc_dvdd18_aon, SOC_DVDD18_AON)
|
||||
GEN_REGISTER_STORE(soc_dvdd18_aon, SOC_DVDD18_AON)
|
||||
GEN_REGISTER_SHOW(soc_dvdd08_ap, SOC_DVDD08_AP)
|
||||
GEN_REGISTER_STORE(soc_dvdd08_ap, SOC_DVDD08_AP)
|
||||
GEN_REGISTER_SHOW(soc_dvdd18_emmc, SOC_DVDD18_EMMC)
|
||||
GEN_REGISTER_STORE(soc_dvdd18_emmc, SOC_DVDD18_EMMC)
|
||||
GEN_REGISTER_SHOW(soc_dvdd33_emmc, SOC_DVDD33_EMMC)
|
||||
GEN_REGISTER_STORE(soc_dvdd33_emmc, SOC_DVDD33_EMMC)
|
||||
|
||||
static DEVICE_ATTR(soc_dvdd18_aon_regs, 0644, soc_dvdd18_aon_registers_show, soc_dvdd18_aon_register_store);
|
||||
static DEVICE_ATTR(soc_dvdd08_ap_regs, 0644, soc_dvdd08_ap_registers_show, soc_dvdd08_ap_register_store);
|
||||
static DEVICE_ATTR(soc_dvdd33_emmc_regs, 0644, soc_dvdd33_emmc_registers_show, soc_dvdd33_emmc_register_store);
|
||||
static DEVICE_ATTR(soc_dvdd18_emmc_regs, 0644, soc_dvdd18_emmc_registers_show, soc_dvdd18_emmc_register_store);
|
||||
static DEVICE_ATTR(soc_apcpu_dvdd_dvddm_regs, 0644, soc_apcpu_dvdd_dvddm_registers_show, soc_apcpu_dvdd_dvddm_register_store);
|
||||
|
||||
static struct attribute *aon_regs_sysfs_entries[] = {
|
||||
&dev_attr_soc_dvdd18_aon_regs.attr,
|
||||
&dev_attr_soc_dvdd08_ap_regs.attr,
|
||||
&dev_attr_soc_dvdd33_emmc_regs.attr,
|
||||
&dev_attr_soc_dvdd18_emmc_regs.attr,
|
||||
&dev_attr_soc_apcpu_dvdd_dvddm_regs.attr,
|
||||
NULL
|
||||
};
|
||||
static const struct attribute_group dev_attr_aon_regs_group = {
|
||||
.attrs = aon_regs_sysfs_entries,
|
||||
};
|
||||
|
||||
|
||||
static const struct aon_regu_desc light_dialog_regus = {
|
||||
.regu_desc = (struct regulator_desc*) &light_dialog_regu_desc,
|
||||
.regu_num = ARRAY_SIZE(light_dialog_regu_desc),
|
||||
};
|
||||
|
||||
static const struct aon_regu_desc light_dialog_ant_regus = {
|
||||
.regu_desc = (struct regulator_desc*) &light_dialog_ant_regu_desc,
|
||||
.regu_num = ARRAY_SIZE(light_dialog_ant_regu_desc),
|
||||
};
|
||||
int light_match_regulator_name(struct aon_regu_desc *regus_set, const char *string)
|
||||
{
|
||||
int index;
|
||||
const char *item;
|
||||
|
||||
static const struct aon_regu_desc light_ricoh_regus = {
|
||||
.regu_desc = (struct regulator_desc*)&light_ricoh_regu_desc,
|
||||
.regu_num = ARRAY_SIZE(light_ricoh_regu_desc),
|
||||
};
|
||||
for(index = 0; index < regus_set->regu_num; index++) {
|
||||
item = regus_set->regu_desc[index].name;
|
||||
if(!item)
|
||||
break;
|
||||
if(!strcmp(item, string))
|
||||
return index;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int light_aon_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct regulator_config config = { };
|
||||
int i;
|
||||
int index;
|
||||
int ret;
|
||||
struct aon_regu_desc *regus_set = NULL;
|
||||
const char *regulator_type;
|
||||
const char *regulator_name;
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_desc *desc;
|
||||
int get_dual_rail_flag = 0;
|
||||
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
@@ -836,37 +636,76 @@ static int light_aon_regulator_probe(struct platform_device *pdev)
|
||||
light_aon_pmic_info.cpu_vol = &apcpu_volts[2]; /* pmic default voltages */
|
||||
light_aon_pmic_info.vddm = light_aon_pmic_info.cpu_vol->vddm;
|
||||
|
||||
/*register all regulators*/
|
||||
/*register regulators*/
|
||||
config.dev = &pdev->dev;
|
||||
config.driver_data = &light_aon_pmic_info;
|
||||
for (i = 0; i < regus_set->regu_num; i++) {
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_desc *desc;
|
||||
|
||||
desc = ®us_set->regu_desc[i];
|
||||
rdev = devm_regulator_register(&pdev->dev, desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to initialize regulator-%d\n", i);
|
||||
return PTR_ERR(rdev);
|
||||
of_property_read_string(np, "regulator-name", ®ulator_name);
|
||||
if(!regulator_name){
|
||||
dev_err(&pdev->dev, "failed to get the regulator-name\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
of_property_read_string(np, "regulator-type", ®ulator_type);
|
||||
if(!regulator_type){
|
||||
dev_err(&pdev->dev, "failed to get the regulator-type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*dual rail only work for cpu/cpu_mem*/
|
||||
if(of_property_read_bool(np, "regulator-dual-rail")){
|
||||
printk("get regual dual rail---->\n");
|
||||
get_dual_rail_flag = 1;
|
||||
}
|
||||
|
||||
index = light_match_regulator_name(regus_set, regulator_name);
|
||||
if(index < 0)
|
||||
{
|
||||
dev_err(&pdev->dev, "no regulator matches %s\n", regulator_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
desc = ®us_set->regu_desc[index];
|
||||
if(!strcmp(regulator_type, "dvdd")) {
|
||||
desc->ops = &apcpu_dvdd_ops;
|
||||
if(get_dual_rail_flag) {
|
||||
light_aon_pmic_info.cpu_dual_rail_flag = 1;
|
||||
get_dual_rail_flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
i = sysfs_create_group(&config.dev->kobj, &dev_attr_aon_regs_group);
|
||||
if (i) {
|
||||
dev_err(&pdev->dev, "Failed to create aon regs debug sysfs.\n");
|
||||
return i;
|
||||
else if(!strcmp(regulator_type, "dvddm")) {
|
||||
desc->ops = &apcpu_dvddm_ops;
|
||||
if(get_dual_rail_flag) {
|
||||
light_aon_pmic_info.vddm_dual_rail_flag = 1;
|
||||
get_dual_rail_flag = 0;
|
||||
}
|
||||
}
|
||||
else if(!strcmp(regulator_type, "common")) {
|
||||
desc->ops = ®u_common_ops;
|
||||
}
|
||||
else if(!strcmp(regulator_type, "gpio")) {
|
||||
desc->ops = ®u_gpio_ops;
|
||||
}
|
||||
else
|
||||
{
|
||||
dev_err(&pdev->dev,
|
||||
"%s, regulator type is not clarified\n", desc->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev, desc, &config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to initialize regulator%s\n", desc->name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, &light_aon_pmic_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id light_pmic_dev_id[] = {
|
||||
{ .compatible = "thead,light-dialog-pmic-ant", .data = &light_dialog_ant_regus},
|
||||
{ .compatible = "thead,light-dialog-pmic", .data = &light_dialog_regus},
|
||||
{ .compatible = "thead,light-ricoh-pmic", .data = &light_ricoh_regus},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, light_pmic_dev_id);
|
||||
@@ -880,7 +719,17 @@ static struct platform_driver light_aon_regulator_driver = {
|
||||
.probe = light_aon_regulator_probe,
|
||||
};
|
||||
|
||||
module_platform_driver(light_aon_regulator_driver);
|
||||
static int __init light_aon_regulator_init(void)
|
||||
{
|
||||
return platform_driver_register(&light_aon_regulator_driver);
|
||||
}
|
||||
postcore_initcall(light_aon_regulator_init);
|
||||
|
||||
static void __exit light_aon_regulator_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&light_aon_regulator_driver);
|
||||
}
|
||||
module_exit(light_aon_regulator_exit);
|
||||
|
||||
MODULE_AUTHOR("fugang.duan <duanfugang.dfg@linux.alibaba.com>");
|
||||
MODULE_AUTHOR("linghui.zlh <linghui.zlh@linux.alibaba.com>");
|
||||
|
||||
@@ -45,7 +45,11 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/light_rpmsg.h>
|
||||
|
||||
#include <linux/light_proc_debug.h>
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
#include <linux/firmware/thead/ipc.h>
|
||||
#include <linux/firmware/thead/light_event.h>
|
||||
#endif
|
||||
#define MBOX_MAX_MSG_LEN 28
|
||||
#define WJ_MBOX_SEND_MAX_MESSAGE_LENGTH 28
|
||||
#define HEXDUMP_BYTES_PER_LINE 28
|
||||
@@ -421,12 +425,41 @@ static void rpmsg_work_handler(struct work_struct *work)
|
||||
struct light_rpmsg_vproc *pri_rpdev;
|
||||
EXPORT_SYMBOL_GPL(pri_rpdev);
|
||||
|
||||
int get_audio_log_mem(struct device *dev, phys_addr_t* mem, size_t* mem_size)
|
||||
{
|
||||
struct resource r;
|
||||
ssize_t fw_size;
|
||||
void *mem_va;
|
||||
struct device_node *node;
|
||||
int ret;
|
||||
|
||||
*mem = 0;
|
||||
*mem_size = 0;
|
||||
|
||||
node = of_parse_phandle(dev->of_node, "log-memory-region", 0);
|
||||
if (!node) {
|
||||
dev_err(dev, "no memory-region specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(node, 0, &r);
|
||||
if (ret) {
|
||||
dev_err(dev, "memory-region get resource faild\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*mem = r.start;
|
||||
*mem_size = resource_size(&r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_rpmsg_probe(struct platform_device *pdev)
|
||||
{
|
||||
int core_id, j, ret = 0;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct light_rpmsg_vproc *rpdev;
|
||||
char dir_name[32] = {0x0};
|
||||
|
||||
if (of_property_read_u32(np, "multi-core-id", &core_id))
|
||||
core_id = 0;
|
||||
@@ -488,9 +521,36 @@ static int light_rpmsg_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
}
|
||||
platform_set_drvdata(pdev, rpdev);
|
||||
|
||||
ret = get_audio_log_mem(dev, &rpdev->log_phy, &rpdev->log_size);
|
||||
if(ret) {
|
||||
return ret;
|
||||
}
|
||||
rpdev->log_mem = ioremap(rpdev->log_phy, rpdev->log_size);
|
||||
if (!IS_ERR(rpdev->log_mem)) {
|
||||
printk("%s:virtual_log_mem=0x%p, phy base=0x%llx,size:%d\n",
|
||||
__func__, rpdev->log_mem, rpdev->log_phy,
|
||||
rpdev->log_size);
|
||||
} else {
|
||||
rpdev->log_mem = NULL;
|
||||
dev_err(dev, "%s:get audio log region fail\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sprintf(dir_name, "audio_proc");
|
||||
rpdev->proc_dir = proc_mkdir(dir_name, NULL);
|
||||
if (NULL != rpdev->proc_dir) {
|
||||
rpdev->log_ctrl = light_create_panic_log_proc(rpdev->log_phy,
|
||||
rpdev->proc_dir, rpdev->log_mem, rpdev->log_size);
|
||||
} else {
|
||||
dev_err(dev, "create %s fail\n", dir_name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, rpdev);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@@ -523,6 +583,7 @@ typedef enum {
|
||||
#define MAX_PM_NOTIFY_TIME 10
|
||||
#define MAX_PM_ASK_TIME 10
|
||||
|
||||
|
||||
static int light_rpmsg_sleep_notify(struct virtqueue *vq, light_pm_type_en type)
|
||||
{
|
||||
int ret;
|
||||
@@ -580,25 +641,44 @@ static int light_rpmsg_suspend(struct device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define C906_RESET_REG 0xfffff4403c
|
||||
|
||||
static void reset_audio(void) {
|
||||
uint64_t *v_addr = ioremap(C906_RESET_REG, 4);
|
||||
if(!v_addr) {
|
||||
printk("io remap failed\r\n");
|
||||
return;
|
||||
}
|
||||
writel(0x37, (volatile void *)v_addr);
|
||||
writel(0x3f, (volatile void *)v_addr);
|
||||
iounmap(C906_RESET_REG);
|
||||
}
|
||||
|
||||
static int light_rpmsg_resume(struct device *dev)
|
||||
{
|
||||
struct light_rpmsg_vproc *rpdev = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
int try_num = 0;
|
||||
printk("%s,%d,enter",__func__,__LINE__);
|
||||
int rst_flag = 0;
|
||||
|
||||
while(rpdev->sleep_flag) {
|
||||
ret = light_rpmsg_sleep_ask(rpdev->ivdev[0].vq[0]);
|
||||
down_timeout(&rpdev->pm_sem, msecs_to_jiffies(200));
|
||||
if(try_num++ > MAX_PM_ASK_TIME) {
|
||||
pr_err("sleep status check faild after try %d time", MAX_PM_ASK_TIME);
|
||||
printk("%s,%d,try %d times, exist",__func__,__LINE__, try_num);
|
||||
return -1;
|
||||
if(!rst_flag) {
|
||||
printk("Reset audio directly now");
|
||||
reset_audio();
|
||||
rst_flag = 1;
|
||||
try_num = 0;
|
||||
} else {
|
||||
pr_err("sleep states check failed after Reset audio");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
printk("%s,%d,try %d times, exist",__func__,__LINE__, try_num);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(light_rpmsg_pm_ops, light_rpmsg_suspend, light_rpmsg_resume);
|
||||
|
||||
@@ -3,3 +3,4 @@ obj-$(CONFIG_LIGHT_IOPMP) += light-iopmp.o
|
||||
obj-$(CONFIG_LIGHT_SUSPEND) += pm-light.o
|
||||
obj-$(CONFIG_LIGHT_REBOOTMODE) += light_event.o
|
||||
obj-$(CONFIG_LIGHT_DDR_PMU) += thead-ddr-pmu.o
|
||||
obj-y += light_regdump.o
|
||||
|
||||
@@ -36,7 +36,7 @@ struct light_aon_msg_event_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
u32 reserve_offset;
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_event {
|
||||
struct device *dev;
|
||||
@@ -52,8 +52,7 @@ struct light_event *light_event;
|
||||
|
||||
static void light_event_msg_hdr_fill(struct light_aon_rpc_msg_hdr *hdr, enum light_aon_misc_func func)
|
||||
{
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_MISC;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_SYS;
|
||||
hdr->func = (uint8_t)func;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
}
|
||||
@@ -61,14 +60,16 @@ static void light_event_msg_hdr_fill(struct light_aon_rpc_msg_hdr *hdr, enum lig
|
||||
static int light_event_aon_reservemem(struct light_event *event)
|
||||
{
|
||||
struct light_aon_ipc *ipc = event->ipc_handle;
|
||||
struct light_aon_rpc_ack_common ack_msg;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(event->dev, "aon reservemem...\n");
|
||||
|
||||
light_event_msg_hdr_fill(&event->msg.hdr, LIGHT_AON_MISC_FUNC_AON_RESERVE_MEM);
|
||||
event->msg.reserve_offset = LIGHT_EVENT_OFFSET;
|
||||
light_event_msg_hdr_fill(&event->msg.hdr, LIGHT_AON_SYS_FUNC_AON_RESERVE_MEM);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &event->msg, true);
|
||||
RPC_SET_BE32(&event->msg.reserve_offset, 0, LIGHT_EVENT_OFFSET);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &event->msg, &ack_msg, true);
|
||||
if (ret)
|
||||
dev_err(event->dev, "failed to set aon reservemem\n");
|
||||
|
||||
|
||||
185
drivers/soc/thead/light_regdump.c
Normal file
185
drivers/soc/thead/light_regdump.c
Normal file
@@ -0,0 +1,185 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2021 Alibaba Group Holding Limited.
|
||||
*/
|
||||
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/firmware/thead/ipc.h>
|
||||
#include <linux/firmware/thead/light_event.h>
|
||||
|
||||
#define DEVNAME "light-regdump"
|
||||
|
||||
struct light_regdump_meminfo {
|
||||
u64 startaddr;
|
||||
u64 size;
|
||||
u64 cfg_offset;
|
||||
};
|
||||
|
||||
struct light_aon_msg_regdump_cfg {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
u64 startaddr;
|
||||
u64 cfg_offset;
|
||||
u64 size;
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_regdump_config {
|
||||
struct cdev cdev;
|
||||
struct class* class;
|
||||
struct resource mem;
|
||||
struct light_regdump_meminfo meminfo;
|
||||
struct light_aon_ipc *ipc_handle;
|
||||
struct light_aon_msg_regdump_cfg msg;
|
||||
};
|
||||
|
||||
enum {
|
||||
REGDUMP_IOC_GET_RSV_MEM = 0x100,
|
||||
REGDUMP_IOC_CONFIG_DONE,
|
||||
};
|
||||
|
||||
static int regdump_open(struct inode* inode, struct file* file)
|
||||
{
|
||||
struct light_regdump_config* priv = container_of(inode->i_cdev, struct light_regdump_config, cdev);
|
||||
|
||||
file->private_data = priv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int regdump_release(struct inode* inode, struct file* file)
|
||||
{
|
||||
struct light_regdump_config* priv = container_of(inode->i_cdev, struct light_regdump_config, cdev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long regdump_ioctl(struct file* file, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct light_regdump_config* priv = (struct light_regdump_config*)file->private_data;
|
||||
struct light_aon_ipc *ipc = priv->ipc_handle;
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case REGDUMP_IOC_GET_RSV_MEM:
|
||||
{
|
||||
printk("%s REGDUMP_IOC_GET_RSV_MEM copy_to_user 0x%x 0x%x\n",
|
||||
__func__, priv->meminfo.startaddr, priv->meminfo.size);
|
||||
copy_to_user(arg, &priv->meminfo, sizeof(struct light_regdump_meminfo));
|
||||
} break;
|
||||
case REGDUMP_IOC_CONFIG_DONE: // inform 902
|
||||
{
|
||||
struct light_aon_rpc_msg_hdr *hdr = &priv->msg.hdr;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_MISC;
|
||||
hdr->func = (uint8_t)LIGHT_AON_MISC_FUNC_REGDUMP_CFG;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
RPC_SET_BE64(&priv->msg.startaddr, 0, priv->meminfo.startaddr);
|
||||
RPC_SET_BE64(&priv->msg.startaddr, 8, priv->meminfo.size);
|
||||
RPC_SET_BE64(&priv->msg.startaddr, 16, priv->meminfo.cfg_offset);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &priv->msg, &ack_msg, true);
|
||||
if (ret)
|
||||
printk("failed to REGDUMP_IOC_CONFIG_DONE\n");
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int regdump_mmap(struct file* file, struct vm_area_struct* vma)
|
||||
{
|
||||
struct light_regdump_config* priv = (struct light_regdump_config*)file->private_data;
|
||||
|
||||
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
|
||||
if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
|
||||
pr_err("-->%s: remap_pfn_range error!\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
printk("phy: 0x%lx, size: 0x%lx PAGE_SHIFT: %d vma->vm_pgoff: 0x%lx vma->vm_start: 0x%lx\n", pfn_to_phys(vma->vm_pgoff), vma->vm_end - vma->vm_start, PAGE_SHIFT, vma->vm_pgoff, vma->vm_start);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations regdump_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = regdump_open,
|
||||
.release = regdump_release,
|
||||
.unlocked_ioctl = regdump_ioctl,
|
||||
.mmap = regdump_mmap,
|
||||
};
|
||||
|
||||
static int light_regdump_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np;
|
||||
int ret;
|
||||
struct light_regdump_config *priv;
|
||||
struct device *dev = &pdev->dev;
|
||||
dev_t devid;
|
||||
struct light_aon_ipc *ipc_handle;
|
||||
|
||||
ret = light_aon_get_handle(&ipc_handle);
|
||||
if (ret == -EPROBE_DEFER) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(struct light_regdump_config), GFP_KERNEL);
|
||||
if (priv == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
np = of_parse_phandle(dev->of_node, "memory-region", 0);
|
||||
if (!np)
|
||||
return -EINVAL;
|
||||
|
||||
ret = of_address_to_resource(np, 0, &priv->mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
printk("%s got mem start 0x%x size 0x%x\n", __func__, priv->mem.start, resource_size(&priv->mem));
|
||||
priv->meminfo.startaddr = priv->mem.start;
|
||||
priv->meminfo.size = resource_size(&priv->mem);
|
||||
priv->meminfo.cfg_offset = 0x2800;
|
||||
priv->ipc_handle = ipc_handle;
|
||||
|
||||
ret = alloc_chrdev_region(&devid, 0, 1, DEVNAME);
|
||||
if (ret)
|
||||
return ret;
|
||||
cdev_init(&priv->cdev, ®dump_fops);
|
||||
ret = cdev_add(&priv->cdev, devid, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
priv->class = class_create(THIS_MODULE, DEVNAME);
|
||||
if (IS_ERR(priv->class))
|
||||
return PTR_ERR(priv->class);
|
||||
device_create(priv->class, &pdev->dev, devid, priv, "%s", DEVNAME);
|
||||
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id light_regdump_match[] = {
|
||||
{.compatible = "thead,light-regdump"},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver light_regdump_driver = {
|
||||
.probe = light_regdump_probe,
|
||||
.driver = {
|
||||
.name = DEVNAME,
|
||||
.of_match_table = light_regdump_match,
|
||||
}
|
||||
};
|
||||
|
||||
builtin_platform_driver(light_regdump_driver);
|
||||
|
||||
MODULE_AUTHOR("nanli.yd <nanli.yd@linux.alibaba.com>");
|
||||
MODULE_DESCRIPTION("Thead Light register dump driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@@ -22,14 +22,21 @@ struct rpc_msg_cpu_info{
|
||||
u16 cpu_id;
|
||||
u16 status;
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct rpc_msg_cpu_info_ack{
|
||||
struct light_aon_rpc_ack_common ack_hdr;
|
||||
u16 cpu_id;
|
||||
u16 status;
|
||||
u32 reserved[5];
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_msg_pm_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
union rpc_func_t {
|
||||
struct rpc_msg_cpu_info cpu_info;
|
||||
} __packed __aligned(4) rpc;
|
||||
} __packed __aligned(4);
|
||||
} __packed __aligned(1) rpc;
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_pm_ctrl {
|
||||
struct device *dev;
|
||||
@@ -40,18 +47,17 @@ struct light_aon_pm_ctrl {
|
||||
|
||||
static struct light_aon_pm_ctrl *aon_pm_ctrl;
|
||||
|
||||
static int light_require_state_pm_ctrl(struct light_aon_msg_pm_ctrl *msg, enum light_aon_misc_func func, bool ack)
|
||||
static int light_require_state_pm_ctrl(struct light_aon_msg_pm_ctrl *msg, enum light_aon_misc_func func, void* ack_msg, bool ack)
|
||||
{
|
||||
pr_debug("notify aon subsys...\n");
|
||||
struct light_aon_ipc *ipc = aon_pm_ctrl->ipc_handle;
|
||||
struct light_aon_rpc_msg_hdr *hdr = &msg->hdr;
|
||||
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_MISC;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_LPM;
|
||||
hdr->func = (uint8_t)func;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
|
||||
return light_aon_call_rpc(ipc, msg, ack);
|
||||
return light_aon_call_rpc(ipc, msg, ack_msg, ack);
|
||||
}
|
||||
|
||||
static int sbi_suspend_finisher(unsigned long suspend_type,
|
||||
@@ -90,7 +96,7 @@ static int light_suspend_prepare(void)
|
||||
int ret;
|
||||
aon_pm_ctrl->suspend_flag = true;
|
||||
struct light_aon_msg_pm_ctrl msg = {0};
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_MISC_FUNC_REQUIRE_STR, true);
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_LPM_FUNC_REQUIRE_STR, NULL, false);
|
||||
if (ret) {
|
||||
pr_err("[%s,%d]failed to initiate Suspend to Ram process to AON subsystem\n",__func__, __LINE__);
|
||||
return ret;
|
||||
@@ -103,7 +109,8 @@ static void light_resume_finish(void)
|
||||
int ret;
|
||||
aon_pm_ctrl->suspend_flag = false;
|
||||
struct light_aon_msg_pm_ctrl msg = {0};
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_MISC_FUNC_RESUME_STR, true);
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_LPM_FUNC_RESUME_STR, &ack_msg, true);
|
||||
if (ret) {
|
||||
pr_err("[%s,%d]failed to clear lowpower state\n",__func__, __LINE__);
|
||||
}
|
||||
@@ -115,9 +122,11 @@ static int thead_cpuhp_offline(unsigned int cpu)
|
||||
if(!aon_pm_ctrl->suspend_flag)
|
||||
{
|
||||
struct light_aon_msg_pm_ctrl msg = {0};
|
||||
msg.rpc.cpu_info.cpu_id = (u16)cpu;
|
||||
msg.rpc.cpu_info.status = 0;
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_MISC_FUNC_CPUHP, true);
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
|
||||
RPC_SET_BE16(&msg.rpc.cpu_info.cpu_id, 0, (u16)cpu);
|
||||
RPC_SET_BE16(&msg.rpc.cpu_info.cpu_id, 2, 0);
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_LPM_FUNC_CPUHP, &ack_msg, true);
|
||||
if (ret) {
|
||||
pr_info("failed to notify aon subsys with cpuhp...%08x\n", ret);
|
||||
return ret;
|
||||
@@ -132,9 +141,10 @@ static int thead_cpuhp_online(unsigned int cpu)
|
||||
if(!aon_pm_ctrl->suspend_flag)
|
||||
{
|
||||
struct light_aon_msg_pm_ctrl msg = {0};
|
||||
msg.rpc.cpu_info.cpu_id = (u16)cpu;
|
||||
msg.rpc.cpu_info.status = 1;
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_MISC_FUNC_CPUHP, true);
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
RPC_SET_BE16(&msg.rpc.cpu_info.cpu_id, 0, (u16)cpu);
|
||||
RPC_SET_BE16(&msg.rpc.cpu_info.cpu_id, 2, 1);
|
||||
ret = light_require_state_pm_ctrl(&msg, LIGHT_AON_LPM_FUNC_CPUHP, &ack_msg, true);
|
||||
if (ret) {
|
||||
pr_info("[%s,%d]failed to bring up aon subsys with cpuhp...%08x\n", __func__, __LINE__, ret);
|
||||
return ret;
|
||||
@@ -152,7 +162,7 @@ static const struct platform_suspend_ops light_suspend_ops = {
|
||||
.enter = light_suspend_enter,
|
||||
.valid = suspend_valid_only_mem,
|
||||
.prepare_late = light_suspend_prepare,
|
||||
.finish = light_resume_finish,
|
||||
.end = light_resume_finish,
|
||||
};
|
||||
|
||||
#define C906_RESET_REG 0xfffff4403c
|
||||
@@ -185,6 +195,34 @@ static const struct platform_hibernation_ops light_hibernation_allmode_ops = {
|
||||
.finish = light_hibernation_platform_finish,
|
||||
};
|
||||
|
||||
int get_audio_text_mem(struct device *dev, phys_addr_t* mem, size_t* mem_size)
|
||||
{
|
||||
struct resource r;
|
||||
ssize_t fw_size;
|
||||
void *mem_va;
|
||||
struct device_node *node;
|
||||
int ret;
|
||||
|
||||
*mem = 0;
|
||||
*mem_size = 0;
|
||||
|
||||
node = of_parse_phandle(dev->of_node, "audio-text-memory-region", 0);
|
||||
if (!node) {
|
||||
dev_err(dev, "no audio-text-memory-region specified\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_address_to_resource(node, 0, &r);
|
||||
if (ret) {
|
||||
dev_err(dev, "audio-text-memory-region get resource faild\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*mem = r.start;
|
||||
*mem_size = resource_size(&r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int light_pm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -203,7 +241,15 @@ static int light_pm_probe(struct platform_device *pdev)
|
||||
suspend_set_ops(&light_suspend_ops);
|
||||
|
||||
/*only save BSS and data section for audio*/
|
||||
hibernate_register_nosave_region(__phys_to_pfn(0x32000000), __phys_to_pfn(0x36600000));
|
||||
phys_addr_t audio_text_mem;
|
||||
size_t audio_text_mem_size;
|
||||
ret = get_audio_text_mem(dev, &audio_text_mem, &audio_text_mem_size);
|
||||
if(ret) {
|
||||
return ret;
|
||||
} else {
|
||||
printk("Get audio text phy mem:0x%011x, size:%d\n", audio_text_mem, audio_text_mem_size);
|
||||
}
|
||||
hibernate_register_nosave_region(__phys_to_pfn(audio_text_mem), __phys_to_pfn(audio_text_mem + audio_text_mem_size));
|
||||
hibernation_set_allmode_ops(&light_hibernation_allmode_ops);
|
||||
|
||||
ret = cpuhp_setup_state_nocalls(CPUHP_BP_PREPARE_DYN, "soc/thead:online",
|
||||
|
||||
@@ -88,6 +88,46 @@ MODULE_PARM_DESC(bufsiz, "data bytes in biggest supported SPI message");
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static ssize_t spidev_speed_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int speed_hz;
|
||||
char *start = (char *)buf;
|
||||
struct spidev_data *spidev = dev_get_drvdata(dev);
|
||||
|
||||
speed_hz = simple_strtoul(start, &start, 0);
|
||||
|
||||
if (speed_hz > spidev->spi->max_speed_hz)
|
||||
dev_err(dev, "speed too large, failed to set, speed:%d hz, max_speed:%d hz\n",
|
||||
speed_hz, spidev->spi->max_speed_hz);
|
||||
else
|
||||
spidev->speed_hz = speed_hz;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t spidev_speed_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct spidev_data *spidev = dev_get_drvdata(dev);
|
||||
|
||||
dev_info(dev, "spi speed:%d hz\n", spidev->speed_hz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(spidev_speed);
|
||||
|
||||
static struct attribute *spidev_speed_sysfs_entries[] = {
|
||||
&dev_attr_spidev_speed.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group dev_attr_spidev_speed_group = {
|
||||
.attrs = spidev_speed_sysfs_entries,
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
spidev_sync(struct spidev_data *spidev, struct spi_message *message)
|
||||
{
|
||||
@@ -780,6 +820,9 @@ static int spidev_probe(struct spi_device *spi)
|
||||
|
||||
spidev->speed_hz = spi->max_speed_hz;
|
||||
|
||||
if (sysfs_create_group(&spi->dev.kobj, &dev_attr_spidev_speed_group))
|
||||
dev_err(&spi->dev, "Failed to create spidev speed sysfs.\n");
|
||||
|
||||
if (status == 0)
|
||||
spi_set_drvdata(spi, spidev);
|
||||
else
|
||||
|
||||
@@ -958,9 +958,21 @@ static void __init unix98_pty_init(void)
|
||||
#else
|
||||
static inline void unix98_pty_init(void) { }
|
||||
#endif
|
||||
static bool nopty = false;
|
||||
|
||||
/* noclkdebug bootargs: for option not init ftrace*/
|
||||
static int __init nopty_setup(char *str)
|
||||
{
|
||||
nopty = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("nopty", nopty_setup);
|
||||
|
||||
static int __init pty_init(void)
|
||||
{
|
||||
if(nopty)
|
||||
return 0;
|
||||
legacy_pty_init();
|
||||
unix98_pty_init();
|
||||
return 0;
|
||||
|
||||
@@ -1591,6 +1591,9 @@ int usb_suspend(struct device *dev, pm_message_t msg)
|
||||
if (udev->quirks & USB_QUIRK_DISCONNECT_SUSPEND)
|
||||
usb_port_disable(udev);
|
||||
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_suspended(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1611,29 +1614,12 @@ int usb_resume_complete(struct device *dev)
|
||||
int usb_resume(struct device *dev, pm_message_t msg)
|
||||
{
|
||||
struct usb_device *udev = to_usb_device(dev);
|
||||
int status;
|
||||
|
||||
/* For all calls, take the device back to full power and
|
||||
* tell the PM core in case it was autosuspended previously.
|
||||
* Unbind the interfaces that will need rebinding later,
|
||||
* because they fail to support reset_resume.
|
||||
* (This can't be done in usb_resume_interface()
|
||||
* above because it doesn't own the right set of locks.)
|
||||
*/
|
||||
status = usb_resume_both(udev, msg);
|
||||
if (status == 0) {
|
||||
pm_runtime_disable(dev);
|
||||
pm_runtime_set_active(dev);
|
||||
pm_runtime_enable(dev);
|
||||
unbind_marked_interfaces(udev);
|
||||
}
|
||||
/* call usb_resume_both in usb_runtime_resume */
|
||||
pm_runtime_enable(dev);
|
||||
unbind_marked_interfaces(udev);
|
||||
|
||||
/* Avoid PM error messages for devices disconnected while suspended
|
||||
* as we'll display regular disconnect messages just a bit later.
|
||||
*/
|
||||
if (status == -ENODEV || status == -ESHUTDOWN)
|
||||
status = 0;
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1640,6 +1640,7 @@ static int dwc3_probe(struct platform_device *pdev)
|
||||
if (ret)
|
||||
goto err5;
|
||||
|
||||
device_enable_async_suspend(dev);
|
||||
pm_runtime_put(dev);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -101,7 +101,7 @@ static void dwc3_thead_deassert(struct dwc3_thead *thead)
|
||||
regmap_update_bits(thead->misc_sysreg, USB3_DRD_SWRST,
|
||||
USB3_DRD_MASK, USB3_DRD_PRST);
|
||||
|
||||
/*
|
||||
/*
|
||||
* 2. Common Block Power-Down Control.
|
||||
* Controls the power-down signals in the PLL block
|
||||
* when the USB 3.0 femtoPHY is in Suspend or Sleep mode.
|
||||
@@ -111,7 +111,7 @@ static void dwc3_thead_deassert(struct dwc3_thead *thead)
|
||||
|
||||
/*
|
||||
* 3. Reference Clock Enable for SS function.
|
||||
* Enables the reference clock to the prescaler.
|
||||
* Enables the reference clock to the prescaler.
|
||||
* The ref_ssp_en signal must remain de-asserted until
|
||||
* the reference clock is running at the appropriate frequency,
|
||||
* at which point ref_ssp_en can be asserted.
|
||||
@@ -225,6 +225,8 @@ static int dwc3_thead_probe(struct platform_device *pdev)
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
device_enable_async_suspend(dev);
|
||||
|
||||
dev_info(dev, "light dwc3 probe ok!\n");
|
||||
|
||||
return 0;
|
||||
@@ -257,9 +259,24 @@ static int dwc3_thead_remove(struct platform_device *pdev)
|
||||
static int dwc3_thead_pm_suspend(struct device *dev)
|
||||
{
|
||||
struct dwc3_thead *thead = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
int ret;
|
||||
|
||||
dwc3_thead_assert(thead);
|
||||
|
||||
if (!IS_ERR(thead->hubswitch)) {
|
||||
ret = regulator_disable(thead->hub1v2);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ERR(thead->hub5v)) {
|
||||
ret = regulator_disable(thead->hub5v);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to disable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
clk_bulk_disable(thead->num_clocks, thead->clks);
|
||||
ret = regulator_disable(thead->vbus);
|
||||
if (ret) {
|
||||
@@ -275,7 +292,7 @@ static int dwc3_thead_pm_suspend(struct device *dev)
|
||||
dev_err(dev, "failed to disable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -298,6 +315,21 @@ static int dwc3_thead_pm_resume(struct device *dev)
|
||||
dev_err(dev, "failed to enable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
|
||||
/* enable regulator here for some extend regulator does not have pm func */
|
||||
if (!IS_ERR(thead->hub1v2)) {
|
||||
ret = regulator_enable(thead->hub1v2);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IS_ERR(thead->hub5v)) {
|
||||
ret = regulator_enable(thead->hub5v);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable regulator hub1v2 %d\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
ret = clk_bulk_prepare_enable(thead->num_clocks, thead->clks);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to enable clk ret=%d\n", ret);
|
||||
|
||||
@@ -379,7 +379,7 @@ static irqreturn_t dw_wdt_irq(int irq, void *devid)
|
||||
}
|
||||
light_event_set_rebootmode(LIGHT_EVENT_SW_WATCHDOG);
|
||||
|
||||
WARN(1, "watchdog app was stuck! watchdog pretimeout event\n");
|
||||
pr_info("watchdog app was stuck! watchdog pretimeout event\n");
|
||||
watchdog_notify_pretimeout(&dw_wdt->wdd);
|
||||
|
||||
dw_wdt_ping(&dw_wdt->wdd);
|
||||
|
||||
@@ -39,8 +39,15 @@ struct light_aon_msg_wdg_ctrl {
|
||||
struct light_aon_rpc_msg_hdr hdr;
|
||||
u32 timeout;
|
||||
u32 running_state;
|
||||
u32 reserved[4];
|
||||
}_packed __aligned(4);
|
||||
u32 reserved[1];
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_aon_msg_wdg_ctrl_ack {
|
||||
struct light_aon_rpc_ack_common ack_hdr;
|
||||
u32 timeout;
|
||||
u32 running_state;
|
||||
u32 reserved[1];
|
||||
} __packed __aligned(1);
|
||||
|
||||
struct light_wdt_device {
|
||||
struct device *dev;
|
||||
@@ -65,8 +72,7 @@ static unsigned int light_wdt_timeout_to_sel(unsigned secs)
|
||||
|
||||
static void light_wdt_msg_hdr_fill(struct light_aon_rpc_msg_hdr *hdr, enum light_aon_misc_func func)
|
||||
{
|
||||
hdr->ver = LIGHT_AON_RPC_VERSION;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_MISC;
|
||||
hdr->svc = (uint8_t)LIGHT_AON_RPC_SVC_WDG;
|
||||
hdr->func = (uint8_t)func;
|
||||
hdr->size = LIGHT_AON_RPC_MSG_NUM;
|
||||
}
|
||||
@@ -74,15 +80,19 @@ static void light_wdt_msg_hdr_fill(struct light_aon_rpc_msg_hdr *hdr, enum light
|
||||
static int light_wdt_is_running(struct light_wdt_device *wdt_dev)
|
||||
{
|
||||
struct light_aon_ipc *ipc = wdt_dev->ipc_handle;
|
||||
struct light_aon_msg_wdg_ctrl_ack ack_msg= {0};
|
||||
int ret;
|
||||
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_WDG_GET_STATE);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_GET_STATE);
|
||||
wdt_dev->msg.running_state = -1;
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, true);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, &ack_msg, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
//RPC_GET_BE32(&ack_msg.timeout, 0, &wdt_dev->msg.timeout);
|
||||
RPC_GET_BE32(&ack_msg.timeout, 4, &wdt_dev->msg.running_state);
|
||||
|
||||
pr_debug("ret = %d, timeout = %d, running_state = %d\n", ret, wdt_dev->msg.timeout,
|
||||
wdt_dev->msg.running_state);
|
||||
|
||||
@@ -100,12 +110,14 @@ static int light_wdt_update_timeout(struct light_wdt_device *wdt_dev, unsigned i
|
||||
* new timeout value which enables the watchdog again.
|
||||
*/
|
||||
struct light_aon_ipc *ipc = wdt_dev->ipc_handle;
|
||||
struct light_aon_msg_wdg_ctrl_ack ack_msg= {0};
|
||||
int ret;
|
||||
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_WDG_TIMEOUTSET);
|
||||
wdt_dev->msg.timeout = timeout;
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_TIMEOUTSET);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, true);
|
||||
RPC_SET_BE32(&wdt_dev->msg.timeout, 0 , timeout);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, &ack_msg, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -139,11 +151,12 @@ static int light_wdt_start(struct watchdog_device *wdd)
|
||||
{
|
||||
struct light_wdt_device *wdt_dev = watchdog_get_drvdata(wdd);
|
||||
struct light_aon_ipc *ipc = wdt_dev->ipc_handle;
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
int ret;
|
||||
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_WDG_START);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_START);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, true);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, &ack_msg, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -154,11 +167,12 @@ static int light_wdt_stop(struct watchdog_device *wdd)
|
||||
{
|
||||
struct light_wdt_device *wdt_dev = watchdog_get_drvdata(wdd);
|
||||
struct light_aon_ipc *ipc = wdt_dev->ipc_handle;
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
int ret;
|
||||
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_WDG_STOP);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_STOP);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, true);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, &ack_msg, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -169,11 +183,12 @@ static int light_wdt_ping(struct watchdog_device *wdd)
|
||||
{
|
||||
struct light_wdt_device *wdt_dev = watchdog_get_drvdata(wdd);
|
||||
struct light_aon_ipc *ipc = wdt_dev->ipc_handle;
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
int ret;
|
||||
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_WDG_PING);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_PING);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, true);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, &ack_msg, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -186,12 +201,12 @@ static int light_wdt_restart(struct watchdog_device *wdd, unsigned long action,
|
||||
struct light_aon_ipc *ipc = wdt_dev->ipc_handle;
|
||||
int ret;
|
||||
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_WDG_RESTART);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_RESTART);
|
||||
|
||||
pr_debug("[%s,%d]: Inform aon to restart the whole system....\n", __func__, __LINE__);
|
||||
|
||||
light_event_set_rebootmode(LIGHT_EVENT_SW_REBOOT);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, false);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, NULL, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
pr_debug("[%s,%d]: Finish to inform aon to restart the whole system....\n", __func__, __LINE__);
|
||||
@@ -228,6 +243,7 @@ static ssize_t aon_sys_wdt_store(struct device *dev,
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct light_wdt_device *wdt_dev = platform_get_drvdata(pdev);
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
struct light_aon_ipc *ipc;
|
||||
int ret;
|
||||
char *start = (char *)buf;
|
||||
@@ -237,10 +253,10 @@ static ssize_t aon_sys_wdt_store(struct device *dev,
|
||||
val = simple_strtoul(start, &start, 0);
|
||||
wdt_dev->is_aon_wdt_ena = val;
|
||||
if (val)
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_AON_WDT_ON);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_AON_WDT_ON);
|
||||
else
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_AON_WDT_OFF);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, true);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_AON_WDT_OFF);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, &ack_msg, true);
|
||||
if (ret){
|
||||
pr_err("%s: err:%d \n",__func__,ret);
|
||||
return -EINVAL;
|
||||
@@ -252,13 +268,14 @@ void light_pm_power_off(void)
|
||||
{
|
||||
struct light_wdt_device *wdt_dev = light_power_off_wdt;
|
||||
struct light_aon_ipc *ipc = wdt_dev->ipc_handle;
|
||||
struct light_aon_rpc_ack_common ack_msg = {0};
|
||||
int ret;
|
||||
|
||||
pr_info("[%s,%d]poweroff system...\n", __func__, __LINE__);
|
||||
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_MISC_FUNC_WDG_POWER_OFF);
|
||||
light_wdt_msg_hdr_fill(&wdt_dev->msg.hdr, LIGHT_AON_WDG_FUNC_POWER_OFF);
|
||||
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, true);
|
||||
ret = light_aon_call_rpc(ipc, &wdt_dev->msg, &ack_msg, true);
|
||||
|
||||
if (ret)
|
||||
pr_err("failed to power off the system\n");
|
||||
|
||||
Reference in New Issue
Block a user