OMAPDSS: DSI: split DSI memory map to smaller blocks

DSI contains three separate blocks: protocol engine, PHY and PLL. At the
moment, all these are memory mapped in one big chunk. We need to split
that memory map into smaller pieces so that we can add proper 'reg'
properties into the DT data for each block.

This patch changes the driver to map the blocks separately. It first
tries to get the memory resource using name, used when booting with DT,
and if that fails, it gets the memory resource by ID, in which case the
driver gets the big chunk from platform data. That big chunk is then
split into the smaller blocks manually.

After DSS DT code has been merged and the old platform code removed, we
can clean up the memory resource management.

Instead of changing the driver in all the places where a register is
read or written, this patch takes a shortcut: it adds an additional
number to the struct which represents the register index. This number is
used to decide which base address to use. In the future we should
consider other approaches.

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 1cd3e47..f6f8d93 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -47,63 +47,73 @@
 
 #define DSI_CATCH_MISSING_TE
 
-struct dsi_reg { u16 idx; };
+struct dsi_reg { u16 module; u16 idx; };
 
-#define DSI_REG(idx)		((const struct dsi_reg) { idx })
+#define DSI_REG(mod, idx)		((const struct dsi_reg) { mod, idx })
 
-#define DSI_SZ_REGS		SZ_1K
 /* DSI Protocol Engine */
 
-#define DSI_REVISION			DSI_REG(0x0000)
-#define DSI_SYSCONFIG			DSI_REG(0x0010)
-#define DSI_SYSSTATUS			DSI_REG(0x0014)
-#define DSI_IRQSTATUS			DSI_REG(0x0018)
-#define DSI_IRQENABLE			DSI_REG(0x001C)
-#define DSI_CTRL			DSI_REG(0x0040)
-#define DSI_GNQ				DSI_REG(0x0044)
-#define DSI_COMPLEXIO_CFG1		DSI_REG(0x0048)
-#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(0x004C)
-#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(0x0050)
-#define DSI_CLK_CTRL			DSI_REG(0x0054)
-#define DSI_TIMING1			DSI_REG(0x0058)
-#define DSI_TIMING2			DSI_REG(0x005C)
-#define DSI_VM_TIMING1			DSI_REG(0x0060)
-#define DSI_VM_TIMING2			DSI_REG(0x0064)
-#define DSI_VM_TIMING3			DSI_REG(0x0068)
-#define DSI_CLK_TIMING			DSI_REG(0x006C)
-#define DSI_TX_FIFO_VC_SIZE		DSI_REG(0x0070)
-#define DSI_RX_FIFO_VC_SIZE		DSI_REG(0x0074)
-#define DSI_COMPLEXIO_CFG2		DSI_REG(0x0078)
-#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(0x007C)
-#define DSI_VM_TIMING4			DSI_REG(0x0080)
-#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(0x0084)
-#define DSI_VM_TIMING5			DSI_REG(0x0088)
-#define DSI_VM_TIMING6			DSI_REG(0x008C)
-#define DSI_VM_TIMING7			DSI_REG(0x0090)
-#define DSI_STOPCLK_TIMING		DSI_REG(0x0094)
-#define DSI_VC_CTRL(n)			DSI_REG(0x0100 + (n * 0x20))
-#define DSI_VC_TE(n)			DSI_REG(0x0104 + (n * 0x20))
-#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(0x0108 + (n * 0x20))
-#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(0x010C + (n * 0x20))
-#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(0x0110 + (n * 0x20))
-#define DSI_VC_IRQSTATUS(n)		DSI_REG(0x0118 + (n * 0x20))
-#define DSI_VC_IRQENABLE(n)		DSI_REG(0x011C + (n * 0x20))
+#define DSI_PROTO			0
+#define DSI_PROTO_SZ			0x200
+
+#define DSI_REVISION			DSI_REG(DSI_PROTO, 0x0000)
+#define DSI_SYSCONFIG			DSI_REG(DSI_PROTO, 0x0010)
+#define DSI_SYSSTATUS			DSI_REG(DSI_PROTO, 0x0014)
+#define DSI_IRQSTATUS			DSI_REG(DSI_PROTO, 0x0018)
+#define DSI_IRQENABLE			DSI_REG(DSI_PROTO, 0x001C)
+#define DSI_CTRL			DSI_REG(DSI_PROTO, 0x0040)
+#define DSI_GNQ				DSI_REG(DSI_PROTO, 0x0044)
+#define DSI_COMPLEXIO_CFG1		DSI_REG(DSI_PROTO, 0x0048)
+#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(DSI_PROTO, 0x004C)
+#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(DSI_PROTO, 0x0050)
+#define DSI_CLK_CTRL			DSI_REG(DSI_PROTO, 0x0054)
+#define DSI_TIMING1			DSI_REG(DSI_PROTO, 0x0058)
+#define DSI_TIMING2			DSI_REG(DSI_PROTO, 0x005C)
+#define DSI_VM_TIMING1			DSI_REG(DSI_PROTO, 0x0060)
+#define DSI_VM_TIMING2			DSI_REG(DSI_PROTO, 0x0064)
+#define DSI_VM_TIMING3			DSI_REG(DSI_PROTO, 0x0068)
+#define DSI_CLK_TIMING			DSI_REG(DSI_PROTO, 0x006C)
+#define DSI_TX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0070)
+#define DSI_RX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0074)
+#define DSI_COMPLEXIO_CFG2		DSI_REG(DSI_PROTO, 0x0078)
+#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(DSI_PROTO, 0x007C)
+#define DSI_VM_TIMING4			DSI_REG(DSI_PROTO, 0x0080)
+#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(DSI_PROTO, 0x0084)
+#define DSI_VM_TIMING5			DSI_REG(DSI_PROTO, 0x0088)
+#define DSI_VM_TIMING6			DSI_REG(DSI_PROTO, 0x008C)
+#define DSI_VM_TIMING7			DSI_REG(DSI_PROTO, 0x0090)
+#define DSI_STOPCLK_TIMING		DSI_REG(DSI_PROTO, 0x0094)
+#define DSI_VC_CTRL(n)			DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20))
+#define DSI_VC_TE(n)			DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20))
+#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20))
+#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(DSI_PROTO, 0x010C + (n * 0x20))
+#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20))
+#define DSI_VC_IRQSTATUS(n)		DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20))
+#define DSI_VC_IRQENABLE(n)		DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))
 
 /* DSIPHY_SCP */
 
