static u8 handle_irq(u8 *io)
{
	u32 irq_status;
	u8 ret = 0;

	irq_status = dsi_rreg(io, DSI_DIRECT_CMD_STS_FLAG_V3);
	if (irq_status & DSI_DIRECT_CMD_STS_FLAG_V3_TE_RECEIVED_FLAG_MASK)
		ret |= DSILINK_IRQ_BTA_TE;

	if (irq_status & DSI_DIRECT_CMD_STS_FLAG_V3_TRIGGER_RECEIVED_FLAG_MASK)
		/* DSI TE polling answer received */
		ret |= DSILINK_IRQ_TRIGGER;

	dsi_wreg(io, DSI_DIRECT_CMD_STS_CLR_V3, irq_status);

	irq_status = dsi_rreg(io, DSI_CMD_MODE_STS_FLAG_V3);
	if (irq_status & DSI_CMD_MODE_STS_FLAG_V3_ERR_NO_TE_FLAG_MASK)
		ret |= DSILINK_IRQ_NO_TE;

	dsi_wreg(io, DSI_CMD_MODE_STS_CLR_V3, irq_status);

	return ret;
}
示例#2
0
static u8 handle_irq(u8 *io)
{
	u32 irq_status;
	u8 ret = 0;

	irq_status = dsi_rreg(io, DSI_DIRECT_CMD_STS_FLAG);
	if (irq_status & DSI_DIRECT_CMD_STS_FLAG_TE_RECEIVED_FLAG_MASK)
		ret |= DSILINK_IRQ_BTA_TE;

	if (irq_status & DSI_DIRECT_CMD_STS_FLAG_TRIGGER_RECEIVED_FLAG_MASK)
		/* DSI TE polling answer received */
		ret |= DSILINK_IRQ_TRIGGER;

	if (irq_status &
		DSI_DIRECT_CMD_STS_FLAG_ACKNOWLEDGE_WITH_ERR_RECEIVED_FLAG_MASK)
		ret |= DSILINK_IRQ_ACK_WITH_ERR;

	dsi_wreg(io, DSI_DIRECT_CMD_STS_CLR, irq_status);

	irq_status = dsi_rreg(io, DSI_CMD_MODE_STS_FLAG);
	if (irq_status & DSI_CMD_MODE_STS_FLAG_ERR_NO_TE_FLAG_MASK)
		ret |= DSILINK_IRQ_NO_TE;

	if (irq_status & DSI_CMD_MODE_STS_FLAG_ERR_TE_MISS_FLAG_MASK)
		ret |= DSILINK_IRQ_TE_MISS;

	dsi_wreg(io, DSI_CMD_MODE_STS_CLR, irq_status);

	irq_status = dsi_rreg(io, DSI_VID_MODE_STS_FLAG);
	dsi_wreg(io, DSI_VID_MODE_STS_CLR, irq_status);
	if (irq_status & DSI_VID_MODE_STS_FLAG_ERR_MISSING_DATA_FLAG_MASK)
		ret |= DSILINK_IRQ_MISSING_DATA;
	if (irq_status & DSI_VID_MODE_STS_FLAG_ERR_MISSING_VSYNC_FLAG_MASK)
		ret |= DSILINK_IRQ_MISSING_VSYNC;

	return ret;
}
static int __devinit nova_dsilink_probe(struct platform_device *pdev)
{
	struct dsilink_device *dsilink;
	struct resource *res;
	int ret = 0;
	char dsihsclkname[10];
	char dsilpclkname[10];

	dsilink = kzalloc(sizeof(struct dsilink_device), GFP_KERNEL);
	if (!dsilink)
		return -ENOMEM;

	if (pdev->id >= MAX_NBR_OF_DSILINKS) {
		ret = -EINVAL;
		goto failed_to_get_correct_id;
	}

	dsilink->dev = &pdev->dev;

	dsilinks[pdev->id] = dsilink;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_warn(&pdev->dev, "get resource failed\n");
		ret = -ENODEV;
		goto failed_get_resource;
	}

	dsilink->io = ioremap(res->start, resource_size(res));
	if (!dsilink->io) {
		dev_warn(&pdev->dev, "iomap failed\n");
		ret = -EINVAL;
		goto failed_map_dsi_io;
	}

	dev_info(&pdev->dev, "iomap: 0x%.8X->0x%.8X\n",
				(u32)res->start, (u32)dsilink->io);


	/* Not all platform has VANA as a regulator */
	dsilink->reg_vana = regulator_get(&pdev->dev, REG_VANA);
	if (IS_ERR(dsilink->reg_vana)) {
		dsilink->reg_vana = NULL;
		dev_dbg(&pdev->dev,
			"%s: Failed to get regulator vana\n", __func__);
	}

	dsilink->reg_epod_dss = regulator_get(&pdev->dev, REG_EPOD_DSS);
	if (IS_ERR(dsilink->reg_epod_dss)) {
		ret = PTR_ERR(dsilink->reg_epod_dss);
		dev_warn(&pdev->dev,
			"%s: Failed to get regulator vsupply\n", __func__);
		goto failed_get_epod_dss;
	}

	dsilink->clk_dsi_sys = clk_get(&pdev->dev, CLK_DSI_SYS);
	if (IS_ERR(dsilink->clk_dsi_sys)) {
		ret = PTR_ERR(dsilink->clk_dsi_sys);
		dev_warn(&pdev->dev, "%s: Failed to get sys clock\n",
								__func__);
		goto failed_to_get_dsi_sys;
	}

	sprintf(dsihsclkname, "%s%d", CLK_DSI_HS, pdev->id);
	dsilink->clk_dsi_hs = clk_get(&pdev->dev, dsihsclkname);
	if (IS_ERR(dsilink->clk_dsi_hs)) {
		ret = PTR_ERR(dsilink->clk_dsi_hs);
		dev_warn(&pdev->dev, "%s: Failed to get clock %s\n",
						__func__, dsihsclkname);
		goto failed_to_get_dsi_hs;
	}

	sprintf(dsilpclkname, "%s%d", CLK_DSI_LP, pdev->id);
	dsilink->clk_dsi_lp = clk_get(&pdev->dev, dsilpclkname);
	if (IS_ERR(dsilink->clk_dsi_lp)) {
		ret = PTR_ERR(dsilink->clk_dsi_lp);
		dev_warn(&pdev->dev, "%s: Failed to get clock %s\n",
						__func__, dsilpclkname);
		goto failed_to_get_dsi_lp;
	}

	/* VANA needs to be on in order to read out the hw version */
	if (dsilink->reg_vana)
		regulator_enable(dsilink->reg_vana);
	regulator_enable(dsilink->reg_epod_dss);
	clk_enable(dsilink->clk_dsi_sys);
	clk_enable(dsilink->clk_dsi_hs);
	clk_enable(dsilink->clk_dsi_lp);
	release_link_reset(pdev->id);

	dsilink->version = dsi_rreg(dsilink->io, DSI_ID_REG);

	dev_info(dsilink->dev, "hw revision 0x%.8X\n", dsilink->version);

	set_link_reset(pdev->id);
	clk_disable(dsilink->clk_dsi_hs);
	clk_disable(dsilink->clk_dsi_lp);
	clk_disable(dsilink->clk_dsi_sys);
	regulator_disable(dsilink->reg_epod_dss);
	if (dsilink->reg_vana)
		regulator_disable(dsilink->reg_vana);

	if (dsilink->version == DSILINK_VERSION_3)
		nova_dsilink_v3_init(&dsilink->ops);
	else if (dsilink->version == DSILINK_VERSION_2_1 ||
				dsilink->version == DSILINK_VERSION_2_0)
		nova_dsilink_v2_init(&dsilink->ops);
	else
		goto failed_wrong_dsilink_version;

	platform_set_drvdata(pdev, dsilink);

	DSILINK_TRACE(dsilink->dev);

	/* Wait 100 us before returning */
	usleep_range(100, 100);

	return 0;

failed_wrong_dsilink_version:
	dev_warn(dsilink->dev, "Unsupported dsilink version\n");
failed_to_get_dsi_lp:
	clk_put(dsilink->clk_dsi_hs);
failed_to_get_dsi_hs:
	clk_put(dsilink->clk_dsi_sys);
failed_to_get_dsi_sys:
	regulator_put(dsilink->reg_epod_dss);
failed_get_epod_dss:
	if (dsilink->reg_vana)
		regulator_put(dsilink->reg_vana);
	dsilink->reg_epod_dss = NULL;
	iounmap(dsilink->io);
failed_map_dsi_io:
failed_get_resource:
failed_to_get_correct_id:
	kfree(dsilink);
	return ret;
}