diff --git a/bcwc_drv.c b/bcwc_drv.c index b2843b2..b1ca623 100644 --- a/bcwc_drv.c +++ b/bcwc_drv.c @@ -25,30 +25,37 @@ static int bcwc_pci_reserve_mem(struct bcwc_private *dev_priv) int ret; /* Reserve resources */ - ret = pci_request_region(dev_priv->pdev, BCWC_PCI_LINK_IO, "Link IO"); + ret = pci_request_region(dev_priv->pdev, BCWC_PCI_S2_IO, "S2 IO"); if (ret) { - dev_err(&dev_priv->pdev->dev, "Failed to request Link IO\n"); + dev_err(&dev_priv->pdev->dev, "Failed to request S2 IO\n"); return ret; } - ret = pci_request_region(dev_priv->pdev, BCWC_PCI_DEV_IO, "Device IO"); + ret = pci_request_region(dev_priv->pdev, BCWC_PCI_ISP_IO, "ISP IO"); if (ret) { - dev_err(&dev_priv->pdev->dev, "Failed to request Device IO\n"); + dev_err(&dev_priv->pdev->dev, "Failed to request ISP IO\n"); return ret; } - /* Link IO */ - start = pci_resource_start(dev_priv->pdev, BCWC_PCI_LINK_IO); - len = pci_resource_len(dev_priv->pdev, BCWC_PCI_LINK_IO); - dev_priv->link_io = ioremap_nocache(start, len); - dev_priv->link_io_len = len; + /* S2 IO */ + start = pci_resource_start(dev_priv->pdev, BCWC_PCI_S2_IO); + len = pci_resource_len(dev_priv->pdev, BCWC_PCI_S2_IO); + dev_priv->s2_io = ioremap_nocache(start, len); + dev_priv->s2_io_len = len; - /* Device IO */ - start = pci_resource_start(dev_priv->pdev, BCWC_PCI_DEV_IO); - len = pci_resource_len(dev_priv->pdev, BCWC_PCI_DEV_IO); - dev_priv->dev_io = ioremap_nocache(start, len); - dev_priv->dev_io_len = len; + /* ISP IO */ + start = pci_resource_start(dev_priv->pdev, BCWC_PCI_ISP_IO); + len = pci_resource_len(dev_priv->pdev, BCWC_PCI_ISP_IO); + dev_priv->isp_io = ioremap_nocache(start, len); + dev_priv->isp_io_len = len; + dev_info(&dev_priv->pdev->dev, + "Allocated S2 regs (BAR %d). %u bytes at 0x%p", + BCWC_PCI_S2_IO, dev_priv->s2_io_len, dev_priv->s2_io); + + dev_info(&dev_priv->pdev->dev, + "Allocated ISP regs (BAR %d). %u bytes at 0x%p", + BCWC_PCI_ISP_IO, dev_priv->isp_io_len, dev_priv->isp_io); return 0; } @@ -174,13 +181,13 @@ static void bcwc_pci_remove(struct pci_dev *pdev) bcwc_irq_disable(dev_priv); pci_disable_msi(pdev); - if (dev_priv->link_io) - iounmap(dev_priv->link_io); - if (dev_priv->dev_io) - iounmap(dev_priv->dev_io); + if (dev_priv->s2_io) + iounmap(dev_priv->s2_io); + if (dev_priv->isp_io) + iounmap(dev_priv->isp_io); - pci_release_region(pdev, BCWC_PCI_DEV_IO); - pci_release_region(pdev, BCWC_PCI_LINK_IO); + pci_release_region(pdev, BCWC_PCI_S2_IO); + pci_release_region(pdev, BCWC_PCI_ISP_IO); } pci_disable_device(pdev); diff --git a/bcwc_drv.h b/bcwc_drv.h index 42091fd..22af202 100644 --- a/bcwc_drv.h +++ b/bcwc_drv.h @@ -15,9 +15,9 @@ #include #include "bcwc_reg.h" -#define BCWC_PCI_DEV_IO 0 -#define BCWC_PCI_DEV_MEM 2 -#define BCWC_PCI_LINK_IO 4 +#define BCWC_PCI_S2_IO 0 +#define BCWC_PCI_S2_MEM 2 +#define BCWC_PCI_ISP_IO 4 struct bcwc_reg { u32 offset; @@ -29,10 +29,10 @@ struct bcwc_private { unsigned int dma_mask; /* Mapped PCI resources */ - void *link_io; - u32 link_io_len; - void *dev_io; - u32 dev_io_len; + void *s2_io; + u32 s2_io_len; + void *isp_io; + u32 isp_io_len; struct work_struct irq_work; diff --git a/bcwc_hw.c b/bcwc_hw.c index f3e72fe..08156f9 100644 --- a/bcwc_hw.c +++ b/bcwc_hw.c @@ -26,7 +26,7 @@ static int bcwc_hw_set_core_clk(struct bcwc_private *dev_priv) static int bcwc_hw_s2_pll_reset(struct bcwc_private *dev_priv) { - BCWC_DEV_REG_WRITE(0x40, DDR_PHY_2C); + BCWC_ISP_REG_WRITE(0x40, DDR_PHY_2C); bcwc_hw_pci_post(dev_priv); return 0; @@ -36,19 +36,19 @@ static int bcwc_hw_s2_init_pcie_link(struct bcwc_private *dev_priv) { u32 reg; - BCWC_DEV_REG_WRITE(S2_PCIE_LINK_D000, 0x10); + BCWC_ISP_REG_WRITE(0x10, S2_PCIE_LINK_D000); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(S2_PCIE_LINK_D120, 0x1804); + BCWC_ISP_REG_WRITE(0x1804, S2_PCIE_LINK_D120); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(S2_PCIE_LINK_D124, 0xac5800); + BCWC_ISP_REG_WRITE(0xac5800, S2_PCIE_LINK_D124); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(S2_PCIE_LINK_D120, 0x1804); + BCWC_ISP_REG_WRITE(0x1804, S2_PCIE_LINK_D120); bcwc_hw_pci_post(dev_priv); - reg = BCWC_DEV_REG_READ(S2_PCIE_LINK_D124); + reg = BCWC_ISP_REG_READ(S2_PCIE_LINK_D124); if (reg == 0xac5800) { } @@ -61,7 +61,7 @@ static int bcwc_hw_s2_pll_init(struct bcwc_private *dev_priv, u32 ddr_speed) u32 reg; int retries = 0; - ref_clk_25 = (BCWC_DEV_REG_READ(S2_PLL_STATUS_04) && 0x8); + ref_clk_25 = (BCWC_ISP_REG_READ(S2_PLL_STATUS_04) && 0x8); if (ref_clk_25) dev_info(&dev_priv->pdev->dev, "Refclk: 25MHz\n"); @@ -71,38 +71,38 @@ static int bcwc_hw_s2_pll_init(struct bcwc_private *dev_priv, u32 ddr_speed) if (ddr_speed == 400) { if (ref_clk_25) { /* Ref clk 25 */ - BCWC_DEV_REG_WRITE(0x00400078, S2_PLL_CTRL_510); + BCWC_ISP_REG_WRITE(0x00400078, S2_PLL_CTRL_510); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x19280804, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x19280804, S2_PLL_CTRL_24); } else { /* Ref clk 24 */ - BCWC_DEV_REG_WRITE(0x03200000, S2_PLL_CTRL_20); + BCWC_ISP_REG_WRITE(0x03200000, S2_PLL_CTRL_20); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x14280603, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x14280603, S2_PLL_CTRL_24); } } else if (ddr_speed == 300) { if (ref_clk_25) { /* Ref clk 25 */ - BCWC_DEV_REG_WRITE(0x03200000, S2_PLL_CTRL_20); + BCWC_ISP_REG_WRITE(0x03200000, S2_PLL_CTRL_20); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x14280804, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x14280804, S2_PLL_CTRL_24); } else { /* Ref clk 24 */ - BCWC_DEV_REG_WRITE(0x00480078, S2_PLL_CTRL_510); + BCWC_ISP_REG_WRITE(0x00480078, S2_PLL_CTRL_510); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x19280c06, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x19280c06, S2_PLL_CTRL_24); } } else if (ddr_speed == 200) { if (ref_clk_25) { /* Ref clk 25 */ - BCWC_DEV_REG_WRITE(0x03200000, S2_PLL_CTRL_20); + BCWC_ISP_REG_WRITE(0x03200000, S2_PLL_CTRL_20); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x14280c06, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x14280c06, S2_PLL_CTRL_24); } else { /* Ref clk 24 */ - BCWC_DEV_REG_WRITE(0x00400078, S2_PLL_CTRL_510); + BCWC_ISP_REG_WRITE(0x00400078, S2_PLL_CTRL_510); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x19281008, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x19281008, S2_PLL_CTRL_24); } } else { if (ddr_speed != 450) { @@ -114,14 +114,14 @@ static int bcwc_hw_s2_pll_init(struct bcwc_private *dev_priv, u32 ddr_speed) if (ref_clk_25) { /* Ref clk 25 */ - BCWC_DEV_REG_WRITE(0x04b00000, S2_PLL_CTRL_20); + BCWC_ISP_REG_WRITE(0x04b00000, S2_PLL_CTRL_20); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x14280904, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x14280904, S2_PLL_CTRL_24); } else { /* Ref clk 24 */ - BCWC_DEV_REG_WRITE(0x0048007d, S2_PLL_CTRL_510); + BCWC_ISP_REG_WRITE(0x0048007d, S2_PLL_CTRL_510); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(0x19280904, S2_PLL_CTRL_24); + BCWC_ISP_REG_WRITE(0x19280904, S2_PLL_CTRL_24); } } @@ -131,7 +131,7 @@ static int bcwc_hw_s2_pll_init(struct bcwc_private *dev_priv, u32 ddr_speed) dev_info(&dev_priv->pdev->dev, "Waiting for PLL to lock\n"); do { - reg = BCWC_DEV_REG_READ(S2_PLL_STATUS_0C) & 0x80; + reg = BCWC_ISP_REG_READ(S2_PLL_STATUS_0C) & 0x80; udelay(10); retries++; } while (!reg && retries <= 10000); @@ -143,12 +143,12 @@ static int bcwc_hw_s2_pll_init(struct bcwc_private *dev_priv, u32 ddr_speed) dev_info(&dev_priv->pdev->dev, "PLL is locked\n"); } - reg = BCWC_DEV_REG_READ(S2_PLL_STATUS_A8); - BCWC_DEV_REG_WRITE(reg | 0x1, S2_PLL_STATUS_A8); + reg = BCWC_ISP_REG_READ(S2_PLL_STATUS_A8); + BCWC_ISP_REG_WRITE(reg | 0x1, S2_PLL_STATUS_A8); bcwc_hw_pci_post(dev_priv); udelay(10000); - reg = BCWC_DEV_REG_READ(S2_PLL_STATUS_A8); + reg = BCWC_ISP_REG_READ(S2_PLL_STATUS_A8); if (reg & 0x1) { dev_info(&dev_priv->pdev->dev, "PLL is in bypass mode\n"); } else { @@ -177,13 +177,13 @@ static int bcwc_hw_s2_init_ddr_controller_soc(struct bcwc_private *dev_priv) return -EIO; } - reg = BCWC_DEV_REG_READ(DDR_PHY_9C); + reg = BCWC_ISP_REG_READ(DDR_PHY_9C); reg &= 0xfffffcff; - BCWC_DEV_REG_WRITE(reg, DDR_PHY_9C); + BCWC_ISP_REG_WRITE(reg, DDR_PHY_9C); bcwc_hw_pci_post(dev_priv); - BCWC_DEV_REG_WRITE(reg | 0x300, DDR_PHY_9C); + BCWC_ISP_REG_WRITE(reg | 0x300, DDR_PHY_9C); bcwc_hw_pci_post(dev_priv); /* @@ -207,44 +207,44 @@ static int bcwc_hw_save_ddr_phy_regs(struct bcwc_private *dev_priv) for (i = 0; i < dev_priv->ddr_phy_num_regs; i++) { offset = dev_priv->ddr_reg_map[i].offset; - reg = BCWC_DEV_REG_READ(offset + DDR_PHY_REG_BASE); + reg = BCWC_ISP_REG_READ(offset + DDR_PHY_REG_BASE); dev_priv->ddr_reg_map[i].value = reg; } return 0; } -static int bcwc_hw_irq_init(struct bcwc_private *dev_priv) +static int bcwc_hw_isp_init(struct bcwc_private *dev_priv) { u32 num_channels, queue_size; u32 reg; int i, retries; - BCWC_LINK_REG_WRITE(IRQ_IPC_NUM_CHAN, 0); + BCWC_ISP_REG_WRITE(0, IRQ_IPC_NUM_CHAN); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_IPC_QUEUE_SIZE, 0); + BCWC_ISP_REG_WRITE(0, IRQ_IPC_QUEUE_SIZE); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_08, 0); + BCWC_ISP_REG_WRITE(0, IRQ_REG_08); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_0C, 0); + BCWC_ISP_REG_WRITE(0, IRQ_FW_HEAP_SIZE); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_10, 0); + BCWC_ISP_REG_WRITE(0, IRQ_REG_10); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_14, 0); + BCWC_ISP_REG_WRITE(0, IRQ_REG_14); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_18, 0); + BCWC_ISP_REG_WRITE(0, IRQ_REG_18); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_1C, 0); + BCWC_ISP_REG_WRITE(0, IRQ_REG_1C); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_41024, 0xffffffff); + BCWC_ISP_REG_WRITE(0xffffffff, IRQ_REG_41024); bcwc_hw_pci_post(dev_priv); /* @@ -252,20 +252,20 @@ static int bcwc_hw_irq_init(struct bcwc_private *dev_priv) * FIXME: Check if we can do 64bit writes on PCIe */ for (i = IRQ_REG_RANGE_START; i <= IRQ_REG_RANGE_END; i += 8) { - BCWC_LINK_REG_WRITE(0xffffff, i); - BCWC_LINK_REG_WRITE(0x000000, i + 4); + BCWC_ISP_REG_WRITE(0xffffff, i); + BCWC_ISP_REG_WRITE(0x000000, i + 4); } bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_40008, 0x80000000); + BCWC_ISP_REG_WRITE( 0x80000000, IRQ_REG_40008); bcwc_hw_pci_post(dev_priv); - BCWC_LINK_REG_WRITE(IRQ_REG_40004, 0x1); + BCWC_ISP_REG_WRITE(0x1, IRQ_REG_40004); bcwc_hw_pci_post(dev_priv); for (retries = 0; retries < 1000; retries++) { - reg = BCWC_LINK_REG_READ(IRQ_REG_40004); + reg = BCWC_ISP_REG_READ(IRQ_REG_40004); if ((reg & 0xff) == 0xf0) break; udelay(10); @@ -276,10 +276,10 @@ static int bcwc_hw_irq_init(struct bcwc_private *dev_priv) return -EIO; } - BCWC_LINK_REG_WRITE(0xffffffff, IRQ_REG_41024); + BCWC_ISP_REG_WRITE(0xffffffff, IRQ_REG_41024); - num_channels = BCWC_LINK_REG_READ(IRQ_IPC_NUM_CHAN) + 1; - queue_size = BCWC_LINK_REG_READ(IRQ_IPC_QUEUE_SIZE); + num_channels = BCWC_ISP_REG_READ(IRQ_IPC_NUM_CHAN) + 1; + queue_size = BCWC_ISP_REG_READ(IRQ_IPC_QUEUE_SIZE); dev_info(&dev_priv->pdev->dev, "Number of IPC channels: %u, queue size: %u\n", @@ -292,8 +292,21 @@ static int bcwc_hw_irq_init(struct bcwc_private *dev_priv) } /* - allocate_device_memory(queue_size, &ret, 0); + bcwc_alloc_dev_mem(queue_size, &ret, 0); */ + + /* Firmware must fit in 4194304 bytes */ + reg = BCWC_ISP_REG_READ(IRQ_FW_HEAP_SIZE); + if (reg > 0x400000) { + dev_info(&dev_priv->pdev->dev, + "Firmware request size too big (%u bytes)\n", + reg); + return -ENOMEM; + } + + dev_info(&dev_priv->pdev->dev, "Firmware request size: %u\n", reg); + + return 0; } static int bcwc_hw_irq_enable(struct bcwc_private *dev_priv) @@ -348,5 +361,7 @@ static int bcwc_hw_power_off(struct bcwc_private *dev_priv) int bcwc_hw_init(struct bcwc_private *dev_priv) { + // bcwc_hw_isp_init(dev_priv); + return 0; } diff --git a/bcwc_hw.h b/bcwc_hw.h index 520403d..f0b66f7 100644 --- a/bcwc_hw.h +++ b/bcwc_hw.h @@ -14,12 +14,60 @@ #include -#define BCWC_LINK_REG_READ(offset) ioread32(dev_priv->link_io + (offset)) -#define BCWC_LINK_REG_WRITE(val, offset) iowrite32((val), \ - dev_priv->link_io + (offset)) -#define BCWC_DEV_REG_READ(offset) ioread32(dev_priv->dev_io + (offset)) -#define BCWC_DEV_REG_WRITE(val, offset) iowrite32((val), \ - dev_priv->dev_io + (offset)) +#define BCWC_S2_REG_READ(offset) _BCWC_S2_REG_READ(dev_priv, (offset)) +#define BCWC_S2_REG_WRITE(val, offset) _BCWC_S2_REG_WRITE(dev_priv, (val), (offset)) +#define BCWC_ISP_REG_READ(offset) _BCWC_ISP_REG_READ(dev_priv, (offset)) +#define BCWC_ISP_REG_WRITE(val, offset) _BCWC_ISP_REG_WRITE(dev_priv, (val), (offset)) + +static inline u32 _BCWC_S2_REG_READ(struct bcwc_private *dev_priv, u32 offset) +{ + if (offset >= dev_priv->s2_io_len) { + dev_err(&dev_priv->pdev->dev, + "S2 IO read out of range at %u\n", offset); + return 0; + } + + // dev_info(&dev_priv->pdev->dev, "Link IO read at %u\n", offset); + return ioread32(dev_priv->s2_io + offset); +} + +static inline void _BCWC_S2_REG_WRITE(struct bcwc_private *dev_priv, u32 val, + u32 offset) +{ + if (offset >= dev_priv->s2_io_len) { + dev_err(&dev_priv->pdev->dev, + "S2 IO write out of range at %u\n", offset); + return; + } + + // dev_info(&dev_priv->pdev->dev, "S2 IO write at %u\n", offset); + iowrite32(val, dev_priv->s2_io + offset); +} + +static inline u32 _BCWC_ISP_REG_READ(struct bcwc_private *dev_priv, u32 offset) +{ + if (offset >= dev_priv->isp_io_len) { + dev_err(&dev_priv->pdev->dev, + "ISP IO read out of range at %u\n", offset); + return 0; + } + + // dev_info(&dev_priv->pdev->dev, "ISP IO read at %u\n", offset); + return ioread32(dev_priv->isp_io + offset); +} + +static inline void _BCWC_ISP_REG_WRITE(struct bcwc_private *dev_priv, u32 val, + u32 offset) +{ + if (offset >= dev_priv->isp_io_len) { + dev_err(&dev_priv->pdev->dev, + "ISP IO write out of range at %u\n", offset); + return; + } + + // dev_info(&dev_priv->pdev->dev, "Dev IO write at %u\n", offset); + iowrite32(val, dev_priv->isp_io + offset); +} extern int bcwc_hw_init(struct bcwc_private *dev_priv); diff --git a/bcwc_reg.h b/bcwc_reg.h index 5a45309..3d6df48 100644 --- a/bcwc_reg.h +++ b/bcwc_reg.h @@ -41,7 +41,7 @@ #define IRQ_IPC_NUM_CHAN 0xc3000 #define IRQ_IPC_QUEUE_SIZE 0xc3004 #define IRQ_REG_08 0xc3008 -#define IRQ_REG_0C 0xc300c +#define IRQ_FW_HEAP_SIZE 0xc300c #define IRQ_REG_10 0xc3010 #define IRQ_REG_14 0xc3014 #define IRQ_REG_18 0xc3018