-#define DSI_DSIPHY_CFG0			DSI_REG(0x200 + 0x0000)
-#define DSI_DSIPHY_CFG1			DSI_REG(0x200 + 0x0004)
-#define DSI_DSIPHY_CFG2			DSI_REG(0x200 + 0x0008)
-#define DSI_DSIPHY_CFG5			DSI_REG(0x200 + 0x0014)
-#define DSI_DSIPHY_CFG10		DSI_REG(0x200 + 0x0028)
+#define DSI_PHY				1
+#define DSI_PHY_OFFSET			0x200
+#define DSI_PHY_SZ			0x40
+
+#define DSI_DSIPHY_CFG0			DSI_REG(DSI_PHY, 0x0000)
+#define DSI_DSIPHY_CFG1			DSI_REG(DSI_PHY, 0x0004)
+#define DSI_DSIPHY_CFG2			DSI_REG(DSI_PHY, 0x0008)
+#define DSI_DSIPHY_CFG5			DSI_REG(DSI_PHY, 0x0014)
+#define DSI_DSIPHY_CFG10		DSI_REG(DSI_PHY, 0x0028)
 
 /* DSI_PLL_CTRL_SCP */
 
-#define DSI_PLL_CONTROL			DSI_REG(0x300 + 0x0000)
-#define DSI_PLL_STATUS			DSI_REG(0x300 + 0x0004)
-#define DSI_PLL_GO			DSI_REG(0x300 + 0x0008)
-#define DSI_PLL_CONFIGURATION1		DSI_REG(0x300 + 0x000C)
-#define DSI_PLL_CONFIGURATION2		DSI_REG(0x300 + 0x0010)
+#define DSI_PLL				2
+#define DSI_PLL_OFFSET			0x300
+#define DSI_PLL_SZ			0x20
+
+#define DSI_PLL_CONTROL			DSI_REG(DSI_PLL, 0x0000)
+#define DSI_PLL_STATUS			DSI_REG(DSI_PLL, 0x0004)
+#define DSI_PLL_GO			DSI_REG(DSI_PLL, 0x0008)
+#define DSI_PLL_CONFIGURATION1		DSI_REG(DSI_PLL, 0x000C)
+#define DSI_PLL_CONFIGURATION2		DSI_REG(DSI_PLL, 0x0010)
 
 #define REG_GET(dsidev, idx, start, end) \
 	FLD_GET(dsi_read_reg(dsidev, idx), start, end)
