* [PATCH v2 1/2] dt-bindings: watchdog: Add ast2600 compatible
From: Joel Stanley @ 2019-08-19 5:17 UTC (permalink / raw)
To: Wim Van Sebroeck, Guenter Roeck, Rob Herring
Cc: devicetree, Ryan Chen, linux-watchdog, linux-aspeed,
Andrew Jeffery, linux-arm-kernel
In-Reply-To: <20190819051738.17370-1-joel@jms.id.au>
This adds a compatible for the ast2600, a new ASPEED SoC.
Signed-off-by: Joel Stanley <joel@jms.id.au>
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
---
v2:
- Add Andrew's r-b
---
Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
index c5077a1f5cb3..d78d4a8fb868 100644
--- a/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
+++ b/Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt
@@ -4,6 +4,7 @@ Required properties:
- compatible: must be one of:
- "aspeed,ast2400-wdt"
- "aspeed,ast2500-wdt"
+ - "aspeed,ast2600-wdt"
- reg: physical base address of the controller and length of memory mapped
region
--
2.23.0.rc1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v2 0/2] watchdog: aspeed: Add support for ast2600
From: Joel Stanley @ 2019-08-19 5:17 UTC (permalink / raw)
To: Wim Van Sebroeck, Guenter Roeck, Rob Herring
Cc: devicetree, Ryan Chen, linux-watchdog, linux-aspeed,
Andrew Jeffery, linux-arm-kernel
Hello,
Here's a small patch series to enable the ast2600 watchdog.
v2 addresses Guenter's review.
Joel Stanley (1):
dt-bindings: watchdog: Add ast2600 compatible
Ryan Chen (1):
watchdog: aspeed: Add support for AST2600
Documentation/devicetree/bindings/watchdog/aspeed-wdt.txt | 1 +
drivers/watchdog/aspeed_wdt.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
--
2.23.0.rc1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: next/master boot: 254 boots: 16 failed, 231 passed with 4 offline, 1 untried/unknown, 2 conflicts (next-20190726)
From: Bjorn Andersson @ 2019-08-19 4:35 UTC (permalink / raw)
To: Mark Brown
Cc: linux-arm-msm, Andy Gross, linux-kernel, linux-arm-kernel,
kernel-build-reports
In-Reply-To: <20190726134843.GC55803@sirena.org.uk>
On Fri 26 Jul 06:48 PDT 2019, Mark Brown wrote:
> On Fri, Jul 26, 2019 at 05:18:01AM -0700, kernelci.org bot wrote:
>
> The past few versions of -next failed to boot on apq8096-db820c:
>
> > defconfig:
> > gcc-8:
> > apq8096-db820c: 1 failed lab
>
> with an RCU stall towards the end of boot:
>
> 00:03:40.521336 [ 18.487538] qcom_q6v5_pas adsp-pil: adsp-pil supply px not found, using dummy regulator
> 00:04:01.523104 [ 39.499613] rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> 00:04:01.533371 [ 39.499657] rcu: 2-...!: (0 ticks this GP) idle=9ca/1/0x4000000000000000 softirq=1450/1450 fqs=50
> 00:04:01.537544 [ 39.504689] (detected by 0, t=5252 jiffies, g=2425, q=619)
> 00:04:01.541727 [ 39.513539] Task dump for CPU 2:
> 00:04:01.547929 [ 39.519096] seq R running task 0 199 198 0x00000000
>
> Full details and logs at:
>
> https://kernelci.org/boot/id/5d3aa7ea59b5142ba868890f/
>
> The last version that worked was from the 15th and there seem to be
> similar issues in mainline since -rc1.
As you might have seen this problem has come and gone on the
apq8096-db820c and I've finally managed to narrow it down a little bit.
The problem first appears on next-20190701, with the introduction of
CONFIG_RANDOMIZE_BASE in the defconfig, but after further efforts I've
concluded that disabling kpti removes or hides the problem.
With kpti=no on the command line I've now successfully booted the db820c
100+ times without problems (a clear improvement from the 75% failure
rate with kpti=yes).
Unfortunately I'm not yet certain why this is causing issues and I'm
also seeing the same rcu stall on SDA845 under certain (erroneous?)
conditions (where I don't expect them).
Regards,
Bjorn
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [V3, 0/2] media: Add support for OV02A10 sensor
From: dongchun.zhu @ 2019-08-19 3:43 UTC (permalink / raw)
To: mchehab, robh+dt, mark.rutland, sakari.ailus, drinkcat, tfiga,
matthias.bgg, bingbu.cao
Cc: devicetree, srv_heupstream, shengnan.wang, sj.huang,
linux-mediatek, dongchun.zhu, louis.kuo, linux-arm-kernel,
linux-media
From: Dongchun Zhu <dongchun.zhu@mediatek.com>
Hello,
This patch adds driver and bindings for Omnivision's OV02A10 2 megapixel CMOS 1/5" sensor,
which has a single MIPI lane interface and output format of 10-bit Raw.
The driver is implemented wth V4L2 framework.
1. Async registered as a V4L2 I2C sub-device.
2. A media entity that can provide several source pads and sink pads to link with other device like Seninf, ISP one after another
to create a default overall camera topology, image frame or meta-data from sensor can flow through particular path to output
preview or capture image or 3A info.
Changes of v3 are mainly addressing comments from Rob, Sakari, Bingbu.
- Fix coding style errors in dt-bindings
- Use macro flag to describle basic line 1224 when updating v-blanking
- Remove unnecessary debug log in driver
Mainly changes of v2 are addressing the comments from Nicolas, Bingbu, Sakari, Rob,
including,
- Put dt binding before driver in series
- Add MAINTAINERS entries
- Squash the MAINTAINERS entry and Kconfig to driver patch
- Add rotation support for driver
- Fix other reviewed issues in v1
Dongchun Zhu (2):
media: dt-bindings: media: i2c: Add bindings for OV02A10
media: i2c: Add Omnivision OV02A10 camera sensor driver
.../devicetree/bindings/media/i2c/ov02a10.txt | 54 ++
MAINTAINERS | 8 +
drivers/media/i2c/Kconfig | 11 +
drivers/media/i2c/Makefile | 1 +
drivers/media/i2c/ov02a10.c | 1018 ++++++++++++++++++++
5 files changed, 1092 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/ov02a10.txt
create mode 100644 drivers/media/i2c/ov02a10.c
--
2.9.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [V3, 2/2] media: i2c: Add Omnivision OV02A10 camera sensor driver
From: dongchun.zhu @ 2019-08-19 3:43 UTC (permalink / raw)
To: mchehab, robh+dt, mark.rutland, sakari.ailus, drinkcat, tfiga,
matthias.bgg, bingbu.cao
Cc: devicetree, srv_heupstream, shengnan.wang, sj.huang,
linux-mediatek, dongchun.zhu, louis.kuo, linux-arm-kernel,
linux-media
In-Reply-To: <20190819034331.13098-1-dongchun.zhu@mediatek.com>
From: Dongchun Zhu <dongchun.zhu@mediatek.com>
This patch adds a V4L2 sub-device driver for OV02A10 image sensor.
The OV02A10 is a 1/5" CMOS sensor from Omnivision,
which supports output format: 10-bit Raw.
The OV02A10 has a single MIPI lane interface and use the I2C bus
for control and the CSI-2 bus for data.
Signed-off-by: Dongchun Zhu <dongchun.zhu@mediatek.com>
---
MAINTAINERS | 1 +
drivers/media/i2c/Kconfig | 11 +
drivers/media/i2c/Makefile | 1 +
drivers/media/i2c/ov02a10.c | 1018 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1031 insertions(+)
create mode 100644 drivers/media/i2c/ov02a10.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 41734fb..4b714a2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11821,6 +11821,7 @@ M: Dongchun Zhu <dongchun.zhu@mediatek.com>
L: linux-media@vger.kernel.org
T: git git://linuxtv.org/media_tree.git
S: Maintained
+F: drivers/media/i2c/ov02a10.c
F: Documentation/devicetree/bindings/media/i2c/ov02a10.txt
OMNIVISION OV2680 SENSOR DRIVER
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 79ce9ec..d063a82 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -617,6 +617,17 @@ config VIDEO_IMX355
To compile this driver as a module, choose M here: the
module will be called imx355.
+config VIDEO_OV02A10
+ tristate "OmniVision OV02A10 sensor support"
+ depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+ depends on MEDIA_CAMERA_SUPPORT
+ help
+ This is a Video4Linux2 sensor driver for the OmniVision
+ OV02A10 camera.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ov02a10.
+
config VIDEO_OV2640
tristate "OmniVision OV2640 sensor support"
depends on VIDEO_V4L2 && I2C
diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
index fd4ea86..f34a7ac 100644
--- a/drivers/media/i2c/Makefile
+++ b/drivers/media/i2c/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_VIDEO_OV5645) += ov5645.o
obj-$(CONFIG_VIDEO_OV5647) += ov5647.o
obj-$(CONFIG_VIDEO_OV5670) += ov5670.o
obj-$(CONFIG_VIDEO_OV5695) += ov5695.o
+obj-$(CONFIG_VIDEO_OV02A10) += ov02a10.o
obj-$(CONFIG_VIDEO_OV6650) += ov6650.o
obj-$(CONFIG_VIDEO_OV7251) += ov7251.o
obj-$(CONFIG_VIDEO_OV7640) += ov7640.o
diff --git a/drivers/media/i2c/ov02a10.c b/drivers/media/i2c/ov02a10.c
new file mode 100644
index 0000000..ff5460a
--- /dev/null
+++ b/drivers/media/i2c/ov02a10.c
@@ -0,0 +1,1018 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <media/media-entity.h>
+#include <media/v4l2-async.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+
+#define CHIP_ID 0x2509
+#define OV02A10_REG_CHIP_ID_H 0x02
+#define OV02A10_REG_CHIP_ID_L 0x03
+#define OV02A10_ID(_msb, _lsb) ((_msb) << 8 | (_lsb))
+
+/* Bit[1] vertical upside down */
+/* Bit[0] horizontal mirror */
+#define REG_MIRROR_FLIP_CONTROL 0x3f
+
+/* Orientation */
+#define REG_CONFIG_MIRROR_FLIP 0x03
+
+#define REG_PAGE_SWITCH 0xfd
+#define REG_GLOBAL_EFFECTIVE 0x01
+#define REG_ENABLE BIT(0)
+
+#define REG_SC_CTRL_MODE 0xac
+#define SC_CTRL_MODE_STANDBY 0x00
+#define SC_CTRL_MODE_STREAMING 0x01
+
+#define OV02A10_REG_EXPOSURE_H 0x03
+#define OV02A10_REG_EXPOSURE_L 0x04
+#define OV02A10_EXPOSURE_MIN 4
+#define OV02A10_EXPOSURE_STEP 1
+
+#define OV02A10_REG_VTS_H 0x05
+#define OV02A10_REG_VTS_L 0x06
+#define OV02A10_VTS_MAX 0x209f
+#define OV02A10_VTS_MIN 0x04cf
+#define OV02A10_BASIC_LINE 1224
+
+#define OV02A10_REG_GAIN 0x24
+#define OV02A10_GAIN_MIN 0x10
+#define OV02A10_GAIN_MAX 0xf8
+#define OV02A10_GAIN_STEP 0x01
+#define OV02A10_GAIN_DEFAULT 0x40
+
+#define REG_NULL 0xff
+
+#define OV02A10_LANES 1
+#define OV02A10_BITS_PER_SAMPLE 10
+
+static const char * const ov02a10_supply_names[] = {
+ "dovdd", /* Digital I/O power */
+ "avdd", /* Analog power */
+ "dvdd", /* Digital core power */
+};
+
+#define OV02A10_NUM_SUPPLIES ARRAY_SIZE(ov02a10_supply_names)
+
+struct regval {
+ u16 addr;
+ u8 val;
+};
+
+struct ov02a10_mode {
+ u32 width;
+ u32 height;
+ u32 exp_def;
+ u32 hts_def;
+ u32 vts_def;
+ const struct regval *reg_list;
+};
+
+struct ov02a10 {
+ struct clk *xvclk;
+ struct gpio_desc *powerdown_gpio;
+ struct gpio_desc *reset_gpio;
+ struct regulator_bulk_data supplies[OV02A10_NUM_SUPPLIES];
+
+ bool streaming;
+ bool upside_down;
+
+ /*
+ * Serialize control access, get/set format, get selection
+ * and start streaming.
+ */
+ struct mutex mutex;
+ struct v4l2_subdev subdev;
+ struct media_pad pad;
+ struct v4l2_ctrl *anal_gain;
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *hblank;
+ struct v4l2_ctrl *vblank;
+ struct v4l2_ctrl *hflip;
+ struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *test_pattern;
+ struct v4l2_mbus_framefmt fmt;
+ struct v4l2_ctrl_handler ctrl_handler;
+
+ const struct ov02a10_mode *cur_mode;
+};
+
+#define to_ov02a10(sd) container_of(sd, struct ov02a10, subdev)
+
+static inline void msleep_range(unsigned int delay_base)
+{
+ usleep_range(delay_base * 1000, delay_base * 1000 + 500);
+}
+
+/* MIPI color bar enable output */
+static const struct regval ov02a10_test_pattern_enable_regs[] = {
+ {0xfd, 0x01},
+ {0x0d, 0x00},
+ {0xb6, 0x01},
+ {0x01, 0x01},
+ {0xfd, 0x01},
+ {0xac, 0x01},
+ {REG_NULL, 0x00}
+};
+
+/* MIPI color bar disable output */
+static const struct regval ov02a10_test_pattern_disable_regs[] = {
+ {0xfd, 0x01},
+ {0x0d, 0x00},
+ {0xb6, 0x00},
+ {0x01, 0x01},
+ {0xfd, 0x01},
+ {0xac, 0x01},
+ {REG_NULL, 0x00}
+};
+
+/*
+ * xvclk 24Mhz
+ * pclk 39Mhz
+ * linelength 934(0x3a6)
+ * framelength 1390(0x56e)
+ * grabwindow_width 1600
+ * grabwindow_height 1200
+ * max_framerate 30fps
+ * mipi_datarate per lane 780Mbps
+ */
+static const struct regval ov02a10_1600x1200_regs[] = {
+ {0xfd, 0x01},
+ {0xac, 0x00},
+ {0xfd, 0x00},
+ {0x2f, 0x29},
+ {0x34, 0x00},
+ {0x35, 0x21},
+ {0x30, 0x15},
+ {0x33, 0x01},
+ {0xfd, 0x01},
+ {0x44, 0x00},
+ {0x2a, 0x4c},
+ {0x2b, 0x1e},
+ {0x2c, 0x60},
+ {0x25, 0x11},
+ {0x03, 0x01},
+ {0x04, 0xae},
+ {0x09, 0x00},
+ {0x0a, 0x02},
+ {0x06, 0xa6},
+ {0x31, 0x00},
+ {0x24, 0x40},
+ {0x01, 0x01},
+ {0xfb, 0x73},
+ {0xfd, 0x01},
+ {0x16, 0x04},
+ {0x1c, 0x09},
+ {0x21, 0x42},
+ {0x12, 0x04},
+ {0x13, 0x10},
+ {0x11, 0x40},
+ {0x33, 0x81},
+ {0xd0, 0x00},
+ {0xd1, 0x01},
+ {0xd2, 0x00},
+ {0x50, 0x10},
+ {0x51, 0x23},
+ {0x52, 0x20},
+ {0x53, 0x10},
+ {0x54, 0x02},
+ {0x55, 0x20},
+ {0x56, 0x02},
+ {0x58, 0x48},
+ {0x5d, 0x15},
+ {0x5e, 0x05},
+ {0x66, 0x66},
+ {0x68, 0x68},
+ {0x6b, 0x00},
+ {0x6c, 0x00},
+ {0x6f, 0x40},
+ {0x70, 0x40},
+ {0x71, 0x0a},
+ {0x72, 0xf0},
+ {0x73, 0x10},
+ {0x75, 0x80},
+ {0x76, 0x10},
+ {0x84, 0x00},
+ {0x85, 0x10},
+ {0x86, 0x10},
+ {0x87, 0x00},
+ {0x8a, 0x22},
+ {0x8b, 0x22},
+ {0x19, 0xf1},
+ {0x29, 0x01},
+ {0xfd, 0x01},
+ {0x9d, 0xd6},
+ {0xa0, 0x29},
+ {0xa1, 0x03},
+ {0xad, 0x62},
+ {0xae, 0x00},
+ {0xaf, 0x85},
+ {0xb1, 0x01},
+ {0x8e, 0x06},
+ {0x8f, 0x40},
+ {0x90, 0x04},
+ {0x91, 0xb0},
+ {0x45, 0x01},
+ {0x46, 0x00},
+ {0x47, 0x6c},
+ {0x48, 0x03},
+ {0x49, 0x8b},
+ {0x4a, 0x00},
+ {0x4b, 0x07},
+ {0x4c, 0x04},
+ {0x4d, 0xb7},
+ {0xf0, 0x40},
+ {0xf1, 0x40},
+ {0xf2, 0x40},
+ {0xf3, 0x40},
+ {0x3f, 0x00},
+ {0xfd, 0x01},
+ {0x05, 0x00},
+ {0x06, 0xa6},
+ {0xfd, 0x01},
+ {REG_NULL, 0x00}
+};
+
+#define OV02A10_LINK_FREQ_390MHZ 390000000
+static const s64 link_freq_menu_items[] = {
+ OV02A10_LINK_FREQ_390MHZ
+};
+
+static const char * const ov02a10_test_pattern_menu[] = {
+ "Disabled",
+ "Color Bar",
+};
+
+static const struct ov02a10_mode supported_modes[] = {
+ {
+ .width = 1600,
+ .height = 1200,
+ .exp_def = 0x01ae,
+ .hts_def = 0x03a6,
+ .vts_def = 0x056e,
+ .reg_list = ov02a10_1600x1200_regs,
+ },
+};
+
+/* Write a register */
+static int ov02a10_write_reg(struct ov02a10 *ov02a10, u8 addr, u8 val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ u8 buf[2] = {addr, val};
+ int ret;
+
+ ret = i2c_master_send(client, buf, 2);
+
+ if (ret != 2) {
+ dev_err(&client->dev, "%s: error: reg=%x, val=%x\n",
+ __func__, addr, val);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int ov02a10_write_array(struct ov02a10 *ov02a10,
+ const struct regval *regs)
+{
+ u32 i;
+ int ret;
+
+ for (i = 0; regs[i].addr != REG_NULL; i++) {
+ ret = ov02a10_write_reg(ov02a10, regs[i].addr, regs[i].val);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Read a register */
+static int ov02a10_read_reg(struct ov02a10 *ov02a10, u8 reg, u8 *val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ u8 data = reg;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = &data,
+ };
+ int ret;
+
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0)
+ goto err_wr;
+
+ msg.flags = I2C_M_RD;
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret < 0)
+ goto err_rd;
+
+ *val = data;
+ return 0;
+
+err_rd:
+ dev_err(&client->dev, "i2c_transfer --I2C_M_RD failed\n");
+err_wr:
+ dev_err(&client->dev, "read error: reg=0x%02x: %d\n", reg, ret);
+ return ret;
+}
+
+static void ov02a10_fill_fmt(const struct ov02a10_mode *mode,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ fmt->width = mode->width;
+ fmt->height = mode->height;
+ fmt->field = V4L2_FIELD_NONE;
+}
+
+static int ov02a10_set_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+ struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format;
+
+ mutex_lock(&ov02a10->mutex);
+
+ if (ov02a10->streaming) {
+ mutex_unlock(&ov02a10->mutex);
+ return -EBUSY;
+ }
+
+ /* Only one sensor mode supported */
+ mbus_fmt->code = ov02a10->fmt.code;
+ ov02a10_fill_fmt(ov02a10->cur_mode, mbus_fmt);
+ ov02a10->fmt = fmt->format;
+
+ mutex_unlock(&ov02a10->mutex);
+
+ return 0;
+}
+
+static int ov02a10_get_fmt(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_format *fmt)
+{
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+ struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format;
+
+ mutex_lock(&ov02a10->mutex);
+
+ fmt->format = ov02a10->fmt;
+ mbus_fmt->code = ov02a10->fmt.code;
+ ov02a10_fill_fmt(ov02a10->cur_mode, mbus_fmt);
+
+ mutex_unlock(&ov02a10->mutex);
+
+ return 0;
+}
+
+static int ov02a10_enum_mbus_code(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_mbus_code_enum *code)
+{
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+
+ if (code->index >= ARRAY_SIZE(supported_modes) || !(code->index))
+ return -EINVAL;
+
+ code->code = ov02a10->fmt.code;
+
+ return 0;
+}
+
+static int ov02a10_enum_frame_sizes(struct v4l2_subdev *sd,
+ struct v4l2_subdev_pad_config *cfg,
+ struct v4l2_subdev_frame_size_enum *fse)
+{
+ if (fse->index >= ARRAY_SIZE(supported_modes) || !(fse->index))
+ return -EINVAL;
+
+ fse->min_width = supported_modes[fse->index].width;
+ fse->max_width = supported_modes[fse->index].width;
+ fse->max_height = supported_modes[fse->index].height;
+ fse->min_height = supported_modes[fse->index].height;
+
+ return 0;
+}
+
+static int __ov02a10_power_on(struct ov02a10 *ov02a10)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ struct device *dev = &client->dev;
+ int ret;
+
+ ret = clk_prepare_enable(ov02a10->xvclk);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable xvclk\n");
+ return ret;
+ }
+
+ /* Note: set 0 is high, set 1 is low */
+ gpiod_set_value_cansleep(ov02a10->reset_gpio, 1);
+ gpiod_set_value_cansleep(ov02a10->powerdown_gpio, 0);
+
+ ret = regulator_bulk_enable(OV02A10_NUM_SUPPLIES, ov02a10->supplies);
+ if (ret < 0) {
+ dev_err(dev, "Failed to enable regulators\n");
+ goto disable_clk;
+ }
+ msleep_range(7);
+
+ gpiod_set_value_cansleep(ov02a10->powerdown_gpio, 1);
+ msleep_range(10);
+
+ gpiod_set_value_cansleep(ov02a10->reset_gpio, 0);
+ msleep_range(10);
+
+ return 0;
+
+disable_clk:
+ clk_disable_unprepare(ov02a10->xvclk);
+
+ return ret;
+}
+
+static void __ov02a10_power_off(struct ov02a10 *ov02a10)
+{
+ clk_disable_unprepare(ov02a10->xvclk);
+ gpiod_set_value_cansleep(ov02a10->reset_gpio, 1);
+ gpiod_set_value_cansleep(ov02a10->powerdown_gpio, 1);
+ regulator_bulk_disable(OV02A10_NUM_SUPPLIES, ov02a10->supplies);
+}
+
+static int __ov02a10_start_stream(struct ov02a10 *ov02a10)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ int ret;
+
+ /* Apply default values of current mode */
+ ret = ov02a10_write_array(ov02a10, ov02a10->cur_mode->reg_list);
+ if (ret)
+ return ret;
+
+ /* Apply customized values from user */
+ ret = __v4l2_ctrl_handler_setup(ov02a10->subdev.ctrl_handler);
+ if (ret)
+ return ret;
+
+ /* Set orientation to 180 degree */
+ if (ov02a10->upside_down) {
+ ret = ov02a10_write_reg(ov02a10, REG_MIRROR_FLIP_CONTROL,
+ REG_CONFIG_MIRROR_FLIP);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to set orientation\n",
+ __func__);
+ return ret;
+ }
+ ret = ov02a10_write_reg(ov02a10, REG_GLOBAL_EFFECTIVE,
+ REG_ENABLE);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* Set stream on register */
+ return ov02a10_write_reg(ov02a10,
+ REG_SC_CTRL_MODE, SC_CTRL_MODE_STREAMING);
+}
+
+static int __ov02a10_stop_stream(struct ov02a10 *ov02a10)
+{
+ return ov02a10_write_reg(ov02a10,
+ REG_SC_CTRL_MODE, SC_CTRL_MODE_STANDBY);
+}
+
+static int ov02a10_entity_init_cfg(struct v4l2_subdev *subdev,
+ struct v4l2_subdev_pad_config *cfg)
+{
+ struct v4l2_subdev_format fmt = { 0 };
+
+ fmt.which = cfg ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
+ fmt.format.width = 1600;
+ fmt.format.height = 1200;
+
+ ov02a10_set_fmt(subdev, cfg, &fmt);
+
+ return 0;
+}
+
+static int ov02a10_s_stream(struct v4l2_subdev *sd, int on)
+{
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ int ret = 0;
+
+ mutex_lock(&ov02a10->mutex);
+
+ if (ov02a10->streaming == on)
+ goto unlock_and_return;
+
+ if (on) {
+ ret = pm_runtime_get_sync(&client->dev);
+ if (ret < 0) {
+ pm_runtime_put_noidle(&client->dev);
+ goto unlock_and_return;
+ }
+
+ ret = __ov02a10_start_stream(ov02a10);
+ if (ret) {
+ __ov02a10_stop_stream(ov02a10);
+ ov02a10->streaming = !on;
+ goto err_rpm_put;
+ }
+ } else {
+ __ov02a10_stop_stream(ov02a10);
+ pm_runtime_put(&client->dev);
+ }
+
+ ov02a10->streaming = on;
+ mutex_unlock(&ov02a10->mutex);
+
+ return ret;
+
+err_rpm_put:
+ pm_runtime_put(&client->dev);
+unlock_and_return:
+ mutex_unlock(&ov02a10->mutex);
+
+ return ret;
+}
+
+static int ov02a10_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+ struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_get_try_format(sd,
+ fh->pad,
+ 0);
+
+ mutex_lock(&ov02a10->mutex);
+ /* Initialize try_fmt */
+ try_fmt->code = ov02a10->fmt.code;
+ ov02a10_fill_fmt(&supported_modes[0], try_fmt);
+
+ mutex_unlock(&ov02a10->mutex);
+
+ return 0;
+}
+
+static int __maybe_unused ov02a10_runtime_resume(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+
+ return __ov02a10_power_on(ov02a10);
+}
+
+static int __maybe_unused ov02a10_runtime_suspend(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+
+ __ov02a10_power_off(ov02a10);
+
+ return 0;
+}
+
+static const struct dev_pm_ops ov02a10_pm_ops = {
+ SET_RUNTIME_PM_OPS(ov02a10_runtime_suspend,
+ ov02a10_runtime_resume, NULL)
+};
+
+static int ov02a10_set_test_pattern(struct ov02a10 *ov02a10, s32 value)
+{
+ if (value)
+ return ov02a10_write_array(ov02a10,
+ ov02a10_test_pattern_enable_regs);
+
+ return ov02a10_write_array(ov02a10,
+ ov02a10_test_pattern_disable_regs);
+}
+
+static int ov02a10_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+ struct ov02a10 *ov02a10 = container_of(ctrl->handler,
+ struct ov02a10, ctrl_handler);
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ s64 max_expo;
+ int ret;
+
+ /* Propagate change of current control to all related controls */
+ if (ctrl->id == V4L2_CID_VBLANK) {
+ /* Update max exposure while meeting expected vblanking */
+ max_expo = ov02a10->cur_mode->height + ctrl->val - 4;
+ __v4l2_ctrl_modify_range(ov02a10->exposure,
+ ov02a10->exposure->minimum, max_expo,
+ ov02a10->exposure->step,
+ ov02a10->exposure->default_value);
+ }
+
+ /* V4L2 controls values will be applied only when power is already up */
+ if (!pm_runtime_get_if_in_use(&client->dev))
+ return 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_EXPOSURE:
+ ret = ov02a10_write_reg(ov02a10, REG_PAGE_SWITCH, REG_ENABLE);
+ if (ret < 0)
+ return ret;
+ ret = ov02a10_write_reg(ov02a10, OV02A10_REG_EXPOSURE_H,
+ ((ctrl->val >> 8) & 0xFF));
+ if (!ret) {
+ ret = ov02a10_write_reg(ov02a10, OV02A10_REG_EXPOSURE_L,
+ (ctrl->val & 0xFF));
+ if (ret < 0)
+ return ret;
+ }
+ ret = ov02a10_write_reg(ov02a10, REG_GLOBAL_EFFECTIVE,
+ REG_ENABLE);
+ if (ret < 0)
+ return ret;
+ break;
+ case V4L2_CID_ANALOGUE_GAIN:
+ ret = ov02a10_write_reg(ov02a10, REG_PAGE_SWITCH, REG_ENABLE);
+ if (ret < 0)
+ return ret;
+ ret = ov02a10_write_reg(ov02a10, OV02A10_REG_GAIN,
+ (ctrl->val & 0xFF));
+ if (ret < 0)
+ return ret;
+ ret = ov02a10_write_reg(ov02a10, REG_GLOBAL_EFFECTIVE,
+ REG_ENABLE);
+ if (ret < 0)
+ return ret;
+ break;
+ case V4L2_CID_VBLANK:
+ ret = ov02a10_write_reg(ov02a10, REG_PAGE_SWITCH, REG_ENABLE);
+ if (ret < 0)
+ return ret;
+ ret = ov02a10_write_reg(ov02a10, OV02A10_REG_VTS_H,
+ (((ctrl->val +
+ ov02a10->cur_mode->height -
+ OV02A10_BASIC_LINE) >> 8)
+ & 0xFF));
+ if (!ret) {
+ ret = ov02a10_write_reg(ov02a10, OV02A10_REG_VTS_L,
+ ((ctrl->val +
+ ov02a10->cur_mode->height -
+ OV02A10_BASIC_LINE) & 0xFF));
+ if (ret < 0)
+ return ret;
+ }
+ ret = ov02a10_write_reg(ov02a10, REG_GLOBAL_EFFECTIVE,
+ REG_ENABLE);
+ if (ret < 0)
+ return ret;
+ break;
+ case V4L2_CID_TEST_PATTERN:
+ ret = ov02a10_set_test_pattern(ov02a10, ctrl->val);
+ if (ret < 0)
+ return ret;
+ break;
+ default:
+ dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
+ __func__, ctrl->id, ctrl->val);
+ ret = -EINVAL;
+ break;
+ };
+
+ pm_runtime_put(&client->dev);
+
+ return ret;
+}
+
+static const struct v4l2_subdev_video_ops ov02a10_video_ops = {
+ .s_stream = ov02a10_s_stream,
+};
+
+static const struct v4l2_subdev_pad_ops ov02a10_pad_ops = {
+ .init_cfg = ov02a10_entity_init_cfg,
+ .enum_mbus_code = ov02a10_enum_mbus_code,
+ .enum_frame_size = ov02a10_enum_frame_sizes,
+ .get_fmt = ov02a10_get_fmt,
+ .set_fmt = ov02a10_set_fmt,
+};
+
+static const struct v4l2_subdev_ops ov02a10_subdev_ops = {
+ .video = &ov02a10_video_ops,
+ .pad = &ov02a10_pad_ops,
+};
+
+static const struct media_entity_operations ov02a10_subdev_entity_ops = {
+ .link_validate = v4l2_subdev_link_validate,
+};
+
+static const struct v4l2_subdev_internal_ops ov02a10_internal_ops = {
+ .open = ov02a10_open,
+};
+
+static const struct v4l2_ctrl_ops ov02a10_ctrl_ops = {
+ .s_ctrl = ov02a10_set_ctrl,
+};
+
+static int ov02a10_initialize_controls(struct ov02a10 *ov02a10)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ const struct ov02a10_mode *mode;
+ struct v4l2_ctrl_handler *handler;
+ struct v4l2_ctrl *ctrl;
+ u64 exposure_max;
+ u32 pixel_rate, h_blank;
+ int ret;
+
+ handler = &ov02a10->ctrl_handler;
+ mode = ov02a10->cur_mode;
+ ret = v4l2_ctrl_handler_init(handler, 10);
+ if (ret)
+ return ret;
+ handler->lock = &ov02a10->mutex;
+
+ ctrl = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ,
+ 0, 0, link_freq_menu_items);
+ if (ctrl)
+ ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ pixel_rate = (link_freq_menu_items[0] * 2 * OV02A10_LANES) /
+ OV02A10_BITS_PER_SAMPLE;
+ v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE,
+ 0, pixel_rate, 1, pixel_rate);
+
+ h_blank = mode->hts_def - mode->width;
+ ov02a10->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
+ h_blank, h_blank, 1, h_blank);
+ if (ov02a10->hblank)
+ ov02a10->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ ov02a10->vblank = v4l2_ctrl_new_std(handler, &ov02a10_ctrl_ops,
+ V4L2_CID_VBLANK, mode->vts_def -
+ mode->height,
+ OV02A10_VTS_MAX - mode->height, 1,
+ mode->vts_def - mode->height);
+
+ exposure_max = mode->vts_def - 4;
+ ov02a10->exposure = v4l2_ctrl_new_std(handler, &ov02a10_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ OV02A10_EXPOSURE_MIN,
+ exposure_max,
+ OV02A10_EXPOSURE_STEP,
+ mode->exp_def);
+
+ ov02a10->anal_gain = v4l2_ctrl_new_std(handler, &ov02a10_ctrl_ops,
+ V4L2_CID_ANALOGUE_GAIN,
+ OV02A10_GAIN_MIN,
+ OV02A10_GAIN_MAX,
+ OV02A10_GAIN_STEP,
+ OV02A10_GAIN_DEFAULT);
+
+ ov02a10->test_pattern =
+ v4l2_ctrl_new_std_menu_items(handler,
+ &ov02a10_ctrl_ops,
+ V4L2_CID_TEST_PATTERN,
+ ARRAY_SIZE(ov02a10_test_pattern_menu) -
+ 1, 0, 0, ov02a10_test_pattern_menu);
+
+ if (handler->error) {
+ ret = handler->error;
+ dev_err(&client->dev,
+ "Failed to init controls(%d)\n", ret);
+ goto err_free_handler;
+ }
+
+ ov02a10->subdev.ctrl_handler = handler;
+
+ return 0;
+
+err_free_handler:
+ v4l2_ctrl_handler_free(handler);
+
+ return ret;
+}
+
+static int ov02a10_check_sensor_id(struct ov02a10 *ov02a10)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ u16 id;
+ u8 pid = 0;
+ u8 ver = 0;
+ int ret;
+
+ /* Check sensor revision */
+ ret = ov02a10_read_reg(ov02a10, OV02A10_REG_CHIP_ID_H, &pid);
+ if (ret)
+ return ret;
+
+ ret = ov02a10_read_reg(ov02a10, OV02A10_REG_CHIP_ID_L, &ver);
+ if (ret)
+ return ret;
+
+ id = OV02A10_ID(pid, ver);
+ if (id != CHIP_ID) {
+ dev_err(&client->dev, "Unexpected sensor id(%04x)\n", id);
+ return ret;
+ }
+
+ dev_info(&client->dev, "Detected OV%04X sensor\n", id);
+
+ return 0;
+}
+
+static int ov02a10_configure_regulators(struct ov02a10 *ov02a10)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&ov02a10->subdev);
+ unsigned int i;
+
+ for (i = 0; i < OV02A10_NUM_SUPPLIES; i++)
+ ov02a10->supplies[i].supply = ov02a10_supply_names[i];
+
+ return devm_regulator_bulk_get(&client->dev,
+ OV02A10_NUM_SUPPLIES,
+ ov02a10->supplies);
+}
+
+static int ov02a10_probe(struct i2c_client *client)
+{
+ struct device *dev = &client->dev;
+ struct ov02a10 *ov02a10;
+ u32 rotation;
+ u32 xclk_freq;
+ int ret;
+
+ ov02a10 = devm_kzalloc(dev, sizeof(*ov02a10), GFP_KERNEL);
+ if (!ov02a10)
+ return -ENOMEM;
+
+ v4l2_i2c_subdev_init(&ov02a10->subdev, client, &ov02a10_subdev_ops);
+ ov02a10->fmt.code = MEDIA_BUS_FMT_SBGGR10_1X10;
+
+ /* Optional indication of physical rotation of sensor */
+ ret = fwnode_property_read_u32(dev_fwnode(dev), "rotation",
+ &rotation);
+ if (!ret) {
+ switch (rotation) {
+ case 180:
+ ov02a10->upside_down = true;
+ ov02a10->fmt.code = MEDIA_BUS_FMT_SRGGB10_1X10;
+ break;
+ case 0:
+ break;
+ default:
+ dev_warn(dev, "%u degrees rotation is not supported, ignoring...\n",
+ rotation);
+ }
+ }
+
+ /* Get system clock (xvclk) */
+ ov02a10->xvclk = devm_clk_get(dev, "xvclk");
+ if (IS_ERR(ov02a10->xvclk)) {
+ dev_err(dev, "Failed to get xvclk\n");
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32(dev->of_node, "clock-frequency", &xclk_freq);
+ if (ret) {
+ dev_err(dev, "Failed to get xclk frequency\n");
+ return ret;
+ }
+
+ /* External clock must be 24MHz, allow 1% tolerance */
+ if (xclk_freq < 23760000 || xclk_freq > 24240000) {
+ dev_err(dev, "external clock frequency %u is not supported\n",
+ xclk_freq);
+ return -EINVAL;
+ }
+ dev_dbg(dev, "external clock frequency %u\n", xclk_freq);
+
+ ret = clk_set_rate(ov02a10->xvclk, xclk_freq);
+ if (ret) {
+ dev_err(dev, "Failed to set xvclk frequency (24MHz)\n");
+ return ret;
+ }
+
+ ov02a10->powerdown_gpio = devm_gpiod_get(dev, "powerdown",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(ov02a10->powerdown_gpio)) {
+ dev_err(dev, "Failed to get powerdown-gpios\n");
+ return -EINVAL;
+ }
+
+ ov02a10->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
+ if (IS_ERR(ov02a10->reset_gpio)) {
+ dev_err(dev, "Failed to get reset-gpios\n");
+ return -EINVAL;
+ }
+
+ ret = ov02a10_configure_regulators(ov02a10);
+ if (ret) {
+ dev_err(dev, "Failed to get power regulators\n");
+ return ret;
+ }
+
+ mutex_init(&ov02a10->mutex);
+ ov02a10->cur_mode = &supported_modes[0];
+ ret = ov02a10_initialize_controls(ov02a10);
+ if (ret) {
+ dev_err(dev, "Failed to initialize controls\n");
+ goto err_destroy_mutex;
+ }
+
+ ret = __ov02a10_power_on(ov02a10);
+ if (ret)
+ goto err_free_handler;
+
+ ret = ov02a10_check_sensor_id(ov02a10);
+ if (ret)
+ goto err_power_off;
+
+ ov02a10->subdev.internal_ops = &ov02a10_internal_ops;
+ ov02a10->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ ov02a10->subdev.entity.ops = &ov02a10_subdev_entity_ops;
+ ov02a10->subdev.entity.function = MEDIA_ENT_F_CAM_SENSOR;
+ ov02a10->pad.flags = MEDIA_PAD_FL_SOURCE;
+ ret = media_entity_pads_init(&ov02a10->subdev.entity, 1, &ov02a10->pad);
+ if (ret < 0) {
+ dev_err(dev, "failed to init entity pads: %d", ret);
+ goto err_power_off;
+ }
+
+ ret = v4l2_async_register_subdev(&ov02a10->subdev);
+ if (ret) {
+ dev_err(dev, "failed to register V4L2 subdev: %d",
+ ret);
+ goto err_clean_entity;
+ }
+
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+ pm_runtime_idle(dev);
+
+ dev_info(dev, "ov02a10 probe --\n");
+ return 0;
+
+err_clean_entity:
+ media_entity_cleanup(&ov02a10->subdev.entity);
+err_power_off:
+ __ov02a10_power_off(ov02a10);
+err_free_handler:
+ v4l2_ctrl_handler_free(ov02a10->subdev.ctrl_handler);
+err_destroy_mutex:
+ mutex_destroy(&ov02a10->mutex);
+
+ return ret;
+}
+
+static int ov02a10_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ov02a10 *ov02a10 = to_ov02a10(sd);
+
+ v4l2_async_unregister_subdev(sd);
+ media_entity_cleanup(&sd->entity);
+ v4l2_ctrl_handler_free(sd->ctrl_handler);
+ pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev))
+ __ov02a10_power_off(ov02a10);
+ pm_runtime_set_suspended(&client->dev);
+ mutex_destroy(&ov02a10->mutex);
+
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_OF)
+static const struct of_device_id ov02a10_of_match[] = {
+ { .compatible = "ovti,ov02a10" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, ov02a10_of_match);
+#endif
+
+static struct i2c_driver ov02a10_i2c_driver = {
+ .driver = {
+ .name = "ov02a10",
+ .pm = &ov02a10_pm_ops,
+ .of_match_table = ov02a10_of_match,
+ },
+ .probe_new = &ov02a10_probe,
+ .remove = &ov02a10_remove,
+};
+
+module_i2c_driver(ov02a10_i2c_driver);
+
+MODULE_AUTHOR("Dongchun Zhu <dongchun.zhu@mediatek.com>");
+MODULE_DESCRIPTION("OmniVision OV02A10 sensor driver");
+MODULE_LICENSE("GPL v2");
+
--
2.9.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [V3, 1/2] media: dt-bindings: media: i2c: Add bindings for OV02A10
From: dongchun.zhu @ 2019-08-19 3:43 UTC (permalink / raw)
To: mchehab, robh+dt, mark.rutland, sakari.ailus, drinkcat, tfiga,
matthias.bgg, bingbu.cao
Cc: devicetree, srv_heupstream, shengnan.wang, sj.huang,
linux-mediatek, dongchun.zhu, louis.kuo, linux-arm-kernel,
linux-media
In-Reply-To: <20190819034331.13098-1-dongchun.zhu@mediatek.com>
From: Dongchun Zhu <dongchun.zhu@mediatek.com>
Add device tree binding documentation for the OV02A10 camera sensor.
Signed-off-by: Dongchun Zhu <dongchun.zhu@mediatek.com>
---
.../devicetree/bindings/media/i2c/ov02a10.txt | 54 ++++++++++++++++++++++
MAINTAINERS | 7 +++
2 files changed, 61 insertions(+)
create mode 100644 Documentation/devicetree/bindings/media/i2c/ov02a10.txt
diff --git a/Documentation/devicetree/bindings/media/i2c/ov02a10.txt b/Documentation/devicetree/bindings/media/i2c/ov02a10.txt
new file mode 100644
index 0000000..4a83a38
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/i2c/ov02a10.txt
@@ -0,0 +1,54 @@
+* Omnivision OV02A10 MIPI CSI-2 sensor
+
+Required Properties:
+- compatible: shall be "ovti,ov02a10"
+- clocks: reference to the xvclk input clock
+- clock-names: shall be "xvclk"
+- avdd-supply: Analog voltage supply, 2.8 volts
+- dovdd-supply: Digital I/O voltage supply, 1.8 volts
+- dvdd-supply: Digital core voltage supply, 1.8 volts
+- reset-gpios: reference to the GPIO connected to the reset pin, if any.
+ This is an active high signal to the OV02A10.
+- powerdown-gpios: reference to the GPIO connected to the powerdown pin,
+ if any. This is an active low signal to the OV02A10.
+
+Optional Properties:
+- rotation: as defined in
+ Documentation/devicetree/bindings/media/video-interfaces.txt,
+ valid values are 0 (sensor mounted upright) and 180 (sensor
+ mounted upside down).
+
+The device node shall contain one 'port' child node with an
+'endpoint' subnode for its digital output video port,
+in accordance with the video interface bindings defined in
+Documentation/devicetree/bindings/media/video-interfaces.txt.
+The endpoint optional property 'data-lanes' shall be "<1>".
+
+Example:
+&i2c4 {
+ ov02a10: camera-sensor@3d {
+ compatible = "ovti,ov02a10";
+ reg = <0x3d>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&camera_pins_cam1_mclk_on>;
+
+ clocks = <&topckgen CLK_TOP_MUX_CAMTG2>,
+ <&topckgen CLK_TOP_UNIVP_192M_D8>;
+ clock-names = "xvclk", "freq_mux";
+
+ avdd-supply = <&mt6358_vcama1_reg>;
+ dvdd-supply = <&mt6358_vcn18_reg>;
+ dovdd-supply = <&mt6358_vcamio_reg>;
+ reset-gpios = <&pio 109 1>;
+ powerdown-gpios = <&pio 107 1>;
+ rotation = <180>;
+
+ port {
+ /* MIPI CSI-2 bus endpoint */
+ ov02a10_core: endpoint {
+ remote-endpoint = <&ov02a10_0>;
+ data-lanes = <1>;
+ };
+ };
+ };
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 783569e..41734fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11816,6 +11816,13 @@ T: git git://linuxtv.org/media_tree.git
S: Maintained
F: drivers/media/i2c/ov13858.c
+OMNIVISION OV02A10 SENSOR DRIVER
+M: Dongchun Zhu <dongchun.zhu@mediatek.com>
+L: linux-media@vger.kernel.org
+T: git git://linuxtv.org/media_tree.git
+S: Maintained
+F: Documentation/devicetree/bindings/media/i2c/ov02a10.txt
+
OMNIVISION OV2680 SENSOR DRIVER
M: Rui Miguel Silva <rmfrfs@gmail.com>
L: linux-media@vger.kernel.org
--
2.9.2
_______________________________________________
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 v12 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function
From: CK Hu @ 2019-08-19 3:13 UTC (permalink / raw)
To: Bibby Hsieh
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, Jassi Brar, linux-kernel,
Daniel Kurtz, Dennis-YC Hsieh, YT Shen, Rob Herring,
linux-mediatek, Houlong Wei, Sascha Hauer, Matthias Brugger,
Jiaguang Zhang, linux-arm-kernel, ginny.chen
In-Reply-To: <20190819025359.11381-12-bibby.hsieh@mediatek.com>
Hi, Bibby:
On Mon, 2019-08-19 at 10:53 +0800, Bibby Hsieh wrote:
> GCE cannot know the register base address, this function
> can help cmdq client to get the cmdq_client_reg structure.
Reviewed-by: CK Hu <ck.hu@mediatek.com>
>
> Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
> ---
> drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
> include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
> 2 files changed, 50 insertions(+)
>
> diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
> index 340a92a254e5..1bed07362b7a 100644
> --- a/drivers/soc/mediatek/mtk-cmdq-helper.c
> +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
> @@ -27,6 +27,35 @@ struct cmdq_instruction {
> u8 op;
> };
>
> +int cmdq_dev_get_client_reg(struct device *dev,
> + struct cmdq_client_reg *client_reg, int idx)
> +{
> + struct of_phandle_args spec;
> + int err;
> +
> + if (!client_reg)
> + return -ENOENT;
> +
> + err = of_parse_phandle_with_fixed_args(dev->of_node,
> + "mediatek,gce-client-reg",
> + 3, idx, &spec);
> + if (err < 0) {
> + dev_err(dev,
> + "error %d can't parse gce-client-reg property (%d)",
> + err, idx);
> +
> + return err;
> + }
> +
> + client_reg->subsys = (u8)spec.args[0];
> + client_reg->offset = (u16)spec.args[1];
> + client_reg->size = (u16)spec.args[2];
> + of_node_put(spec.np);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(cmdq_dev_get_client_reg);
> +
> static void cmdq_client_timeout(struct timer_list *t)
> {
> struct cmdq_client *client = from_timer(client, t, timer);
> diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
> index a345870a6d10..6215d4fc4ba3 100644
> --- a/include/linux/soc/mediatek/mtk-cmdq.h
> +++ b/include/linux/soc/mediatek/mtk-cmdq.h
> @@ -15,6 +15,12 @@
>
> struct cmdq_pkt;
>
> +struct cmdq_client_reg {
> + u8 subsys;
> + u16 offset;
> + u16 size;
> +};
> +
> struct cmdq_client {
> spinlock_t lock;
> u32 pkt_cnt;
> @@ -24,6 +30,21 @@ struct cmdq_client {
> u32 timeout_ms; /* in unit of microsecond */
> };
>
> +/**
> + * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
> + * node of CMDQ client
> + * @dev: device of CMDQ mailbox clienti
> + * @client_reg: CMDQ client reg pointer
> + * @idx: the index of desired reg
> + *
> + * Return: 0 for success; else the error code is returned
> + *
> + * Help CMDQ client pasing the cmdq client reg
> + * from the device node of CMDQ client.
> + */
> +int cmdq_dev_get_client_reg(struct device *dev,
> + struct cmdq_client_reg *client_reg, int idx);
> +
> /**
> * cmdq_mbox_create() - create CMDQ mailbox client and channel
> * @dev: device of CMDQ mailbox client
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v12 11/12] soc: mediatek: cmdq: add cmdq_dev_get_client_reg function
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
GCE cannot know the register base address, this function
can help cmdq client to get the cmdq_client_reg structure.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 29 ++++++++++++++++++++++++++
include/linux/soc/mediatek/mtk-cmdq.h | 21 +++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 340a92a254e5..1bed07362b7a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -27,6 +27,35 @@ struct cmdq_instruction {
u8 op;
};
+int cmdq_dev_get_client_reg(struct device *dev,
+ struct cmdq_client_reg *client_reg, int idx)
+{
+ struct of_phandle_args spec;
+ int err;
+
+ if (!client_reg)
+ return -ENOENT;
+
+ err = of_parse_phandle_with_fixed_args(dev->of_node,
+ "mediatek,gce-client-reg",
+ 3, idx, &spec);
+ if (err < 0) {
+ dev_err(dev,
+ "error %d can't parse gce-client-reg property (%d)",
+ err, idx);
+
+ return err;
+ }
+
+ client_reg->subsys = (u8)spec.args[0];
+ client_reg->offset = (u16)spec.args[1];
+ client_reg->size = (u16)spec.args[2];
+ of_node_put(spec.np);
+
+ return 0;
+}
+EXPORT_SYMBOL(cmdq_dev_get_client_reg);
+
static void cmdq_client_timeout(struct timer_list *t)
{
struct cmdq_client *client = from_timer(client, t, timer);
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index a345870a6d10..6215d4fc4ba3 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -15,6 +15,12 @@
struct cmdq_pkt;
+struct cmdq_client_reg {
+ u8 subsys;
+ u16 offset;
+ u16 size;
+};
+
struct cmdq_client {
spinlock_t lock;
u32 pkt_cnt;
@@ -24,6 +30,21 @@ struct cmdq_client {
u32 timeout_ms; /* in unit of microsecond */
};
+/**
+ * cmdq_dev_get_client_reg() - parse cmdq client reg from the device
+ * node of CMDQ client
+ * @dev: device of CMDQ mailbox clienti
+ * @client_reg: CMDQ client reg pointer
+ * @idx: the index of desired reg
+ *
+ * Return: 0 for success; else the error code is returned
+ *
+ * Help CMDQ client pasing the cmdq client reg
+ * from the device node of CMDQ client.
+ */
+int cmdq_dev_get_client_reg(struct device *dev,
+ struct cmdq_client_reg *client_reg, int idx);
+
/**
* cmdq_mbox_create() - create CMDQ mailbox client and channel
* @dev: device of CMDQ mailbox client
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 06/12] soc: mediatek: cmdq: clear the event in cmdq initial flow
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
GCE hardware stored event information in own internal sysram,
if the initial value in those sysram is not zero value
it will cause a situation that gce can wait the event immediately
after client ask gce to wait event but not really trigger the
corresponding hardware.
In order to make sure that the wait event function is
exactly correct, we need to clear the sysram value in
cmdq initial flow.
Fixes: 623a6143a845 ("mailbox: mediatek: Add Mediatek CMDQ driver")
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/mailbox/mtk-cmdq-mailbox.c | 5 +++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 2 ++
include/linux/soc/mediatek/mtk-cmdq.h | 3 ---
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 69daaadc3a5f..9a6ce9f5a7db 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -21,6 +21,7 @@
#define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE)
#define CMDQ_CURR_IRQ_STATUS 0x10
+#define CMDQ_SYNC_TOKEN_UPDATE 0x68
#define CMDQ_THR_SLOT_CYCLES 0x30
#define CMDQ_THR_BASE 0x100
#define CMDQ_THR_SIZE 0x80
@@ -104,8 +105,12 @@ static void cmdq_thread_resume(struct cmdq_thread *thread)
static void cmdq_init(struct cmdq *cmdq)
{
+ int i;
+
WARN_ON(clk_enable(cmdq->clock) < 0);
writel(CMDQ_THR_ACTIVE_SLOT_CYCLES, cmdq->base + CMDQ_THR_SLOT_CYCLES);
+ for (i = 0; i <= CMDQ_MAX_EVENT; i++)
+ writel(i, cmdq->base + CMDQ_SYNC_TOKEN_UPDATE);
clk_disable(cmdq->clock);
}
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index ccb73422c2fa..911475da7a53 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -19,6 +19,8 @@
#define CMDQ_WFE_UPDATE BIT(31)
#define CMDQ_WFE_WAIT BIT(15)
#define CMDQ_WFE_WAIT_VALUE 0x1
+/** cmdq event maximum */
+#define CMDQ_MAX_EVENT 0x3ff
/*
* CMDQ_CODE_MASK:
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 54ade13a9b15..4e8899972db4 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -13,9 +13,6 @@
#define CMDQ_NO_TIMEOUT 0xffffffffu
-/** cmdq event maximum */
-#define CMDQ_MAX_EVENT 0x3ff
-
struct cmdq_pkt;
struct cmdq_client {
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 09/12] soc: mediatek: cmdq: define the instruction struct
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
Define an instruction structure for gce driver to append command.
This structure can make the client's code more readability.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 105 +++++++++++++++--------
include/linux/mailbox/mtk-cmdq-mailbox.h | 2 +
2 files changed, 73 insertions(+), 34 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 7aa0517ff2f3..e1e41914ed7a 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -9,12 +9,24 @@
#include <linux/mailbox_controller.h>
#include <linux/soc/mediatek/mtk-cmdq.h>
-#define CMDQ_ARG_A_WRITE_MASK 0xffff
#define CMDQ_WRITE_ENABLE_MASK BIT(0)
#define CMDQ_EOC_IRQ_EN BIT(0)
#define CMDQ_EOC_CMD ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
<< 32 | CMDQ_EOC_IRQ_EN)
+struct cmdq_instruction {
+ union {
+ u32 value;
+ u32 mask;
+ };
+ union {
+ u16 offset;
+ u16 event;
+ };
+ u8 subsys;
+ u8 op;
+};
+
static void cmdq_client_timeout(struct timer_list *t)
{
struct cmdq_client *client = from_timer(client, t, timer);
@@ -110,10 +122,8 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt)
}
EXPORT_SYMBOL(cmdq_pkt_destroy);
-static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
- u32 arg_a, u32 arg_b)
+static struct cmdq_instruction *cmdq_pkt_append_command(struct cmdq_pkt *pkt)
{
- u64 *cmd_ptr;
if (unlikely(pkt->cmd_buf_size + CMDQ_INST_SIZE > pkt->buf_size)) {
/*
@@ -127,81 +137,108 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
pkt->cmd_buf_size += CMDQ_INST_SIZE;
WARN_ONCE(1, "%s: buffer size %u is too small !\n",
__func__, (u32)pkt->buf_size);
- return -ENOMEM;
+ return NULL;
}
- cmd_ptr = pkt->va_base + pkt->cmd_buf_size;
- (*cmd_ptr) = (u64)((code << CMDQ_OP_CODE_SHIFT) | arg_a) << 32 | arg_b;
+
pkt->cmd_buf_size += CMDQ_INST_SIZE;
- return 0;
+ return pkt->va_base + pkt->cmd_buf_size - CMDQ_INST_SIZE;
}
int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
{
- u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
- (subsys << CMDQ_SUBSYS_SHIFT);
+ struct cmdq_instruction *inst;
+
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_WRITE;
+ inst->value = value;
+ inst->offset = offset;
+ inst->subsys = subsys;
- return cmdq_pkt_append_command(pkt, CMDQ_CODE_WRITE, arg_a, value);
+ return 0;
}
EXPORT_SYMBOL(cmdq_pkt_write);
int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
u16 offset, u32 value, u32 mask)
{
- u32 offset_mask = offset;
- int err = 0;
+ struct cmdq_instruction *inst;
+ u16 offset_mask = offset;
if (mask != 0xffffffff) {
- err = cmdq_pkt_append_command(pkt, CMDQ_CODE_MASK, 0, ~mask);
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_MASK;
+ inst->mask = ~mask;
offset_mask |= CMDQ_WRITE_ENABLE_MASK;
}
- err |= cmdq_pkt_write(pkt, value, subsys, offset_mask);
- return err;
+ return cmdq_pkt_write(pkt, subsys, offset_mask, value);
}
EXPORT_SYMBOL(cmdq_pkt_write_mask);
int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
{
- u32 arg_b;
+ struct cmdq_instruction *inst;
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
- /*
- * WFE arg_b
- * bit 0-11: wait value
- * bit 15: 1 - wait, 0 - no wait
- * bit 16-27: update value
- * bit 31: 1 - update, 0 - no update
- */
- arg_b = CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | CMDQ_WFE_WAIT_VALUE;
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_WFE;
+ inst->value = CMDQ_WFE_OPTION;
+ inst->event = event;
- return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event, arg_b);
+ return 0;
}
EXPORT_SYMBOL(cmdq_pkt_wfe);
int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
{
+ struct cmdq_instruction *inst;
+
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
- return cmdq_pkt_append_command(pkt, CMDQ_CODE_WFE, event,
- CMDQ_WFE_UPDATE);
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_WFE;
+ inst->value = CMDQ_WFE_UPDATE;
+ inst->event = event;
+
+ return 0;
}
EXPORT_SYMBOL(cmdq_pkt_clear_event);
static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
{
- int err;
+ struct cmdq_instruction *inst;
+
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
- /* insert EOC and generate IRQ for each command iteration */
- err = cmdq_pkt_append_command(pkt, CMDQ_CODE_EOC, 0, CMDQ_EOC_IRQ_EN);
+ inst->op = CMDQ_CODE_EOC;
+ inst->value = CMDQ_EOC_IRQ_EN;
- /* JUMP to end */
- err |= cmdq_pkt_append_command(pkt, CMDQ_CODE_JUMP, 0, CMDQ_JUMP_PASS);
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_JUMP;
+ inst->value = CMDQ_JUMP_PASS;
- return err;
+ return 0;
}
static void cmdq_pkt_flush_async_cb(struct cmdq_cb_data data)
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index 911475da7a53..c8adedefaf42 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -19,6 +19,8 @@
#define CMDQ_WFE_UPDATE BIT(31)
#define CMDQ_WFE_WAIT BIT(15)
#define CMDQ_WFE_WAIT_VALUE 0x1
+#define CMDQ_WFE_OPTION (CMDQ_WFE_UPDATE | CMDQ_WFE_WAIT | \
+ CMDQ_WFE_WAIT_VALUE)
/** cmdq event maximum */
#define CMDQ_MAX_EVENT 0x3ff
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 12/12] arm64: dts: add gce node for mt8183
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
add gce device node for mt8183
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 08274bfcebd8..a81c995bbea9 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -8,6 +8,7 @@
#include <dt-bindings/clock/mt8183-clk.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gce/mt8183-gce.h>
/ {
compatible = "mediatek,mt8183";
@@ -212,6 +213,15 @@
clock-names = "spi", "wrap";
};
+ gce: mailbox@10238000 {
+ compatible = "mediatek,mt8183-gce";
+ reg = <0 0x10238000 0 0x4000>;
+ interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_LOW>;
+ #mbox-cells = <3>;
+ clocks = <&infracfg CLK_INFRA_GCE>;
+ clock-names = "gce";
+ };
+
uart0: serial@11002000 {
compatible = "mediatek,mt8183-uart",
"mediatek,mt6577-uart";
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 03/12] dt-binding: gce: add binding for gce client reg property
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
cmdq driver provide a function that get the relationship
of sub system number from device node for client.
add specification for #subsys-cells, mediatek,gce-client-reg.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/mailbox/mtk-gce.txt | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 1f7f8f2a3f49..7b13787ab13d 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -25,8 +25,16 @@ Required properties:
Required properties for a client device:
- mboxes: Client use mailbox to communicate with GCE, it should have this
property and list of phandle, mailbox specifiers.
-- mediatek,gce-subsys: u32, specify the sub-system id which is corresponding
- to the register address.
+Optional properties for a client device:
+- mediatek,gce-client-reg: Specify the sub-system id which is corresponding
+ to the register address, it should have this property and list of phandle,
+ sub-system specifiers.
+ <&phandle subsys_number start_offset size>
+ phandle: Label name of a gce node.
+ subsys_number: specify the sub-system id which is corresponding
+ to the register address.
+ start_offset: the start offset of register address that GCE can access.
+ size: the total size of register address that GCE can access.
Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, event ids.
@@ -48,9 +56,9 @@ Example for a client device:
compatible = "mediatek,mt8173-mmsys";
mboxes = <&gce 0 CMDQ_THR_PRIO_LOWEST 1>,
<&gce 1 CMDQ_THR_PRIO_LOWEST 1>;
- mediatek,gce-subsys = <SUBSYS_1400XXXX>;
mutex-event-eof = <CMDQ_EVENT_MUTEX0_STREAM_EOF
CMDQ_EVENT_MUTEX1_STREAM_EOF>;
-
+ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x3000 0x1000>,
+ <&gce SUBSYS_1401XXXX 0x2000 0x100>;
...
};
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 01/12] dt-binding: gce: remove thread-num property
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
"thread-num" is an unused property so we remove it from example.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Documentation/devicetree/bindings/mailbox/mtk-gce.txt | 1 -
1 file changed, 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index 7d72b21c9e94..cfe40b01d164 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -39,7 +39,6 @@ Example:
interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_LOW>;
clocks = <&infracfg CLK_INFRA_GCE>;
clock-names = "gce";
- thread-num = CMDQ_THR_MAX_COUNT;
#mbox-cells = <3>;
};
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 02/12] dt-binding: gce: add gce header file for mt8183
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
Add documentation for the mt8183 gce.
Add gce header file defined the gce hardware event,
subsys number and constant for mt8183.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/mailbox/mtk-gce.txt | 6 +-
include/dt-bindings/gce/mt8183-gce.h | 177 ++++++++++++++++++
2 files changed, 180 insertions(+), 3 deletions(-)
create mode 100644 include/dt-bindings/gce/mt8183-gce.h
diff --git a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
index cfe40b01d164..1f7f8f2a3f49 100644
--- a/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
+++ b/Documentation/devicetree/bindings/mailbox/mtk-gce.txt
@@ -9,7 +9,7 @@ CMDQ driver uses mailbox framework for communication. Please refer to
mailbox.txt for generic information about mailbox device-tree bindings.
Required properties:
-- compatible: Must be "mediatek,mt8173-gce"
+- compatible: can be "mediatek,mt8173-gce" or "mediatek,mt8183-gce"
- reg: Address range of the GCE unit
- interrupts: The interrupt signal from the GCE block
- clock: Clocks according to the common clock binding
@@ -28,8 +28,8 @@ Required properties for a client device:
- mediatek,gce-subsys: u32, specify the sub-system id which is corresponding
to the register address.
-Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'. Such as
-sub-system ids, thread priority, event ids.
+Some vaules of properties are defined in 'dt-bindings/gce/mt8173-gce.h'
+or 'dt-binding/gce/mt8183-gce.h'. Such as sub-system ids, thread priority, event ids.
Example:
diff --git a/include/dt-bindings/gce/mt8183-gce.h b/include/dt-bindings/gce/mt8183-gce.h
new file mode 100644
index 000000000000..aeb95154fac2
--- /dev/null
+++ b/include/dt-bindings/gce/mt8183-gce.h
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Bibby Hsieh <bibby.hsieh@mediatek.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_GCE_MT8183_H
+#define _DT_BINDINGS_GCE_MT8183_H
+
+#define CMDQ_NO_TIMEOUT 0xffffffff
+
+#define CMDQ_THR_MAX_COUNT 24
+
+/* GCE HW thread priority */
+#define CMDQ_THR_PRIO_LOWEST 0
+#define CMDQ_THR_PRIO_HIGHEST 1
+
+/* GCE SUBSYS */
+#define SUBSYS_1300XXXX 0
+#define SUBSYS_1400XXXX 1
+#define SUBSYS_1401XXXX 2
+#define SUBSYS_1402XXXX 3
+#define SUBSYS_1502XXXX 4
+#define SUBSYS_1880XXXX 5
+#define SUBSYS_1881XXXX 6
+#define SUBSYS_1882XXXX 7
+#define SUBSYS_1883XXXX 8
+#define SUBSYS_1884XXXX 9
+#define SUBSYS_1000XXXX 10
+#define SUBSYS_1001XXXX 11
+#define SUBSYS_1002XXXX 12
+#define SUBSYS_1003XXXX 13
+#define SUBSYS_1004XXXX 14
+#define SUBSYS_1005XXXX 15
+#define SUBSYS_1020XXXX 16
+#define SUBSYS_1028XXXX 17
+#define SUBSYS_1700XXXX 18
+#define SUBSYS_1701XXXX 19
+#define SUBSYS_1702XXXX 20
+#define SUBSYS_1703XXXX 21
+#define SUBSYS_1800XXXX 22
+#define SUBSYS_1801XXXX 23
+#define SUBSYS_1802XXXX 24
+#define SUBSYS_1804XXXX 25
+#define SUBSYS_1805XXXX 26
+#define SUBSYS_1808XXXX 27
+#define SUBSYS_180aXXXX 28
+#define SUBSYS_180bXXXX 29
+
+#define CMDQ_EVENT_DISP_RDMA0_SOF 0
+#define CMDQ_EVENT_DISP_RDMA1_SOF 1
+#define CMDQ_EVENT_MDP_RDMA0_SOF 2
+#define CMDQ_EVENT_MDP_RSZ0_SOF 4
+#define CMDQ_EVENT_MDP_RSZ1_SOF 5
+#define CMDQ_EVENT_MDP_TDSHP_SOF 6
+#define CMDQ_EVENT_MDP_WROT0_SOF 7
+#define CMDQ_EVENT_MDP_WDMA0_SOF 8
+#define CMDQ_EVENT_DISP_OVL0_SOF 9
+#define CMDQ_EVENT_DISP_OVL0_2L_SOF 10
+#define CMDQ_EVENT_DISP_OVL1_2L_SOF 11
+#define CMDQ_EVENT_DISP_WDMA0_SOF 12
+#define CMDQ_EVENT_DISP_COLOR0_SOF 13
+#define CMDQ_EVENT_DISP_CCORR0_SOF 14
+#define CMDQ_EVENT_DISP_AAL0_SOF 15
+#define CMDQ_EVENT_DISP_GAMMA0_SOF 16
+#define CMDQ_EVENT_DISP_DITHER0_SOF 17
+#define CMDQ_EVENT_DISP_PWM0_SOF 18
+#define CMDQ_EVENT_DISP_DSI0_SOF 19
+#define CMDQ_EVENT_DISP_DPI0_SOF 20
+#define CMDQ_EVENT_DISP_RSZ_SOF 22
+#define CMDQ_EVENT_MDP_AAL_SOF 23
+#define CMDQ_EVENT_MDP_CCORR_SOF 24
+#define CMDQ_EVENT_DISP_DBI_SOF 25
+#define CMDQ_EVENT_DISP_RDMA0_EOF 26
+#define CMDQ_EVENT_DISP_RDMA1_EOF 27
+#define CMDQ_EVENT_MDP_RDMA0_EOF 28
+#define CMDQ_EVENT_MDP_RSZ0_EOF 30
+#define CMDQ_EVENT_MDP_RSZ1_EOF 31
+#define CMDQ_EVENT_MDP_TDSHP_EOF 32
+#define CMDQ_EVENT_MDP_WROT0_EOF 33
+#define CMDQ_EVENT_MDP_WDMA0_EOF 34
+#define CMDQ_EVENT_DISP_OVL0_EOF 35
+#define CMDQ_EVENT_DISP_OVL0_2L_EOF 36
+#define CMDQ_EVENT_DISP_OVL1_2L_EOF 37
+#define CMDQ_EVENT_DISP_WDMA0_EOF 38
+#define CMDQ_EVENT_DISP_COLOR0_EOF 39
+#define CMDQ_EVENT_DISP_CCORR0_EOF 40
+#define CMDQ_EVENT_DISP_AAL0_EOF 41
+#define CMDQ_EVENT_DISP_GAMMA0_EOF 42
+#define CMDQ_EVENT_DISP_DITHER0_EOF 43
+#define CMDQ_EVENT_DSI0_EOF 44
+#define CMDQ_EVENT_DPI0_EOF 45
+#define CMDQ_EVENT_DISP_RSZ_EOF 47
+#define CMDQ_EVENT_MDP_AAL_EOF 48
+#define CMDQ_EVENT_MDP_CCORR_EOF 49
+#define CMDQ_EVENT_DBI_EOF 50
+#define CMDQ_EVENT_MUTEX_STREAM_DONE0 130
+#define CMDQ_EVENT_MUTEX_STREAM_DONE1 131
+#define CMDQ_EVENT_MUTEX_STREAM_DONE2 132
+#define CMDQ_EVENT_MUTEX_STREAM_DONE3 133
+#define CMDQ_EVENT_MUTEX_STREAM_DONE4 134
+#define CMDQ_EVENT_MUTEX_STREAM_DONE5 135
+#define CMDQ_EVENT_MUTEX_STREAM_DONE6 136
+#define CMDQ_EVENT_MUTEX_STREAM_DONE7 137
+#define CMDQ_EVENT_MUTEX_STREAM_DONE8 138
+#define CMDQ_EVENT_MUTEX_STREAM_DONE9 139
+#define CMDQ_EVENT_MUTEX_STREAM_DONE10 140
+#define CMDQ_EVENT_MUTEX_STREAM_DONE11 141
+#define CMDQ_EVENT_DISP_RDMA0_BUF_UNDERRUN_EVEN 142
+#define CMDQ_EVENT_DISP_RDMA1_BUF_UNDERRUN_EVEN 143
+#define CMDQ_EVENT_DSI0_TE_EVENT 144
+#define CMDQ_EVENT_DSI0_IRQ_EVENT 145
+#define CMDQ_EVENT_DSI0_DONE_EVENT 146
+#define CMDQ_EVENT_DISP_WDMA0_SW_RST_DONE 150
+#define CMDQ_EVENT_MDP_WDMA_SW_RST_DONE 151
+#define CMDQ_EVENT_MDP_WROT0_SW_RST_DONE 152
+#define CMDQ_EVENT_MDP_RDMA0_SW_RST_DONE 154
+#define CMDQ_EVENT_DISP_OVL0_FRAME_RST_DONE_PULE 155
+#define CMDQ_EVENT_DISP_OVL0_2L_FRAME_RST_DONE_ULSE 156
+#define CMDQ_EVENT_DISP_OVL1_2L_FRAME_RST_DONE_ULSE 157
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_0 257
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_1 258
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_2 259
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_3 260
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_4 261
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_5 262
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_6 263
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_7 264
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_8 265
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_9 266
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_10 267
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_11 268
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_12 269
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_13 270
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_14 271
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_15 272
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_16 273
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_17 274
+#define CMDQ_EVENT_ISP_FRAME_DONE_P2_18 275
+#define CMDQ_EVENT_AMD_FRAME_DONE 276
+#define CMDQ_EVENT_DVE_DONE 277
+#define CMDQ_EVENT_WMFE_DONE 278
+#define CMDQ_EVENT_RSC_DONE 279
+#define CMDQ_EVENT_MFB_DONE 280
+#define CMDQ_EVENT_WPE_A_DONE 281
+#define CMDQ_EVENT_SPE_B_DONE 282
+#define CMDQ_EVENT_OCC_DONE 283
+#define CMDQ_EVENT_VENC_CMDQ_FRAME_DONE 289
+#define CMDQ_EVENT_JPG_ENC_CMDQ_DONE 290
+#define CMDQ_EVENT_JPG_DEC_CMDQ_DONE 291
+#define CMDQ_EVENT_VENC_CMDQ_MB_DONE 292
+#define CMDQ_EVENT_VENC_CMDQ_128BYTE_DONE 293
+#define CMDQ_EVENT_ISP_FRAME_DONE_A 321
+#define CMDQ_EVENT_ISP_FRAME_DONE_B 322
+#define CMDQ_EVENT_CAMSV0_PASS1_DONE 323
+#define CMDQ_EVENT_CAMSV1_PASS1_DONE 324
+#define CMDQ_EVENT_CAMSV2_PASS1_DONE 325
+#define CMDQ_EVENT_TSF_DONE 326
+#define CMDQ_EVENT_SENINF_CAM0_FIFO_FULL 327
+#define CMDQ_EVENT_SENINF_CAM1_FIFO_FULL 328
+#define CMDQ_EVENT_SENINF_CAM2_FIFO_FULL 329
+#define CMDQ_EVENT_SENINF_CAM3_FIFO_FULL 330
+#define CMDQ_EVENT_SENINF_CAM4_FIFO_FULL 331
+#define CMDQ_EVENT_SENINF_CAM5_FIFO_FULL 332
+#define CMDQ_EVENT_SENINF_CAM6_FIFO_FULL 333
+#define CMDQ_EVENT_SENINF_CAM7_FIFO_FULL 334
+#define CMDQ_EVENT_IPU_CORE0_DONE0 353
+#define CMDQ_EVENT_IPU_CORE0_DONE1 354
+#define CMDQ_EVENT_IPU_CORE0_DONE2 355
+#define CMDQ_EVENT_IPU_CORE0_DONE3 356
+#define CMDQ_EVENT_IPU_CORE1_DONE0 385
+#define CMDQ_EVENT_IPU_CORE1_DONE1 386
+#define CMDQ_EVENT_IPU_CORE1_DONE2 387
+#define CMDQ_EVENT_IPU_CORE1_DONE3 388
+
+#endif
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 10/12] soc: mediatek: cmdq: add polling function
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
add polling function in cmdq helper functions
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 28 ++++++++++++++++++++++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 1 +
include/linux/soc/mediatek/mtk-cmdq.h | 15 +++++++++++++
3 files changed, 44 insertions(+)
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index e1e41914ed7a..340a92a254e5 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -220,6 +220,34 @@ int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
}
EXPORT_SYMBOL(cmdq_pkt_clear_event);
+int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
+ u16 offset, u32 value, u32 mask)
+{
+ struct cmdq_instruction *inst;
+
+ if (mask != 0xffffffff) {
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_MASK;
+ inst->value = ~mask;
+ offset = offset | 0x1;
+ }
+
+ inst = cmdq_pkt_append_command(pkt);
+ if (!inst)
+ return -ENOMEM;
+
+ inst->op = CMDQ_CODE_POLL;
+ inst->value = value;
+ inst->offset = offset;
+ inst->subsys = subsys;
+
+ return 0;
+}
+EXPORT_SYMBOL(cmdq_pkt_poll);
+
static int cmdq_pkt_finalize(struct cmdq_pkt *pkt)
{
struct cmdq_instruction *inst;
diff --git a/include/linux/mailbox/mtk-cmdq-mailbox.h b/include/linux/mailbox/mtk-cmdq-mailbox.h
index c8adedefaf42..9e3502945bc1 100644
--- a/include/linux/mailbox/mtk-cmdq-mailbox.h
+++ b/include/linux/mailbox/mtk-cmdq-mailbox.h
@@ -46,6 +46,7 @@
enum cmdq_code {
CMDQ_CODE_MASK = 0x02,
CMDQ_CODE_WRITE = 0x04,
+ CMDQ_CODE_POLL = 0x08,
CMDQ_CODE_JUMP = 0x10,
CMDQ_CODE_WFE = 0x20,
CMDQ_CODE_EOC = 0x40,
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 9618debb9ceb..a345870a6d10 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -99,6 +99,21 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
*/
int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
+/**
+ * cmdq_pkt_poll() - Append polling command to the CMDQ packet, ask GCE to
+ * execute an instruction that wait for a specified hardware
+ * register to check for the value. All GCE hardware
+ * threads will be blocked by this instruction.
+ * @pkt: the CMDQ packet
+ * @subsys: the CMDQ sub system code
+ * @offset: register offset from CMDQ sub system
+ * @value: the specified target register value
+ * @mask: the specified target register mask
+ *
+ * Return: 0 for success; else the error code is returned
+ */
+int cmdq_pkt_poll(struct cmdq_pkt *pkt, u8 subsys,
+ u16 offset, u32 value, u32 mask);
/**
* cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
* packet and call back at the end of done packet
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 04/12] mailbox: mediatek: cmdq: move the CMDQ_IRQ_MASK into cmdq driver data
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
The interrupt mask and thread number has positive correlation,
so we move the CMDQ_IRQ_MASK into cmdq driver data and calculate
it by thread number.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/mailbox/mtk-cmdq-mailbox.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 00d5219094e5..8fddd26288e8 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -18,7 +18,6 @@
#include <linux/of_device.h>
#define CMDQ_OP_CODE_MASK (0xff << CMDQ_OP_CODE_SHIFT)
-#define CMDQ_IRQ_MASK 0xffff
#define CMDQ_NUM_CMD(t) (t->cmd_buf_size / CMDQ_INST_SIZE)
#define CMDQ_CURR_IRQ_STATUS 0x10
@@ -72,6 +71,7 @@ struct cmdq {
void __iomem *base;
u32 irq;
u32 thread_nr;
+ u32 irq_mask;
struct cmdq_thread *thread;
struct clk *clock;
bool suspended;
@@ -285,11 +285,11 @@ static irqreturn_t cmdq_irq_handler(int irq, void *dev)
unsigned long irq_status, flags = 0L;
int bit;
- irq_status = readl(cmdq->base + CMDQ_CURR_IRQ_STATUS) & CMDQ_IRQ_MASK;
- if (!(irq_status ^ CMDQ_IRQ_MASK))
+ irq_status = readl(cmdq->base + CMDQ_CURR_IRQ_STATUS) & cmdq->irq_mask;
+ if (!(irq_status ^ cmdq->irq_mask))
return IRQ_NONE;
- for_each_clear_bit(bit, &irq_status, fls(CMDQ_IRQ_MASK)) {
+ for_each_clear_bit(bit, &irq_status, cmdq->thread_nr) {
struct cmdq_thread *thread = &cmdq->thread[bit];
spin_lock_irqsave(&thread->chan->lock, flags);
@@ -473,6 +473,9 @@ static int cmdq_probe(struct platform_device *pdev)
dev_err(dev, "failed to get irq\n");
return -EINVAL;
}
+
+ cmdq->thread_nr = (u32)(unsigned long)of_device_get_match_data(dev);
+ cmdq->irq_mask = GENMASK(cmdq->thread_nr - 1, 0);
err = devm_request_irq(dev, cmdq->irq, cmdq_irq_handler, IRQF_SHARED,
"mtk_cmdq", cmdq);
if (err < 0) {
@@ -489,7 +492,6 @@ static int cmdq_probe(struct platform_device *pdev)
return PTR_ERR(cmdq->clock);
}
- cmdq->thread_nr = (u32)(unsigned long)of_device_get_match_data(dev);
cmdq->mbox.dev = dev;
cmdq->mbox.chans = devm_kcalloc(dev, cmdq->thread_nr,
sizeof(*cmdq->mbox.chans), GFP_KERNEL);
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 08/12] soc: mediatek: cmdq: change the type of input parameter
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
According to the cmdq hardware design, the subsys is u8,
the offset is u16 and the event id is u16.
This patch changes the type of subsys, offset and event id
to the correct type.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 10 +++++-----
include/linux/soc/mediatek/mtk-cmdq.h | 10 +++++-----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index 082b8978651e..7aa0517ff2f3 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -136,7 +136,7 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
return 0;
}
-int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value)
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
{
u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
(subsys << CMDQ_SUBSYS_SHIFT);
@@ -145,8 +145,8 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value)
}
EXPORT_SYMBOL(cmdq_pkt_write);
-int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
- u32 offset, u32 value, u32 mask)
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
+ u16 offset, u32 value, u32 mask)
{
u32 offset_mask = offset;
int err = 0;
@@ -161,7 +161,7 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
}
EXPORT_SYMBOL(cmdq_pkt_write_mask);
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
{
u32 arg_b;
@@ -181,7 +181,7 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
}
EXPORT_SYMBOL(cmdq_pkt_wfe);
-int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event)
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
{
if (event >= CMDQ_MAX_EVENT)
return -EINVAL;
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 39d813dde4b4..9618debb9ceb 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -66,7 +66,7 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
*
* Return: 0 for success; else the error code is returned
*/
-int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value);
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
/**
* cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
@@ -78,8 +78,8 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value);
*
* Return: 0 for success; else the error code is returned
*/
-int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
- u32 offset, u32 value, u32 mask);
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
+ u16 offset, u32 value, u32 mask);
/**
* cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
@@ -88,7 +88,7 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
*
* Return: 0 for success; else the error code is returned
*/
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
/**
* cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
@@ -97,7 +97,7 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event);
*
* Return: 0 for success; else the error code is returned
*/
-int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event);
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
/**
* cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 00/12] support gce on mt8183 platform
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
Changes since v11:
- correct some data type to avoid type conversion.
Changes since v10:
- remove subsys-cell from gce device node
- use of_parse_phandle_with_fixed_args instead of
of_parse_phandle_with_args
Changes since v8 and v9:
- change the error return code in cmdq_dev_get_client_reg()
Changes since v7:
- remove the memory allocation out of cmdq_dev_get_client_reg()
- rebase onto 5.2-rc1
Changes since v6:
- remove cmdq_dev_get_event function and gce event property
- separate some changes to indepentent patch
- change the binding document related to gce-client-reg property
Changes since v5:
- fix typo
- remove gce-event-name form the dt-binding
- add reasons in commit message
Changes since v4:
- refine the architecture of the packet encoder function
- refine the gce enevt property
- change the patch's title
Changes since v3:
- fix a typo in dt-binding and dtsi
- cast the return value to right format
Changes since v2:
- according to CK's review comment, change the property name and
refine the parameter
- change the patch's title
- remove unused property from dt-binding and dts
Changes since v1:
- add prefix "cmdq" in the commit subject
- add dt-binding document for get event and subsys function
- add fix up tag in fixup patch
- fix up some coding style (alignment)
MTK will support gce function on mt8183 platform.
dt-binding: gce: add gce header file for mt8183
mailbox: mediatek: cmdq: support mt8183 gce function
arm64: dts: add gce node for mt8183
Besides above patches, we refine gce driver on those patches.
soc: mediatek: cmdq: reorder the parameter
soc: mediatek: cmdq: change the type of input parameter
mailbox: mediatek: cmdq: move the CMDQ_IRQ_MASK into cmdq driver data
soc: mediatek: cmdq: clear the event in cmdq initial flow
In order to enhance the convenience of gce usage, we add new
helper functions and refine the method of instruction combining.
dt-binding: gce: remove thread-num property
dt-binding: gce: add binding for gce client reg property
soc: mediatek: cmdq: define the instruction struct
soc: mediatek: cmdq: add polling function
soc: mediatek: cmdq: add cmdq_dev_get_client_reg function
Bibby Hsieh (12):
dt-binding: gce: remove thread-num property
dt-binding: gce: add gce header file for mt8183
dt-binding: gce: add binding for gce client reg property
mailbox: mediatek: cmdq: move the CMDQ_IRQ_MASK into cmdq driver data
mailbox: mediatek: cmdq: support mt8183 gce function
soc: mediatek: cmdq: clear the event in cmdq initial flow
soc: mediatek: cmdq: reorder the parameter
soc: mediatek: cmdq: change the type of input parameter
soc: mediatek: cmdq: define the instruction struct
soc: mediatek: cmdq: add polling function
soc: mediatek: cmdq: add cmdq_dev_get_client_reg function
arm64: dts: add gce node for mt8183
.../devicetree/bindings/mailbox/mtk-gce.txt | 23 ++-
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 10 +
drivers/mailbox/mtk-cmdq-mailbox.c | 18 +-
drivers/soc/mediatek/mtk-cmdq-helper.c | 172 +++++++++++++----
include/dt-bindings/gce/mt8183-gce.h | 177 ++++++++++++++++++
include/linux/mailbox/mtk-cmdq-mailbox.h | 5 +
include/linux/soc/mediatek/mtk-cmdq.h | 53 +++++-
7 files changed, 396 insertions(+), 62 deletions(-)
create mode 100644 include/dt-bindings/gce/mt8183-gce.h
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v12 05/12] mailbox: mediatek: cmdq: support mt8183 gce function
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
add mt8183 compatible name for supporting gce function
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/mailbox/mtk-cmdq-mailbox.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c
index 8fddd26288e8..69daaadc3a5f 100644
--- a/drivers/mailbox/mtk-cmdq-mailbox.c
+++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -539,6 +539,7 @@ static const struct dev_pm_ops cmdq_pm_ops = {
static const struct of_device_id cmdq_of_ids[] = {
{.compatible = "mediatek,mt8173-gce", .data = (void *)16},
+ {.compatible = "mediatek,mt8183-gce", .data = (void *)24},
{}
};
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v12 07/12] soc: mediatek: cmdq: reorder the parameter
From: Bibby Hsieh @ 2019-08-19 2:53 UTC (permalink / raw)
To: Jassi Brar, Matthias Brugger, Rob Herring, CK HU
Cc: devicetree, Nicolas Boichat, Philipp Zabel, srv_heupstream,
Daoyuan Huang, Sascha Hauer, linux-kernel, Daniel Kurtz,
Dennis-YC Hsieh, linux-mediatek, Houlong Wei, Sascha Hauer,
YT Shen, Jiaguang Zhang, Bibby Hsieh, linux-arm-kernel,
ginny.chen
In-Reply-To: <20190819025359.11381-1-bibby.hsieh@mediatek.com>
The order of gce instructions is [subsys offset value]
so reorder the parameter of cmdq_pkt_write_mask
and cmdq_pkt_write function.
Signed-off-by: Bibby Hsieh <bibby.hsieh@mediatek.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
---
drivers/soc/mediatek/mtk-cmdq-helper.c | 6 +++---
include/linux/soc/mediatek/mtk-cmdq.h | 10 +++++-----
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c
index ff9fef5a032b..082b8978651e 100644
--- a/drivers/soc/mediatek/mtk-cmdq-helper.c
+++ b/drivers/soc/mediatek/mtk-cmdq-helper.c
@@ -136,7 +136,7 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
return 0;
}
-int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value)
{
u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
(subsys << CMDQ_SUBSYS_SHIFT);
@@ -145,8 +145,8 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
}
EXPORT_SYMBOL(cmdq_pkt_write);
-int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
- u32 subsys, u32 offset, u32 mask)
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
+ u32 offset, u32 value, u32 mask)
{
u32 offset_mask = offset;
int err = 0;
diff --git a/include/linux/soc/mediatek/mtk-cmdq.h b/include/linux/soc/mediatek/mtk-cmdq.h
index 4e8899972db4..39d813dde4b4 100644
--- a/include/linux/soc/mediatek/mtk-cmdq.h
+++ b/include/linux/soc/mediatek/mtk-cmdq.h
@@ -60,26 +60,26 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
/**
* cmdq_pkt_write() - append write command to the CMDQ packet
* @pkt: the CMDQ packet
- * @value: the specified target register value
* @subsys: the CMDQ sub system code
* @offset: register offset from CMDQ sub system
+ * @value: the specified target register value
*
* Return: 0 for success; else the error code is returned
*/
-int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset);
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 subsys, u32 offset, u32 value);
/**
* cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
* @pkt: the CMDQ packet
- * @value: the specified target register value
* @subsys: the CMDQ sub system code
* @offset: register offset from CMDQ sub system
+ * @value: the specified target register value
* @mask: the specified target register mask
*
* Return: 0 for success; else the error code is returned
*/
-int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
- u32 subsys, u32 offset, u32 mask);
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 subsys,
+ u32 offset, u32 value, u32 mask);
/**
* cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
--
2.18.0
_______________________________________________
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] clk: spear: Make structure i2s_sclk_masks constant
From: Viresh Kumar @ 2019-08-19 2:20 UTC (permalink / raw)
To: Nishka Dasgupta; +Cc: sboyd, vireshk, mturquette, linux-clk, linux-arm-kernel
In-Reply-To: <20190813085714.8079-1-nishkadg.linux@gmail.com>
On 13-08-19, 14:27, Nishka Dasgupta wrote:
> Static structure i2s_sclk_masks, having type aux_clk_masks, is only used
> when it is passed as the sixth argument to function clk_register_aux().
> However, clk_register_aux() is defined with its sixth argument as const.
> Hence i2s_sclk_masks is not modified by clk_register_aux, which is also
> the only usage of the former. Therefore make i2s_sclk_masks constant as
> it is never modified.
> Issue found with Coccinelle.
>
> Signed-off-by: Nishka Dasgupta <nishkadg.linux@gmail.com>
> ---
> drivers/clk/spear/spear1340_clock.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/clk/spear/spear1340_clock.c b/drivers/clk/spear/spear1340_clock.c
> index e5bc8c828cf0..9163bbb46411 100644
> --- a/drivers/clk/spear/spear1340_clock.c
> +++ b/drivers/clk/spear/spear1340_clock.c
> @@ -335,7 +335,7 @@ static const struct aux_clk_masks i2s_prs1_masks = {
> };
>
> /* i2s sclk (bit clock) syynthesizers masks */
> -static struct aux_clk_masks i2s_sclk_masks = {
> +static const struct aux_clk_masks i2s_sclk_masks = {
> .eq_sel_mask = AUX_EQ_SEL_MASK,
> .eq_sel_shift = SPEAR1340_I2S_SCLK_EQ_SEL_SHIFT,
> .eq1_mask = AUX_EQ1_SEL,
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
--
viresh
_______________________________________________
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 2/2] clk: Add support for AST2600 SoC
From: Joel Stanley @ 2019-08-19 2:03 UTC (permalink / raw)
To: Stephen Boyd
Cc: Ryan Chen, linux-aspeed, Andrew Jeffery, Michael Turquette,
Linux Kernel Mailing List, Rob Herring, linux-clk, Linux ARM
In-Reply-To: <20190816171441.3B8F720665@mail.kernel.org>
On Fri, 16 Aug 2019 at 17:14, Stephen Boyd <sboyd@kernel.org> wrote:
>
> Quoting Joel Stanley (2019-08-16 08:58:06)
> > diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/clk-ast2600.c
> > new file mode 100644
> > index 000000000000..083d5299238c
> > --- /dev/null
> > +++ b/drivers/clk/clk-ast2600.c
> > @@ -0,0 +1,701 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +// Copyright IBM Corp
> > +// Copyright ASPEED Technology
> > +
> [...]
> > +#define ASPEED_DPLL_PARAM 0x260
> > +
> > +#define ASPEED_G6_STRAP1 0x500
> > +
> > +/* Globally visible clocks */
> > +static DEFINE_SPINLOCK(aspeed_clk_lock);
>
> I guess we can be guaranteed that the two drivers aren't compiled into
> the same image? Otherwise this will alias with clk-aspeed.c and make
> kallsyms annoying to use.
I will change the name.
>
> > +
> > +/* Keeps track of all clocks */
> > +static struct clk_hw_onecell_data *aspeed_g6_clk_data;
> > +
> > +static void __iomem *scu_g6_base;
> > +
> > +static const struct aspeed_gate_data aspeed_g6_gates[] = {
> > + /* clk rst name parent flags */
> > + [ASPEED_CLK_GATE_MCLK] = { 0, -1, "mclk-gate", "mpll", CLK_IS_CRITICAL }, /* SDRAM */
>
> Please document CLK_IS_CRITICAL usage. I guess it's memory so never turn
> it off?
Yes.
I added some comments and removed some uses that I didn't know the
reason for. We can add them back later if required, with the
reasoning.
> > +static const char * const vclk_parent_names[] = {
>
> Can you use the new way of specifying clk parents instead of just using
> strings?
How does this work? I had a browse of the APIs in clk-provider.h and
it appeared the functions all take char *s still.
> > + hw = clk_hw_register_fixed_factor(NULL, "ahb", "hpll", 0, 1, axi_div * ahb_div);
>
> There aren't checks for if these things fail. I guess it doesn't matter
> and just let it fail hard?
I think that's sensible here. If the system has run out of memory this
early on then there's not going to be much that works.
Thanks for the review. I've fixed all of the style issues you
mentioned, but would appreciate some guidance on the parent API.
Cheers,
Joel
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC V2 10/11] interconnect: mediatek: Add mt8183 interconnect provider driver
From: Henry Chen @ 2019-08-19 1:53 UTC (permalink / raw)
To: Georgi Djakov
Cc: Nicolas Boichat, Weiyi Lu, James Liao, Viresh Kumar,
Linux PM list, linux-kernel, Stephen Boyd, Fan Chen, devicetree,
Rob Herring, linux-mediatek, Matthias Brugger, linux-arm-kernel
In-Reply-To: <b8db4f70-4b95-5a98-38b4-9990bae023b4@linaro.org>
Hi Georgi,
Sorry for late reply.
On Tue, 2019-05-14 at 09:43 +0300, Georgi Djakov wrote:
> Hi Henry,
>
> On 4/30/19 11:51, Henry Chen wrote:
> > Introduce Mediatek MT8183 specific provider driver using the
> > interconnect framework.
> >
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> > drivers/interconnect/Kconfig | 1 +
> > drivers/interconnect/Makefile | 1 +
> > drivers/interconnect/mediatek/Kconfig | 13 ++
> > drivers/interconnect/mediatek/Makefile | 5 +
> > drivers/interconnect/mediatek/mt8183.c | 223 +++++++++++++++++++++++++++++++++
> > 5 files changed, 243 insertions(+)
> > create mode 100644 drivers/interconnect/mediatek/Kconfig
> > create mode 100644 drivers/interconnect/mediatek/Makefile
> > create mode 100644 drivers/interconnect/mediatek/mt8183.c
> >
> > diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
> > index 07a8276..ac41ea6 100644
> > --- a/drivers/interconnect/Kconfig
> > +++ b/drivers/interconnect/Kconfig
> > @@ -11,5 +11,6 @@ menuconfig INTERCONNECT
> > if INTERCONNECT
> >
> > source "drivers/interconnect/qcom/Kconfig"
> > +source "drivers/interconnect/mediatek/Kconfig"
> >
> > endif
> > diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
> > index 28f2ab0..253f24a3 100644
> > --- a/drivers/interconnect/Makefile
> > +++ b/drivers/interconnect/Makefile
> > @@ -4,3 +4,4 @@ icc-core-objs := core.o
> >
> > obj-$(CONFIG_INTERCONNECT) += icc-core.o
> > obj-$(CONFIG_INTERCONNECT_QCOM) += qcom/
> > +obj-$(CONFIG_INTERCONNECT_MTK) += mediatek/
> > diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
> > new file mode 100644
> > index 0000000..0686494
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Kconfig
> > @@ -0,0 +1,13 @@
> > +config INTERCONNECT_MTK
> > + bool "Mediatek Network-on-Chip interconnect drivers"
> > + depends on ARCH_MEDIATEK
> > + help
> > + Support for Mediatek's Network-on-Chip interconnect hardware.
> > +
> > +config INTERCONNECT_MTK_MT8183
> > + tristate "Mediatek MT8183 interconnect driver"
> > + depends on INTERCONNECT_MTK
> > + depends on (MTK_DVFSRC && OF)
> > + help
> > + This is a driver for the Mediatek Network-on-Chip on mt8183-based
> > + platforms.
> > diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
> > new file mode 100644
> > index 0000000..a39ceee
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/Makefile
> > @@ -0,0 +1,5 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +
> > +mtk-mt8183-objs := mt8183.o
> > +
> > +obj-$(CONFIG_INTERCONNECT_MTK_MT8183) += mtk-mt8183.o
> > \ No newline at end of file
> > diff --git a/drivers/interconnect/mediatek/mt8183.c b/drivers/interconnect/mediatek/mt8183.c
> > new file mode 100644
> > index 0000000..38ffe0b
> > --- /dev/null
> > +++ b/drivers/interconnect/mediatek/mt8183.c
> > @@ -0,0 +1,223 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (c) 2019, The Linux Foundation. All rights reserved.
> > + *
> > + */
> > +
> > +#include <dt-bindings/interconnect/mtk,mt8183.h>
> > +#include <linux/device.h>
> > +#include <linux/interconnect.h>
>
> This is not needed.
ok, thanks.
>
> > +#include <linux/interconnect-provider.h>
> > +#include <linux/module.h>
> > +#include <linux/of_device.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/platform_device.h>
> > +#include <soc/mediatek/mtk_dvfsrc.h>
> > +
> > +#define MT8183_MAX_LINKS 6
> > +
> > +/**
> > + * struct mtk_icc_node - Mediatek specific interconnect nodes
> > + * @name: the node name used in debugfs
> > + * @ep: true if the node is an end point.
> > + * @id: a unique node identifier
> > + * @links: an array of nodes where we can go next while traversing
> > + * @num_links: the total number of @links
> > + * @buswidth: width of the interconnect between a node and the bus
>
> Maybe mention the units?
ok, I will add it.
>
> > + * @sum_avg: current sum aggregate value of all avg bw requests
> > + * @max_peak: current max aggregate value of all peak bw requests
>
> units?
>
> > + */
> > +struct mtk_icc_node {
> > + unsigned char *name;
> > + bool ep;
> > + u16 id;
> > + u16 links[MT8183_MAX_LINKS];
> > + u16 num_links;
> > + u16 buswidth;
> > + u64 sum_avg;
> > + u64 max_peak;
> > +};
> > +
> > +struct mtk_icc_desc {
> > + struct mtk_icc_node **nodes;
> > + size_t num_nodes;
> > +};
> > +
> > +#define DEFINE_MNODE(_name, _id, _buswidth, _ep, _numlinks, ...) \
>
> We can drop the _numlinks and..
ok, thank you for the advice.
>
> > + static struct mtk_icc_node _name = { \
> > + .name = #_name, \
> > + .id = _id, \
> > + .buswidth = _buswidth, \
> > + .ep = _ep, \
> > + .num_links = _numlinks, \
>
> ..just use .num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ }))
>
> > + .links = { __VA_ARGS__ }, \
> > +}
> > +
> > +DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0, 0);
> > +DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, 1, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(gpu, MASTER_GPU, 256, 0, 1, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, 1, SLAVE_DDR_EMI);
> > +DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, 1, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, 1, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, 1, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, 1, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, 1, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, 1, MASTER_MMSYS);
> > +DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, 1, MASTER_MMSYS);
> > +
> > +static struct mtk_icc_node *mt8183_icc_nodes[] = {
> > + &ddr_emi,
> > + &mcusys,
> > + &gpu,
> > + &mmsys,
> > + &mm_vpu,
> > + &mm_disp,
> > + &mm_vdec,
> > + &mm_venc,
> > + &mm_cam,
> > + &mm_img,
> > + &mm_mdp,
> > +};
> > +
> > +static struct mtk_icc_desc mt8183_icc = {
> > + .nodes = mt8183_icc_nodes,
> > + .num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
> > +};
> > +
> > +static int mt8183_icc_aggregate(struct icc_node *node, u32 avg_bw,
> > + u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
> > +{
> > + struct mtk_icc_node *in;
> > +
> > + in = node->data;
> > +
> > + *agg_avg += avg_bw;
> > + *agg_peak = max_t(u32, *agg_peak, peak_bw);
> > +
> > + in->sum_avg = *agg_avg;
> > + in->max_peak = *agg_peak;
> > +
> > + return 0;
> > +}
> > +
> > +static int mt8183_icc_set(struct icc_node *src, struct icc_node *dst)
> > +{
> > + int ret = 0;
> > + struct mtk_icc_node *node;
> > +
> > + node = dst->data;
> > + if (node->ep) {
> > + pr_debug("sum_avg (%llu), max_peak (%llu)\n",
> > + node->sum_avg, node->max_peak);
> > + mtk_dvfsrc_send_request(src->provider->dev->parent,
> > + MTK_DVFSRC_CMD_BW_REQUEST,
> > + node->max_peak);
> > + }
> > +
> > + return ret;
> > +}
> > +
> > +static int mt8183_icc_probe(struct platform_device *pdev)
> > +{
> > + int ret;
> > + const struct mtk_icc_desc *desc;
> > + struct icc_node *node;
> > + struct icc_onecell_data *data;
> > + struct icc_provider *provider;
> > + struct mtk_icc_node **mnodes;
> > + size_t num_nodes, i, j;
> > +
> > + desc = of_device_get_match_data(&pdev->dev);
> > + if (!desc)
> > + return -EINVAL;
> > +
> > + mnodes = desc->nodes;
> > + num_nodes = desc->num_nodes;
> > +
> > + provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
> > + if (!provider)
> > + return -ENOMEM;
> > +
> > + data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
> > + if (!data)
> > + return -ENOMEM;
> > +
> > + provider->dev = &pdev->dev;
> > + provider->set = mt8183_icc_set;
> > + provider->aggregate = mt8183_icc_aggregate;
> > + provider->xlate = of_icc_xlate_onecell;
> > + INIT_LIST_HEAD(&provider->nodes);
> > + provider->data = data;
> > +
> > + ret = icc_provider_add(provider);
> > + if (ret) {
> > + dev_err(&pdev->dev, "error adding interconnect provider\n");
> > + return ret;
> > + }
> > +
> > + for (i = 0; i < num_nodes; i++) {
> > + node = icc_node_create(mnodes[i]->id);
> > + if (IS_ERR(node)) {
> > + ret = PTR_ERR(node);
> > + goto err;
> > + }
> > +
> > + node->name = mnodes[i]->name;
> > + node->data = mnodes[i];
> > + icc_node_add(node, provider);
> > +
> > + dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
> > + mnodes[i]->name, mnodes[i]->num_links);
> > +
> > + /* populate links */
> > + for (j = 0; j < mnodes[i]->num_links; j++)
> > + icc_link_create(node, mnodes[i]->links[j]);
> > +
> > + data->nodes[i] = node;
> > + }
> > + data->num_nodes = num_nodes;
> > +
> > + platform_set_drvdata(pdev, provider);
> > +
> > + return ret;
>
> just return 0;
ok.
>
> > +err:
> > + list_for_each_entry(node, &provider->nodes, node_list) {
> > + icc_node_del(node);
> > + icc_node_destroy(node->id);
> > + }
> > +
> > + icc_provider_del(provider);
> > + return ret;
> > +}
> > +
> > +static int mt8183_icc_remove(struct platform_device *pdev)
> > +{
> > + struct icc_provider *provider = platform_get_drvdata(pdev);
> > + struct icc_node *n;
> > +
> > + list_for_each_entry(n, &provider->nodes, node_list) {
> > + icc_node_del(n);
> > + icc_node_destroy(n->id);
> > + }
> > +
> > + return icc_provider_del(provider);
> > +}
> > +
> > +static const struct of_device_id mt8183_icc_of_match[] = {
> > + { .compatible = "mediatek,mt8183-emi-icc", .data = &mt8183_icc },
>
> A separate -icc compatible should not be needed.
ok.
>
> Thanks,
> Georgi
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC V2 09/11] dt-bindings: interconnect: Add header for interconnect node
From: Henry Chen @ 2019-08-19 1:43 UTC (permalink / raw)
To: Rob Herring
Cc: Nicolas Boichat, Weiyi Lu, James Liao, Viresh Kumar, linux-kernel,
Stephen Boyd, Fan Chen, devicetree, linux-mediatek,
Matthias Brugger, Georgi Djakov, linux-arm-kernel
In-Reply-To: <20190501202844.GA5092@bogus>
On Wed, 2019-05-01 at 15:28 -0500, Rob Herring wrote:
> On Tue, Apr 30, 2019 at 04:51:03PM +0800, Henry Chen wrote:
> > Add header file for mt8183 interconnect node that could be shared between
> > the interconeect provider driver and Device Tree source files.
> >
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> > include/dt-bindings/interconnect/mtk,mt8183.h | 18 ++++++++++++++++++
> > 1 file changed, 18 insertions(+)
> > create mode 100644 include/dt-bindings/interconnect/mtk,mt8183.h
>
> This goes with the binding patch.
ok, will merged into previous patch 08.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [RFC V2 08/11] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
From: Henry Chen @ 2019-08-19 1:39 UTC (permalink / raw)
To: Rob Herring
Cc: Nicolas Boichat, Weiyi Lu, James Liao, Viresh Kumar, linux-kernel,
Stephen Boyd, Fan Chen, devicetree, linux-mediatek,
Matthias Brugger, Georgi Djakov, linux-arm-kernel
In-Reply-To: <20190501202753.GA2862@bogus>
Hi Rob,
Sorry for late reply.
On Wed, 2019-05-01 at 15:27 -0500, Rob Herring wrote:
> On Tue, Apr 30, 2019 at 04:51:02PM +0800, Henry Chen wrote:
> > Add interconnect provider dt-bindings for MT8183.
> >
> > Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
> > ---
> > .../bindings/interconnect/mtk,mt8183.txt | 24 ++++++++++++++++++++++
> > 1 file changed, 24 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/interconnect/mtk,mt8183.txt
> >
> > diff --git a/Documentation/devicetree/bindings/interconnect/mtk,mt8183.txt b/Documentation/devicetree/bindings/interconnect/mtk,mt8183.txt
> > new file mode 100644
> > index 0000000..1cf1841
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/interconnect/mtk,mt8183.txt
> > @@ -0,0 +1,24 @@
> > +Mediatek MT8183 interconnect binding
>
> This should be part of the dvfsrc binding.
ok, will add these into dvfsrc binding.
>
> > +
> > +MT8183 interconnect providers support dram bandwidth requirements. The provider
> > +is able to communicate with the DVFSRC and send the dram bandwidth to it.
> > +Provider nodes must reside within an DVFSRC device node.
> > +
> > +Required properties :
> > +- compatible : shall contain only one of the following:
> > + "mediatek,mt8183-emi-icc"
> > +- #interconnect-cells : should contain 1
> > +
> > +Examples:
> > +
> > +dvfsrc@10012000 {
> > + compatible = "mediatek,mt8183-dvfsrc";
> > + reg = <0 0x10012000 0 0x1000>;
> > + clocks = <&infracfg CLK_INFRA_DVFSRC>;
> > + clock-names = "dvfsrc";
> > + ddr_emi: interconnect {
> > + compatible = "mediatek,mt8183-emi-icc";
> > + #interconnect-cells = <1>;
>
> No need for a child node here. Just move #interconnect-cells to the
> parent.
Ihave tried and it cannot work if move "#interconnect-cells" to the
parent.
The provider nodes must reside within an DVFSRC device node.
>
> Rob
_______________________________________________
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