Commit 1625be9d authored by Mikhail Karpenko's avatar Mikhail Karpenko
Browse files

Merge branch 'master' of https://github.com/Elphel/linux-elphel into debug

parents 7180ee47 d8d417d9
Loading
Loading
Loading
Loading
+4 −6

File changed.

Preview size limit exceeded, changes collapsed.

+39 −3
Original line number Diff line number Diff line
@@ -6,15 +6,51 @@
	</projects>
	<buildSpec>
		<buildCommand>
			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
			<triggers>clean,full,incremental,</triggers>
			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
			<triggers>full,incremental,</triggers>
			<arguments>
				<dictionary>
					<key>LaunchConfigHandle</key>
					<value>&lt;project&gt;/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.genmakebuilder.launch</value>
				</dictionary>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
			<triggers>full,incremental,</triggers>
			<arguments>
				<dictionary>
					<key>LaunchConfigHandle</key>
					<value>&lt;project&gt;/.externalToolBuilders/org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder.launch</value>
				</dictionary>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
			<triggers>full,incremental,</triggers>
			<arguments>
				<dictionary>
					<key>LaunchConfigHandle</key>
					<value>&lt;project&gt;/.externalToolBuilders/bitbake compile [Builder].launch</value>
				</dictionary>
				<dictionary>
					<key>incclean</key>
					<value>true</value>
				</dictionary>
			</arguments>
		</buildCommand>
		<buildCommand>
			<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
			<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
			<triggers>full,incremental,</triggers>
			<arguments>
				<dictionary>
					<key>LaunchConfigHandle</key>
					<value>&lt;project&gt;/.externalToolBuilders/bitbake deploy [Builder].launch</value>
				</dictionary>
				<dictionary>
					<key>incclean</key>
					<value>true</value>
				</dictionary>
			</arguments>
		</buildCommand>
	</buildSpec>
+38 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <linux/ahci_platform.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
@@ -39,6 +40,7 @@ static const struct of_device_id ahci_elphel_of_match[];
struct elphel_ahci_priv {
	u32 clb_offs;
	u32 fb_offs;
	u32 base_addr;
};

static int elphel_port_start(struct ata_port *ap)
@@ -53,6 +55,8 @@ static int elphel_port_start(struct ata_port *ap)
	libahci_debug_init(ap->host);

	dev_info(dev, "starting port %d", ap->port_no);
	libahci_debug_wait_flag();

	pp = devm_kzalloc(dev, sizeof(struct ahci_port_priv), GFP_KERNEL);
	if (!pp)
		return -ENOMEM;