@@ -277,7 +287,9 @@
 
 struct dsi_data {
 	struct platform_device *pdev;
-	void __iomem	*base;
+	void __iomem *proto_base;
+	void __iomem *phy_base;
+	void __iomem *pll_base;
 
 	int module_id;
 
@@ -414,16 +426,32 @@
 		const struct dsi_reg idx, u32 val)
 {
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	void __iomem *base;
 
-	__raw_writel(val, dsi->base + idx.idx);
+	switch(idx.module) {
+		case DSI_PROTO: base = dsi->proto_base; break;
+		case DSI_PHY: base = dsi->phy_base; break;
+		case DSI_PLL: base = dsi->pll_base; break;
+		default: return;
+	}
+
+	__raw_writel(val, base + idx.idx);
 }
 
 static inline u32 dsi_read_reg(struct platform_device *dsidev,
 		const struct dsi_reg idx)
 {
 	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+	void __iomem *base;
 
-	return __raw_readl(dsi->base + idx.idx);
+	switch(idx.module) {
+		case DSI_PROTO: base = dsi->proto_base; break;
+		case DSI_PHY: base = dsi->phy_base; break;
+		case DSI_PLL: base = dsi->pll_base; break;
+		default: return 0;
+	}
+
+	return __raw_readl(base + idx.idx);
 }
 
 static void dsi_bus_lock(struct omap_dss_device *dssdev)
@@ -5346,8 +5374,9 @@
 {
 	u32 rev;
 	int r, i;
-	struct resource *dsi_mem;
 	struct dsi_data *dsi;
+	struct resource *res;
+	struct resource temp_res;
 
 	dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);
 	if (!dsi)
@@ -5377,16 +5406,64 @@
 	dsi->te_timer.function = dsi_te_timeout;
 	dsi->te_timer.data = 0;
 #endif
-	dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0);
-	if (!dsi_mem) {
-		DSSERR("can't get IORESOURCE_MEM DSI\n");
-		return -EINVAL;
+
+	res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto");
+	if (!res) {
+		res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
+		if (!res) {
+			DSSERR("can't get IORESOURCE_MEM DSI\n");
+			return -EINVAL;
+		}
+
+		temp_res.start = res->start;
+		temp_res.end = temp_res.start + DSI_PROTO_SZ - 1;
+		res = &temp_res;
 	}
 
-	dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start,
-				 resource_size(dsi_mem));
-	if (!dsi->base) {
-		DSSERR("can't ioremap DSI\n");
+	dsi->proto_base = devm_ioremap(&dsidev->dev, res->start,
+		resource_size(res));
+	if (!dsi->proto_base) {
+		DSSERR("can't ioremap DSI protocol engine\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "phy");
+	if (!res) {
+		res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
+		if (!res) {
+			DSSERR("can't get IORESOURCE_MEM DSI\n");
+			return -EINVAL;
+		}
+
+		temp_res.start = res->start + DSI_PHY_OFFSET;
+		temp_res.end = temp_res.start + DSI_PHY_SZ - 1;
+		res = &temp_res;
+	}
+
+	dsi->phy_base = devm_ioremap(&dsidev->dev, res->start,
+		resource_size(res));
+	if (!dsi->proto_base) {
+		DSSERR("can't ioremap DSI PHY\n");
+		return -ENOMEM;
+	}
+
+	res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "pll");
+	if (!res) {
+		res = platform_get_resource(dsidev, IORESOURCE_MEM, 0);
+		if (!res) {
+			DSSERR("can't get IORESOURCE_MEM DSI\n");
+			return -EINVAL;
+		}
+
+		temp_res.start = res->start + DSI_PLL_OFFSET;
+		temp_res.end = temp_res.start + DSI_PLL_SZ - 1;
+		res = &temp_res;
+	}
+
+	dsi->pll_base = devm_ioremap(&dsidev->dev, res->start,
+		resource_size(res));
+	if (!dsi->proto_base) {
+		DSSERR("can't ioremap DSI PLL\n");
 		return -ENOMEM;
 	}