From 68104467ec19a56db2799049e53e910089c66c75 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 17 Dec 2013 13:53:28 +0200 Subject: 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 --- drivers/video/omap2/dss/dsi.c | 195 +++++++++++++++++++++++++++++------------- 1 file changed, 136 insertions(+), 59 deletions(-) (limited to 'drivers/video/omap2') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 1cd3e47fd43f..f6f8d93c4be9 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_clk_calc_ctx { 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 @@ static inline void dsi_write_reg(struct platform_device *dsidev, const struct dsi_reg idx, u32 val) { struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + void __iomem *base; + + 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, dsi->base + idx.idx); + __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 @@ static int omap_dsihw_probe(struct platform_device *dsidev) { 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 @@ static int omap_dsihw_probe(struct platform_device *dsidev) 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->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->base = devm_ioremap(&dsidev->dev, dsi_mem->start, - resource_size(dsi_mem)); - if (!dsi->base) { - DSSERR("can't ioremap DSI\n"); + 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; } -- cgit v1.2.3