@@ -68,15 +72,18 @@ static int elphel_port_start(struct ata_port *ap)
	 * Set predefined addresses
	 */
	pp->cmd_slot = hpriv->mmio + dpriv->clb_offs;
	pp->cmd_slot_dma = virt_to_phys(pp->cmd_slot);
	//pp->cmd_slot_dma = virt_to_phys(pp->cmd_slot);
	pp->cmd_slot_dma = 0x80000000 + dpriv->clb_offs;

	pp->rx_fis = hpriv->mmio + dpriv->fb_offs;
	pp->rx_fis_dma = virt_to_phys(pp->rx_fis);
	//pp->rx_fis_dma = virt_to_phys(pp->rx_fis);
	pp->rx_fis_dma = 0x80000000 + dpriv->fb_offs;

	dev_info(dev, "cmd_slot and rx_fis addresses are set");
	dev_info(dev, "\tmmio address: 0x%p", hpriv->mmio);
	dev_info(dev, "\tcommand slot virtual address: 0x%p", pp->cmd_slot);
	dev_info(dev, "\rx fis virtual address: 0x%p", pp->rx_fis);
	/*printk(KERN_DEBUG "cmd_slot: 0x%p", pp->cmd_slot);
	printk(KERN_DEBUG "cmd_slot_dma: 0x%08u", pp->cmd_slot_dma);
	printk(KERN_DEBUG "rx_fis: 0x%p", pp->rx_fis);
	printk(KERN_DEBUG "rx_fis_dma: 0x%08u", pp->rx_fis_dma);
	printk(KERN_DEBUG "base_addr: 0x%08u", dpriv->base_addr);*/

	/*
	 * Save off initial list of interrupts to be enabled.
@@ -93,7 +100,10 @@ static int elphel_parse_prop(const struct device_node *devn,
		struct device *dev,
		struct elphel_ahci_priv *dpriv)
{
	u64 size;
	unsigned int flags;
	const __be32 *val;
	struct resource res;

	if (!devn) {
		dev_err(dev, "device tree node is not found");
@@ -104,6 +114,14 @@ static int elphel_parse_prop(const struct device_node *devn,
	dpriv->clb_offs = be32_to_cpup(val);
	val = of_get_property(devn, PROP_NAME_FB_OFFS, NULL);
	dpriv->fb_offs = be32_to_cpup(val);
	val = of_get_address(devn, 0, NULL, NULL);
	if (val != NULL) {
		dpriv->base_addr = be32_to_cpu(val);
		dev_info(dev, "base_addr: 0x%08u", dpriv->base_addr);
	} else {
		dev_err(dev, "can not get register address");
	}
	//of_address_to_resource(devn, 0, &res);

	return 0;
}
@@ -120,6 +138,7 @@ static int elphel_drv_probe(struct platform_device *pdev)
	unsigned int reg_val;

	dev_info(&pdev->dev, "probing Elphel AHCI driver");

	drv_priv = devm_kzalloc(dev, sizeof(struct elphel_ahci_priv), GFP_KERNEL);
	if (!drv_priv)
		return -ENOMEM;
@@ -149,6 +168,19 @@ static int elphel_drv_probe(struct platform_device *pdev)
	reg_val = readl(hpriv->mmio + HOST_VERSION);
	dev_info(dev, "HOST VS register: 0x%08x", reg_val);

	phys_addr_t paddr = virt_to_phys(hpriv->mmio);
	void *vaddr = phys_to_virt(paddr);
	dev_err(dev, "current mmio virt addr: %p\n", hpriv->mmio);
	dev_err(dev, "current mmio virt addr as uint: %u\n", hpriv->mmio);
	dev_err(dev, "mmio phys addr: %u\n", paddr);
	dev_err(dev, "mmio phys addr as tr: %p\n", paddr);
	dev_err(dev, "back converted mmio virt addr: %p\n", vaddr);
	//printk(KERN_DEBUG, "current mmio virt addr: %p\n", hpriv->mmio);
	//printk(KERN_DEBUG, "mmio phys addr: %u\n", paddr);
	//printk(KERN_DEBUG, "back converted mmio virt addr: %p\n", vaddr);
	printk(KERN_DEBUG "======");


	ret = ahci_platform_init_host(pdev, hpriv, &ahci_elphel_port_info,
			&ahci_platform_sht);
	if (ret) {
+8 −4
Original line number Diff line number Diff line
@@ -602,6 +602,7 @@ static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
	int offset = ahci_scr_offset(link->ap, sc_reg);

	int len;
	u32 tmp;
	char *msg_str = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL);
	if (msg_str != NULL) {
		len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "read port %u SATA status and control registers", link->ap->port_no);
@@ -612,7 +613,8 @@ static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
		*val = readl(port_mmio + offset);

		if (msg_str != NULL) {
			len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\tport %u offset: 0x%x, value: 0x%x", link->ap->port_no, offset, *val);
			tmp = readl(port_mmio + PORT_CMD);
			len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\tport %u offset: 0x%x, value: 0x%x, PxCMD: 0x%08x", link->ap->port_no, offset, *val, tmp);
			libahci_debug_event(link->ap, msg_str, len);
		}

@@ -1730,7 +1732,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
	ata_tf_to_fis(&tf, 0, 0, d2h_fis);

	if (msg_str != NULL) {
		len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\tprocced to sata_link_hardreset");
		len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "\tproceed to sata_link_hardreset");
		libahci_debug_event(ap, msg_str, len);
	}
	rc = sata_link_hardreset(link, timing, deadline, &online,
@@ -2302,6 +2304,8 @@ unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
		pp->fbs_last_dev = qc->dev->link->pmp;
	}

	//libahci_debug_wait_flag();

	writel(1 << qc->tag, port_mmio + PORT_CMD_ISSUE);

	ahci_sw_activity(qc->dev->link);
@@ -2531,7 +2535,7 @@ static void ahci_enable_fbs(struct ata_port *ap)

	int len;
	char *msg_str = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL);
	if (msg_str != NULL) {
	if (msg_str != NULL && pp->fbs_supported) {
		len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "enable port %u FIS-based switching", ap->port_no);
		libahci_debug_event(ap, msg_str, len);
		kfree(msg_str);
@@ -2573,7 +2577,7 @@ static void ahci_disable_fbs(struct ata_port *ap)

	int len;
	char *msg_str = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL);
	if (msg_str != NULL) {
	if (msg_str != NULL && pp->fbs_supported) {
		len = snprintf(msg_str, LIBAHCI_DEBUG_BUFSZ, "disable port %u FIS-based switching", ap->port_no);
		libahci_debug_event(ap, msg_str, len);
		kfree(msg_str);
+79 −29
Original line number Diff line number Diff line
@@ -15,7 +15,8 @@
static struct dentry	*debug_root = NULL;
static struct libahci_debug_list debug_list = {.debug = 0};
static struct ahci_cmd	cmd;
static struct simple_buff init_buff;
static bool load_flag = false;
volatile unsigned int *mem_buff;

/*
 * Print PxIS (0x10) analysis
@@ -247,6 +248,7 @@ static int libahci_debug_host_show(struct seq_file *f, void *p)
{
	struct ata_host		*host = f->private;
	struct host_regs	hr = {0};
	phys_addr_t			buff_addr;

	libahci_debug_read_host_regs(host, &hr);
	seq_printf(f, "CAP:\t\t0x%08X\n", hr.CAP);
@@ -261,6 +263,9 @@ static int libahci_debug_host_show(struct seq_file *f, void *p)
	seq_printf(f, "EM_CTL:\t\t0x%08X\n", hr.EM_CTL);
	seq_printf(f, "BOHC:\t\t0x%08X\n", hr.BOHC);

	buff_addr = virt_to_phys(mem_buff);
	seq_printf(f, "\nbuffer location:\t\t0x%08X\n", buff_addr);

	return 0;
}

@@ -315,7 +320,6 @@ static int libahci_debug_rdesc_open(struct inode *i_node, struct file *f)
static int libahci_debug_events_open(struct inode *i_node, struct file *f)
{
	int					err = 0;
	int					sz;
	unsigned long		flags;
	struct libahci_debug_list *list;
	struct ata_port		*port = i_node->i_private;
@@ -344,13 +348,6 @@ static int libahci_debug_events_open(struct inode *i_node, struct file *f)
	// Associate debug list entry with corresponding file
	f->private_data = list;

	// Copy the content of init buffer to libahci_debug_buff
	/*if (init_buff.tail > init_buff.head) {
		sz = init_buff.tail- init_buff.head;
		memcpy(list->libahci_debug_buf, init_buff.buff, sz);
		list->tail = sz;
	}*/

