* Re: [PATCH v2] PCI: aardvark: Wait for endpoint to be ready before training link
From: Remi Pommarel @ 2019-08-06 18:49 UTC (permalink / raw)
To: Thomas Petazzoni, Lorenzo Pieralisi, Bjorn Helgaas
Cc: linux-pci, Ellie Reeves, linux-kernel, linux-arm-kernel
In-Reply-To: <20190522213351.21366-2-repk@triplefau.lt>
On Wed, May 22, 2019 at 11:33:50PM +0200, Remi Pommarel wrote:
> When configuring pcie reset pin from gpio (e.g. initially set by
> u-boot) to pcie function this pin goes low for a brief moment
> asserting the PERST# signal. Thus connected device enters fundamental
> reset process and link configuration can only begin after a minimal
> 100ms delay (see [1]).
>
> Because the pin configuration comes from the "default" pinctrl it is
> implicitly configured before the probe callback is called:
>
> driver_probe_device()
> really_probe()
> ...
> pinctrl_bind_pins() /* Here pin goes from gpio to PCIE reset
> function and PERST# is asserted */
> ...
> drv->probe()
>
> [1] "PCI Express Base Specification", REV. 4.0
> PCI Express, February 19 2014, 6.6.1 Conventional Reset
>
> Signed-off-by: Remi Pommarel <repk@triplefau.lt>
> ---
> Changes since v1:
> - Add a comment about pinctrl implicit pin configuration
> - Use more legible msleep
> - Use PCI_PM_D3COLD_WAIT macro
>
> Please note that I will unlikely be able to answer any comments from May
> 24th to June 10th.
> ---
> drivers/pci/controller/pci-aardvark.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
> index 134e0306ff00..d998c2b9cd04 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -324,6 +324,14 @@ static void advk_pcie_setup_hw(struct advk_pcie *pcie)
> reg |= PIO_CTRL_ADDR_WIN_DISABLE;
> advk_writel(pcie, reg, PIO_CTRL);
>
> + /*
> + * PERST# signal could have been asserted by pinctrl subsystem before
> + * probe() callback has been called, making the endpoint going into
> + * fundamental reset. As required by PCI Express spec a delay for at
> + * least 100ms after such a reset before link training is needed.
> + */
> + msleep(PCI_PM_D3COLD_WAIT);
> +
> /* Start link training */
> reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
> reg |= PCIE_CORE_LINK_TRAINING;
> --
> 2.20.1
Gentle ping.
--
Remi
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3] PCI: aardvark: Use LTSSM state to build link training flag
From: Remi Pommarel @ 2019-08-06 18:50 UTC (permalink / raw)
To: Thomas Petazzoni, Lorenzo Pieralisi, Bjorn Helgaas
Cc: linux-pci, Ellie Reeves, linux-kernel, linux-arm-kernel
In-Reply-To: <20190522213351.21366-3-repk@triplefau.lt>
On Wed, May 22, 2019 at 11:33:51PM +0200, Remi Pommarel wrote:
> Aardvark's PCI_EXP_LNKSTA_LT flag in its link status register is not
> implemented and does not reflect the actual link training state (the
> flag is always set to 0). In order to support link re-training feature
> this flag has to be emulated. The Link Training and Status State
> Machine (LTSSM) flag in Aardvark LMI config register could be used as
> a link training indicator. Indeed if the LTSSM is in L0 or upper state
> then link training has completed (see [1]).
>
> Unfortunately because after asking a link retraining it takes a while
> for the LTSSM state to become less than 0x10 (due to L0s to recovery
> state transition delays), LTSSM can still be in L0 while link training
> has not finished yet. So this waits for link to be in recovery or lesser
> state before returning after asking for a link retrain.
>
> [1] "PCI Express Base Specification", REV. 4.0
> PCI Express, February 19 2014, Table 4-14
>
> Signed-off-by: Remi Pommarel <repk@triplefau.lt>
> ---
> Changes since v1:
> - Rename retraining flag field
> - Fix DEVCTL register writing
>
> Changes since v2:
> - Rewrite patch logic so it is more legible
>
> Please note that I will unlikely be able to answer any comments from May
> 24th to June 10th.
> ---
> drivers/pci/controller/pci-aardvark.c | 29 ++++++++++++++++++++++++++-
> 1 file changed, 28 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
> index 134e0306ff00..8803083b2174 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -180,6 +180,8 @@
> #define LINK_WAIT_MAX_RETRIES 10
> #define LINK_WAIT_USLEEP_MIN 90000
> #define LINK_WAIT_USLEEP_MAX 100000
> +#define RETRAIN_WAIT_MAX_RETRIES 10
> +#define RETRAIN_WAIT_USLEEP_US 2000
>
> #define MSI_IRQ_NUM 32
>
> @@ -239,6 +241,17 @@ static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
> return -ETIMEDOUT;
> }
>
> +static void advk_pcie_wait_for_retrain(struct advk_pcie *pcie)
> +{
> + size_t retries;
> +
> + for (retries = 0; retries < RETRAIN_WAIT_MAX_RETRIES; ++retries) {
> + if (!advk_pcie_link_up(pcie))
> + break;
> + udelay(RETRAIN_WAIT_USLEEP_US);
> + }
> +}
> +
> static void advk_pcie_setup_hw(struct advk_pcie *pcie)
> {
> u32 reg;
> @@ -426,11 +439,20 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
> return PCI_BRIDGE_EMUL_HANDLED;
> }
>
> + case PCI_EXP_LNKCTL: {
> + /* u32 contains both PCI_EXP_LNKCTL and PCI_EXP_LNKSTA */
> + u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) &
> + ~(PCI_EXP_LNKSTA_LT << 16);
> + if (!advk_pcie_link_up(pcie))
> + val |= (PCI_EXP_LNKSTA_LT << 16);
> + *value = val;
> + return PCI_BRIDGE_EMUL_HANDLED;
> + }
> +
> case PCI_CAP_LIST_ID:
> case PCI_EXP_DEVCAP:
> case PCI_EXP_DEVCTL:
> case PCI_EXP_LNKCAP:
> - case PCI_EXP_LNKCTL:
> *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg);
> return PCI_BRIDGE_EMUL_HANDLED;
> default:
> @@ -447,8 +469,13 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
>
> switch (reg) {
> case PCI_EXP_DEVCTL:
> + advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
> + break;
> +
> case PCI_EXP_LNKCTL:
> advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
> + if (new & PCI_EXP_LNKCTL_RL)
> + advk_pcie_wait_for_retrain(pcie);
> break;
>
> case PCI_EXP_RTCTL:
> --
> 2.20.1
Gentle ping.
Please note that the SError problem discussed in V1 has been handled
and merged in arm-trusted-firmware's mainline.
--
Remi
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v8 05/14] media: rkisp1: add Rockchip ISP1 subdev driver
From: Helen Koike @ 2019-08-06 18:51 UTC (permalink / raw)
To: hans.verkuil
Cc: devicetree, eddie.cai.linux, kernel, heiko, jacob2.chen,
jeffy.chen, zyc, linux-kernel, tfiga, linux-rockchip, Allon Huang,
Jacob Chen, laurent.pinchart, sakari.ailus, zhengsq, mchehab,
ezequiel, linux-arm-kernel, linux-media
In-Reply-To: <20190730184256.30338-6-helen.koike@collabora.com>
Hi Hans,
On 7/30/19 3:42 PM, Helen Koike wrote:
> From: Jacob Chen <jacob2.chen@rock-chips.com>
>
> Add the subdev driver for rockchip isp1.
>
> Signed-off-by: Jacob Chen <jacob2.chen@rock-chips.com>
> Signed-off-by: Shunqian Zheng <zhengsq@rock-chips.com>
> Signed-off-by: Yichong Zhong <zyc@rock-chips.com>
> Signed-off-by: Jacob Chen <cc@rock-chips.com>
> Signed-off-by: Eddie Cai <eddie.cai.linux@gmail.com>
> Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
> Signed-off-by: Allon Huang <allon.huang@rock-chips.com>
> Signed-off-by: Tomasz Figa <tfiga@chromium.org>
> [fixed unknown entity type / switched to PIXEL_RATE]
> Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
> [update for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.com>
>
> ---
>
> Changes in v8: None
> Changes in v7:
> - fixed warning because of unknown entity type
> - fixed v4l2-compliance errors regarding rkisp1 formats, try formats
> and default values
> - fix typo riksp1/rkisp1
> - redesign: remove mipi/csi subdevice, sensors connect directly to the
> isp subdevice in the media topology now. As a consequence, remove the
> hack in mipidphy_g_mbus_config() where information from the sensor was
> being propagated through the topology.
> - From the old dphy:
> * cache get_remote_sensor() in s_stream
> * use V4L2_CID_PIXEL_RATE instead of V4L2_CID_LINK_FREQ
> - Replace stream state with a boolean
> - code styling and checkpatch fixes
> - fix stop_stream (return after calling stop, do not reenable the stream)
> - fix rkisp1_isp_sd_get_selection when V4L2_SUBDEV_FORMAT_TRY is set
> - fix get format in output (isp_sd->out_fmt.mbus_code was being ignored)
> - s/intput/input
> - remove #define sd_to_isp_sd(_sd), add a static inline as it will be
> reused by the capture
>
> drivers/media/platform/rockchip/isp1/rkisp1.c | 1286 +++++++++++++++++
> drivers/media/platform/rockchip/isp1/rkisp1.h | 111 ++
> 2 files changed, 1397 insertions(+)
> create mode 100644 drivers/media/platform/rockchip/isp1/rkisp1.c
> create mode 100644 drivers/media/platform/rockchip/isp1/rkisp1.h
>
> diff --git a/drivers/media/platform/rockchip/isp1/rkisp1.c b/drivers/media/platform/rockchip/isp1/rkisp1.c
> new file mode 100644
> index 000000000000..6d0c0ffb5e03
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/isp1/rkisp1.c
> @@ -0,0 +1,1286 @@
> +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> +/*
> + * Rockchip isp1 driver
> + *
> + * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
> + */
> +
> +#include <linux/iopoll.h>
> +#include <linux/phy/phy.h>
> +#include <linux/phy/phy-mipi-dphy.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/videodev2.h>
> +#include <linux/vmalloc.h>
> +#include <media/v4l2-event.h>
> +
> +#include "common.h"
> +#include "regs.h"
> +
> +#define CIF_ISP_INPUT_W_MAX 4032
> +#define CIF_ISP_INPUT_H_MAX 3024
> +#define CIF_ISP_INPUT_W_MIN 32
> +#define CIF_ISP_INPUT_H_MIN 32
> +#define CIF_ISP_OUTPUT_W_MAX CIF_ISP_INPUT_W_MAX
> +#define CIF_ISP_OUTPUT_H_MAX CIF_ISP_INPUT_H_MAX
> +#define CIF_ISP_OUTPUT_W_MIN CIF_ISP_INPUT_W_MIN
> +#define CIF_ISP_OUTPUT_H_MIN CIF_ISP_INPUT_H_MIN
> +
> +/*
> + * NOTE: MIPI controller and input MUX are also configured in this file,
> + * because ISP Subdev is not only describe ISP submodule(input size,format,
> + * output size, format), but also a virtual route device.
> + */
> +
> +/*
> + * There are many variables named with format/frame in below code,
> + * please see here for their meaning.
> + *
> + * Cropping regions of ISP
> + *
> + * +---------------------------------------------------------+
> + * | Sensor image |
> + * | +---------------------------------------------------+ |
> + * | | ISP_ACQ (for black level) | |
> + * | | in_frm | |
> + * | | +--------------------------------------------+ | |
> + * | | | ISP_OUT | | |
> + * | | | in_crop | | |
> + * | | | +---------------------------------+ | | |
> + * | | | | ISP_IS | | | |
> + * | | | | rkisp1_isp_subdev: out_crop | | | |
> + * | | | +---------------------------------+ | | |
> + * | | +--------------------------------------------+ | |
> + * | +---------------------------------------------------+ |
> + * +---------------------------------------------------------+
> + */
> +
> +static inline struct rkisp1_device *sd_to_isp_dev(struct v4l2_subdev *sd)
> +{
> + return container_of(sd->v4l2_dev, struct rkisp1_device, v4l2_dev);
> +}
> +
> +/* Get sensor by enabled media link */
> +static struct v4l2_subdev *get_remote_sensor(struct v4l2_subdev *sd)
> +{
> + struct media_pad *local, *remote;
> + struct media_entity *sensor_me;
> +
> + local = &sd->entity.pads[RKISP1_ISP_PAD_SINK];
> + remote = media_entity_remote_pad(local);
> + if (!remote) {
> + v4l2_warn(sd, "No link between isp and sensor\n");
> + return NULL;
> + }
> +
> + sensor_me = media_entity_remote_pad(local)->entity;
> + return media_entity_to_v4l2_subdev(sensor_me);
> +}
> +
> +static struct rkisp1_sensor *sd_to_sensor(struct rkisp1_device *dev,
> + struct v4l2_subdev *sd)
> +{
> + struct rkisp1_sensor *sensor;
> +
> + list_for_each_entry(sensor, &dev->sensors, list)
> + if (sensor->sd == sd)
> + return sensor;
> +
> + return NULL;
> +}
> +
> +/**************** register operations ****************/
> +
> +/*
> + * Image Stabilization.
> + * This should only be called when configuring CIF
> + * or at the frame end interrupt
> + */
> +static void rkisp1_config_ism(struct rkisp1_device *dev)
> +{
> + void __iomem *base = dev->base_addr;
> + struct v4l2_rect *out_crop = &dev->isp_sdev.out_crop;
> + u32 val;
> +
> + writel(0, base + CIF_ISP_IS_RECENTER);
> + writel(0, base + CIF_ISP_IS_MAX_DX);
> + writel(0, base + CIF_ISP_IS_MAX_DY);
> + writel(0, base + CIF_ISP_IS_DISPLACE);
> + writel(out_crop->left, base + CIF_ISP_IS_H_OFFS);
> + writel(out_crop->top, base + CIF_ISP_IS_V_OFFS);
> + writel(out_crop->width, base + CIF_ISP_IS_H_SIZE);
> + writel(out_crop->height, base + CIF_ISP_IS_V_SIZE);
> +
> + /* IS(Image Stabilization) is always on, working as output crop */
> + writel(1, base + CIF_ISP_IS_CTRL);
> + val = readl(base + CIF_ISP_CTRL);
> + val |= CIF_ISP_CTRL_ISP_CFG_UPD;
> + writel(val, base + CIF_ISP_CTRL);
> +}
> +
> +/*
> + * configure isp blocks with input format, size......
> + */
> +static int rkisp1_config_isp(struct rkisp1_device *dev)
> +{
> + u32 isp_ctrl = 0, irq_mask = 0, acq_mult = 0, signal = 0;
> + struct v4l2_rect *out_crop, *in_crop;
> + void __iomem *base = dev->base_addr;
> + struct v4l2_mbus_framefmt *in_frm;
> + struct ispsd_out_fmt *out_fmt;
> + struct rkisp1_sensor *sensor;
> + struct ispsd_in_fmt *in_fmt;
> +
> + sensor = dev->active_sensor;
> + in_frm = &dev->isp_sdev.in_frm;
> + in_fmt = &dev->isp_sdev.in_fmt;
> + out_fmt = &dev->isp_sdev.out_fmt;
> + out_crop = &dev->isp_sdev.out_crop;
> + in_crop = &dev->isp_sdev.in_crop;
> +
> + if (in_fmt->fmt_type == FMT_BAYER) {
> + acq_mult = 1;
> + if (out_fmt->fmt_type == FMT_BAYER) {
> + if (sensor->mbus.type == V4L2_MBUS_BT656)
> + isp_ctrl =
> + CIF_ISP_CTRL_ISP_MODE_RAW_PICT_ITU656;
> + else
> + isp_ctrl =
> + CIF_ISP_CTRL_ISP_MODE_RAW_PICT;
> + } else {
> + writel(CIF_ISP_DEMOSAIC_TH(0xc),
> + base + CIF_ISP_DEMOSAIC);
> +
> + if (sensor->mbus.type == V4L2_MBUS_BT656)
> + isp_ctrl = CIF_ISP_CTRL_ISP_MODE_BAYER_ITU656;
> + else
> + isp_ctrl = CIF_ISP_CTRL_ISP_MODE_BAYER_ITU601;
> + }
> + } else if (in_fmt->fmt_type == FMT_YUV) {
> + acq_mult = 2;
> + if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
> + isp_ctrl = CIF_ISP_CTRL_ISP_MODE_ITU601;
> + } else {
> + if (sensor->mbus.type == V4L2_MBUS_BT656)
> + isp_ctrl = CIF_ISP_CTRL_ISP_MODE_ITU656;
> + else
> + isp_ctrl = CIF_ISP_CTRL_ISP_MODE_ITU601;
> +
> + }
> +
> + irq_mask |= CIF_ISP_DATA_LOSS;
> + }
> +
> + /* Set up input acquisition properties */
> + if (sensor->mbus.type == V4L2_MBUS_BT656 ||
> + sensor->mbus.type == V4L2_MBUS_PARALLEL) {
> + if (sensor->mbus.flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
> + signal = CIF_ISP_ACQ_PROP_POS_EDGE;
> + }
> +
> + if (sensor->mbus.type == V4L2_MBUS_PARALLEL) {
> + if (sensor->mbus.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
> + signal |= CIF_ISP_ACQ_PROP_VSYNC_LOW;
> +
> + if (sensor->mbus.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
> + signal |= CIF_ISP_ACQ_PROP_HSYNC_LOW;
> + }
> +
> + writel(isp_ctrl, base + CIF_ISP_CTRL);
> + writel(signal | in_fmt->yuv_seq |
> + CIF_ISP_ACQ_PROP_BAYER_PAT(in_fmt->bayer_pat) |
> + CIF_ISP_ACQ_PROP_FIELD_SEL_ALL, base + CIF_ISP_ACQ_PROP);
> + writel(0, base + CIF_ISP_ACQ_NR_FRAMES);
> +
> + /* Acquisition Size */
> + writel(0, base + CIF_ISP_ACQ_H_OFFS);
> + writel(0, base + CIF_ISP_ACQ_V_OFFS);
> + writel(acq_mult * in_frm->width, base + CIF_ISP_ACQ_H_SIZE);
> + writel(in_frm->height, base + CIF_ISP_ACQ_V_SIZE);
> +
> + /* ISP Out Area */
> + writel(in_crop->left, base + CIF_ISP_OUT_H_OFFS);
> + writel(in_crop->top, base + CIF_ISP_OUT_V_OFFS);
> + writel(in_crop->width, base + CIF_ISP_OUT_H_SIZE);
> + writel(in_crop->height, base + CIF_ISP_OUT_V_SIZE);
> +
> + /* interrupt mask */
> + irq_mask |= CIF_ISP_FRAME | CIF_ISP_V_START | CIF_ISP_PIC_SIZE_ERROR |
> + CIF_ISP_FRAME_IN;
> + writel(irq_mask, base + CIF_ISP_IMSC);
> +
> + if (out_fmt->fmt_type == FMT_BAYER)
> + rkisp1_params_disable_isp(&dev->params_vdev);
> + else
> + rkisp1_params_configure_isp(&dev->params_vdev, in_fmt,
> + dev->isp_sdev.quantization);
> +
> + return 0;
> +}
> +
> +static int rkisp1_config_dvp(struct rkisp1_device *dev)
> +{
> + struct ispsd_in_fmt *in_fmt = &dev->isp_sdev.in_fmt;
> + void __iomem *base = dev->base_addr;
> + u32 val, input_sel;
> +
> + switch (in_fmt->bus_width) {
> + case 8:
> + input_sel = CIF_ISP_ACQ_PROP_IN_SEL_8B_ZERO;
> + break;
> + case 10:
> + input_sel = CIF_ISP_ACQ_PROP_IN_SEL_10B_ZERO;
> + break;
> + case 12:
> + input_sel = CIF_ISP_ACQ_PROP_IN_SEL_12B;
> + break;
> + default:
> + v4l2_err(&dev->v4l2_dev, "Invalid bus width\n");
> + return -EINVAL;
> + }
> +
> + val = readl(base + CIF_ISP_ACQ_PROP);
> + writel(val | input_sel, base + CIF_ISP_ACQ_PROP);
> +
> + return 0;
> +}
> +
> +static int rkisp1_config_mipi(struct rkisp1_device *dev)
> +{
> + struct ispsd_in_fmt *in_fmt = &dev->isp_sdev.in_fmt;
> + struct rkisp1_sensor *sensor = dev->active_sensor;
> + void __iomem *base = dev->base_addr;
> + unsigned int lanes;
> + u32 mipi_ctrl;
> +
> + /*
> + * sensor->mbus is set in isp or d-phy notifier_bound function
> + */
> + switch (sensor->mbus.flags & V4L2_MBUS_CSI2_LANES) {
> + case V4L2_MBUS_CSI2_4_LANE:
> + lanes = 4;
> + break;
> + case V4L2_MBUS_CSI2_3_LANE:
> + lanes = 3;
> + break;
> + case V4L2_MBUS_CSI2_2_LANE:
> + lanes = 2;
> + break;
> + case V4L2_MBUS_CSI2_1_LANE:
> + lanes = 1;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + mipi_ctrl = CIF_MIPI_CTRL_NUM_LANES(lanes - 1) |
> + CIF_MIPI_CTRL_SHUTDOWNLANES(0xf) |
> + CIF_MIPI_CTRL_ERR_SOT_SYNC_HS_SKIP |
> + CIF_MIPI_CTRL_CLOCKLANE_ENA;
> +
> + writel(mipi_ctrl, base + CIF_MIPI_CTRL);
> +
> + /* Configure Data Type and Virtual Channel */
> + writel(CIF_MIPI_DATA_SEL_DT(in_fmt->mipi_dt) | CIF_MIPI_DATA_SEL_VC(0),
> + base + CIF_MIPI_IMG_DATA_SEL);
> +
> + /* Clear MIPI interrupts */
> + writel(~0, base + CIF_MIPI_ICR);
> + /*
> + * Disable CIF_MIPI_ERR_DPHY interrupt here temporary for
> + * isp bus may be dead when switch isp.
> + */
> + writel(CIF_MIPI_FRAME_END | CIF_MIPI_ERR_CSI | CIF_MIPI_ERR_DPHY |
> + CIF_MIPI_SYNC_FIFO_OVFLW(0x03) | CIF_MIPI_ADD_DATA_OVFLW,
> + base + CIF_MIPI_IMSC);
> +
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev, "\n MIPI_CTRL 0x%08x\n"
> + " MIPI_IMG_DATA_SEL 0x%08x\n"
> + " MIPI_STATUS 0x%08x\n"
> + " MIPI_IMSC 0x%08x\n",
> + readl(base + CIF_MIPI_CTRL),
> + readl(base + CIF_MIPI_IMG_DATA_SEL),
> + readl(base + CIF_MIPI_STATUS),
> + readl(base + CIF_MIPI_IMSC));
> +
> + return 0;
> +}
> +
> +/* Configure MUX */
> +static int rkisp1_config_path(struct rkisp1_device *dev)
> +{
> + struct rkisp1_sensor *sensor = dev->active_sensor;
> + u32 dpcl = readl(dev->base_addr + CIF_VI_DPCL);
> + int ret = 0;
> +
> + if (sensor->mbus.type == V4L2_MBUS_BT656 ||
> + sensor->mbus.type == V4L2_MBUS_PARALLEL) {
> + ret = rkisp1_config_dvp(dev);
> + dpcl |= CIF_VI_DPCL_IF_SEL_PARALLEL;
> + } else if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
> + ret = rkisp1_config_mipi(dev);
> + dpcl |= CIF_VI_DPCL_IF_SEL_MIPI;
> + }
> +
> + writel(dpcl, dev->base_addr + CIF_VI_DPCL);
> +
> + return ret;
> +}
> +
> +/* Hareware configure Entry */
> +static int rkisp1_config_cif(struct rkisp1_device *dev)
> +{
> + u32 cif_id;
> + int ret;
> +
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev,
> + "SP streaming = %d, MP streaming = %d\n",
> + dev->stream[RKISP1_STREAM_SP].streaming,
> + dev->stream[RKISP1_STREAM_MP].streaming);
> +
> + cif_id = readl(dev->base_addr + CIF_VI_ID);
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev, "CIF_ID 0x%08x\n", cif_id);
> +
> + ret = rkisp1_config_isp(dev);
> + if (ret < 0)
> + return ret;
> + ret = rkisp1_config_path(dev);
> + if (ret < 0)
> + return ret;
> + rkisp1_config_ism(dev);
> +
> + return 0;
> +}
> +
> +/* Mess register operations to stop isp */
> +static int rkisp1_isp_stop(struct rkisp1_device *dev)
> +{
> + void __iomem *base = dev->base_addr;
> + u32 val;
> +
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev,
> + "SP streaming = %d, MP streaming = %d\n",
> + dev->stream[RKISP1_STREAM_SP].streaming,
> + dev->stream[RKISP1_STREAM_MP].streaming);
> +
> + /*
> + * ISP(mi) stop in mi frame end -> Stop ISP(mipi) ->
> + * Stop ISP(isp) ->wait for ISP isp off
> + */
> + /* stop and clear MI, MIPI, and ISP interrupts */
> + writel(0, base + CIF_MIPI_IMSC);
> + writel(~0, base + CIF_MIPI_ICR);
> +
> + writel(0, base + CIF_ISP_IMSC);
> + writel(~0, base + CIF_ISP_ICR);
> +
> + writel(0, base + CIF_MI_IMSC);
> + writel(~0, base + CIF_MI_ICR);
> + val = readl(base + CIF_MIPI_CTRL);
> + writel(val & (~CIF_MIPI_CTRL_OUTPUT_ENA), base + CIF_MIPI_CTRL);
> + /* stop ISP */
> + val = readl(base + CIF_ISP_CTRL);
> + val &= ~(CIF_ISP_CTRL_ISP_INFORM_ENABLE | CIF_ISP_CTRL_ISP_ENABLE);
> + writel(val, base + CIF_ISP_CTRL);
> +
> + val = readl(base + CIF_ISP_CTRL);
> + writel(val | CIF_ISP_CTRL_ISP_CFG_UPD, base + CIF_ISP_CTRL);
> +
> + readx_poll_timeout(readl, base + CIF_ISP_RIS,
> + val, val & CIF_ISP_OFF, 20, 100);
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev,
> + "streaming(MP:%d, SP:%d), MI_CTRL:%x, ISP_CTRL:%x, MIPI_CTRL:%x\n",
> + dev->stream[RKISP1_STREAM_SP].streaming,
> + dev->stream[RKISP1_STREAM_MP].streaming,
> + readl(base + CIF_MI_CTRL),
> + readl(base + CIF_ISP_CTRL),
> + readl(base + CIF_MIPI_CTRL));
> +
> + writel(CIF_IRCL_MIPI_SW_RST | CIF_IRCL_ISP_SW_RST, base + CIF_IRCL);
> + writel(0x0, base + CIF_IRCL);
> +
> + return 0;
> +}
> +
> +/* Mess register operations to start isp */
> +static int rkisp1_isp_start(struct rkisp1_device *dev)
> +{
> + struct rkisp1_sensor *sensor = dev->active_sensor;
> + void __iomem *base = dev->base_addr;
> + u32 val;
> +
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev,
> + "SP streaming = %d, MP streaming = %d\n",
> + dev->stream[RKISP1_STREAM_SP].streaming,
> + dev->stream[RKISP1_STREAM_MP].streaming);
> +
> + /* Activate MIPI */
> + if (sensor->mbus.type == V4L2_MBUS_CSI2_DPHY) {
> + val = readl(base + CIF_MIPI_CTRL);
> + writel(val | CIF_MIPI_CTRL_OUTPUT_ENA, base + CIF_MIPI_CTRL);
> + }
> + /* Activate ISP */
> + val = readl(base + CIF_ISP_CTRL);
> + val |= CIF_ISP_CTRL_ISP_CFG_UPD | CIF_ISP_CTRL_ISP_ENABLE |
> + CIF_ISP_CTRL_ISP_INFORM_ENABLE;
> + writel(val, base + CIF_ISP_CTRL);
> +
> + /* XXX: Is the 1000us too long?
> + * CIF spec says to wait for sufficient time after enabling
> + * the MIPI interface and before starting the sensor output.
> + */
> + usleep_range(1000, 1200);
> +
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev,
> + "SP streaming = %d, MP streaming = %d MI_CTRL 0x%08x\n"
> + " ISP_CTRL 0x%08x MIPI_CTRL 0x%08x\n",
> + dev->stream[RKISP1_STREAM_SP].streaming,
> + dev->stream[RKISP1_STREAM_MP].streaming,
> + readl(base + CIF_MI_CTRL),
> + readl(base + CIF_ISP_CTRL),
> + readl(base + CIF_MIPI_CTRL));
> +
> + return 0;
> +}
> +
> +static void rkisp1_config_clk(struct rkisp1_device *dev)
> +{
> + u32 val = CIF_ICCL_ISP_CLK | CIF_ICCL_CP_CLK | CIF_ICCL_MRSZ_CLK |
> + CIF_ICCL_SRSZ_CLK | CIF_ICCL_JPEG_CLK | CIF_ICCL_MI_CLK |
> + CIF_ICCL_IE_CLK | CIF_ICCL_MIPI_CLK | CIF_ICCL_DCROP_CLK;
> +
> + writel(val, dev->base_addr + CIF_ICCL);
> +}
> +
> +/***************************** isp sub-devs *******************************/
> +
> +static const struct ispsd_in_fmt rkisp1_isp_input_formats[] = {
> + {
> + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW10,
> + .bayer_pat = RAW_BGGR,
> + .bus_width = 10,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW10,
> + .bayer_pat = RAW_RGGB,
> + .bus_width = 10,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW10,
> + .bayer_pat = RAW_GBRG,
> + .bus_width = 10,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW10,
> + .bayer_pat = RAW_GRBG,
> + .bus_width = 10,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW12,
> + .bayer_pat = RAW_RGGB,
> + .bus_width = 12,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW12,
> + .bayer_pat = RAW_BGGR,
> + .bus_width = 12,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW12,
> + .bayer_pat = RAW_GBRG,
> + .bus_width = 12,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW12,
> + .bayer_pat = RAW_GRBG,
> + .bus_width = 12,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW8,
> + .bayer_pat = RAW_RGGB,
> + .bus_width = 8,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW8,
> + .bayer_pat = RAW_BGGR,
> + .bus_width = 8,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW8,
> + .bayer_pat = RAW_GBRG,
> + .bus_width = 8,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
> + .fmt_type = FMT_BAYER,
> + .mipi_dt = CIF_CSI2_DT_RAW8,
> + .bayer_pat = RAW_GRBG,
> + .bus_width = 8,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_YUYV8_1X16,
> + .fmt_type = FMT_YUV,
> + .mipi_dt = CIF_CSI2_DT_YUV422_8b,
> + .yuv_seq = CIF_ISP_ACQ_PROP_YCBYCR,
> + .bus_width = 16,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_YVYU8_1X16,
> + .fmt_type = FMT_YUV,
> + .mipi_dt = CIF_CSI2_DT_YUV422_8b,
> + .yuv_seq = CIF_ISP_ACQ_PROP_YCRYCB,
> + .bus_width = 16,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
> + .fmt_type = FMT_YUV,
> + .mipi_dt = CIF_CSI2_DT_YUV422_8b,
> + .yuv_seq = CIF_ISP_ACQ_PROP_CBYCRY,
> + .bus_width = 16,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_VYUY8_1X16,
> + .fmt_type = FMT_YUV,
> + .mipi_dt = CIF_CSI2_DT_YUV422_8b,
> + .yuv_seq = CIF_ISP_ACQ_PROP_CRYCBY,
> + .bus_width = 16,
> + },
> +};
> +
> +static const struct ispsd_out_fmt rkisp1_isp_output_formats[] = {
> + {
> + .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8,
> + .fmt_type = FMT_YUV,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
> + .fmt_type = FMT_BAYER,
> + }, {
> + .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
> + .fmt_type = FMT_BAYER,
> + },
> +};
> +
> +static const struct ispsd_in_fmt *find_in_fmt(u32 mbus_code)
> +{
> + unsigned int i, array_size = ARRAY_SIZE(rkisp1_isp_input_formats);
> + const struct ispsd_in_fmt *fmt;
> +
> + for (i = 0; i < array_size; i++) {
> + fmt = &rkisp1_isp_input_formats[i];
> + if (fmt->mbus_code == mbus_code)
> + return fmt;
> + }
> +
> + return NULL;
> +}
> +
> +static const struct ispsd_out_fmt *find_out_fmt(u32 mbus_code)
> +{
> + unsigned int i, array_size = ARRAY_SIZE(rkisp1_isp_output_formats);
> + const struct ispsd_out_fmt *fmt;
> +
> + for (i = 0; i < array_size; i++) {
> + fmt = &rkisp1_isp_output_formats[i];
> + if (fmt->mbus_code == mbus_code)
> + return fmt;
> + }
> +
> + return NULL;
> +}
> +
> +static int rkisp1_isp_sd_enum_mbus_code(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_mbus_code_enum *code)
> +{
> + unsigned int i = code->index;
> +
> + if ((code->pad != RKISP1_ISP_PAD_SINK) &&
> + (code->pad != RKISP1_ISP_PAD_SOURCE_PATH)) {
> + if (i > 0)
> + return -EINVAL;
> + code->code = MEDIA_BUS_FMT_FIXED;
> + return 0;
> + }
> +
> + if (code->pad == RKISP1_ISP_PAD_SINK) {
> + if (i >= ARRAY_SIZE(rkisp1_isp_input_formats))
> + return -EINVAL;
> + code->code = rkisp1_isp_input_formats[i].mbus_code;
> + } else {
> + if (i >= ARRAY_SIZE(rkisp1_isp_output_formats))
> + return -EINVAL;
> + code->code = rkisp1_isp_output_formats[i].mbus_code;
> + }
> +
> + return 0;
> +}
> +
> +static int rkisp1_isp_sd_init_config(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg)
> +{
> + struct v4l2_rect *mf_in_crop, *mf_out_crop;
> + struct v4l2_mbus_framefmt *mf_in, *mf_out;
> +
> + mf_in = v4l2_subdev_get_try_format(sd, cfg, RKISP1_ISP_PAD_SINK);
> + mf_in->width = RKISP1_DEFAULT_WIDTH;
> + mf_in->height = RKISP1_DEFAULT_HEIGHT;
> + mf_in->field = V4L2_FIELD_NONE;
> + mf_in->code = rkisp1_isp_input_formats[0].mbus_code;
> +
> + mf_in_crop = v4l2_subdev_get_try_crop(sd, cfg, RKISP1_ISP_PAD_SINK);
> + mf_in_crop->width = RKISP1_DEFAULT_WIDTH;
> + mf_in_crop->height = RKISP1_DEFAULT_HEIGHT;
> + mf_in_crop->left = 0;
> + mf_in_crop->top = 0;
> +
> + mf_out = v4l2_subdev_get_try_format(sd, cfg,
> + RKISP1_ISP_PAD_SOURCE_PATH);
> + *mf_out = *mf_in;
> + mf_out->code = rkisp1_isp_output_formats[0].mbus_code;
> + mf_out->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> +
> + mf_out_crop = v4l2_subdev_get_try_crop(sd, cfg,
> + RKISP1_ISP_PAD_SOURCE_PATH);
> + *mf_out_crop = *mf_in_crop;
> +
> + return 0;
> +}
> +
> +static int rkisp1_isp_sd_get_fmt(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct rkisp1_isp_subdev *isp_sd = sd_to_isp_sd(sd);
> + struct v4l2_mbus_framefmt *mf = &fmt->format;
> +
> + if ((fmt->pad != RKISP1_ISP_PAD_SINK) &&
> + (fmt->pad != RKISP1_ISP_PAD_SOURCE_PATH)) {
> + fmt->format.code = MEDIA_BUS_FMT_FIXED;
> + /*
> + * NOTE: setting a format here doesn't make much sense
> + * but v4l2-compliance complains
> + */
> + fmt->format.width = RKISP1_DEFAULT_WIDTH;
> + fmt->format.height = RKISP1_DEFAULT_HEIGHT;
As I had mentioned to you, this is called for the isp pads connected to the
DMA engines for statistics and parameters (meta data).
If I remove those, I get the following errors:
Sub-Device ioctls (Sink Pad 1):
test Try VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
fail: v4l2-test-subdevs.cpp(311): fmt.width == 0 || fmt.width > 65536
fail: v4l2-test-subdevs.cpp(356): checkMBusFrameFmt(node, fmt.format)
test Try VIDIOC_SUBDEV_G/S_FMT: FAIL
test Try VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
test Active VIDIOC_SUBDEV_ENUM_MBUS_CODE/FRAME_SIZE/FRAME_INTERVAL: OK
fail: v4l2-test-subdevs.cpp(311): fmt.width == 0 || fmt.width > 65536
fail: v4l2-test-subdevs.cpp(356): checkMBusFrameFmt(node, fmt.format)
test Active VIDIOC_SUBDEV_G/S_FMT: FAIL
test Active VIDIOC_SUBDEV_G/S_SELECTION/CROP: OK
test VIDIOC_SUBDEV_G/S_FRAME_INTERVAL: OK (Not Supported)
Here is the full log: http://ix.io/1QNt
Is this a bug in v4l2-compliance?
Thanks
Helen
> + fmt->format.field = V4L2_FIELD_NONE;
> + return 0;
> + }
> +
> + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> + mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
> + fmt->format = *mf;
> + return 0;
> + }
> +
> + if (fmt->pad == RKISP1_ISP_PAD_SINK) {
> + *mf = isp_sd->in_frm;
> + } else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_PATH) {
> + /* format of source pad */
> + *mf = isp_sd->in_frm;
> + mf->code = isp_sd->out_fmt.mbus_code;
> + /* window size of source pad */
> + mf->width = isp_sd->out_crop.width;
> + mf->height = isp_sd->out_crop.height;
> + mf->quantization = isp_sd->quantization;
> + }
> + mf->field = V4L2_FIELD_NONE;
> +
> + return 0;
> +}
> +
> +static void rkisp1_isp_sd_try_fmt(struct v4l2_subdev *sd,
> + unsigned int pad,
> + struct v4l2_mbus_framefmt *fmt)
> +{
> + struct rkisp1_device *isp_dev = sd_to_isp_dev(sd);
> + struct rkisp1_isp_subdev *isp_sd = &isp_dev->isp_sdev;
> + const struct ispsd_out_fmt *out_fmt;
> + const struct ispsd_in_fmt *in_fmt;
> +
> + switch (pad) {
> + case RKISP1_ISP_PAD_SINK:
> + in_fmt = find_in_fmt(fmt->code);
> + if (in_fmt)
> + fmt->code = in_fmt->mbus_code;
> + else
> + fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10;
> + fmt->width = clamp_t(u32, fmt->width, CIF_ISP_INPUT_W_MIN,
> + CIF_ISP_INPUT_W_MAX);
> + fmt->height = clamp_t(u32, fmt->height, CIF_ISP_INPUT_H_MIN,
> + CIF_ISP_INPUT_H_MAX);
> + break;
> + case RKISP1_ISP_PAD_SOURCE_PATH:
> + out_fmt = find_out_fmt(fmt->code);
> + if (out_fmt)
> + fmt->code = out_fmt->mbus_code;
> + else
> + fmt->code = rkisp1_isp_output_formats[0].mbus_code;
> + /* window size is set in s_selection */
> + fmt->width = isp_sd->out_crop.width;
> + fmt->height = isp_sd->out_crop.height;
> + /* full range by default */
> + if (!fmt->quantization)
> + fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> + break;
> + }
> +
> + fmt->field = V4L2_FIELD_NONE;
> +}
> +
> +static int rkisp1_isp_sd_set_fmt(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_format *fmt)
> +{
> + struct rkisp1_device *isp_dev = sd_to_isp_dev(sd);
> + struct rkisp1_isp_subdev *isp_sd = &isp_dev->isp_sdev;
> + struct v4l2_mbus_framefmt *mf = &fmt->format;
> +
> + if ((fmt->pad != RKISP1_ISP_PAD_SINK) &&
> + (fmt->pad != RKISP1_ISP_PAD_SOURCE_PATH))
> + return rkisp1_isp_sd_get_fmt(sd, cfg, fmt);
> +
> + rkisp1_isp_sd_try_fmt(sd, fmt->pad, mf);
> +
> + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> + struct v4l2_mbus_framefmt *try_mf;
> +
> + try_mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
> + *try_mf = *mf;
> + return 0;
> + }
> +
> + if (fmt->pad == RKISP1_ISP_PAD_SINK) {
> + const struct ispsd_in_fmt *in_fmt;
> +
> + in_fmt = find_in_fmt(mf->code);
> + isp_sd->in_fmt = *in_fmt;
> + isp_sd->in_frm = *mf;
> + } else if (fmt->pad == RKISP1_ISP_PAD_SOURCE_PATH) {
> + const struct ispsd_out_fmt *out_fmt;
> +
> + /* Ignore width/height */
> + out_fmt = find_out_fmt(mf->code);
> + isp_sd->out_fmt = *out_fmt;
> + /*
> + * It is quantization for output,
> + * isp use bt601 limit-range in internal
> + */
> + isp_sd->quantization = mf->quantization;
> + }
> +
> + return 0;
> +}
> +
> +static void rkisp1_isp_sd_try_crop(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_selection *sel)
> +{
> + struct rkisp1_isp_subdev *isp_sd = sd_to_isp_sd(sd);
> + struct v4l2_mbus_framefmt in_frm = isp_sd->in_frm;
> + struct v4l2_rect in_crop = isp_sd->in_crop;
> + struct v4l2_rect *input = &sel->r;
> +
> + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
> + in_frm = *v4l2_subdev_get_try_format(sd, cfg,
> + RKISP1_ISP_PAD_SINK);
> + in_crop = *v4l2_subdev_get_try_crop(sd, cfg,
> + RKISP1_ISP_PAD_SINK);
> + }
> +
> + input->left = ALIGN(input->left, 2);
> + input->width = ALIGN(input->width, 2);
> +
> + if (sel->pad == RKISP1_ISP_PAD_SINK) {
> + input->left = clamp_t(u32, input->left, 0, in_frm.width);
> + input->top = clamp_t(u32, input->top, 0, in_frm.height);
> + input->width = clamp_t(u32, input->width, CIF_ISP_INPUT_W_MIN,
> + in_frm.width - input->left);
> + input->height = clamp_t(u32, input->height,
> + CIF_ISP_INPUT_H_MIN,
> + in_frm.height - input->top);
> + } else if (sel->pad == RKISP1_ISP_PAD_SOURCE_PATH) {
> + input->left = clamp_t(u32, input->left, 0, in_crop.width);
> + input->top = clamp_t(u32, input->top, 0, in_crop.height);
> + input->width = clamp_t(u32, input->width, CIF_ISP_OUTPUT_W_MIN,
> + in_crop.width - input->left);
> + input->height = clamp_t(u32, input->height,
> + CIF_ISP_OUTPUT_H_MIN,
> + in_crop.height - input->top);
> + }
> +}
> +
> +static int rkisp1_isp_sd_get_selection(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_selection *sel)
> +{
> + struct rkisp1_isp_subdev *isp_sd = sd_to_isp_sd(sd);
> + struct v4l2_mbus_framefmt *frm;
> + struct v4l2_rect *rect;
> +
> + if (sel->pad != RKISP1_ISP_PAD_SOURCE_PATH &&
> + sel->pad != RKISP1_ISP_PAD_SINK)
> + return -EINVAL;
> +
> + switch (sel->target) {
> + case V4L2_SEL_TGT_CROP_BOUNDS:
> + if (sel->pad == RKISP1_ISP_PAD_SINK) {
> + if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
> + frm = v4l2_subdev_get_try_format(sd, cfg,
> + sel->pad);
> + else
> + frm = &isp_sd->in_frm;
> +
> + sel->r.height = frm->height;
> + sel->r.width = frm->width;
> + sel->r.left = 0;
> + sel->r.top = 0;
> + } else {
> + if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
> + rect = v4l2_subdev_get_try_crop(sd, cfg,
> + RKISP1_ISP_PAD_SINK);
> + else
> + rect = &isp_sd->in_crop;
> + sel->r = *rect;
> + }
> + break;
> + case V4L2_SEL_TGT_CROP:
> + if (sel->which == V4L2_SUBDEV_FORMAT_TRY)
> + rect = v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
> + else if (sel->pad == RKISP1_ISP_PAD_SINK)
> + rect = &isp_sd->in_crop;
> + else
> + rect = &isp_sd->out_crop;
> + sel->r = *rect;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static int rkisp1_isp_sd_set_selection(struct v4l2_subdev *sd,
> + struct v4l2_subdev_pad_config *cfg,
> + struct v4l2_subdev_selection *sel)
> +{
> + struct rkisp1_isp_subdev *isp_sd = sd_to_isp_sd(sd);
> + struct rkisp1_device *dev = sd_to_isp_dev(sd);
> +
> + if (sel->pad != RKISP1_ISP_PAD_SOURCE_PATH &&
> + sel->pad != RKISP1_ISP_PAD_SINK)
> + return -EINVAL;
> + if (sel->target != V4L2_SEL_TGT_CROP)
> + return -EINVAL;
> +
> + v4l2_dbg(1, rkisp1_debug, &dev->v4l2_dev,
> + "%s: pad: %d sel(%d,%d)/%dx%d\n", __func__, sel->pad,
> + sel->r.left, sel->r.top, sel->r.width, sel->r.height);
> + rkisp1_isp_sd_try_crop(sd, cfg, sel);
> +
> + if (sel->which == V4L2_SUBDEV_FORMAT_TRY) {
> + struct v4l2_rect *try_sel =
> + v4l2_subdev_get_try_crop(sd, cfg, sel->pad);
> +
> + *try_sel = sel->r;
> + return 0;
> + }
> +
> + if (sel->pad == RKISP1_ISP_PAD_SINK)
> + isp_sd->in_crop = sel->r;
> + else
> + isp_sd->out_crop = sel->r;
> +
> + return 0;
> +}
> +
> +static int mipi_csi2_s_stream_start(struct rkisp1_isp_subdev *isp_sd,
> + struct rkisp1_sensor *sensor)
> +{
> + union phy_configure_opts opts = { 0 };
> + struct phy_configure_opts_mipi_dphy *cfg = &opts.mipi_dphy;
> + struct v4l2_ctrl *pixel_rate;
> + s64 pixel_clock;
> +
> + pixel_rate = v4l2_ctrl_find(sensor->sd->ctrl_handler,
> + V4L2_CID_PIXEL_RATE);
> + if (!pixel_rate) {
> + v4l2_warn(sensor->sd, "No pixel rate control in subdev\n");
> + return -EPIPE;
> + }
> +
> + pixel_clock = v4l2_ctrl_g_ctrl_int64(pixel_rate);
> + if (!pixel_clock) {
> + v4l2_err(sensor->sd, "Invalid pixel rate value\n");
> + return -EINVAL;
> + }
> +
> + phy_mipi_dphy_get_default_config(pixel_clock, isp_sd->in_fmt.bus_width,
> + sensor->lanes, cfg);
> + phy_set_mode(sensor->dphy, PHY_MODE_MIPI_DPHY);
> + phy_configure(sensor->dphy, &opts);
> + phy_power_on(sensor->dphy);
> +
> + return 0;
> +}
> +
> +static void mipi_csi2_s_stream_stop(struct rkisp1_sensor *sensor)
> +{
> + phy_power_off(sensor->dphy);
> +}
> +
> +static int rkisp1_isp_sd_s_stream(struct v4l2_subdev *sd, int on)
> +{
> + struct rkisp1_device *isp_dev = sd_to_isp_dev(sd);
> + struct v4l2_subdev *sensor_sd;
> + int ret = 0;
> +
> + if (!on) {
> + ret = rkisp1_isp_stop(isp_dev);
> + if (ret < 0)
> + return ret;
> + mipi_csi2_s_stream_stop(isp_dev->active_sensor);
> + return 0;
> + }
> +
> + sensor_sd = get_remote_sensor(sd);
> + if (!sensor_sd)
> + return -ENODEV;
> +
> + isp_dev->active_sensor = sd_to_sensor(isp_dev, sensor_sd);
> + if (!isp_dev->active_sensor)
> + return -ENODEV;
> +
> + atomic_set(&isp_dev->isp_sdev.frm_sync_seq, 0);
> + ret = rkisp1_config_cif(isp_dev);
> + if (ret < 0)
> + return ret;
> +
> + /* TODO: support other interfaces */
> + if (isp_dev->active_sensor->mbus.type != V4L2_MBUS_CSI2_DPHY)
> + return -EINVAL;
> +
> + ret = mipi_csi2_s_stream_start(&isp_dev->isp_sdev,
> + isp_dev->active_sensor);
> + if (ret < 0)
> + return ret;
> +
> + ret = rkisp1_isp_start(isp_dev);
> + if (ret)
> + mipi_csi2_s_stream_stop(isp_dev->active_sensor);
> +
> + return ret;
> +}
> +
> +static int rkisp1_isp_sd_s_power(struct v4l2_subdev *sd, int on)
> +{
> + struct rkisp1_device *isp_dev = sd_to_isp_dev(sd);
> + int ret;
> +
> + v4l2_dbg(1, rkisp1_debug, &isp_dev->v4l2_dev, "s_power: %d\n", on);
> +
> + if (on) {
> + ret = pm_runtime_get_sync(isp_dev->dev);
> + if (ret < 0)
> + return ret;
> +
> + rkisp1_config_clk(isp_dev);
> + } else {
> + ret = pm_runtime_put(isp_dev->dev);
> + if (ret < 0)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +static int rkisp1_subdev_link_validate(struct media_link *link)
> +{
> + if (link->source->index == RKISP1_ISP_PAD_SINK_PARAMS)
> + return 0;
> +
> + return v4l2_subdev_link_validate(link);
> +}
> +
> +static int rkisp1_subdev_fmt_link_validate(struct v4l2_subdev *sd,
> + struct media_link *link,
> + struct v4l2_subdev_format *source_fmt,
> + struct v4l2_subdev_format *sink_fmt)
> +{
> + if (source_fmt->format.code != sink_fmt->format.code)
> + return -EINVAL;
> +
> + /* Crop is available */
> + if (source_fmt->format.width < sink_fmt->format.width ||
> + source_fmt->format.height < sink_fmt->format.height)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +static void rkisp1_isp_queue_event_sof(struct rkisp1_isp_subdev *isp)
> +{
> + struct v4l2_event event = {
> + .type = V4L2_EVENT_FRAME_SYNC,
> + .u.frame_sync.frame_sequence =
> + atomic_inc_return(&isp->frm_sync_seq) - 1,
> + };
> + v4l2_event_queue(isp->sd.devnode, &event);
> +}
> +
> +static int rkisp1_isp_sd_subs_evt(struct v4l2_subdev *sd, struct v4l2_fh *fh,
> + struct v4l2_event_subscription *sub)
> +{
> + if (sub->type != V4L2_EVENT_FRAME_SYNC)
> + return -EINVAL;
> +
> + /* Line number. For now only zero accepted. */
> + if (sub->id != 0)
> + return -EINVAL;
> +
> + return v4l2_event_subscribe(fh, sub, 0, NULL);
> +}
> +
> +static const struct v4l2_subdev_pad_ops rkisp1_isp_sd_pad_ops = {
> + .enum_mbus_code = rkisp1_isp_sd_enum_mbus_code,
> + .get_selection = rkisp1_isp_sd_get_selection,
> + .set_selection = rkisp1_isp_sd_set_selection,
> + .init_cfg = rkisp1_isp_sd_init_config,
> + .get_fmt = rkisp1_isp_sd_get_fmt,
> + .set_fmt = rkisp1_isp_sd_set_fmt,
> + .link_validate = rkisp1_subdev_fmt_link_validate,
> +};
> +
> +static const struct media_entity_operations rkisp1_isp_sd_media_ops = {
> + .link_validate = rkisp1_subdev_link_validate,
> +};
> +
> +static const struct v4l2_subdev_video_ops rkisp1_isp_sd_video_ops = {
> + .s_stream = rkisp1_isp_sd_s_stream,
> +};
> +
> +static const struct v4l2_subdev_core_ops rkisp1_isp_core_ops = {
> + .subscribe_event = rkisp1_isp_sd_subs_evt,
> + .unsubscribe_event = v4l2_event_subdev_unsubscribe,
> + .s_power = rkisp1_isp_sd_s_power,
> +};
> +
> +static struct v4l2_subdev_ops rkisp1_isp_sd_ops = {
> + .core = &rkisp1_isp_core_ops,
> + .video = &rkisp1_isp_sd_video_ops,
> + .pad = &rkisp1_isp_sd_pad_ops,
> +};
> +
> +static void rkisp1_isp_sd_init_default_fmt(struct rkisp1_isp_subdev *isp_sd)
> +{
> + struct v4l2_mbus_framefmt *in_frm = &isp_sd->in_frm;
> + struct v4l2_rect *in_crop = &isp_sd->in_crop;
> + struct v4l2_rect *out_crop = &isp_sd->out_crop;
> + struct ispsd_in_fmt *in_fmt = &isp_sd->in_fmt;
> + struct ispsd_out_fmt *out_fmt = &isp_sd->out_fmt;
> +
> + *in_fmt = rkisp1_isp_input_formats[0];
> + in_frm->width = RKISP1_DEFAULT_WIDTH;
> + in_frm->height = RKISP1_DEFAULT_HEIGHT;
> + in_frm->code = in_fmt->mbus_code;
> +
> + in_crop->width = in_frm->width;
> + in_crop->height = in_frm->height;
> + in_crop->left = 0;
> + in_crop->top = 0;
> +
> + /* propagate to source */
> + *out_crop = *in_crop;
> + *out_fmt = rkisp1_isp_output_formats[0];
> + isp_sd->quantization = V4L2_QUANTIZATION_FULL_RANGE;
> +}
> +
> +int rkisp1_register_isp_subdev(struct rkisp1_device *isp_dev,
> + struct v4l2_device *v4l2_dev)
> +{
> + struct rkisp1_isp_subdev *isp_sdev = &isp_dev->isp_sdev;
> + struct v4l2_subdev *sd = &isp_sdev->sd;
> + int ret;
> +
> + v4l2_subdev_init(sd, &rkisp1_isp_sd_ops);
> + sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS;
> + sd->entity.ops = &rkisp1_isp_sd_media_ops;
> + snprintf(sd->name, sizeof(sd->name), "rkisp1-isp-subdev");
> +
> + isp_sdev->pads[RKISP1_ISP_PAD_SINK].flags =
> + MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT;
> + isp_sdev->pads[RKISP1_ISP_PAD_SINK_PARAMS].flags = MEDIA_PAD_FL_SINK;
> + isp_sdev->pads[RKISP1_ISP_PAD_SOURCE_PATH].flags = MEDIA_PAD_FL_SOURCE;
> + isp_sdev->pads[RKISP1_ISP_PAD_SOURCE_STATS].flags = MEDIA_PAD_FL_SOURCE;
> + sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
> + ret = media_entity_pads_init(&sd->entity, RKISP1_ISP_PAD_MAX,
> + isp_sdev->pads);
> + if (ret < 0)
> + return ret;
> +
> + sd->owner = THIS_MODULE;
> + v4l2_set_subdevdata(sd, isp_dev);
> +
> + sd->grp_id = GRP_ID_ISP;
> + ret = v4l2_device_register_subdev(v4l2_dev, sd);
> + if (ret < 0) {
> + v4l2_err(sd, "Failed to register isp subdev\n");
> + goto err_cleanup_media_entity;
> + }
> +
> + rkisp1_isp_sd_init_default_fmt(isp_sdev);
> +
> + return 0;
> +err_cleanup_media_entity:
> + media_entity_cleanup(&sd->entity);
> + return ret;
> +}
> +
> +void rkisp1_unregister_isp_subdev(struct rkisp1_device *isp_dev)
> +{
> + struct v4l2_subdev *sd = &isp_dev->isp_sdev.sd;
> +
> + v4l2_device_unregister_subdev(sd);
> + media_entity_cleanup(&sd->entity);
> +}
> +
> +/**************** Interrupter Handler ****************/
> +
> +void rkisp1_mipi_isr(unsigned int mis, struct rkisp1_device *dev)
> +{
> + struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
> + void __iomem *base = dev->base_addr;
> + u32 val;
> +
> + writel(~0, base + CIF_MIPI_ICR);
> +
> + /*
> + * Disable DPHY errctrl interrupt, because this dphy
> + * erctrl signal is asserted until the next changes
> + * of line state. This time is may be too long and cpu
> + * is hold in this interrupt.
> + */
> + if (mis & CIF_MIPI_ERR_CTRL(0x0f)) {
> + val = readl(base + CIF_MIPI_IMSC);
> + writel(val & ~CIF_MIPI_ERR_CTRL(0x0f), base + CIF_MIPI_IMSC);
> + dev->isp_sdev.dphy_errctrl_disabled = true;
> + }
> +
> + /*
> + * Enable DPHY errctrl interrupt again, if mipi have receive
> + * the whole frame without any error.
> + */
> + if (mis == CIF_MIPI_FRAME_END) {
> + /*
> + * Enable DPHY errctrl interrupt again, if mipi have receive
> + * the whole frame without any error.
> + */
> + if (dev->isp_sdev.dphy_errctrl_disabled) {
> + val = readl(base + CIF_MIPI_IMSC);
> + val |= CIF_MIPI_ERR_CTRL(0x0f);
> + writel(val, base + CIF_MIPI_IMSC);
> + dev->isp_sdev.dphy_errctrl_disabled = false;
> + }
> + } else {
> + v4l2_warn(v4l2_dev, "MIPI mis error: 0x%08x\n", mis);
> + }
> +}
> +
> +void rkisp1_isp_isr(unsigned int isp_mis, struct rkisp1_device *dev)
> +{
> + void __iomem *base = dev->base_addr;
> + unsigned int isp_mis_tmp = 0;
> + unsigned int isp_err = 0;
> +
> + /* start edge of v_sync */
> + if (isp_mis & CIF_ISP_V_START) {
> + rkisp1_isp_queue_event_sof(&dev->isp_sdev);
> +
> + writel(CIF_ISP_V_START, base + CIF_ISP_ICR);
> + isp_mis_tmp = readl(base + CIF_ISP_MIS);
> + if (isp_mis_tmp & CIF_ISP_V_START)
> + v4l2_err(&dev->v4l2_dev, "isp icr v_statr err: 0x%x\n",
> + isp_mis_tmp);
> + }
> +
> + if ((isp_mis & CIF_ISP_PIC_SIZE_ERROR)) {
> + /* Clear pic_size_error */
> + writel(CIF_ISP_PIC_SIZE_ERROR, base + CIF_ISP_ICR);
> + isp_err = readl(base + CIF_ISP_ERR);
> + v4l2_err(&dev->v4l2_dev,
> + "CIF_ISP_PIC_SIZE_ERROR (0x%08x)", isp_err);
> + writel(isp_err, base + CIF_ISP_ERR_CLR);
> + } else if ((isp_mis & CIF_ISP_DATA_LOSS)) {
> + /* Clear data_loss */
> + writel(CIF_ISP_DATA_LOSS, base + CIF_ISP_ICR);
> + v4l2_err(&dev->v4l2_dev, "CIF_ISP_DATA_LOSS\n");
> + writel(CIF_ISP_DATA_LOSS, base + CIF_ISP_ICR);
> + }
> +
> + /* sampled input frame is complete */
> + if (isp_mis & CIF_ISP_FRAME_IN) {
> + writel(CIF_ISP_FRAME_IN, base + CIF_ISP_ICR);
> + isp_mis_tmp = readl(base + CIF_ISP_MIS);
> + if (isp_mis_tmp & CIF_ISP_FRAME_IN)
> + v4l2_err(&dev->v4l2_dev, "isp icr frame_in err: 0x%x\n",
> + isp_mis_tmp);
> + }
> +
> + /* frame was completely put out */
> + if (isp_mis & CIF_ISP_FRAME) {
> + u32 isp_ris = 0;
> + /* Clear Frame In (ISP) */
> + writel(CIF_ISP_FRAME, base + CIF_ISP_ICR);
> + isp_mis_tmp = readl(base + CIF_ISP_MIS);
> + if (isp_mis_tmp & CIF_ISP_FRAME)
> + v4l2_err(&dev->v4l2_dev,
> + "isp icr frame end err: 0x%x\n", isp_mis_tmp);
> +
> + isp_ris = readl(base + CIF_ISP_RIS);
> + if (isp_ris & (CIF_ISP_AWB_DONE | CIF_ISP_AFM_FIN |
> + CIF_ISP_EXP_END | CIF_ISP_HIST_MEASURE_RDY))
> + rkisp1_stats_isr(&dev->stats_vdev, isp_ris);
> + }
> +
> + /*
> + * Then update changed configs. Some of them involve
> + * lot of register writes. Do those only one per frame.
> + * Do the updates in the order of the processing flow.
> + */
> + rkisp1_params_isr(&dev->params_vdev, isp_mis);
> +}
> diff --git a/drivers/media/platform/rockchip/isp1/rkisp1.h b/drivers/media/platform/rockchip/isp1/rkisp1.h
> new file mode 100644
> index 000000000000..b0366e354ec2
> --- /dev/null
> +++ b/drivers/media/platform/rockchip/isp1/rkisp1.h
> @@ -0,0 +1,111 @@
> +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
> +/*
> + * Rockchip isp1 driver
> + *
> + * Copyright (C) 2017 Rockchip Electronics Co., Ltd.
> + */
> +
> +#ifndef _RKISP1_H
> +#define _RKISP1_H
> +
> +#include <linux/platform_device.h>
> +#include <media/v4l2-fwnode.h>
> +
> +#include "common.h"
> +
> +struct rkisp1_stream;
> +
> +/*
> + * struct ispsd_in_fmt - ISP intput-pad format
> + *
> + * Translate mbus_code to hardware format values
> + *
> + * @bus_width: used for parallel
> + */
> +struct ispsd_in_fmt {
> + u32 mbus_code;
> + u8 fmt_type;
> + u32 mipi_dt;
> + u32 yuv_seq;
> + enum rkisp1_fmt_raw_pat_type bayer_pat;
> + u8 bus_width;
> +};
> +
> +struct ispsd_out_fmt {
> + u32 mbus_code;
> + u8 fmt_type;
> +};
> +
> +struct rkisp1_ie_config {
> + unsigned int effect;
> +};
> +
> +enum rkisp1_isp_pad {
> + RKISP1_ISP_PAD_SINK,
> + RKISP1_ISP_PAD_SINK_PARAMS,
> + RKISP1_ISP_PAD_SOURCE_PATH,
> + RKISP1_ISP_PAD_SOURCE_STATS,
> + RKISP1_ISP_PAD_MAX
> +};
> +
> +/*
> + * struct rkisp1_isp_subdev - ISP sub-device
> + *
> + * See Cropping regions of ISP in rkisp1.c for details
> + * @in_frm: input size, don't have to be equal to sensor size
> + * @in_fmt: input format
> + * @in_crop: crop for sink pad
> + * @out_fmt: output format
> + * @out_crop: output size
> + *
> + * @dphy_errctrl_disabled: if dphy errctrl is disabled(avoid endless interrupt)
> + * @frm_sync_seq: frame sequence, to sync frame_id between video devices.
> + * @quantization: output quantization
> + */
> +struct rkisp1_isp_subdev {
> + struct v4l2_subdev sd;
> + struct media_pad pads[RKISP1_ISP_PAD_MAX];
> + struct v4l2_ctrl_handler ctrl_handler;
> + struct v4l2_mbus_framefmt in_frm;
> + struct ispsd_in_fmt in_fmt;
> + struct v4l2_rect in_crop;
> + struct ispsd_out_fmt out_fmt;
> + struct v4l2_rect out_crop;
> + bool dphy_errctrl_disabled;
> + atomic_t frm_sync_seq;
> + enum v4l2_quantization quantization;
> +};
> +
> +int rkisp1_register_isp_subdev(struct rkisp1_device *isp_dev,
> + struct v4l2_device *v4l2_dev);
> +
> +void rkisp1_unregister_isp_subdev(struct rkisp1_device *isp_dev);
> +
> +void rkisp1_mipi_isr(unsigned int mipi_mis, struct rkisp1_device *dev);
> +
> +void rkisp1_isp_isr(unsigned int isp_mis, struct rkisp1_device *dev);
> +
> +static inline
> +struct ispsd_out_fmt *rkisp1_get_ispsd_out_fmt(struct rkisp1_isp_subdev *isp_sdev)
> +{
> + return &isp_sdev->out_fmt;
> +}
> +
> +static inline
> +struct ispsd_in_fmt *rkisp1_get_ispsd_in_fmt(struct rkisp1_isp_subdev *isp_sdev)
> +{
> + return &isp_sdev->in_fmt;
> +}
> +
> +static inline
> +struct v4l2_rect *rkisp1_get_isp_sd_win(struct rkisp1_isp_subdev *isp_sdev)
> +{
> + return &isp_sdev->out_crop;
> +}
> +
> +static inline struct rkisp1_isp_subdev *sd_to_isp_sd(struct v4l2_subdev *sd)
> +{
> + return container_of(sd, struct rkisp1_isp_subdev, sd);
> +}
> +
> +#endif /* _RKISP1_H */
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] arm64: dts: allwinner: a64: Drop PMU node
From: Emmanuel Vadot @ 2019-08-06 19:10 UTC (permalink / raw)
To: Vasily Khoruzhick
Cc: Mark Rutland, devicetree, Jared D . McNeill, Maxime Ripard,
Chen-Yu Tsai, Rob Herring, Harald Geyer, linux-arm-kernel
In-Reply-To: <20190806140135.4739-1-anarsoul@gmail.com>
On Tue, 6 Aug 2019 07:01:35 -0700
Vasily Khoruzhick <anarsoul@gmail.com> wrote:
> Looks like PMU in A64 is broken, it generates no interrupts at all and
> as result 'perf top' shows no events.
>
> Tested on Pine64-LTS.
>
> Fixes: 34a97fcc71c2 ("arm64: dts: allwinner: a64: Add PMU node")
> Cc: Harald Geyer <harald@ccbib.org>
> Cc: Jared D. McNeill <jmcneill@NetBSD.org>
> Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
> ---
> arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 9 ---------
> 1 file changed, 9 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index 9cc9bdde81ac..cd92f546c483 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -142,15 +142,6 @@
> clock-output-names = "ext-osc32k";
> };
>
> - pmu {
> - compatible = "arm,cortex-a53-pmu";
> - interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>,
> - <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>,
> - <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>,
> - <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>;
> - interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
> - };
> -
> psci {
> compatible = "arm,psci-0.2";
> method = "smc";
> --
> 2.22.0
It doesn't work for me too on FreeBSD, and yes the interrupts are
wrong but this is not the problem. Maybe there is a reset line but it's
not documented in the documentation.
Reviewed-by: Emmanuel Vadot <manu@FreeBSD.org>
--
Emmanuel Vadot <manu@bidouilliste.com> <manu@freebsd.org>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 2/2] dt-bindings: net: meson-dwmac: convert to yaml
From: Martin Blumenstingl @ 2019-08-06 19:11 UTC (permalink / raw)
To: Neil Armstrong
Cc: devicetree, netdev, linux-kernel, robh+dt, linux-amlogic,
linux-arm-kernel
In-Reply-To: <20190806125041.16105-3-narmstrong@baylibre.com>
On Tue, Aug 6, 2019 at 2:50 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Synopsys DWMAC Glue for Amlogic SoCs over to a YAML schemas.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
thank you for taking care of this conversion!
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
[...]
> + amlogic,tx-delay-ns:
> + $ref: /schemas/types.yaml#definitions/uint32
> + description:
> + The internal RGMII TX clock delay (provided by this driver) in
> + nanoseconds. Allowed values are 0ns, 2ns, 4ns, 6ns.
once I have more time I will try to see whether we can define an enum
with these values, then invalid values will yield a warning/error when
building the .dtb (which seems to be a good idea)
this comment shouldn't prevent this patch from being applied as the
initial conversion will already make life a lot easier
Martin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFCv2 4/9] dt-bindings: reset: amlogic, meson-reset: convert to yaml
From: Martin Blumenstingl @ 2019-08-06 19:12 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-amlogic, robh+dt, linux-arm-kernel, p.zabel, devicetree
In-Reply-To: <20190805120320.32282-5-narmstrong@baylibre.com>
On Mon, Aug 5, 2019 at 2:06 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Amlogic Reset controller over to a YAML schemas.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFCv2 8/9] dt-bindings: serial: meson-uart: convert to yaml
From: Martin Blumenstingl @ 2019-08-06 19:18 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-amlogic, robh+dt, linux-serial, linux-arm-kernel,
devicetree
In-Reply-To: <20190805120320.32282-9-narmstrong@baylibre.com>
Hi Neil,
On Mon, Aug 5, 2019 at 2:06 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Amlogic UART Serial controller over to a YAML schemas.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
two nit-picks below, but overall this looks good:
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
> ---
> .../bindings/serial/amlogic,meson-uart.txt | 38 ----------
> .../bindings/serial/amlogic,meson-uart.yaml | 73 +++++++++++++++++++
> 2 files changed, 73 insertions(+), 38 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/serial/amlogic,meson-uart.txt
> create mode 100644 Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
>
> diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.txt b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.txt
> deleted file mode 100644
> index c06c045126fc..000000000000
> --- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.txt
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -Amlogic Meson SoC UART Serial Interface
> -=======================================
> -
> -The Amlogic Meson SoC UART Serial Interface is present on a large range
> -of SoCs, and can be present either in the "Always-On" power domain or the
> -"Everything-Else" power domain.
> -
> -The particularity of the "Always-On" Serial Interface is that the hardware
> -is active since power-on and does not need any clock gating and is usable
> -as very early serial console.
> -
> -Required properties:
> -- compatible : compatible: value should be different for each SoC family as :
> - - Meson6 : "amlogic,meson6-uart"
> - - Meson8 : "amlogic,meson8-uart"
> - - Meson8b : "amlogic,meson8b-uart"
> - - GX (GXBB, GXL, GXM) : "amlogic,meson-gx-uart"
> - eventually followed by : "amlogic,meson-ao-uart" if this UART interface
> - is in the "Always-On" power domain.
> -- reg : offset and length of the register set for the device.
> -- interrupts : identifier to the device interrupt
> -- clocks : a list of phandle + clock-specifier pairs, one for each
> - entry in clock names.
> -- clock-names :
> - * "xtal" for external xtal clock identifier
> - * "pclk" for the bus core clock, either the clk81 clock or the gate clock
> - * "baud" for the source of the baudrate generator, can be either the xtal
> - or the pclk.
> -
> -e.g.
> -uart_A: serial@84c0 {
> - compatible = "amlogic,meson-gx-uart";
> - reg = <0x0 0x84c0 0x0 0x14>;
> - interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
> - /* Use xtal as baud rate clock source */
> - clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
> - clock-names = "xtal", "pclk", "baud";
> -};
> diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> new file mode 100644
> index 000000000000..5d48a8c04aa9
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml
> @@ -0,0 +1,73 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +# Copyright 2019 BayLibre, SAS
> +%YAML 1.2
> +---
> +$id: "http://devicetree.org/schemas/serial/amlogic,meson-uart.yaml#"
> +$schema: "http://devicetree.org/meta-schemas/core.yaml#"
> +
> +title: Amlogic Meson SoC UART Serial Interface
> +
> +maintainers:
> + - Neil Armstrong <narmstrong@baylibre.com>
> +
> +description: |
> + The Amlogic Meson SoC UART Serial Interface is present on a large range
> + of SoCs, and can be present either in the "Always-On" power domain or the
> + "Everything-Else" power domain.
> +
> + The particularity of the "Always-On" Serial Interface is that the hardware
> + is active since power-on and does not need any clock gating and is usable
> + as very early serial console.
> +
> +properties:
> + compatible:
> + oneOf:
> + - description: Allways-on power domain UART controller
Always instead of Allways
[...]
> +examples:
> + - |
> + serial@84c0 {
> + compatible = "amlogic,meson-gx-uart";
> + reg = <0x84c0 0x14>;
> + interrupts = <26>;
> + clocks = <&xtal>, <&pclk>, <&xtal>;
> + clock-names = "xtal", "pclk", "baud";
> + };
more a hint than a nit-pick: you can add #includes to the example,
just like in the real .dtb
then you can keep the GIC_SPI and IRQ_TYPE_... macros
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFCv2 2/9] dt-bindings: rng: amlogic,meson-rng: convert to yaml
From: Martin Blumenstingl @ 2019-08-06 19:19 UTC (permalink / raw)
To: Neil Armstrong
Cc: linux-amlogic, robh+dt, linux-crypto, linux-arm-kernel,
devicetree
In-Reply-To: <20190805120320.32282-3-narmstrong@baylibre.com>
On Mon, Aug 5, 2019 at 2:04 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Amlogic Random Number generator over to a YAML schemas.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFCv2 6/9] dt-bindings: phy: meson-g12a-usb2-phy: convert to yaml
From: Martin Blumenstingl @ 2019-08-06 19:21 UTC (permalink / raw)
To: Neil Armstrong
Cc: kishon, linux-amlogic, robh+dt, linux-arm-kernel, devicetree
In-Reply-To: <20190805120320.32282-7-narmstrong@baylibre.com>
On Mon, Aug 5, 2019 at 2:05 PM Neil Armstrong <narmstrong@baylibre.com> wrote:
>
> Now that we have the DT validation in place, let's convert the device tree
> bindings for the Amlogic G12A USB2 PHY over to a YAML schemas.
>
> While the original phy bindings specifies phy-supply as required,
> the examples and implementations makes it optional, thus phy-supply
> is not in the required list of attributes.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] MIPS: BCM63XX: Mark expected switch fall-through
From: Paul Burton @ 2019-08-06 19:22 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: Paul Burton, Florian Fainelli, Gustavo A. R. Silva, James Hogan,
linux-mips@vger.kernel.org, Ralf Baechle,
linux-kernel@vger.kernel.org,
bcm-kernel-feedback-list@broadcom.com,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190805185533.GA10551@embeddedor>
Hello,
Gustavo A. R. Silva wrote:
> Mark switch cases where we are expecting to fall through.
>
> This patch fixes the following warning (Building: bcm63xx_defconfig mips):
>
> arch/mips/pci/ops-bcm63xx.c: In function ‘bcm63xx_pcie_can_access’:
> arch/mips/pci/ops-bcm63xx.c:474:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
> if (PCI_SLOT(devfn) == 0)
> ^
> arch/mips/pci/ops-bcm63xx.c:477:2: note: here
> default:
> ^~~~~~~
>
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
Applied to mips-fixes.
Thanks,
Paul
[ This message was auto-generated; if you believe anything is incorrect
then please email paul.burton@mips.com to report it. ]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 4/6] arm64: dts: meson: sei510: Add minimal thermal zone
From: Martin Blumenstingl @ 2019-08-06 19:24 UTC (permalink / raw)
To: Guillaume La Roque
Cc: devicetree, linux-pm, khilman, daniel.lezcano, linux-kernel,
linux-amlogic, linux-arm-kernel
In-Reply-To: <20190806130506.8753-5-glaroque@baylibre.com>
On Tue, Aug 6, 2019 at 3:06 PM Guillaume La Roque <glaroque@baylibre.com> wrote:
>
> Add minimal thermal zone for two temperature sensor
> One is located close to the DDR and the other one is
> located close to the PLLs (between the CPU and GPU)
>
> Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
I'm not familiar with the thermal subsystem but this looks sane so:
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 5/6] arm64: dts: amlogic: odroid-n2: add minimal thermal zone
From: Martin Blumenstingl @ 2019-08-06 19:25 UTC (permalink / raw)
To: Guillaume La Roque
Cc: devicetree, linux-pm, khilman, daniel.lezcano, linux-kernel,
linux-amlogic, linux-arm-kernel
In-Reply-To: <20190806130506.8753-6-glaroque@baylibre.com>
On Tue, Aug 6, 2019 at 3:06 PM Guillaume La Roque <glaroque@baylibre.com> wrote:
>
> Add minimal thermal zone for two temperature sensor
> One is located close to the DDR and the other one is
> located close to the PLLs (between the CPU and GPU)
>
> Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
I'm not familiar with the thermal subsystem but this looks sane so:
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH net 0/3] net: stmmac: Fixes for -net
From: David Miller @ 2019-08-06 19:26 UTC (permalink / raw)
To: Jose.Abreu
Cc: Joao.Pinto, alexandre.torgue, netdev, linux-kernel,
mcoquelin.stm32, peppe.cavallaro, linux-stm32, linux-arm-kernel
In-Reply-To: <cover.1565097294.git.joabreu@synopsys.com>
From: Jose Abreu <Jose.Abreu@synopsys.com>
Date: Tue, 6 Aug 2019 15:16:15 +0200
> Couple of fixes for -net. More info in commit log.
Series applied, thank you.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v2] arm64/cache: fix -Woverride-init compiler warnings
From: Qian Cai @ 2019-08-06 19:34 UTC (permalink / raw)
To: will, catalin.marinas
Cc: mark.rutland, Qian Cai, linux-kernel, linux-arm-kernel
The commit 155433cb365e ("arm64: cache: Remove support for ASID-tagged
VIVT I-caches") introduced some compiation warnings from GCC (and
Clang),
arch/arm64/kernel/cpuinfo.c:38:26: warning: initialized field
overwritten [-Woverride-init]
[ICACHE_POLICY_VIPT] = "VIPT",
^~~~~~
arch/arm64/kernel/cpuinfo.c:38:26: note: (near initialization for
'icache_policy_str[2]')
arch/arm64/kernel/cpuinfo.c:39:26: warning: initialized field
overwritten [-Woverride-init]
[ICACHE_POLICY_PIPT] = "PIPT",
^~~~~~
arch/arm64/kernel/cpuinfo.c:39:26: note: (near initialization for
'icache_policy_str[3]')
arch/arm64/kernel/cpuinfo.c:40:27: warning: initialized field
overwritten [-Woverride-init]
[ICACHE_POLICY_VPIPT] = "VPIPT",
^~~~~~~
arch/arm64/kernel/cpuinfo.c:40:27: note: (near initialization for
'icache_policy_str[0]')
because it initializes icache_policy_str[0 ... 3] twice. Since the array
is only used in cpuinfo_detect_icache_policy(), fix it by initializing
a specific field there just before using.
Fixes: 155433cb365e ("arm64: cache: Remove support for ASID-tagged VIVT I-caches")
Signed-off-by: Qian Cai <cai@lca.pw>
---
v2: Initialize a specific field in cpuinfo_detect_icache_policy().
arch/arm64/kernel/cpuinfo.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
index 876055e37352..a0c495a3f4fd 100644
--- a/arch/arm64/kernel/cpuinfo.c
+++ b/arch/arm64/kernel/cpuinfo.c
@@ -34,10 +34,7 @@ DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
static struct cpuinfo_arm64 boot_cpu_data;
static char *icache_policy_str[] = {
- [0 ... ICACHE_POLICY_PIPT] = "RESERVED/UNKNOWN",
- [ICACHE_POLICY_VIPT] = "VIPT",
- [ICACHE_POLICY_PIPT] = "PIPT",
- [ICACHE_POLICY_VPIPT] = "VPIPT",
+ [0 ... ICACHE_POLICY_PIPT] = "RESERVED/UNKNOWN"
};
unsigned long __icache_flags;
@@ -310,13 +307,16 @@ static void cpuinfo_detect_icache_policy(struct cpuinfo_arm64 *info)
switch (l1ip) {
case ICACHE_POLICY_PIPT:
+ icache_policy_str[ICACHE_POLICY_PIPT] = "PIPT";
break;
case ICACHE_POLICY_VPIPT:
+ icache_policy_str[ICACHE_POLICY_VPIPT] = "VPIPT";
set_bit(ICACHEF_VPIPT, &__icache_flags);
break;
default:
/* Fallthrough */
case ICACHE_POLICY_VIPT:
+ icache_policy_str[ICACHE_POLICY_VIPT] = "VIPT";
/* Assume aliasing */
set_bit(ICACHEF_ALIASING, &__icache_flags);
}
--
2.20.1 (Apple Git-117)
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH net-next v2 00/10] net: stmmac: Improvements for -next
From: Jakub Kicinski @ 2019-08-06 19:40 UTC (permalink / raw)
To: Jose Abreu
Cc: Joao Pinto, Alexandre Torgue, netdev, linux-kernel, linux-stm32,
Maxime Coquelin, Giuseppe Cavallaro, David S. Miller,
linux-arm-kernel
In-Reply-To: <cover.1565098881.git.joabreu@synopsys.com>
On Tue, 6 Aug 2019 15:42:41 +0200, Jose Abreu wrote:
> Couple of improvements for -next tree. More info in commit logs.
Code looks good to me now, thanks!
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] drm/amdgpu: fix compile error about readq/writeq on arm ARCH
From: Alex Deucher @ 2019-08-06 19:45 UTC (permalink / raw)
To: Christian Koenig
Cc: linux-arm-kernel, kernel-build-reports, Tao Zhou, amd-gfx list,
Mark Brown, Linux-Next Mailing List, Deucher, Alexander,
Dennis Li, Hawking Zhang
In-Reply-To: <a19ac490-a803-84c0-5598-e78edbb3447b@gmail.com>
On Tue, Aug 6, 2019 at 7:26 AM Christian König
<ckoenig.leichtzumerken@gmail.com> wrote:
>
> Am 06.08.19 um 12:31 schrieb Tao Zhou:
> > readq/writeq can't be found on arm architecture, implement them
> > with 32 bits operations
>
> Mhm, wasn't the whole point about using readq/writeq that we needed
> 64bit atomic operations?
It might be better to use atomic64_read/atomic64_set like we do for doorbells.
Alex
>
> Christian.
>
> >
> > Signed-off-by: Tao Zhou <tao.zhou1@amd.com>
> > ---
> > drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > index f62d4f30e810..aaf7f31cf8df 100644
> > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> > @@ -29,6 +29,7 @@
> > #include <linux/kthread.h>
> > #include <linux/console.h>
> > #include <linux/slab.h>
> > +#include <linux/io-64-nonatomic-lo-hi.h>
> > #include <drm/drmP.h>
> > #include <drm/drm_atomic_helper.h>
> > #include <drm/drm_probe_helper.h>
>
> _______________________________________________
> amd-gfx mailing list
> amd-gfx@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 1/2] dma-mapping: fix page attributes for dma_mmap_*
From: Shawn Anastasio @ 2019-08-06 19:39 UTC (permalink / raw)
To: Christoph Hellwig, iommu
Cc: Gavin Li, linux-kernel, Will Deacon, Michael Ellerman,
linuxppc-dev, Russell King, linux-mips, Paul Burton,
Catalin Marinas, James Hogan, Robin Murphy, linux-arm-kernel
In-Reply-To: <20190805080145.5694-2-hch@lst.de>
On 8/5/19 10:01 AM, Christoph Hellwig wrote:
> diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h
> index 3813211a9aad..9ae5cee543c4 100644
> --- a/include/linux/dma-noncoherent.h
> +++ b/include/linux/dma-noncoherent.h
> @@ -42,13 +42,8 @@ void arch_dma_free(struct device *dev, size_t size, void *cpu_addr,
> dma_addr_t dma_addr, unsigned long attrs);
> long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
> dma_addr_t dma_addr);
> -
> -#ifdef CONFIG_ARCH_HAS_DMA_MMAP_PGPROT
> pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
> unsigned long attrs);
> -#else
> -# define arch_dma_mmap_pgprot(dev, prot, attrs) pgprot_noncached(prot)
> -#endif
Nit, but maybe the prototype should still be ifdef'd here? It at least
could prevent a reader from incorrectly thinking that the function is
always present.
Also, like Will mentioned earlier, the function name isn't entirely
accurate anymore. I second the suggestion of using something like
arch_dma_noncoherent_pgprot(). As for your idea of defining
pgprot_dmacoherent for all architectures as
#ifndef pgprot_dmacoherent
#define pgprot_dmacoherent pgprot_noncached
#endif
I think that the name here is kind of misleading too, since this
definition will only be used when there is no support for proper
DMA coherency.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [v2,2/2] PCI: mediatek: Add controller support for MT7629
From: Bjorn Helgaas @ 2019-08-06 19:50 UTC (permalink / raw)
To: Lorenzo Pieralisi
Cc: Mark Rutland, devicetree, Ryder Lee, Linux PCI, youlin.pei,
Linux Kernel Mailing List, Jianjun Wang, Rob Herring,
linux-mediatek, Matthias Brugger, linux-arm
In-Reply-To: <20190806162432.GA15498@e121166-lin.cambridge.arm.com>
On Tue, Aug 6, 2019 at 11:24 AM Lorenzo Pieralisi
<lorenzo.pieralisi@arm.com> wrote:
>
> [trim the CC list please to keep only required maintainers]
>
> On Mon, Jul 29, 2019 at 03:38:38PM +0800, Jianjun Wang wrote:
> > On Fri, 2019-06-28 at 15:34 +0800, Jianjun Wang wrote:
> > > MT7629 is an ARM platform SoC which has the same PCIe IP with MT7622.
> > >
> > > The HW default value of its Device ID is invalid, fix its Device ID to
> > > match the hardware implementation.
> > >
> > > Acked-by: Ryder Lee <ryder.lee@mediatek.com>
> > > Signed-off-by: Jianjun Wang <jianjun.wang@mediatek.com>
> > > ---
> > > drivers/pci/controller/pcie-mediatek.c | 18 ++++++++++++++++++
> > > include/linux/pci_ids.h | 1 +
> > > 2 files changed, 19 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
> > > index 80601e1b939e..e5e6740b635d 100644
> > > --- a/drivers/pci/controller/pcie-mediatek.c
> > > +++ b/drivers/pci/controller/pcie-mediatek.c
> > > @@ -73,6 +73,7 @@
> > > #define PCIE_MSI_VECTOR 0x0c0
> > >
> > > #define PCIE_CONF_VEND_ID 0x100
> > > +#define PCIE_CONF_DEVICE_ID 0x102
> > > #define PCIE_CONF_CLASS_ID 0x106
> > >
> > > #define PCIE_INT_MASK 0x420
> > > @@ -141,12 +142,16 @@ struct mtk_pcie_port;
> > > /**
> > > * struct mtk_pcie_soc - differentiate between host generations
> > > * @need_fix_class_id: whether this host's class ID needed to be fixed or not
> > > + * @need_fix_device_id: whether this host's Device ID needed to be fixed or not
> > > + * @device_id: Device ID which this host need to be fixed
> > > * @ops: pointer to configuration access functions
> > > * @startup: pointer to controller setting functions
> > > * @setup_irq: pointer to initialize IRQ functions
> > > */
> > > struct mtk_pcie_soc {
> > > bool need_fix_class_id;
> > > + bool need_fix_device_id;
> > > + unsigned int device_id;
> > > struct pci_ops *ops;
> > > int (*startup)(struct mtk_pcie_port *port);
> > > int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
> > > @@ -696,6 +701,9 @@ static int mtk_pcie_startup_port_v2(struct mtk_pcie_port *port)
> > > writew(val, port->base + PCIE_CONF_CLASS_ID);
> > > }
> > >
> > > + if (soc->need_fix_device_id)
> > > + writew(soc->device_id, port->base + PCIE_CONF_DEVICE_ID);
> > > +
> > > /* 100ms timeout value should be enough for Gen1/2 training */
> > > err = readl_poll_timeout(port->base + PCIE_LINK_STATUS_V2, val,
> > > !!(val & PCIE_PORT_LINKUP_V2), 20,
> > > @@ -1216,11 +1224,21 @@ static const struct mtk_pcie_soc mtk_pcie_soc_mt7622 = {
> > > .setup_irq = mtk_pcie_setup_irq,
> > > };
> > >
> > > +static const struct mtk_pcie_soc mtk_pcie_soc_mt7629 = {
> > > + .need_fix_class_id = true,
> > > + .need_fix_device_id = true,
> > > + .device_id = PCI_DEVICE_ID_MEDIATEK_7629,
> > > + .ops = &mtk_pcie_ops_v2,
> > > + .startup = mtk_pcie_startup_port_v2,
> > > + .setup_irq = mtk_pcie_setup_irq,
> > > +};
> > > +
> > > static const struct of_device_id mtk_pcie_ids[] = {
> > > { .compatible = "mediatek,mt2701-pcie", .data = &mtk_pcie_soc_v1 },
> > > { .compatible = "mediatek,mt7623-pcie", .data = &mtk_pcie_soc_v1 },
> > > { .compatible = "mediatek,mt2712-pcie", .data = &mtk_pcie_soc_mt2712 },
> > > { .compatible = "mediatek,mt7622-pcie", .data = &mtk_pcie_soc_mt7622 },
> > > + { .compatible = "mediatek,mt7629-pcie", .data = &mtk_pcie_soc_mt7629 },
> > > {},
> > > };
> > >
> > > diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
> > > index 70e86148cb1e..aa32962759b2 100644
> > > --- a/include/linux/pci_ids.h
> > > +++ b/include/linux/pci_ids.h
> > > @@ -2131,6 +2131,7 @@
> > > #define PCI_VENDOR_ID_MYRICOM 0x14c1
> > >
> > > #define PCI_VENDOR_ID_MEDIATEK 0x14c3
> > > +#define PCI_DEVICE_ID_MEDIATEK_7629 0x7629
> > >
> > > #define PCI_VENDOR_ID_TITAN 0x14D2
> > > #define PCI_DEVICE_ID_TITAN_010L 0x8001
> >
> > Hi Bjorn & Lorenzo,
> >
> > Is this patch ok or is there anything I need to fixed?
>
> The commit log need to be fixed and I will do it, the code if
> Bjorn is OK with it I can merge it.
Sure, I'm fine with this. I don't think there's a need to add
PCI_DEVICE_ID_MEDIATEK_7629, since it's only used in one place, but
I'm fine with the code.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 2/6] thermal: amlogic: Add thermal driver to support G12 SoCs
From: Martin Blumenstingl @ 2019-08-06 19:52 UTC (permalink / raw)
To: guillaume La Roque
Cc: devicetree, linux-pm, khilman, daniel.lezcano, linux-kernel,
linux-amlogic, linux-arm-kernel
In-Reply-To: <14e14cd9-46bd-0d43-654c-6db64397f5c7@baylibre.com>
Hi Guillaume,
On Mon, Aug 5, 2019 at 2:48 PM guillaume La Roque <glaroque@baylibre.com> wrote:
>
> Hi Martin,
>
> again thanks for your review.
you're welcome - thank you for working on the driver :-)
[...]
> > The IP block has more functionality, which may be added to this driver
> > in the future:
> > - reading up to 16 stored temperature samples
>
> it's not working, you can verify it if you check the regmap define in the driver. in fact temp is only write in one register, it's confirmed by amlogic.
I missed that - so please skip this part
[...]
> >> +config AMLOGIC_THERMAL
> > we typically use "MESON" in the Kconfig symbols:
> > $ grep -c AMLOGIC .config
> > 1
> > $ grep -c MESON .config
> > 33
> >
> > I also wonder if we should add G12 or G12A so we don't conflict with
> > upcoming thermal sensors with a different design (assuming that this
> > will be a thing).
> > for example we already have three different USB2 PHY drivers
> >
> > [...]
>
> i check with Neil and for new family it's better to use Amlogic instead of meson.
can you please share the considerations behind this decision?
if new drivers should use AMLOGIC_* Kconfig symbols instead of MESON_*
then we all should know about it
> i don't add G12 because we already know it's same sensors for SM1 SoC family [0].
my idea behind this was to avoid conflicts in the future
in case of the thermal driver we may be fine with using a generic name
assuming that Amlogic will not switch to a new IP block in the next
years
I'm not saying you have to change the name - I'm bringing this up so
you can decide for yourself based on examples from the past
here are a few examples:
- when Kevin upstreamed the MMC driver for GX he decided to use
MMC_MESON_GX for the Kconfig symbol name. it turns out that this is
smart because there are at least two other MMC controller IPs on the
32-bit SoCs. due to him including GX in the name the drivers are easy
to differentiate (MMC_MESON_MX_SDIO and MMC_MESON_MX_SDHC being the
other ones, while the latter is not upstream yet)
- when Carlo upstreamed the eFuse driver he decided to use MESON_EFUSE
for the Kconfig symbol name. I found out much later that the 32-bit
SoCs use a different IP (or at least direct register access instead of
going through Secure Monitor). the driver for the 32-bit SoCs now uses
MESON_MX_EFUSE. if you don't know which driver applies where then it's
easy to mix up MESON_EFUSE and MESON_MX_EFUSE
- when Jerome upstreamed the ALSA driver for AXG (which is also used
on G12A and G12B) he decided to use the SND_MESON_AXG_* prefix for the
Kconfig symbol names. in my opinion this was a good choice because GXM
and everything earlier (including the 32-bit SoCs) use a different
audio IP block. we won't have a Kconfig symbol name clash when a
driver for the "older" SoCs is upstreamed
- (there are more examples, Meson8b USB PHY driver, Meson8b DWMAC
glue, ... - just like there's many examples where the IP block is
mostly compatible with older generations: SAR ADC, RNG, SPI, ...)
I'm not sure what driver naming rules other mainline SoC teams use
to me it seems that the rule for Allwinner driver names is to use the
"code-name of the first SoC the IP block appeared in"
[...]
> >> +static int amlogic_thermal_get_temp(void *data, int *temp)
> >> +{
> >> + unsigned int tvalue;
> >> + struct amlogic_thermal *pdata = data;
> >> +
> >> + if (!data)
> >> + return -EINVAL;
> >> +
> >> + regmap_read(pdata->regmap, TSENSOR_STAT0, &tvalue);
> >> + *temp = code_to_temp(pdata,
> >> + tvalue & TSENSOR_READ_TEMP_MASK);
> > maybe simply move the implementation from code_to_temp here?
>
> for the optional function it could be a problem if i move all in code_to_temp.
>
> i prefer to have a function which are just do the conversion.
I didn't consider this before but you are right
if the other temperature registers (like IRQ thresholds) also use a
"temperature code" then it should be a dedicated function (so it'll be
easier to add more functionality to the driver)
Martin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 05/14] gpio: lpc32xx: allow building on non-lpc32xx targets
From: Sylvain Lemieux @ 2019-08-06 20:02 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andrew Lunn, LINUXWATCHDOG, Linux Kernel Mailing List,
Jason Cooper, David S. Miller, Greg Kroah-Hartman,
Gregory Clement, USB list, Russell King, Vladimir Zapolskiy,
Bartosz Golaszewski, soc, Alan Stern, Guenter Roeck,
open list:GPIO SUBSYSTEM, Networking, Lee Jones, linux-serial,
Linus Walleij, moderated list:ARM PORT, Sebastian Hesselbarth
In-Reply-To: <20190731195713.3150463-6-arnd@arndb.de>
Hi Arnd,
On Wed, Jul 31, 2019 at 4:00 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> The driver uses hardwire MMIO addresses instead of the data
> that is passed in device tree. Change it over to only
> hardcode the register offset values and allow compile-testing.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/gpio/Kconfig | 8 +++++
> drivers/gpio/Makefile | 2 +-
> drivers/gpio/gpio-lpc32xx.c | 63 ++++++++++++++++++++++++-------------
> 3 files changed, 50 insertions(+), 23 deletions(-)
>
[...]
> diff --git a/drivers/gpio/gpio-lpc32xx.c b/drivers/gpio/gpio-lpc32xx.c
> index 24885b3db3d5..548f7cb69386 100644
> --- a/drivers/gpio/gpio-lpc32xx.c
> +++ b/drivers/gpio/gpio-lpc32xx.c
[...]
> @@ -498,6 +509,10 @@ static int lpc32xx_gpio_probe(struct platform_device *pdev)
> {
> int i;
>
> + gpio_reg_base = devm_platform_ioremap_resource(pdev, 0);
> + if (gpio_reg_base)
> + return -ENXIO;
The probe function will always return an error.
Please replace the previous 2 lines with:
if (IS_ERR(gpio_reg_base))
return PTR_ERR(gpio_reg_base);
You can add my acked-by and tested-by in the v2 patch.
Acked-by: Sylvain Lemieux <slemieux.tyco@gmail.com>
Tested-by: Sylvain Lemieux <slemieux.tyco@gmail.com>
> +
> for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) {
> if (pdev->dev.of_node) {
> lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate;
> @@ -527,3 +542,7 @@ static struct platform_driver lpc32xx_gpio_driver = {
> };
>
> module_platform_driver(lpc32xx_gpio_driver);
> +
> +MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
> +MODULE_LICENSE("GPL");
> +MODULE_DESCRIPTION("GPIO driver for LPC32xx SoC");
> --
> 2.20.0
>
Sylvain
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 07/14] net: lpc-enet: move phy setup into platform code
From: Sylvain Lemieux @ 2019-08-06 20:11 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andrew Lunn, LINUXWATCHDOG, Linux Kernel Mailing List,
Jason Cooper, David S. Miller, Greg Kroah-Hartman,
Gregory Clement, USB list, Russell King, Vladimir Zapolskiy,
open list:GPIO SUBSYSTEM, soc, Alan Stern, Guenter Roeck,
linux-serial, Networking, Linus Walleij, moderated list:ARM PORT,
Sebastian Hesselbarth
In-Reply-To: <20190731195713.3150463-8-arnd@arndb.de>
On Wed, Jul 31, 2019 at 4:01 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> Setting the phy mode requires touching a platform specific
> register, which prevents us from building the driver without
> its header files.
>
> Move it into a separate function in arch/arm/mach/lpc32xx
> to hide the core registers from the network driver.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/arm/mach-lpc32xx/common.c | 12 ++++++++++++
> drivers/net/ethernet/nxp/lpc_eth.c | 12 +-----------
> include/linux/soc/nxp/lpc32xx-misc.h | 5 +++++
> 3 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
> index f648324d5fb4..a475339333c1 100644
> --- a/arch/arm/mach-lpc32xx/common.c
> +++ b/arch/arm/mach-lpc32xx/common.c
> @@ -63,6 +63,18 @@ u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr)
> }
> EXPORT_SYMBOL_GPL(lpc32xx_return_iram);
>
> +void lpc32xx_set_phy_interface_mode(phy_interface_t mode)
> +{
> + u32 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
> + tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
> + if (mode == PHY_INTERFACE_MODE_MII)
> + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
> + else
> + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
> + __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
> +}
> +EXPORT_SYMBOL_GPL(lpc32xx_set_phy_interface_mode);
> +
> static struct map_desc lpc32xx_io_desc[] __initdata = {
> {
> .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START),
> diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
> index bcdd0adcfb0c..0893b77c385d 100644
> --- a/drivers/net/ethernet/nxp/lpc_eth.c
> +++ b/drivers/net/ethernet/nxp/lpc_eth.c
> @@ -20,9 +20,6 @@
> #include <linux/spinlock.h>
> #include <linux/soc/nxp/lpc32xx-misc.h>
>
> -#include <mach/hardware.h>
> -#include <mach/platform.h>
> -
> #define MODNAME "lpc-eth"
> #define DRV_VERSION "1.00"
>
> @@ -1237,16 +1234,9 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
> dma_addr_t dma_handle;
> struct resource *res;
> int irq, ret;
> - u32 tmp;
>
> /* Setup network interface for RMII or MII mode */
> - tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
> - tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
> - if (lpc_phy_interface_mode(dev) == PHY_INTERFACE_MODE_MII)
> - tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
> - else
> - tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
> - __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
> + lpc32xx_set_phy_interface_mode(lpc_phy_interface_mode(dev));
>
> /* Get platform resources */
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> diff --git a/include/linux/soc/nxp/lpc32xx-misc.h b/include/linux/soc/nxp/lpc32xx-misc.h
> index f232e1a1bcdc..af4f82f6cf3b 100644
> --- a/include/linux/soc/nxp/lpc32xx-misc.h
> +++ b/include/linux/soc/nxp/lpc32xx-misc.h
> @@ -9,9 +9,11 @@
> #define __SOC_LPC32XX_MISC_H
>
> #include <linux/types.h>
> +#include <linux/phy.h>
>
> #ifdef CONFIG_ARCH_LPC32XX
> extern u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr);
> +extern void lpc32xx_set_phy_interface_mode(phy_interface_t mode);
> #else
> static inline u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr)
> {
> @@ -19,6 +21,9 @@ static inline u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaadd
> *dmaaddr = 0;
> return 0;
> }
> +static inline void lpc32xx_set_phy_interface_mode(phy_interface_t mode)
> +{
> +}
> #endif
>
> #endif /* __SOC_LPC32XX_MISC_H */
> --
> 2.20.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 07/14] net: lpc-enet: move phy setup into platform code
From: Sylvain Lemieux @ 2019-08-06 20:12 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andrew Lunn, LINUXWATCHDOG, Linux Kernel Mailing List,
Jason Cooper, David S. Miller, Greg Kroah-Hartman,
Gregory Clement, USB list, Russell King, Vladimir Zapolskiy,
open list:GPIO SUBSYSTEM, soc, Alan Stern, Guenter Roeck,
linux-serial, Networking, Linus Walleij, moderated list:ARM PORT,
Sebastian Hesselbarth
In-Reply-To: <20190731195713.3150463-8-arnd@arndb.de>
Acked-by: Sylvain Lemieux <slemieux.tyco@gmail.com>
On Wed, Jul 31, 2019 at 4:01 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> Setting the phy mode requires touching a platform specific
> register, which prevents us from building the driver without
> its header files.
>
> Move it into a separate function in arch/arm/mach/lpc32xx
> to hide the core registers from the network driver.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/arm/mach-lpc32xx/common.c | 12 ++++++++++++
> drivers/net/ethernet/nxp/lpc_eth.c | 12 +-----------
> include/linux/soc/nxp/lpc32xx-misc.h | 5 +++++
> 3 files changed, 18 insertions(+), 11 deletions(-)
>
> diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
> index f648324d5fb4..a475339333c1 100644
> --- a/arch/arm/mach-lpc32xx/common.c
> +++ b/arch/arm/mach-lpc32xx/common.c
> @@ -63,6 +63,18 @@ u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr)
> }
> EXPORT_SYMBOL_GPL(lpc32xx_return_iram);
>
> +void lpc32xx_set_phy_interface_mode(phy_interface_t mode)
> +{
> + u32 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
> + tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
> + if (mode == PHY_INTERFACE_MODE_MII)
> + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
> + else
> + tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
> + __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
> +}
> +EXPORT_SYMBOL_GPL(lpc32xx_set_phy_interface_mode);
> +
> static struct map_desc lpc32xx_io_desc[] __initdata = {
> {
> .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START),
> diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
> index bcdd0adcfb0c..0893b77c385d 100644
> --- a/drivers/net/ethernet/nxp/lpc_eth.c
> +++ b/drivers/net/ethernet/nxp/lpc_eth.c
> @@ -20,9 +20,6 @@
> #include <linux/spinlock.h>
> #include <linux/soc/nxp/lpc32xx-misc.h>
>
> -#include <mach/hardware.h>
> -#include <mach/platform.h>
> -
> #define MODNAME "lpc-eth"
> #define DRV_VERSION "1.00"
>
> @@ -1237,16 +1234,9 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
> dma_addr_t dma_handle;
> struct resource *res;
> int irq, ret;
> - u32 tmp;
>
> /* Setup network interface for RMII or MII mode */
> - tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
> - tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
> - if (lpc_phy_interface_mode(dev) == PHY_INTERFACE_MODE_MII)
> - tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
> - else
> - tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
> - __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
> + lpc32xx_set_phy_interface_mode(lpc_phy_interface_mode(dev));
>
> /* Get platform resources */
> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> diff --git a/include/linux/soc/nxp/lpc32xx-misc.h b/include/linux/soc/nxp/lpc32xx-misc.h
> index f232e1a1bcdc..af4f82f6cf3b 100644
> --- a/include/linux/soc/nxp/lpc32xx-misc.h
> +++ b/include/linux/soc/nxp/lpc32xx-misc.h
> @@ -9,9 +9,11 @@
> #define __SOC_LPC32XX_MISC_H
>
> #include <linux/types.h>
> +#include <linux/phy.h>
>
> #ifdef CONFIG_ARCH_LPC32XX
> extern u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr);
> +extern void lpc32xx_set_phy_interface_mode(phy_interface_t mode);
> #else
> static inline u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr)
> {
> @@ -19,6 +21,9 @@ static inline u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaadd
> *dmaaddr = 0;
> return 0;
> }
> +static inline void lpc32xx_set_phy_interface_mode(phy_interface_t mode)
> +{
> +}
> #endif
>
> #endif /* __SOC_LPC32XX_MISC_H */
> --
> 2.20.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 08/14] net: lpc-enet: allow compile testing
From: Sylvain Lemieux @ 2019-08-06 20:13 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andrew Lunn, LINUXWATCHDOG, Linux Kernel Mailing List,
Jason Cooper, David S. Miller, Greg Kroah-Hartman,
Gregory Clement, USB list, Russell King, Vladimir Zapolskiy,
open list:GPIO SUBSYSTEM, soc, Alan Stern, Guenter Roeck,
linux-serial, Networking, Linus Walleij, moderated list:ARM PORT,
Sebastian Hesselbarth
In-Reply-To: <20190731195713.3150463-9-arnd@arndb.de>
Acked-by: Sylvain Lemieux <slemieux.tyco@gmail.com>
On Wed, Jul 31, 2019 at 4:01 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> The lpc-enet driver can now be built on all platforms, so
> allow compile testing as well.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> drivers/net/ethernet/nxp/Kconfig | 2 +-
> drivers/net/ethernet/nxp/lpc_eth.c | 1 +
> 2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/nxp/Kconfig b/drivers/net/ethernet/nxp/Kconfig
> index 261f107e2be0..418afb84c84b 100644
> --- a/drivers/net/ethernet/nxp/Kconfig
> +++ b/drivers/net/ethernet/nxp/Kconfig
> @@ -1,7 +1,7 @@
> # SPDX-License-Identifier: GPL-2.0-only
> config LPC_ENET
> tristate "NXP ethernet MAC on LPC devices"
> - depends on ARCH_LPC32XX
> + depends on ARCH_LPC32XX || COMPILE_TEST
> select PHYLIB
> help
> Say Y or M here if you want to use the NXP ethernet MAC included on
> diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c
> index 0893b77c385d..34fdf2100772 100644
> --- a/drivers/net/ethernet/nxp/lpc_eth.c
> +++ b/drivers/net/ethernet/nxp/lpc_eth.c
> @@ -14,6 +14,7 @@
> #include <linux/crc32.h>
> #include <linux/etherdevice.h>
> #include <linux/module.h>
> +#include <linux/of.h>
> #include <linux/of_net.h>
> #include <linux/phy.h>
> #include <linux/platform_device.h>
> --
> 2.20.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 10/14] ARM: lpc32xx: clean up header files
From: Sylvain Lemieux @ 2019-08-06 20:16 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andrew Lunn, LINUXWATCHDOG, Linux Kernel Mailing List,
Jason Cooper, David S. Miller, Greg Kroah-Hartman,
Gregory Clement, USB list, Russell King, Vladimir Zapolskiy,
open list:GPIO SUBSYSTEM, soc, Alan Stern, Guenter Roeck,
linux-serial, Networking, Linus Walleij, moderated list:ARM PORT,
Sebastian Hesselbarth
In-Reply-To: <20190731195713.3150463-11-arnd@arndb.de>
Acked-by: Sylvain Lemieux <slemieux.tyco@gmail.com>
On Wed, Jul 31, 2019 at 4:03 PM Arnd Bergmann <arnd@arndb.de> wrote:
>
> All device drivers have stopped relying on mach/*.h headers,
> so move the remaining headers into arch/arm/mach-lpc32xx/lpc32xx.h
> to prepare for multiplatform builds.
>
> The mach/entry-macro.S file has been unused for a long time now
> and can simply get removed.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> arch/arm/mach-lpc32xx/common.c | 3 +-
> .../mach-lpc32xx/include/mach/entry-macro.S | 28 -------------------
> arch/arm/mach-lpc32xx/include/mach/hardware.h | 25 -----------------
> .../mach-lpc32xx/include/mach/uncompress.h | 4 +--
> .../{include/mach/platform.h => lpc32xx.h} | 18 ++++++++++--
> arch/arm/mach-lpc32xx/pm.c | 3 +-
> arch/arm/mach-lpc32xx/serial.c | 3 +-
> arch/arm/mach-lpc32xx/suspend.S | 3 +-
> 8 files changed, 21 insertions(+), 66 deletions(-)
> delete mode 100644 arch/arm/mach-lpc32xx/include/mach/entry-macro.S
> delete mode 100644 arch/arm/mach-lpc32xx/include/mach/hardware.h
> rename arch/arm/mach-lpc32xx/{include/mach/platform.h => lpc32xx.h} (98%)
>
> diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
> index a475339333c1..304ea61a0716 100644
> --- a/arch/arm/mach-lpc32xx/common.c
> +++ b/arch/arm/mach-lpc32xx/common.c
> @@ -13,8 +13,7 @@
> #include <asm/mach/map.h>
> #include <asm/system_info.h>
>
> -#include <mach/hardware.h>
> -#include <mach/platform.h>
> +#include "lpc32xx.h"
> #include "common.h"
>
> /*
> diff --git a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S
> deleted file mode 100644
> index eec0f5f7e722..000000000000
> --- a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S
> +++ /dev/null
> @@ -1,28 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-or-later */
> -/*
> - * arch/arm/mach-lpc32xx/include/mach/entry-macro.S
> - *
> - * Author: Kevin Wells <kevin.wells@nxp.com>
> - *
> - * Copyright (C) 2010 NXP Semiconductors
> - */
> -
> -#include <mach/hardware.h>
> -#include <mach/platform.h>
> -
> -#define LPC32XX_INTC_MASKED_STATUS_OFS 0x8
> -
> - .macro get_irqnr_preamble, base, tmp
> - ldr \base, =IO_ADDRESS(LPC32XX_MIC_BASE)
> - .endm
> -
> -/*
> - * Return IRQ number in irqnr. Also return processor Z flag status in CPSR
> - * as set if an interrupt is pending.
> - */
> - .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> - ldr \irqstat, [\base, #LPC32XX_INTC_MASKED_STATUS_OFS]
> - clz \irqnr, \irqstat
> - rsb \irqnr, \irqnr, #31
> - teq \irqstat, #0
> - .endm
> diff --git a/arch/arm/mach-lpc32xx/include/mach/hardware.h b/arch/arm/mach-lpc32xx/include/mach/hardware.h
> deleted file mode 100644
> index 4866f096ffce..000000000000
> --- a/arch/arm/mach-lpc32xx/include/mach/hardware.h
> +++ /dev/null
> @@ -1,25 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0-or-later */
> -/*
> - * arch/arm/mach-lpc32xx/include/mach/hardware.h
> - *
> - * Copyright (c) 2005 MontaVista Software, Inc. <source@mvista.com>
> - */
> -
> -#ifndef __ASM_ARCH_HARDWARE_H
> -#define __ASM_ARCH_HARDWARE_H
> -
> -/*
> - * Start of virtual addresses for IO devices
> - */
> -#define IO_BASE 0xF0000000
> -
> -/*
> - * This macro relies on fact that for all HW i/o addresses bits 20-23 are 0
> - */
> -#define IO_ADDRESS(x) IOMEM(((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\
> - IO_BASE)
> -
> -#define io_p2v(x) ((void __iomem *) (unsigned long) IO_ADDRESS(x))
> -#define io_v2p(x) ((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff))
> -
> -#endif
> diff --git a/arch/arm/mach-lpc32xx/include/mach/uncompress.h b/arch/arm/mach-lpc32xx/include/mach/uncompress.h
> index a568812a0b91..74b7aa0da0e4 100644
> --- a/arch/arm/mach-lpc32xx/include/mach/uncompress.h
> +++ b/arch/arm/mach-lpc32xx/include/mach/uncompress.h
> @@ -12,15 +12,13 @@
>
> #include <linux/io.h>
>
> -#include <mach/hardware.h>
> -#include <mach/platform.h>
> -
> /*
> * Uncompress output is hardcoded to standard UART 5
> */
>
> #define UART_FIFO_CTL_TX_RESET (1 << 2)
> #define UART_STATUS_TX_MT (1 << 6)
> +#define LPC32XX_UART5_BASE 0x40090000
>
> #define _UARTREG(x) (void __iomem *)(LPC32XX_UART5_BASE + (x))
>
> diff --git a/arch/arm/mach-lpc32xx/include/mach/platform.h b/arch/arm/mach-lpc32xx/lpc32xx.h
> similarity index 98%
> rename from arch/arm/mach-lpc32xx/include/mach/platform.h
> rename to arch/arm/mach-lpc32xx/lpc32xx.h
> index 1c53790444fc..5eeb884a1993 100644
> --- a/arch/arm/mach-lpc32xx/include/mach/platform.h
> +++ b/arch/arm/mach-lpc32xx/lpc32xx.h
> @@ -7,8 +7,8 @@
> * Copyright (C) 2010 NXP Semiconductors
> */
>
> -#ifndef __ASM_ARCH_PLATFORM_H
> -#define __ASM_ARCH_PLATFORM_H
> +#ifndef __ARM_LPC32XX_H
> +#define __ARM_LPC32XX_H
>
> #define _SBF(f, v) ((v) << (f))
> #define _BIT(n) _SBF(n, 1)
> @@ -700,4 +700,18 @@
> #define LPC32XX_USB_OTG_DEV_CLOCK_ON _BIT(1)
> #define LPC32XX_USB_OTG_HOST_CLOCK_ON _BIT(0)
>
> +/*
> + * Start of virtual addresses for IO devices
> + */
> +#define IO_BASE 0xF0000000
> +
> +/*
> + * This macro relies on fact that for all HW i/o addresses bits 20-23 are 0
> + */
> +#define IO_ADDRESS(x) IOMEM(((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\
> + IO_BASE)
> +
> +#define io_p2v(x) ((void __iomem *) (unsigned long) IO_ADDRESS(x))
> +#define io_v2p(x) ((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff))
> +
> #endif
> diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c
> index 32bca351a73b..b27fa1b9f56c 100644
> --- a/arch/arm/mach-lpc32xx/pm.c
> +++ b/arch/arm/mach-lpc32xx/pm.c
> @@ -70,8 +70,7 @@
>
> #include <asm/cacheflush.h>
>
> -#include <mach/hardware.h>
> -#include <mach/platform.h>
> +#include "lpc32xx.h"
> #include "common.h"
>
> #define TEMP_IRAM_AREA IO_ADDRESS(LPC32XX_IRAM_BASE)
> diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c
> index cfb35e5691cd..3e765c4bf986 100644
> --- a/arch/arm/mach-lpc32xx/serial.c
> +++ b/arch/arm/mach-lpc32xx/serial.c
> @@ -16,8 +16,7 @@
> #include <linux/clk.h>
> #include <linux/io.h>
>
> -#include <mach/hardware.h>
> -#include <mach/platform.h>
> +#include "lpc32xx.h"
> #include "common.h"
>
> #define LPC32XX_SUART_FIFO_SIZE 64
> diff --git a/arch/arm/mach-lpc32xx/suspend.S b/arch/arm/mach-lpc32xx/suspend.S
> index 374f9f07fe48..3f0a8282ef6f 100644
> --- a/arch/arm/mach-lpc32xx/suspend.S
> +++ b/arch/arm/mach-lpc32xx/suspend.S
> @@ -11,8 +11,7 @@
> */
> #include <linux/linkage.h>
> #include <asm/assembler.h>
> -#include <mach/platform.h>
> -#include <mach/hardware.h>
> +#include "lpc32xx.h"
>
> /* Using named register defines makes the code easier to follow */
> #define WORK1_REG r0
> --
> 2.20.0
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH] arm64: dts: allwinner: a64: Drop PMU node
From: Harald Geyer @ 2019-08-06 20:19 UTC (permalink / raw)
To: Vasily Khoruzhick
Cc: Mark Rutland, devicetree, Jared D . McNeill, Maxime Ripard,
Chen-Yu Tsai, Rob Herring, Robin Murphy, arm-linux
In-Reply-To: <CA+E=qVfh7mirJhRsDTeuAVgG55ia936uFSFVKR0N5Pn4GCF1UA@mail.gmail.com>
Vasily Khoruzhick writes:
> On Tue, Aug 6, 2019 at 7:35 AM Robin Murphy <robin.murphy@arm.com> wrote:
> >
> > On 06/08/2019 15:01, Vasily Khoruzhick wrote:
> > > Looks like PMU in A64 is broken, it generates no interrupts at all and
> > > as result 'perf top' shows no events.
> >
> > Does something like 'perf stat sleep 1' at least count cycles correctly?
> > It could well just be that the interrupt numbers are wrong...
>
> Looks like it does, at least result looks plausible:
I'm using perf stat regularly (cache benchmarks) and it works fine.
Unfortunately I wasn't aware that perf stat is a poor test for
the interrupts part of the node, when I added it. So I'm not too
surprised I got it wrong.
However, it would be unfortunate if the node got removed completely,
because perf stat would not work anymore. Maybe we can only remove
the interrupts or just fix them even if the HW doesn't work?
Harald
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox