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

Commit f4f2f667 authored by Mukesh Kumar Savaliya's avatar Mukesh Kumar Savaliya Committed by Gerrit - the friendly Code Review server
Browse files

serial: msm_geni_serial: Enhance debug logs and support



This patch adds useful and optimal debug logs at correct places.
Also adds HW version check and rectifies existing logs. In addition
added support to extract FW and HW verion from the adb shell which
can help in future debug.

Change-Id: I0c9fb55bf78bf34b2ae9071d36f5ec9703be2778
Signed-off-by: default avatarMukesh Kumar Savaliya <msavaliy@codeaurora.org>
parent 5431ddf1
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -1568,6 +1568,8 @@ void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
{
	u32 m_cmd0 = 0;
	u32 m_irq_status = 0;
	u32 s_cmd0 = 0;
	u32 s_irq_status = 0;
	u32 geni_status = 0;
	u32 geni_ios = 0;
	u32 dma_rx_irq = 0;
@@ -1594,10 +1596,12 @@ void geni_se_dump_dbg_regs(struct se_geni_rsc *rsc, void __iomem *base,
	}
	m_cmd0 = geni_read_reg(base, SE_GENI_M_CMD0);
	m_irq_status = geni_read_reg(base, SE_GENI_M_IRQ_STATUS);
	s_cmd0 = geni_read_reg(base, SE_GENI_S_CMD0);
	s_irq_status = geni_read_reg(base, SE_GENI_S_IRQ_STATUS);
	geni_status = geni_read_reg(base, SE_GENI_STATUS);
	geni_ios = geni_read_reg(base, SE_GENI_IOS);
	dma_rx_irq = geni_read_reg(base, SE_DMA_TX_IRQ_STAT);
	dma_tx_irq = geni_read_reg(base, SE_DMA_RX_IRQ_STAT);
	dma_tx_irq = geni_read_reg(base, SE_DMA_TX_IRQ_STAT);
	dma_rx_irq = geni_read_reg(base, SE_DMA_RX_IRQ_STAT);
	rx_fifo_status = geni_read_reg(base, SE_GENI_RX_FIFO_STATUS);
	tx_fifo_status = geni_read_reg(base, SE_GENI_TX_FIFO_STATUS);
	se_dma_dbg = geni_read_reg(base, SE_DMA_DEBUG_REG0);
+102 −22
Original line number Diff line number Diff line
@@ -133,6 +133,14 @@
#define UART_CONSOLE_RX_WM	(2)
#define QUP_VER			(0x20050000)

struct msm_geni_serial_ver_info {
	int hw_major_ver;
	int hw_minor_ver;
	int hw_step_ver;
	int m_fw_ver;
	int s_fw_ver;
};

struct msm_geni_serial_port {
	struct uart_port uport;
	char name[20];
@@ -169,6 +177,7 @@ struct msm_geni_serial_port {
	int ioctl_count;
	int edge_count;
	bool manual_flow;
	struct msm_geni_serial_ver_info ver_info;
};

static const struct uart_ops msm_geni_serial_pops;
@@ -193,6 +202,7 @@ static void msm_geni_serial_stop_rx(struct uart_port *uport);
static int msm_geni_serial_runtime_resume(struct device *dev);
static int msm_geni_serial_runtime_suspend(struct device *dev);
static int uart_line_id;
static int msm_geni_serial_get_ver_info(struct uart_port *uport);

#define GET_DEV_PORT(uport) \
	container_of(uport, struct msm_geni_serial_port, uport)
@@ -326,7 +336,7 @@ static void wait_for_transfers_inflight(struct uart_port *uport)
static int vote_clock_on(struct uart_port *uport)
{
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
	int usage_count = atomic_read(&uport->dev->power.usage_count);
	int usage_count;
	int ret = 0;

	ret = msm_geni_serial_power_on(uport);
@@ -335,15 +345,18 @@ static int vote_clock_on(struct uart_port *uport)
		return ret;
	}
	port->ioctl_count++;
	IPC_LOG_MSG(port->ipc_log_pwr, "%s%s ioctl %d usage_count %d\n",
		__func__, current->comm, port->ioctl_count, usage_count);
	usage_count = atomic_read(&uport->dev->power.usage_count);
	IPC_LOG_MSG(port->ipc_log_pwr,
		"%s :%s ioctl:%d usage_count:%d edge-Count:%d\n",
		__func__, current->comm, port->ioctl_count,
		usage_count, port->edge_count);
	return 0;
}

static int vote_clock_off(struct uart_port *uport)
{
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);
	int usage_count = atomic_read(&uport->dev->power.usage_count);
	int usage_count;

	if (!pm_runtime_enabled(uport->dev)) {
		dev_err(uport->dev, "RPM not available.Can't enable clocks\n");
@@ -360,7 +373,8 @@ static int vote_clock_off(struct uart_port *uport)
	wait_for_transfers_inflight(uport);
	port->ioctl_count--;
	msm_geni_serial_power_off(uport);
	IPC_LOG_MSG(port->ipc_log_pwr, "%s%s ioctl %d usage_count %d\n",
	usage_count = atomic_read(&uport->dev->power.usage_count);
	IPC_LOG_MSG(port->ipc_log_pwr, "%s:%s ioctl:%d usage_count:%d\n",
		__func__, current->comm, port->ioctl_count, usage_count);
	return 0;
};
@@ -395,7 +409,8 @@ static void msm_geni_serial_break_ctl(struct uart_port *uport, int ctl)

	if (!uart_console(uport) && device_pending_suspend(uport)) {
		IPC_LOG_MSG(port->ipc_log_misc,
				"%s.Device is suspended.\n", __func__);
				"%s.Device is suspended, %s\n",
				__func__, current->comm);
		return;
	}

@@ -418,9 +433,14 @@ static unsigned int msm_geni_serial_get_mctrl(struct uart_port *uport)
{
	u32 geni_ios = 0;
	unsigned int mctrl = TIOCM_DSR | TIOCM_CAR;
	struct msm_geni_serial_port *port = GET_DEV_PORT(uport);

	if (device_pending_suspend(uport))
	if (!uart_console(uport) && device_pending_suspend(uport)) {
		IPC_LOG_MSG(port->ipc_log_misc,
				"%s.Device is suspended, %s\n",
				__func__, current->comm);
		return TIOCM_DSR | TIOCM_CAR | TIOCM_CTS;
	}

	geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS);
	if (!(geni_ios & IO2_DATA_IN))
@@ -442,7 +462,8 @@ static void msm_geni_serial_set_mctrl(struct uart_port *uport,

	if (device_pending_suspend(uport)) {
		IPC_LOG_MSG(port->ipc_log_misc,
				"%s.Device is suspended.\n", __func__);
			"%s.Device is suspended, %s: mctrl=0x%x\n",
			 __func__, current->comm, mctrl);
		return;
	}
	if (!(mctrl & TIOCM_RTS)) {
@@ -455,6 +476,10 @@ static void msm_geni_serial_set_mctrl(struct uart_port *uport,
							SE_UART_MANUAL_RFR);
	/* Write to flow control must complete before return to client*/
	mb();
	IPC_LOG_MSG(port->ipc_log_misc,
			"%s:%s, mctrl=0x%x, manual_rfr=0x%x, flow=%s\n",
			__func__, current->comm, mctrl, uart_manual_rfr,
			(port->manual_flow ? "OFF" : "ON"));
}

static const char *msm_geni_serial_get_type(struct uart_port *uport)
@@ -884,6 +909,7 @@ static void msm_geni_serial_start_tx(struct uart_port *uport)
	struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);
	unsigned int geni_status;
	unsigned int geni_ios;
	static unsigned int ios_log_limit;

	if (!uart_console(uport) && !pm_runtime_active(uport->dev)) {
		IPC_LOG_MSG(msm_port->ipc_log_misc,
@@ -926,9 +952,11 @@ static void msm_geni_serial_start_tx(struct uart_port *uport)
	return;
check_flow_ctrl:
	geni_ios = geni_read_reg_nolog(uport->membase, SE_GENI_IOS);
	if (!(geni_ios & IO2_DATA_IN))
	if (++ios_log_limit % 5 == 0) {
		IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: ios: 0x%08x\n",
						__func__, geni_ios);
		ios_log_limit = 0;
	}
exit_start_tx:
	if (!uart_console(uport))
		msm_geni_serial_power_off(uport);
@@ -1076,9 +1104,10 @@ static void start_rx_sequencer(struct uart_port *uport)
	 * go through.
	 */
	mb();
	geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
exit_start_rx_sequencer:
	IPC_LOG_MSG(port->ipc_log_misc, "%s 0x%x\n", __func__, geni_status);
	geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
	IPC_LOG_MSG(port->ipc_log_misc, "%s: 0x%x, dma_dbg:0x%x\n", __func__,
		geni_status, geni_read_reg(uport->membase, SE_DMA_DEBUG_REG0));
}

static void msm_geni_serial_start_rx(struct uart_port *uport)
@@ -1176,6 +1205,8 @@ static void stop_rx_sequencer(struct uart_port *uport)
						      DMA_RX_BUF_SIZE);
		port->rx_dma = (dma_addr_t)NULL;
	}
	geni_status = geni_read_reg_nolog(uport->membase, SE_GENI_STATUS);
	IPC_LOG_MSG(port->ipc_log_misc, "%s: 0x%x\n", __func__, geni_status);
}

static void msm_geni_serial_stop_rx(struct uart_port *uport)
@@ -1712,16 +1743,6 @@ static int msm_geni_serial_startup(struct uart_port *uport)
		}
	}

	if (unlikely(get_se_proto(uport->membase) != UART)) {
		dev_err(uport->dev, "%s: Invalid FW %d loaded.\n",
				 __func__, get_se_proto(uport->membase));
		ret = -ENXIO;
		goto exit_startup;
	}
	IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: FW Ver:0x%x%x\n",
		__func__,
		get_se_m_fw(uport->membase), get_se_s_fw(uport->membase));

	get_tx_fifo_size(msm_port);
	if (!msm_port->port_setup) {
		if (msm_geni_serial_port_setup(uport))
@@ -2050,6 +2071,23 @@ static ssize_t msm_geni_serial_xfer_mode_store(struct device *dev,
static DEVICE_ATTR(xfer_mode, 0644, msm_geni_serial_xfer_mode_show,
					msm_geni_serial_xfer_mode_store);

static ssize_t ver_info_show(struct device *dev,
			struct device_attribute *attr, char *buf)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct msm_geni_serial_port *port = platform_get_drvdata(pdev);
	ssize_t ret = 0;
	int len = (sizeof(struct msm_geni_serial_ver_info) * 2);

	ret = snprintf(buf, len, "FW ver=0x%x%x, HW ver=%d.%d.%d\n",
		port->ver_info.m_fw_ver, port->ver_info.m_fw_ver,
		port->ver_info.hw_major_ver, port->ver_info.hw_minor_ver,
		port->ver_info.hw_step_ver);

	return ret;
}
static DEVICE_ATTR_RO(ver_info);

#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
static int __init msm_geni_console_setup(struct console *co, char *options)
{
@@ -2349,6 +2387,43 @@ static const struct of_device_id msm_geni_device_tbl[] = {
	{},
};

static int msm_geni_serial_get_ver_info(struct uart_port *uport)
{
	int hw_ver, ret = 0;
	struct msm_geni_serial_port *msm_port = GET_DEV_PORT(uport);

	se_geni_clks_on(&msm_port->serial_rsc);
	/* Basic HW and FW info */
	if (unlikely(get_se_proto(uport->membase) != UART)) {
		dev_err(uport->dev, "%s: Invalid FW %d loaded.\n",
			 __func__, get_se_proto(uport->membase));
		ret = -ENXIO;
		goto exit_ver_info;
	}

	msm_port->ver_info.m_fw_ver = get_se_m_fw(uport->membase);
	msm_port->ver_info.s_fw_ver = get_se_s_fw(uport->membase);
	IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: FW Ver:0x%x%x\n",
		__func__,
		msm_port->ver_info.m_fw_ver, msm_port->ver_info.s_fw_ver);

	hw_ver = geni_se_qupv3_hw_version(msm_port->wrapper_dev,
		&msm_port->ver_info.hw_major_ver,
		&msm_port->ver_info.hw_minor_ver,
		&msm_port->ver_info.hw_step_ver);
	if (hw_ver)
		dev_err(uport->dev, "%s:Err getting HW version %d\n",
						__func__, hw_ver);
	else
		IPC_LOG_MSG(msm_port->ipc_log_misc, "%s: HW Ver:%x.%x.%x\n",
			__func__, msm_port->ver_info.hw_major_ver,
			msm_port->ver_info.hw_minor_ver,
			msm_port->ver_info.hw_step_ver);
exit_ver_info:
	se_geni_clks_off(&msm_port->serial_rsc);
	return ret;
}

static int msm_geni_serial_probe(struct platform_device *pdev)
{
	int ret = 0;
@@ -2571,8 +2646,13 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
				line, uport->fifosize, is_console);
	device_create_file(uport->dev, &dev_attr_loopback);
	device_create_file(uport->dev, &dev_attr_xfer_mode);
	device_create_file(uport->dev, &dev_attr_ver_info);
	msm_geni_serial_debug_init(uport, is_console);
	dev_port->port_setup = false;
	ret = msm_geni_serial_get_ver_info(uport);
	if (ret)
		goto exit_geni_serial_probe;

	ret = uart_add_one_port(drv, uport);
	if (!ret) {
		if (strcmp(id->compatible, "qcom,msm-geni-console") == 0)