fail_handler:
	return err;
}
@@ -479,19 +476,6 @@ void libahci_debug_event(const struct ata_port *port, char *msg, size_t msg_sz)
			}
			kfree(format_msg);
		}
	} else if (init_buff.initialized) {
		// debugfs file is not open, write to tmp buffer
		/*format_msg = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL);
		if (format_msg != NULL) {
				spin_lock_irqsave(&pos->debug_list_lock, flags);
				len = snprintf(format_msg, LIBAHCI_DEBUG_BUFSZ, "%s %s\n", EVT_MARKER, msg);
				for (i = 0; i < len; i++) {
					init_buff.buff[(init_buff.tail+ i) % LIBAHCI_DEBUG_BUFSZ] = format_msg[i];
				}
				init_buff.tail = (init_buff.tail + len) % LIBAHCI_DEBUG_BUFSZ;
				spin_unlock_irqrestore(&pos->debug_list_lock, flags);
		}*/

	}
}
EXPORT_SYMBOL_GPL(libahci_debug_event);
@@ -668,6 +652,70 @@ static int libahci_debug_fis_release(struct inode *i_node, struct file *f)
	return 0;
}

static ssize_t libahci_debug_load(struct file *f, const char __user *buff, size_t buff_sz, loff_t *ppos)
{
	load_flag = true;

	return buff_sz;
}

