linux/drivers/staging/media/imx/imx8mq-mipi-csi2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * NXP i.MX8MQ SoC series MIPI-CSI2 receiver driver
   4 *
   5 * Copyright (C) 2021 Purism SPC
   6 */
   7
   8#include <linux/clk.h>
   9#include <linux/clk-provider.h>
  10#include <linux/delay.h>
  11#include <linux/errno.h>
  12#include <linux/interconnect.h>
  13#include <linux/interrupt.h>
  14#include <linux/io.h>
  15#include <linux/kernel.h>
  16#include <linux/mfd/syscon.h>
  17#include <linux/module.h>
  18#include <linux/mutex.h>
  19#include <linux/of.h>
  20#include <linux/of_device.h>
  21#include <linux/platform_device.h>
  22#include <linux/pm_runtime.h>
  23#include <linux/regmap.h>
  24#include <linux/regulator/consumer.h>
  25#include <linux/reset.h>
  26#include <linux/spinlock.h>
  27
  28#include <media/v4l2-common.h>
  29#include <media/v4l2-device.h>
  30#include <media/v4l2-fwnode.h>
  31#include <media/v4l2-mc.h>
  32#include <media/v4l2-subdev.h>
  33
  34#define MIPI_CSI2_DRIVER_NAME                   "imx8mq-mipi-csi2"
  35#define MIPI_CSI2_SUBDEV_NAME                   MIPI_CSI2_DRIVER_NAME
  36
  37#define MIPI_CSI2_PAD_SINK                      0
  38#define MIPI_CSI2_PAD_SOURCE                    1
  39#define MIPI_CSI2_PADS_NUM                      2
  40
  41#define MIPI_CSI2_DEF_PIX_WIDTH                 640
  42#define MIPI_CSI2_DEF_PIX_HEIGHT                480
  43
  44/* Register map definition */
  45
  46/* i.MX8MQ CSI-2 controller CSR */
  47#define CSI2RX_CFG_NUM_LANES                    0x100
  48#define CSI2RX_CFG_DISABLE_DATA_LANES           0x104
  49#define CSI2RX_BIT_ERR                          0x108
  50#define CSI2RX_IRQ_STATUS                       0x10c
  51#define CSI2RX_IRQ_MASK                         0x110
  52#define CSI2RX_IRQ_MASK_ALL                     0x1ff
  53#define CSI2RX_IRQ_MASK_ULPS_STATUS_CHANGE      0x8
  54#define CSI2RX_ULPS_STATUS                      0x114
  55#define CSI2RX_PPI_ERRSOT_HS                    0x118
  56#define CSI2RX_PPI_ERRSOTSYNC_HS                0x11c
  57#define CSI2RX_PPI_ERRESC                       0x120
  58#define CSI2RX_PPI_ERRSYNCESC                   0x124
  59#define CSI2RX_PPI_ERRCONTROL                   0x128
  60#define CSI2RX_CFG_DISABLE_PAYLOAD_0            0x12c
  61#define CSI2RX_CFG_VID_VC_IGNORE                0x180
  62#define CSI2RX_CFG_VID_VC                       0x184
  63#define CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL        0x188
  64#define CSI2RX_CFG_DISABLE_PAYLOAD_1            0x130
  65
  66enum {
  67        ST_POWERED      = 1,
  68        ST_STREAMING    = 2,
  69        ST_SUSPENDED    = 4,
  70};
  71
  72enum imx8mq_mipi_csi_clk {
  73        CSI2_CLK_CORE,
  74        CSI2_CLK_ESC,
  75        CSI2_CLK_UI,
  76        CSI2_NUM_CLKS,
  77};
  78
  79static const char * const imx8mq_mipi_csi_clk_id[CSI2_NUM_CLKS] = {
  80        [CSI2_CLK_CORE] = "core",
  81        [CSI2_CLK_ESC] = "esc",
  82        [CSI2_CLK_UI] = "ui",
  83};
  84
  85#define CSI2_NUM_CLKS   ARRAY_SIZE(imx8mq_mipi_csi_clk_id)
  86
  87#define GPR_CSI2_1_RX_ENABLE            BIT(13)
  88#define GPR_CSI2_1_VID_INTFC_ENB        BIT(12)
  89#define GPR_CSI2_1_HSEL                 BIT(10)
  90#define GPR_CSI2_1_CONT_CLK_MODE        BIT(8)
  91#define GPR_CSI2_1_S_PRG_RXHS_SETTLE(x) (((x) & 0x3f) << 2)
  92
  93/*
  94 * The send level configures the number of entries that must accumulate in
  95 * the Pixel FIFO before the data will be transferred to the video output.
  96 * The exact value needed for this configuration is dependent on the rate at
  97 * which the sensor transfers data to the CSI-2 Controller and the user
  98 * video clock.
  99 *
 100 * The calculation is the classical rate-in rate-out type of problem: If the
 101 * video bandwidth is 10% faster than the incoming mipi data and the video
 102 * line length is 500 pixels, then the fifo should be allowed to fill
 103 * 10% of the line length or 50 pixels. If the gap data is ok, then the level
 104 * can be set to 16 and ignored.
 105 */
 106#define CSI2RX_SEND_LEVEL                       64
 107
 108struct csi_state {
 109        struct device *dev;
 110        void __iomem *regs;
 111        struct clk_bulk_data clks[CSI2_NUM_CLKS];
 112        struct reset_control *rst;
 113        struct regulator *mipi_phy_regulator;
 114
 115        struct v4l2_subdev sd;
 116        struct media_pad pads[MIPI_CSI2_PADS_NUM];
 117        struct v4l2_async_notifier notifier;
 118        struct v4l2_subdev *src_sd;
 119
 120        struct v4l2_fwnode_bus_mipi_csi2 bus;
 121
 122        struct mutex lock; /* Protect csi2_fmt, format_mbus, state, hs_settle */
 123        const struct csi2_pix_format *csi2_fmt;
 124        struct v4l2_mbus_framefmt format_mbus[MIPI_CSI2_PADS_NUM];
 125        u32 state;
 126        u32 hs_settle;
 127
 128        struct regmap *phy_gpr;
 129        u8 phy_gpr_reg;
 130
 131        struct icc_path                 *icc_path;
 132        s32                             icc_path_bw;
 133};
 134
 135/* -----------------------------------------------------------------------------
 136 * Format helpers
 137 */
 138
 139struct csi2_pix_format {
 140        u32 code;
 141        u8 width;
 142};
 143
 144static const struct csi2_pix_format imx8mq_mipi_csi_formats[] = {
 145        /* RAW (Bayer and greyscale) formats. */
 146        {
 147                .code = MEDIA_BUS_FMT_SBGGR8_1X8,
 148                .width = 8,
 149        }, {
 150                .code = MEDIA_BUS_FMT_SGBRG8_1X8,
 151                .width = 8,
 152        }, {
 153                .code = MEDIA_BUS_FMT_SGRBG8_1X8,
 154                .width = 8,
 155        }, {
 156                .code = MEDIA_BUS_FMT_SRGGB8_1X8,
 157                .width = 8,
 158        }, {
 159                .code = MEDIA_BUS_FMT_Y8_1X8,
 160                .width = 8,
 161        }, {
 162                .code = MEDIA_BUS_FMT_SBGGR10_1X10,
 163                .width = 10,
 164        }, {
 165                .code = MEDIA_BUS_FMT_SGBRG10_1X10,
 166                .width = 10,
 167        }, {
 168                .code = MEDIA_BUS_FMT_SGRBG10_1X10,
 169                .width = 10,
 170        }, {
 171                .code = MEDIA_BUS_FMT_SRGGB10_1X10,
 172                .width = 10,
 173        }, {
 174                .code = MEDIA_BUS_FMT_Y10_1X10,
 175                .width = 10,
 176        }, {
 177                .code = MEDIA_BUS_FMT_SBGGR12_1X12,
 178                .width = 12,
 179        }, {
 180                .code = MEDIA_BUS_FMT_SGBRG12_1X12,
 181                .width = 12,
 182        }, {
 183                .code = MEDIA_BUS_FMT_SGRBG12_1X12,
 184                .width = 12,
 185        }, {
 186                .code = MEDIA_BUS_FMT_SRGGB12_1X12,
 187                .width = 12,
 188        }, {
 189                .code = MEDIA_BUS_FMT_Y12_1X12,
 190                .width = 12,
 191        }, {
 192                .code = MEDIA_BUS_FMT_SBGGR14_1X14,
 193                .width = 14,
 194        }, {
 195                .code = MEDIA_BUS_FMT_SGBRG14_1X14,
 196                .width = 14,
 197        }, {
 198                .code = MEDIA_BUS_FMT_SGRBG14_1X14,
 199                .width = 14,
 200        }, {
 201                .code = MEDIA_BUS_FMT_SRGGB14_1X14,
 202                .width = 14,
 203        }, {
 204        /* YUV formats */
 205                .code = MEDIA_BUS_FMT_YUYV8_2X8,
 206                .width = 16,
 207        }, {
 208                .code = MEDIA_BUS_FMT_YUYV8_1X16,
 209                .width = 16,
 210        }
 211};
 212
 213static const struct csi2_pix_format *find_csi2_format(u32 code)
 214{
 215        unsigned int i;
 216
 217        for (i = 0; i < ARRAY_SIZE(imx8mq_mipi_csi_formats); i++)
 218                if (code == imx8mq_mipi_csi_formats[i].code)
 219                        return &imx8mq_mipi_csi_formats[i];
 220        return NULL;
 221}
 222
 223/* -----------------------------------------------------------------------------
 224 * Hardware configuration
 225 */
 226
 227static inline void imx8mq_mipi_csi_write(struct csi_state *state, u32 reg, u32 val)
 228{
 229        writel(val, state->regs + reg);
 230}
 231
 232static int imx8mq_mipi_csi_sw_reset(struct csi_state *state)
 233{
 234        int ret;
 235
 236        /*
 237         * these are most likely self-clearing reset bits. to make it
 238         * more clear, the reset-imx7 driver should implement the
 239         * .reset() operation.
 240         */
 241        ret = reset_control_assert(state->rst);
 242        if (ret < 0) {
 243                dev_err(state->dev, "Failed to assert resets: %d\n", ret);
 244                return ret;
 245        }
 246
 247        return 0;
 248}
 249
 250static void imx8mq_mipi_csi_system_enable(struct csi_state *state, int on)
 251{
 252        if (!on) {
 253                imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES, 0xf);
 254                return;
 255        }
 256
 257        regmap_update_bits(state->phy_gpr,
 258                           state->phy_gpr_reg,
 259                           0x3fff,
 260                           GPR_CSI2_1_RX_ENABLE |
 261                           GPR_CSI2_1_VID_INTFC_ENB |
 262                           GPR_CSI2_1_HSEL |
 263                           GPR_CSI2_1_CONT_CLK_MODE |
 264                           GPR_CSI2_1_S_PRG_RXHS_SETTLE(state->hs_settle));
 265}
 266
 267static void imx8mq_mipi_csi_set_params(struct csi_state *state)
 268{
 269        int lanes = state->bus.num_data_lanes;
 270
 271        imx8mq_mipi_csi_write(state, CSI2RX_CFG_NUM_LANES, lanes - 1);
 272        imx8mq_mipi_csi_write(state, CSI2RX_CFG_DISABLE_DATA_LANES,
 273                              (0xf << lanes) & 0xf);
 274        imx8mq_mipi_csi_write(state, CSI2RX_IRQ_MASK, CSI2RX_IRQ_MASK_ALL);
 275        /*
 276         * 0x180 bit 0 controls the Virtual Channel behaviour: when set the
 277         * interface ignores the Virtual Channel (VC) field in received packets;
 278         * when cleared it causes the interface to only accept packets whose VC
 279         * matches the value to which VC is set at offset 0x184.
 280         */
 281        imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_VC_IGNORE, 1);
 282        imx8mq_mipi_csi_write(state, CSI2RX_CFG_VID_P_FIFO_SEND_LEVEL,
 283                              CSI2RX_SEND_LEVEL);
 284}
 285
 286static int imx8mq_mipi_csi_clk_enable(struct csi_state *state)
 287{
 288        return clk_bulk_prepare_enable(CSI2_NUM_CLKS, state->clks);
 289}
 290
 291static void imx8mq_mipi_csi_clk_disable(struct csi_state *state)
 292{
 293        clk_bulk_disable_unprepare(CSI2_NUM_CLKS, state->clks);
 294}
 295
 296static int imx8mq_mipi_csi_clk_get(struct csi_state *state)
 297{
 298        unsigned int i;
 299
 300        for (i = 0; i < CSI2_NUM_CLKS; i++)
 301                state->clks[i].id = imx8mq_mipi_csi_clk_id[i];
 302
 303        return devm_clk_bulk_get(state->dev, CSI2_NUM_CLKS, state->clks);
 304}
 305
 306static int imx8mq_mipi_csi_calc_hs_settle(struct csi_state *state)
 307{
 308        s64 link_freq;
 309        u32 lane_rate;
 310        unsigned long esc_clk_rate;
 311        u32 min_ths_settle, max_ths_settle, ths_settle_ns, esc_clk_period_ns;
 312
 313        /* Calculate the line rate from the pixel rate. */
 314        link_freq = v4l2_get_link_freq(state->src_sd->ctrl_handler,
 315                                       state->csi2_fmt->width,
 316                                       state->bus.num_data_lanes * 2);
 317        if (link_freq < 0) {
 318                dev_err(state->dev, "Unable to obtain link frequency: %d\n",
 319                        (int)link_freq);
 320                return link_freq;
 321        }
 322
 323        lane_rate = link_freq * 2;
 324        if (lane_rate < 80000000 || lane_rate > 1500000000) {
 325                dev_dbg(state->dev, "Out-of-bound lane rate %u\n", lane_rate);
 326                return -EINVAL;
 327        }
 328
 329        /*
 330         * The D-PHY specification requires Ths-settle to be in the range
 331         * 85ns + 6*UI to 140ns + 10*UI, with the unit interval UI being half
 332         * the clock period.
 333         *
 334         * The Ths-settle value is expressed in the hardware as a multiple of
 335         * the Esc clock period:
 336         *
 337         * Ths-settle = (PRG_RXHS_SETTLE + 1) * Tperiod of RxClkInEsc
 338         *
 339         * Due to the one cycle inaccuracy introduced by rounding, the
 340         * documentation recommends picking a value away from the boundaries.
 341         * Let's pick the average.
 342         */
 343        esc_clk_rate = clk_get_rate(state->clks[CSI2_CLK_ESC].clk);
 344        if (!esc_clk_rate) {
 345                dev_err(state->dev, "Could not get esc clock rate.\n");
 346                return -EINVAL;
 347        }
 348
 349        dev_dbg(state->dev, "esc clk rate: %lu\n", esc_clk_rate);
 350        esc_clk_period_ns = 1000000000 / esc_clk_rate;
 351
 352        min_ths_settle = 85 + 6 * 1000000 / (lane_rate / 1000);
 353        max_ths_settle = 140 + 10 * 1000000 / (lane_rate / 1000);
 354        ths_settle_ns = (min_ths_settle + max_ths_settle) / 2;
 355
 356        state->hs_settle = ths_settle_ns / esc_clk_period_ns - 1;
 357
 358        dev_dbg(state->dev, "lane rate %u Ths_settle %u hs_settle %u\n",
 359                lane_rate, ths_settle_ns, state->hs_settle);
 360
 361        return 0;
 362}
 363
 364static int imx8mq_mipi_csi_start_stream(struct csi_state *state)
 365{
 366        int ret;
 367
 368        ret = imx8mq_mipi_csi_sw_reset(state);
 369        if (ret)
 370                return ret;
 371
 372        imx8mq_mipi_csi_set_params(state);
 373        ret = imx8mq_mipi_csi_calc_hs_settle(state);
 374        if (ret)
 375                return ret;
 376
 377        imx8mq_mipi_csi_system_enable(state, true);
 378
 379        return 0;
 380}
 381
 382static void imx8mq_mipi_csi_stop_stream(struct csi_state *state)
 383{
 384        imx8mq_mipi_csi_system_enable(state, false);
 385}
 386
 387/* -----------------------------------------------------------------------------
 388 * V4L2 subdev operations
 389 */
 390
 391static struct csi_state *mipi_sd_to_csi2_state(struct v4l2_subdev *sdev)
 392{
 393        return container_of(sdev, struct csi_state, sd);
 394}
 395
 396static int imx8mq_mipi_csi_s_stream(struct v4l2_subdev *sd, int enable)
 397{
 398        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 399        int ret = 0;
 400
 401        imx8mq_mipi_csi_write(state, CSI2RX_IRQ_MASK,
 402                              CSI2RX_IRQ_MASK_ULPS_STATUS_CHANGE);
 403
 404        if (enable) {
 405                ret = pm_runtime_resume_and_get(state->dev);
 406                if (ret < 0)
 407                        return ret;
 408        }
 409
 410        mutex_lock(&state->lock);
 411
 412        if (enable) {
 413                if (state->state & ST_SUSPENDED) {
 414                        ret = -EBUSY;
 415                        goto unlock;
 416                }
 417
 418                ret = imx8mq_mipi_csi_start_stream(state);
 419                if (ret < 0)
 420                        goto unlock;
 421
 422                ret = v4l2_subdev_call(state->src_sd, video, s_stream, 1);
 423                if (ret < 0)
 424                        goto unlock;
 425
 426                state->state |= ST_STREAMING;
 427        } else {
 428                v4l2_subdev_call(state->src_sd, video, s_stream, 0);
 429                imx8mq_mipi_csi_stop_stream(state);
 430                state->state &= ~ST_STREAMING;
 431        }
 432
 433unlock:
 434        mutex_unlock(&state->lock);
 435
 436        if (!enable || ret < 0)
 437                pm_runtime_put(state->dev);
 438
 439        return ret;
 440}
 441
 442static struct v4l2_mbus_framefmt *
 443imx8mq_mipi_csi_get_format(struct csi_state *state,
 444                           struct v4l2_subdev_state *sd_state,
 445                           enum v4l2_subdev_format_whence which,
 446                           unsigned int pad)
 447{
 448        if (which == V4L2_SUBDEV_FORMAT_TRY)
 449                return v4l2_subdev_get_try_format(&state->sd, sd_state, pad);
 450
 451        return &state->format_mbus[pad];
 452}
 453
 454static int imx8mq_mipi_csi_init_cfg(struct v4l2_subdev *sd,
 455                                    struct v4l2_subdev_state *sd_state)
 456{
 457        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 458        struct v4l2_mbus_framefmt *fmt_sink;
 459        struct v4l2_mbus_framefmt *fmt_source;
 460        enum v4l2_subdev_format_whence which;
 461
 462        which = sd_state ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
 463        fmt_sink = imx8mq_mipi_csi_get_format(state, sd_state, which,
 464                                              MIPI_CSI2_PAD_SINK);
 465
 466        fmt_sink->code = MEDIA_BUS_FMT_SGBRG10_1X10;
 467        fmt_sink->width = MIPI_CSI2_DEF_PIX_WIDTH;
 468        fmt_sink->height = MIPI_CSI2_DEF_PIX_HEIGHT;
 469        fmt_sink->field = V4L2_FIELD_NONE;
 470
 471        fmt_sink->colorspace = V4L2_COLORSPACE_RAW;
 472        fmt_sink->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt_sink->colorspace);
 473        fmt_sink->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt_sink->colorspace);
 474        fmt_sink->quantization =
 475                V4L2_MAP_QUANTIZATION_DEFAULT(false, fmt_sink->colorspace,
 476                                              fmt_sink->ycbcr_enc);
 477
 478        fmt_source = imx8mq_mipi_csi_get_format(state, sd_state, which,
 479                                                MIPI_CSI2_PAD_SOURCE);
 480        *fmt_source = *fmt_sink;
 481
 482        return 0;
 483}
 484
 485static int imx8mq_mipi_csi_get_fmt(struct v4l2_subdev *sd,
 486                                   struct v4l2_subdev_state *sd_state,
 487                                   struct v4l2_subdev_format *sdformat)
 488{
 489        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 490        struct v4l2_mbus_framefmt *fmt;
 491
 492        fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which,
 493                                         sdformat->pad);
 494
 495        mutex_lock(&state->lock);
 496
 497        sdformat->format = *fmt;
 498
 499        mutex_unlock(&state->lock);
 500
 501        return 0;
 502}
 503
 504static int imx8mq_mipi_csi_enum_mbus_code(struct v4l2_subdev *sd,
 505                                          struct v4l2_subdev_state *sd_state,
 506                                          struct v4l2_subdev_mbus_code_enum *code)
 507{
 508        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 509
 510        /*
 511         * We can't transcode in any way, the source format is identical
 512         * to the sink format.
 513         */
 514        if (code->pad == MIPI_CSI2_PAD_SOURCE) {
 515                struct v4l2_mbus_framefmt *fmt;
 516
 517                if (code->index > 0)
 518                        return -EINVAL;
 519
 520                fmt = imx8mq_mipi_csi_get_format(state, sd_state, code->which,
 521                                                 code->pad);
 522                code->code = fmt->code;
 523                return 0;
 524        }
 525
 526        if (code->pad != MIPI_CSI2_PAD_SINK)
 527                return -EINVAL;
 528
 529        if (code->index >= ARRAY_SIZE(imx8mq_mipi_csi_formats))
 530                return -EINVAL;
 531
 532        code->code = imx8mq_mipi_csi_formats[code->index].code;
 533
 534        return 0;
 535}
 536
 537static int imx8mq_mipi_csi_set_fmt(struct v4l2_subdev *sd,
 538                                   struct v4l2_subdev_state *sd_state,
 539                                   struct v4l2_subdev_format *sdformat)
 540{
 541        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 542        struct csi2_pix_format const *csi2_fmt;
 543        struct v4l2_mbus_framefmt *fmt;
 544
 545        /*
 546         * The device can't transcode in any way, the source format can't be
 547         * modified.
 548         */
 549        if (sdformat->pad == MIPI_CSI2_PAD_SOURCE)
 550                return imx8mq_mipi_csi_get_fmt(sd, sd_state, sdformat);
 551
 552        if (sdformat->pad != MIPI_CSI2_PAD_SINK)
 553                return -EINVAL;
 554
 555        csi2_fmt = find_csi2_format(sdformat->format.code);
 556        if (!csi2_fmt)
 557                csi2_fmt = &imx8mq_mipi_csi_formats[0];
 558
 559        fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which,
 560                                         sdformat->pad);
 561
 562        mutex_lock(&state->lock);
 563
 564        fmt->code = csi2_fmt->code;
 565        fmt->width = sdformat->format.width;
 566        fmt->height = sdformat->format.height;
 567
 568        sdformat->format = *fmt;
 569
 570        /* Propagate the format from sink to source. */
 571        fmt = imx8mq_mipi_csi_get_format(state, sd_state, sdformat->which,
 572                                         MIPI_CSI2_PAD_SOURCE);
 573        *fmt = sdformat->format;
 574
 575        /* Store the CSI2 format descriptor for active formats. */
 576        if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
 577                state->csi2_fmt = csi2_fmt;
 578
 579        mutex_unlock(&state->lock);
 580
 581        return 0;
 582}
 583
 584static const struct v4l2_subdev_video_ops imx8mq_mipi_csi_video_ops = {
 585        .s_stream       = imx8mq_mipi_csi_s_stream,
 586};
 587
 588static const struct v4l2_subdev_pad_ops imx8mq_mipi_csi_pad_ops = {
 589        .init_cfg               = imx8mq_mipi_csi_init_cfg,
 590        .enum_mbus_code         = imx8mq_mipi_csi_enum_mbus_code,
 591        .get_fmt                = imx8mq_mipi_csi_get_fmt,
 592        .set_fmt                = imx8mq_mipi_csi_set_fmt,
 593};
 594
 595static const struct v4l2_subdev_ops imx8mq_mipi_csi_subdev_ops = {
 596        .video  = &imx8mq_mipi_csi_video_ops,
 597        .pad    = &imx8mq_mipi_csi_pad_ops,
 598};
 599
 600/* -----------------------------------------------------------------------------
 601 * Media entity operations
 602 */
 603
 604static const struct media_entity_operations imx8mq_mipi_csi_entity_ops = {
 605        .link_validate  = v4l2_subdev_link_validate,
 606        .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
 607};
 608
 609/* -----------------------------------------------------------------------------
 610 * Async subdev notifier
 611 */
 612
 613static struct csi_state *
 614mipi_notifier_to_csi2_state(struct v4l2_async_notifier *n)
 615{
 616        return container_of(n, struct csi_state, notifier);
 617}
 618
 619static int imx8mq_mipi_csi_notify_bound(struct v4l2_async_notifier *notifier,
 620                                        struct v4l2_subdev *sd,
 621                                        struct v4l2_async_subdev *asd)
 622{
 623        struct csi_state *state = mipi_notifier_to_csi2_state(notifier);
 624        struct media_pad *sink = &state->sd.entity.pads[MIPI_CSI2_PAD_SINK];
 625
 626        state->src_sd = sd;
 627
 628        return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED |
 629                                               MEDIA_LNK_FL_IMMUTABLE);
 630}
 631
 632static const struct v4l2_async_notifier_operations imx8mq_mipi_csi_notify_ops = {
 633        .bound = imx8mq_mipi_csi_notify_bound,
 634};
 635
 636static int imx8mq_mipi_csi_async_register(struct csi_state *state)
 637{
 638        struct v4l2_fwnode_endpoint vep = {
 639                .bus_type = V4L2_MBUS_CSI2_DPHY,
 640        };
 641        struct v4l2_async_subdev *asd;
 642        struct fwnode_handle *ep;
 643        unsigned int i;
 644        int ret;
 645
 646        v4l2_async_notifier_init(&state->notifier);
 647
 648        ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(state->dev), 0, 0,
 649                                             FWNODE_GRAPH_ENDPOINT_NEXT);
 650        if (!ep)
 651                return -ENOTCONN;
 652
 653        ret = v4l2_fwnode_endpoint_parse(ep, &vep);
 654        if (ret)
 655                goto err_parse;
 656
 657        for (i = 0; i < vep.bus.mipi_csi2.num_data_lanes; ++i) {
 658                if (vep.bus.mipi_csi2.data_lanes[i] != i + 1) {
 659                        dev_err(state->dev,
 660                                "data lanes reordering is not supported");
 661                        ret = -EINVAL;
 662                        goto err_parse;
 663                }
 664        }
 665
 666        state->bus = vep.bus.mipi_csi2;
 667
 668        dev_dbg(state->dev, "data lanes: %d flags: 0x%08x\n",
 669                state->bus.num_data_lanes,
 670                state->bus.flags);
 671
 672        asd = v4l2_async_notifier_add_fwnode_remote_subdev(&state->notifier,
 673                                                           ep, struct v4l2_async_subdev);
 674        if (IS_ERR(asd)) {
 675                ret = PTR_ERR(asd);
 676                goto err_parse;
 677        }
 678
 679        fwnode_handle_put(ep);
 680
 681        state->notifier.ops = &imx8mq_mipi_csi_notify_ops;
 682
 683        ret = v4l2_async_subdev_notifier_register(&state->sd, &state->notifier);
 684        if (ret)
 685                return ret;
 686
 687        return v4l2_async_register_subdev(&state->sd);
 688
 689err_parse:
 690        fwnode_handle_put(ep);
 691
 692        return ret;
 693}
 694
 695/* -----------------------------------------------------------------------------
 696 * Suspend/resume
 697 */
 698
 699static int imx8mq_mipi_csi_pm_suspend(struct device *dev, bool runtime)
 700{
 701        struct v4l2_subdev *sd = dev_get_drvdata(dev);
 702        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 703        int ret = 0;
 704
 705        mutex_lock(&state->lock);
 706
 707        if (state->state & ST_POWERED) {
 708                imx8mq_mipi_csi_stop_stream(state);
 709                imx8mq_mipi_csi_clk_disable(state);
 710                state->state &= ~ST_POWERED;
 711                if (!runtime)
 712                        state->state |= ST_SUSPENDED;
 713        }
 714
 715        mutex_unlock(&state->lock);
 716
 717        ret = icc_set_bw(state->icc_path, 0, 0);
 718        if (ret)
 719                dev_err(dev, "icc_set_bw failed with %d\n", ret);
 720
 721        return ret ? -EAGAIN : 0;
 722}
 723
 724static int imx8mq_mipi_csi_pm_resume(struct device *dev, bool runtime)
 725{
 726        struct v4l2_subdev *sd = dev_get_drvdata(dev);
 727        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 728        int ret = 0;
 729
 730        ret = icc_set_bw(state->icc_path, 0, state->icc_path_bw);
 731        if (ret) {
 732                dev_err(dev, "icc_set_bw failed with %d\n", ret);
 733                return ret;
 734        }
 735
 736        mutex_lock(&state->lock);
 737
 738        if (!runtime && !(state->state & ST_SUSPENDED))
 739                goto unlock;
 740
 741        if (!(state->state & ST_POWERED)) {
 742                state->state |= ST_POWERED;
 743                ret = imx8mq_mipi_csi_clk_enable(state);
 744        }
 745        if (state->state & ST_STREAMING) {
 746                ret = imx8mq_mipi_csi_start_stream(state);
 747                if (ret)
 748                        goto unlock;
 749        }
 750
 751        state->state &= ~ST_SUSPENDED;
 752
 753unlock:
 754        mutex_unlock(&state->lock);
 755
 756        return ret ? -EAGAIN : 0;
 757}
 758
 759static int __maybe_unused imx8mq_mipi_csi_suspend(struct device *dev)
 760{
 761        return imx8mq_mipi_csi_pm_suspend(dev, false);
 762}
 763
 764static int __maybe_unused imx8mq_mipi_csi_resume(struct device *dev)
 765{
 766        return imx8mq_mipi_csi_pm_resume(dev, false);
 767}
 768
 769static int __maybe_unused imx8mq_mipi_csi_runtime_suspend(struct device *dev)
 770{
 771        return imx8mq_mipi_csi_pm_suspend(dev, true);
 772}
 773
 774static int __maybe_unused imx8mq_mipi_csi_runtime_resume(struct device *dev)
 775{
 776        return imx8mq_mipi_csi_pm_resume(dev, true);
 777}
 778
 779static const struct dev_pm_ops imx8mq_mipi_csi_pm_ops = {
 780        SET_RUNTIME_PM_OPS(imx8mq_mipi_csi_runtime_suspend,
 781                           imx8mq_mipi_csi_runtime_resume,
 782                           NULL)
 783        SET_SYSTEM_SLEEP_PM_OPS(imx8mq_mipi_csi_suspend, imx8mq_mipi_csi_resume)
 784};
 785
 786/* -----------------------------------------------------------------------------
 787 * Probe/remove & platform driver
 788 */
 789
 790static int imx8mq_mipi_csi_subdev_init(struct csi_state *state)
 791{
 792        struct v4l2_subdev *sd = &state->sd;
 793
 794        v4l2_subdev_init(sd, &imx8mq_mipi_csi_subdev_ops);
 795        sd->owner = THIS_MODULE;
 796        snprintf(sd->name, sizeof(sd->name), "%s %s",
 797                 MIPI_CSI2_SUBDEV_NAME, dev_name(state->dev));
 798
 799        sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 800
 801        sd->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
 802        sd->entity.ops = &imx8mq_mipi_csi_entity_ops;
 803
 804        sd->dev = state->dev;
 805
 806        state->csi2_fmt = &imx8mq_mipi_csi_formats[0];
 807        imx8mq_mipi_csi_init_cfg(sd, NULL);
 808
 809        state->pads[MIPI_CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK
 810                                         | MEDIA_PAD_FL_MUST_CONNECT;
 811        state->pads[MIPI_CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE
 812                                           | MEDIA_PAD_FL_MUST_CONNECT;
 813        return media_entity_pads_init(&sd->entity, MIPI_CSI2_PADS_NUM,
 814                                      state->pads);
 815}
 816
 817static void imx8mq_mipi_csi_release_icc(struct platform_device *pdev)
 818{
 819        struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
 820        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 821
 822        icc_put(state->icc_path);
 823}
 824
 825static int imx8mq_mipi_csi_init_icc(struct platform_device *pdev)
 826{
 827        struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
 828        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 829
 830        /* Optional interconnect request */
 831        state->icc_path = of_icc_get(&pdev->dev, "dram");
 832        if (IS_ERR_OR_NULL(state->icc_path))
 833                return PTR_ERR_OR_ZERO(state->icc_path);
 834
 835        state->icc_path_bw = MBps_to_icc(700);
 836
 837        return 0;
 838}
 839
 840static int imx8mq_mipi_csi_parse_dt(struct csi_state *state)
 841{
 842        struct device *dev = state->dev;
 843        struct device_node *np = state->dev->of_node;
 844        struct device_node *node;
 845        phandle ph;
 846        u32 out_val[2];
 847        int ret = 0;
 848
 849        state->rst = devm_reset_control_array_get_exclusive(dev);
 850        if (IS_ERR(state->rst)) {
 851                dev_err(dev, "Failed to get reset: %pe\n", state->rst);
 852                return PTR_ERR(state->rst);
 853        }
 854
 855        ret = of_property_read_u32_array(np, "fsl,mipi-phy-gpr", out_val,
 856                                         ARRAY_SIZE(out_val));
 857        if (ret) {
 858                dev_err(dev, "no fsl,mipi-phy-gpr property found: %d\n", ret);
 859                return ret;
 860        }
 861
 862        ph = *out_val;
 863
 864        node = of_find_node_by_phandle(ph);
 865        if (!node) {
 866                dev_err(dev, "Error finding node by phandle\n");
 867                return -ENODEV;
 868        }
 869        state->phy_gpr = syscon_node_to_regmap(node);
 870        of_node_put(node);
 871        if (IS_ERR(state->phy_gpr)) {
 872                dev_err(dev, "failed to get gpr regmap: %pe\n", state->phy_gpr);
 873                return PTR_ERR(state->phy_gpr);
 874        }
 875
 876        state->phy_gpr_reg = out_val[1];
 877        dev_dbg(dev, "phy gpr register set to 0x%x\n", state->phy_gpr_reg);
 878
 879        return ret;
 880}
 881
 882static int imx8mq_mipi_csi_probe(struct platform_device *pdev)
 883{
 884        struct device *dev = &pdev->dev;
 885        struct csi_state *state;
 886        int ret;
 887
 888        state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
 889        if (!state)
 890                return -ENOMEM;
 891
 892        state->dev = dev;
 893
 894        ret = imx8mq_mipi_csi_parse_dt(state);
 895        if (ret < 0) {
 896                dev_err(dev, "Failed to parse device tree: %d\n", ret);
 897                return ret;
 898        }
 899
 900        /* Acquire resources. */
 901        state->regs = devm_platform_ioremap_resource(pdev, 0);
 902        if (IS_ERR(state->regs))
 903                return PTR_ERR(state->regs);
 904
 905        ret = imx8mq_mipi_csi_clk_get(state);
 906        if (ret < 0)
 907                return ret;
 908
 909        platform_set_drvdata(pdev, &state->sd);
 910
 911        mutex_init(&state->lock);
 912
 913        ret = imx8mq_mipi_csi_subdev_init(state);
 914        if (ret < 0)
 915                goto mutex;
 916
 917        ret = imx8mq_mipi_csi_init_icc(pdev);
 918        if (ret)
 919                goto mutex;
 920
 921        /* Enable runtime PM. */
 922        pm_runtime_enable(dev);
 923        if (!pm_runtime_enabled(dev)) {
 924                ret = imx8mq_mipi_csi_pm_resume(dev, true);
 925                if (ret < 0)
 926                        goto icc;
 927        }
 928
 929        ret = imx8mq_mipi_csi_async_register(state);
 930        if (ret < 0)
 931                goto cleanup;
 932
 933        return 0;
 934
 935cleanup:
 936        pm_runtime_disable(&pdev->dev);
 937        imx8mq_mipi_csi_pm_suspend(&pdev->dev, true);
 938
 939        media_entity_cleanup(&state->sd.entity);
 940        v4l2_async_notifier_unregister(&state->notifier);
 941        v4l2_async_notifier_cleanup(&state->notifier);
 942        v4l2_async_unregister_subdev(&state->sd);
 943icc:
 944        imx8mq_mipi_csi_release_icc(pdev);
 945mutex:
 946        mutex_destroy(&state->lock);
 947
 948        return ret;
 949}
 950
 951static int imx8mq_mipi_csi_remove(struct platform_device *pdev)
 952{
 953        struct v4l2_subdev *sd = platform_get_drvdata(pdev);
 954        struct csi_state *state = mipi_sd_to_csi2_state(sd);
 955
 956        v4l2_async_notifier_unregister(&state->notifier);
 957        v4l2_async_notifier_cleanup(&state->notifier);
 958        v4l2_async_unregister_subdev(&state->sd);
 959
 960        pm_runtime_disable(&pdev->dev);
 961        imx8mq_mipi_csi_pm_suspend(&pdev->dev, true);
 962        media_entity_cleanup(&state->sd.entity);
 963        mutex_destroy(&state->lock);
 964        pm_runtime_set_suspended(&pdev->dev);
 965        imx8mq_mipi_csi_release_icc(pdev);
 966
 967        return 0;
 968}
 969
 970static const struct of_device_id imx8mq_mipi_csi_of_match[] = {
 971        { .compatible = "fsl,imx8mq-mipi-csi2", },
 972        { /* sentinel */ },
 973};
 974MODULE_DEVICE_TABLE(of, imx8mq_mipi_csi_of_match);
 975
 976static struct platform_driver imx8mq_mipi_csi_driver = {
 977        .probe          = imx8mq_mipi_csi_probe,
 978        .remove         = imx8mq_mipi_csi_remove,
 979        .driver         = {
 980                .of_match_table = imx8mq_mipi_csi_of_match,
 981                .name           = MIPI_CSI2_DRIVER_NAME,
 982                .pm             = &imx8mq_mipi_csi_pm_ops,
 983        },
 984};
 985
 986module_platform_driver(imx8mq_mipi_csi_driver);
 987
 988MODULE_DESCRIPTION("i.MX8MQ MIPI CSI-2 receiver driver");
 989MODULE_AUTHOR("Martin Kepplinger <martin.kepplinger@puri.sm>");
 990MODULE_LICENSE("GPL v2");
 991MODULE_ALIAS("platform:imx8mq-mipi-csi2");
 992