Re: [PATCH v7 12/16] intel-ipu3: css: Initialize css hardware

2018-11-09 Thread Sakari Ailus
Hi Yong,

On Mon, Oct 29, 2018 at 03:23:06PM -0700, Yong Zhi wrote:
> This patch implements the functions to initialize
> and configure IPU3 h/w such as clock, irq and power.
> 
> Signed-off-by: Yong Zhi 
> Signed-off-by: Tomasz Figa 
> ---
>  drivers/media/pci/intel/ipu3/ipu3-css.c | 537 
> 
>  drivers/media/pci/intel/ipu3/ipu3-css.h | 203 
>  2 files changed, 740 insertions(+)
>  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css.c
>  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css.h
> 

...

> diff --git a/drivers/media/pci/intel/ipu3/ipu3-css.h 
> b/drivers/media/pci/intel/ipu3/ipu3-css.h
> new file mode 100644
> index 000..d16d0c4
> --- /dev/null
> +++ b/drivers/media/pci/intel/ipu3/ipu3-css.h

...

> +/* IPU3 Camera Sub System structure */
> +struct ipu3_css {
> + struct device *dev;
> + void __iomem *base;
> + const struct firmware *fw;
> + struct imgu_fw_header *fwp;
> + int iomem_length;

u32? The same for the length parameter in ccs_init().

-- 
Regards,

Sakari Ailus
sakari.ai...@linux.intel.com


[PATCH v7 12/16] intel-ipu3: css: Initialize css hardware

2018-10-29 Thread Yong Zhi
This patch implements the functions to initialize
and configure IPU3 h/w such as clock, irq and power.

Signed-off-by: Yong Zhi 
Signed-off-by: Tomasz Figa 
---
 drivers/media/pci/intel/ipu3/ipu3-css.c | 537 
 drivers/media/pci/intel/ipu3/ipu3-css.h | 203 
 2 files changed, 740 insertions(+)
 create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css.c
 create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css.h

diff --git a/drivers/media/pci/intel/ipu3/ipu3-css.c 
b/drivers/media/pci/intel/ipu3/ipu3-css.c
new file mode 100644
index 000..164830f
--- /dev/null
+++ b/drivers/media/pci/intel/ipu3/ipu3-css.c
@@ -0,0 +1,537 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2018 Intel Corporation
+
+#include 
+#include 
+
+#include "ipu3-css.h"
+#include "ipu3-css-fw.h"
+#include "ipu3-css-params.h"
+#include "ipu3-dmamap.h"
+#include "ipu3-tables.h"
+
+/* IRQ configuration */
+#define IMGU_IRQCTRL_IRQ_MASK  (IMGU_IRQCTRL_IRQ_SP1 | \
+IMGU_IRQCTRL_IRQ_SP2 | \
+IMGU_IRQCTRL_IRQ_SW_PIN(0) | \
+IMGU_IRQCTRL_IRQ_SW_PIN(1))
+
+/*** css hw ***/
+
+/* In the style of writesl() defined in include/asm-generic/io.h */
+static inline void writes(const void *mem, ssize_t count, void __iomem *addr)
+{
+   if (count >= 4) {
+   const u32 *buf = mem;
+
+   count /= 4;
+   do {
+   writel(*buf++, addr);
+   addr += 4;
+   } while (--count);
+   }
+}
+
+/* Wait until register `reg', masked with `mask', becomes `cmp' */
+static int ipu3_hw_wait(void __iomem *base, int reg, u32 mask, u32 cmp)
+{
+   u32 val;
+
+   return readl_poll_timeout(base + reg, val, (val & mask) == cmp,
+ 1000, 100 * 1000);
+}
+
+/* Initialize the IPU3 CSS hardware and associated h/w blocks */
+
+int ipu3_css_set_powerup(struct device *dev, void __iomem *base)
+{
+   static const unsigned int freq = 450;
+   u32 pm_ctrl, state, val;
+
+   dev_dbg(dev, "%s\n", __func__);
+   /* Clear the CSS busy signal */
+   readl(base + IMGU_REG_GP_BUSY);
+   writel(0, base + IMGU_REG_GP_BUSY);
+
+   /* Wait for idle signal */
+   if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_IDLE_STS,
+IMGU_STATE_IDLE_STS)) {
+   dev_err(dev, "failed to set CSS idle\n");
+   goto fail;
+   }
+
+   /* Reset the css */
+   writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_RESET,
+  base + IMGU_REG_PM_CTRL);
+
+   usleep_range(200, 300);
+
+   /** Prepare CSS */
+
+   pm_ctrl = readl(base + IMGU_REG_PM_CTRL);
+   state = readl(base + IMGU_REG_STATE);
+
+   dev_dbg(dev, "CSS pm_ctrl 0x%x state 0x%x (power %s)\n",
+   pm_ctrl, state, state & IMGU_STATE_POWER_DOWN ? "down" : "up");
+
+   /* Power up CSS using wrapper */
+   if (state & IMGU_STATE_POWER_DOWN) {
+   writel(IMGU_PM_CTRL_RACE_TO_HALT | IMGU_PM_CTRL_START,
+  base + IMGU_REG_PM_CTRL);
+   if (ipu3_hw_wait(base, IMGU_REG_PM_CTRL,
+IMGU_PM_CTRL_START, 0)) {
+   dev_err(dev, "failed to power up CSS\n");
+   goto fail;
+   }
+   usleep_range(2000, 3000);
+   } else {
+   writel(IMGU_PM_CTRL_RACE_TO_HALT, base + IMGU_REG_PM_CTRL);
+   }
+
+   /* Set the busy bit */
+   writel(readl(base + IMGU_REG_GP_BUSY) | 1, base + IMGU_REG_GP_BUSY);
+
+   /* Set CSS clock frequency */
+   pm_ctrl = readl(base + IMGU_REG_PM_CTRL);
+   val = pm_ctrl & ~(IMGU_PM_CTRL_CSS_PWRDN | IMGU_PM_CTRL_RST_AT_EOF);
+   writel(val, base + IMGU_REG_PM_CTRL);
+   writel(0, base + IMGU_REG_GP_BUSY);
+   if (ipu3_hw_wait(base, IMGU_REG_STATE,
+IMGU_STATE_PWRDNM_FSM_MASK, 0)) {
+   dev_err(dev, "failed to pwrdn CSS\n");
+   goto fail;
+   }
+   val = (freq / IMGU_SYSTEM_REQ_FREQ_DIVIDER) & IMGU_SYSTEM_REQ_FREQ_MASK;
+   writel(val, base + IMGU_REG_SYSTEM_REQ);
+   writel(1, base + IMGU_REG_GP_BUSY);
+   writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_FORCE_HALT,
+  base + IMGU_REG_PM_CTRL);
+   if (ipu3_hw_wait(base, IMGU_REG_STATE, IMGU_STATE_HALT_STS,
+IMGU_STATE_HALT_STS)) {
+   dev_err(dev, "failed to halt CSS\n");
+   goto fail;
+   }
+
+   writel(readl(base + IMGU_REG_PM_CTRL) | IMGU_PM_CTRL_START,
+  base + IMGU_REG_PM_CTRL);
+   if (ipu3_hw_wait(base, IMGU_REG_PM_CTRL, IMGU_PM_CTRL_START, 0)) {
+   dev_err(dev, "failed to start CSS\n");
+   goto fail;
+   }
+   writel(readl(base + IMGU_REG_PM_CTRL) |