/*
 * This function waits until the loading flag is set through debugfs file.
 * The state of the flag is checked every 100ms.
 */
void libahci_debug_wait_flag(void)
{
	printk(KERN_DEBUG "%s Waiting for flag to be written to debugfs", MARKER);
	while (load_flag == false) {
		/*set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(msecs_to_jiffies(100));*/
		msleep(500);
	}
	load_flag = false;
}
EXPORT_SYMBOL_GPL(libahci_debug_wait_flag);

/*
 * Copy controller registers to buffer memory
 */
void libahci_debug_state_dump(struct device *dev)
{
	static u32 page_cntr;
	phys_addr_t v2p;
	u32 *p2v;
	int i;

	if (!mem_buff) {
		dev_err(dev, "dump buffer has not been allocated");
		return;
	}

	v2p = virt_to_phys(mem_buff);
	dev_info(dev, "write to buffer: 0x%08x", v2p);
	mem_buff[0] = 0xdeadbeef;
	for (i = 1; i < 100; i++) {
		mem_buff[i] = 0xa5a5a5a5;
	}
	/*__cpu_flush_kern_all();
	outer_flush_all();
	for (i = 0; i < 100; i++) {
		v2p = virt_to_phys(mem_buff + 4*i);
		dev_info(dev, "read phys addr: 0x%x, data: 0x%08x", v2p, *(mem_buff + 4*i));
	}*/
}

static void libahci_debug_buff_init(struct device *dev)
{
	dma_addr_t dma_handle;

	dev_info(dev, "trying to allocate dump buffer");
	mem_buff = dmam_alloc_coherent(dev, PAGE_SIZE, &dma_handle, GFP_KERNEL);
	if (!mem_buff)
		dev_err(dev, "unable to allocate memory");
	else
		dev_info(dev, "buffer allocated at 0x%08x", dma_handle);
}

static const struct file_operations libahci_debug_host_ops = {
	.open				= libahci_debug_host_open,
	.read				= seq_read,
@@ -703,6 +751,10 @@ static const struct file_operations libahci_debug_chdr_ops = {
	.release			= libahci_debug_fis_release,
};

static const struct file_operations libahci_debug_load_ops= {
		.write			= libahci_debug_load,
};

static int libahci_debug_init_sg(void)
{
	cmd.sg_buff = kzalloc(CMD_DMA_BUFSZ, GFP_KERNEL);
@@ -731,6 +783,9 @@ int libahci_debug_init(struct ata_host *host)
	}
	debugfs_create_file("rdesc_host", 0644,
			debug_root, host, &libahci_debug_host_ops);
	debugfs_create_file("loading", 0222,
			debug_root, host, &libahci_debug_load_ops);

	/* Create subdir for each port and add there several files:
	 * one for port registers, one for port events log and
	 * two files for working with FISes
@@ -752,13 +807,8 @@ int libahci_debug_init(struct ata_host *host)
		goto fail_handler;
	}

	/*init_buff.buff = kzalloc(LIBAHCI_DEBUG_BUFSZ, GFP_KERNEL);
	if (init_buff.buff == NULL) {
		kfree(cmd.sg_buff);
		goto fail_handler;
	}
	init_buff.initialized = true;*/

	libahci_debug_buff_init(host->dev);
	libahci_debug_state_dump(host->dev);
	return 0;

fail_handler:
Loading