linux/drivers/media/platform/exynos4-is/mipi-csis.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Samsung S5P/EXYNOS SoC series MIPI-CSI receiver driver
   4 *
   5 * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd.
   6 * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/delay.h>
  11#include <linux/device.h>
  12#include <linux/errno.h>
  13#include <linux/interrupt.h>
  14#include <linux/io.h>
  15#include <linux/irq.h>
  16#include <linux/kernel.h>
  17#include <linux/memory.h>
  18#include <linux/module.h>
  19#include <linux/of.h>
  20#include <linux/of_graph.h>
  21#include <linux/phy/phy.h>
  22#include <linux/platform_device.h>
  23#include <linux/pm_runtime.h>
  24#include <linux/regulator/consumer.h>
  25#include <linux/sizes.h>
  26#include <linux/slab.h>
  27#include <linux/spinlock.h>
  28#include <linux/videodev2.h>
  29#include <media/drv-intf/exynos-fimc.h>
  30#include <media/v4l2-fwnode.h>
  31#include <media/v4l2-subdev.h>
  32
  33#include "mipi-csis.h"
  34
  35static int debug;
  36module_param(debug, int, 0644);
  37MODULE_PARM_DESC(debug, "Debug level (0-2)");
  38
  39/* Register map definition */
  40
  41/* CSIS global control */
  42#define S5PCSIS_CTRL                    0x00
  43#define S5PCSIS_CTRL_DPDN_DEFAULT       (0 << 31)
  44#define S5PCSIS_CTRL_DPDN_SWAP          (1 << 31)
  45#define S5PCSIS_CTRL_ALIGN_32BIT        (1 << 20)
  46#define S5PCSIS_CTRL_UPDATE_SHADOW      (1 << 16)
  47#define S5PCSIS_CTRL_WCLK_EXTCLK        (1 << 8)
  48#define S5PCSIS_CTRL_RESET              (1 << 4)
  49#define S5PCSIS_CTRL_ENABLE             (1 << 0)
  50
  51/* D-PHY control */
  52#define S5PCSIS_DPHYCTRL                0x04
  53#define S5PCSIS_DPHYCTRL_HSS_MASK       (0x1f << 27)
  54#define S5PCSIS_DPHYCTRL_ENABLE         (0x1f << 0)
  55
  56#define S5PCSIS_CONFIG                  0x08
  57#define S5PCSIS_CFG_FMT_YCBCR422_8BIT   (0x1e << 2)
  58#define S5PCSIS_CFG_FMT_RAW8            (0x2a << 2)
  59#define S5PCSIS_CFG_FMT_RAW10           (0x2b << 2)
  60#define S5PCSIS_CFG_FMT_RAW12           (0x2c << 2)
  61/* User defined formats, x = 1...4 */
  62#define S5PCSIS_CFG_FMT_USER(x)         ((0x30 + x - 1) << 2)
  63#define S5PCSIS_CFG_FMT_MASK            (0x3f << 2)
  64#define S5PCSIS_CFG_NR_LANE_MASK        3
  65
  66/* Interrupt mask */
  67#define S5PCSIS_INTMSK                  0x10
  68#define S5PCSIS_INTMSK_EVEN_BEFORE      (1 << 31)
  69#define S5PCSIS_INTMSK_EVEN_AFTER       (1 << 30)
  70#define S5PCSIS_INTMSK_ODD_BEFORE       (1 << 29)
  71#define S5PCSIS_INTMSK_ODD_AFTER        (1 << 28)
  72#define S5PCSIS_INTMSK_FRAME_START      (1 << 27)
  73#define S5PCSIS_INTMSK_FRAME_END        (1 << 26)
  74#define S5PCSIS_INTMSK_ERR_SOT_HS       (1 << 12)
  75#define S5PCSIS_INTMSK_ERR_LOST_FS      (1 << 5)
  76#define S5PCSIS_INTMSK_ERR_LOST_FE      (1 << 4)
  77#define S5PCSIS_INTMSK_ERR_OVER         (1 << 3)
  78#define S5PCSIS_INTMSK_ERR_ECC          (1 << 2)
  79#define S5PCSIS_INTMSK_ERR_CRC          (1 << 1)
  80#define S5PCSIS_INTMSK_ERR_UNKNOWN      (1 << 0)
  81#define S5PCSIS_INTMSK_EXYNOS4_EN_ALL   0xf000103f
  82#define S5PCSIS_INTMSK_EXYNOS5_EN_ALL   0xfc00103f
  83
  84/* Interrupt source */
  85#define S5PCSIS_INTSRC                  0x14
  86#define S5PCSIS_INTSRC_EVEN_BEFORE      (1 << 31)
  87#define S5PCSIS_INTSRC_EVEN_AFTER       (1 << 30)
  88#define S5PCSIS_INTSRC_EVEN             (0x3 << 30)
  89#define S5PCSIS_INTSRC_ODD_BEFORE       (1 << 29)
  90#define S5PCSIS_INTSRC_ODD_AFTER        (1 << 28)
  91#define S5PCSIS_INTSRC_ODD              (0x3 << 28)
  92#define S5PCSIS_INTSRC_NON_IMAGE_DATA   (0xf << 28)
  93#define S5PCSIS_INTSRC_FRAME_START      (1 << 27)
  94#define S5PCSIS_INTSRC_FRAME_END        (1 << 26)
  95#define S5PCSIS_INTSRC_ERR_SOT_HS       (0xf << 12)
  96#define S5PCSIS_INTSRC_ERR_LOST_FS      (1 << 5)
  97#define S5PCSIS_INTSRC_ERR_LOST_FE      (1 << 4)
  98#define S5PCSIS_INTSRC_ERR_OVER         (1 << 3)
  99#define S5PCSIS_INTSRC_ERR_ECC          (1 << 2)
 100#define S5PCSIS_INTSRC_ERR_CRC          (1 << 1)
 101#define S5PCSIS_INTSRC_ERR_UNKNOWN      (1 << 0)
 102#define S5PCSIS_INTSRC_ERRORS           0xf03f
 103
 104/* Pixel resolution */
 105#define S5PCSIS_RESOL                   0x2c
 106#define CSIS_MAX_PIX_WIDTH              0xffff
 107#define CSIS_MAX_PIX_HEIGHT             0xffff
 108
 109/* Non-image packet data buffers */
 110#define S5PCSIS_PKTDATA_ODD             0x2000
 111#define S5PCSIS_PKTDATA_EVEN            0x3000
 112#define S5PCSIS_PKTDATA_SIZE            SZ_4K
 113
 114enum {
 115        CSIS_CLK_MUX,
 116        CSIS_CLK_GATE,
 117};
 118
 119static char *csi_clock_name[] = {
 120        [CSIS_CLK_MUX]  = "sclk_csis",
 121        [CSIS_CLK_GATE] = "csis",
 122};
 123#define NUM_CSIS_CLOCKS ARRAY_SIZE(csi_clock_name)
 124#define DEFAULT_SCLK_CSIS_FREQ  166000000UL
 125
 126static const char * const csis_supply_name[] = {
 127        "vddcore",  /* CSIS Core (1.0V, 1.1V or 1.2V) suppply */
 128        "vddio",    /* CSIS I/O and PLL (1.8V) supply */
 129};
 130#define CSIS_NUM_SUPPLIES ARRAY_SIZE(csis_supply_name)
 131
 132enum {
 133        ST_POWERED      = 1,
 134        ST_STREAMING    = 2,
 135        ST_SUSPENDED    = 4,
 136};
 137
 138struct s5pcsis_event {
 139        u32 mask;
 140        const char * const name;
 141        unsigned int counter;
 142};
 143
 144static const struct s5pcsis_event s5pcsis_events[] = {
 145        /* Errors */
 146        { S5PCSIS_INTSRC_ERR_SOT_HS,    "SOT Error" },
 147        { S5PCSIS_INTSRC_ERR_LOST_FS,   "Lost Frame Start Error" },
 148        { S5PCSIS_INTSRC_ERR_LOST_FE,   "Lost Frame End Error" },
 149        { S5PCSIS_INTSRC_ERR_OVER,      "FIFO Overflow Error" },
 150        { S5PCSIS_INTSRC_ERR_ECC,       "ECC Error" },
 151        { S5PCSIS_INTSRC_ERR_CRC,       "CRC Error" },
 152        { S5PCSIS_INTSRC_ERR_UNKNOWN,   "Unknown Error" },
 153        /* Non-image data receive events */
 154        { S5PCSIS_INTSRC_EVEN_BEFORE,   "Non-image data before even frame" },
 155        { S5PCSIS_INTSRC_EVEN_AFTER,    "Non-image data after even frame" },
 156        { S5PCSIS_INTSRC_ODD_BEFORE,    "Non-image data before odd frame" },
 157        { S5PCSIS_INTSRC_ODD_AFTER,     "Non-image data after odd frame" },
 158        /* Frame start/end */
 159        { S5PCSIS_INTSRC_FRAME_START,   "Frame Start" },
 160        { S5PCSIS_INTSRC_FRAME_END,     "Frame End" },
 161};
 162#define S5PCSIS_NUM_EVENTS ARRAY_SIZE(s5pcsis_events)
 163
 164struct csis_pktbuf {
 165        u32 *data;
 166        unsigned int len;
 167};
 168
 169struct csis_drvdata {
 170        /* Mask of all used interrupts in S5PCSIS_INTMSK register */
 171        u32 interrupt_mask;
 172};
 173
 174/**
 175 * struct csis_state - the driver's internal state data structure
 176 * @lock: mutex serializing the subdev and power management operations,
 177 *        protecting @format and @flags members
 178 * @pads: CSIS pads array
 179 * @sd: v4l2_subdev associated with CSIS device instance
 180 * @index: the hardware instance index
 181 * @pdev: CSIS platform device
 182 * @phy: pointer to the CSIS generic PHY
 183 * @regs: mmapped I/O registers memory
 184 * @supplies: CSIS regulator supplies
 185 * @clock: CSIS clocks
 186 * @irq: requested s5p-mipi-csis irq number
 187 * @interrupt_mask: interrupt mask of the all used interrupts
 188 * @flags: the state variable for power and streaming control
 189 * @clk_frequency: device bus clock frequency
 190 * @hs_settle: HS-RX settle time
 191 * @num_lanes: number of MIPI-CSI data lanes used
 192 * @max_num_lanes: maximum number of MIPI-CSI data lanes supported
 193 * @wclk_ext: CSI wrapper clock: 0 - bus clock, 1 - external SCLK_CAM
 194 * @csis_fmt: current CSIS pixel format
 195 * @format: common media bus format for the source and sink pad
 196 * @slock: spinlock protecting structure members below
 197 * @pkt_buf: the frame embedded (non-image) data buffer
 198 * @events: MIPI-CSIS event (error) counters
 199 */
 200struct csis_state {
 201        struct mutex lock;
 202        struct media_pad pads[CSIS_PADS_NUM];
 203        struct v4l2_subdev sd;
 204        u8 index;
 205        struct platform_device *pdev;
 206        struct phy *phy;
 207        void __iomem *regs;
 208        struct regulator_bulk_data supplies[CSIS_NUM_SUPPLIES];
 209        struct clk *clock[NUM_CSIS_CLOCKS];
 210        int irq;
 211        u32 interrupt_mask;
 212        u32 flags;
 213
 214        u32 clk_frequency;
 215        u32 hs_settle;
 216        u32 num_lanes;
 217        u32 max_num_lanes;
 218        u8 wclk_ext;
 219
 220        const struct csis_pix_format *csis_fmt;
 221        struct v4l2_mbus_framefmt format;
 222
 223        spinlock_t slock;
 224        struct csis_pktbuf pkt_buf;
 225        struct s5pcsis_event events[S5PCSIS_NUM_EVENTS];
 226};
 227
 228/**
 229 * struct csis_pix_format - CSIS pixel format description
 230 * @pix_width_alignment: horizontal pixel alignment, width will be
 231 *                       multiple of 2^pix_width_alignment
 232 * @code: corresponding media bus code
 233 * @fmt_reg: S5PCSIS_CONFIG register value
 234 * @data_alignment: MIPI-CSI data alignment in bits
 235 */
 236struct csis_pix_format {
 237        unsigned int pix_width_alignment;
 238        u32 code;
 239        u32 fmt_reg;
 240        u8 data_alignment;
 241};
 242
 243static const struct csis_pix_format s5pcsis_formats[] = {
 244        {
 245                .code = MEDIA_BUS_FMT_VYUY8_2X8,
 246                .fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
 247                .data_alignment = 32,
 248        }, {
 249                .code = MEDIA_BUS_FMT_JPEG_1X8,
 250                .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
 251                .data_alignment = 32,
 252        }, {
 253                .code = MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8,
 254                .fmt_reg = S5PCSIS_CFG_FMT_USER(1),
 255                .data_alignment = 32,
 256        }, {
 257                .code = MEDIA_BUS_FMT_SGRBG8_1X8,
 258                .fmt_reg = S5PCSIS_CFG_FMT_RAW8,
 259                .data_alignment = 24,
 260        }, {
 261                .code = MEDIA_BUS_FMT_SGRBG10_1X10,
 262                .fmt_reg = S5PCSIS_CFG_FMT_RAW10,
 263                .data_alignment = 24,
 264        }, {
 265                .code = MEDIA_BUS_FMT_SGRBG12_1X12,
 266                .fmt_reg = S5PCSIS_CFG_FMT_RAW12,
 267                .data_alignment = 24,
 268        }
 269};
 270
 271#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
 272#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
 273
 274static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
 275{
 276        return container_of(sdev, struct csis_state, sd);
 277}
 278
 279static const struct csis_pix_format *find_csis_format(
 280        struct v4l2_mbus_framefmt *mf)
 281{
 282        int i;
 283
 284        for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
 285                if (mf->code == s5pcsis_formats[i].code)
 286                        return &s5pcsis_formats[i];
 287        return NULL;
 288}
 289
 290static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
 291{
 292        u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
 293        if (on)
 294                val |= state->interrupt_mask;
 295        else
 296                val &= ~state->interrupt_mask;
 297        s5pcsis_write(state, S5PCSIS_INTMSK, val);
 298}
 299
 300static void s5pcsis_reset(struct csis_state *state)
 301{
 302        u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
 303
 304        s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
 305        udelay(10);
 306}
 307
 308static void s5pcsis_system_enable(struct csis_state *state, int on)
 309{
 310        u32 val, mask;
 311
 312        val = s5pcsis_read(state, S5PCSIS_CTRL);
 313        if (on)
 314                val |= S5PCSIS_CTRL_ENABLE;
 315        else
 316                val &= ~S5PCSIS_CTRL_ENABLE;
 317        s5pcsis_write(state, S5PCSIS_CTRL, val);
 318
 319        val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
 320        val &= ~S5PCSIS_DPHYCTRL_ENABLE;
 321        if (on) {
 322                mask = (1 << (state->num_lanes + 1)) - 1;
 323                val |= (mask & S5PCSIS_DPHYCTRL_ENABLE);
 324        }
 325        s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
 326}
 327
 328/* Called with the state.lock mutex held */
 329static void __s5pcsis_set_format(struct csis_state *state)
 330{
 331        struct v4l2_mbus_framefmt *mf = &state->format;
 332        u32 val;
 333
 334        v4l2_dbg(1, debug, &state->sd, "fmt: %#x, %d x %d\n",
 335                 mf->code, mf->width, mf->height);
 336
 337        /* Color format */
 338        val = s5pcsis_read(state, S5PCSIS_CONFIG);
 339        val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
 340        s5pcsis_write(state, S5PCSIS_CONFIG, val);
 341
 342        /* Pixel resolution */
 343        val = (mf->width << 16) | mf->height;
 344        s5pcsis_write(state, S5PCSIS_RESOL, val);
 345}
 346
 347static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
 348{
 349        u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
 350
 351        val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
 352        s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
 353}
 354
 355static void s5pcsis_set_params(struct csis_state *state)
 356{
 357        u32 val;
 358
 359        val = s5pcsis_read(state, S5PCSIS_CONFIG);
 360        val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (state->num_lanes - 1);
 361        s5pcsis_write(state, S5PCSIS_CONFIG, val);
 362
 363        __s5pcsis_set_format(state);
 364        s5pcsis_set_hsync_settle(state, state->hs_settle);
 365
 366        val = s5pcsis_read(state, S5PCSIS_CTRL);
 367        if (state->csis_fmt->data_alignment == 32)
 368                val |= S5PCSIS_CTRL_ALIGN_32BIT;
 369        else /* 24-bits */
 370                val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
 371
 372        val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
 373        if (state->wclk_ext)
 374                val |= S5PCSIS_CTRL_WCLK_EXTCLK;
 375        s5pcsis_write(state, S5PCSIS_CTRL, val);
 376
 377        /* Update the shadow register. */
 378        val = s5pcsis_read(state, S5PCSIS_CTRL);
 379        s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
 380}
 381
 382static void s5pcsis_clk_put(struct csis_state *state)
 383{
 384        int i;
 385
 386        for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
 387                if (IS_ERR(state->clock[i]))
 388                        continue;
 389                clk_unprepare(state->clock[i]);
 390                clk_put(state->clock[i]);
 391                state->clock[i] = ERR_PTR(-EINVAL);
 392        }
 393}
 394
 395static int s5pcsis_clk_get(struct csis_state *state)
 396{
 397        struct device *dev = &state->pdev->dev;
 398        int i, ret;
 399
 400        for (i = 0; i < NUM_CSIS_CLOCKS; i++)
 401                state->clock[i] = ERR_PTR(-EINVAL);
 402
 403        for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
 404                state->clock[i] = clk_get(dev, csi_clock_name[i]);
 405                if (IS_ERR(state->clock[i])) {
 406                        ret = PTR_ERR(state->clock[i]);
 407                        goto err;
 408                }
 409                ret = clk_prepare(state->clock[i]);
 410                if (ret < 0) {
 411                        clk_put(state->clock[i]);
 412                        state->clock[i] = ERR_PTR(-EINVAL);
 413                        goto err;
 414                }
 415        }
 416        return 0;
 417err:
 418        s5pcsis_clk_put(state);
 419        dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
 420        return ret;
 421}
 422
 423static void dump_regs(struct csis_state *state, const char *label)
 424{
 425        struct {
 426                u32 offset;
 427                const char * const name;
 428        } registers[] = {
 429                { 0x00, "CTRL" },
 430                { 0x04, "DPHYCTRL" },
 431                { 0x08, "CONFIG" },
 432                { 0x0c, "DPHYSTS" },
 433                { 0x10, "INTMSK" },
 434                { 0x2c, "RESOL" },
 435                { 0x38, "SDW_CONFIG" },
 436        };
 437        u32 i;
 438
 439        v4l2_info(&state->sd, "--- %s ---\n", label);
 440
 441        for (i = 0; i < ARRAY_SIZE(registers); i++) {
 442                u32 cfg = s5pcsis_read(state, registers[i].offset);
 443                v4l2_info(&state->sd, "%10s: 0x%08x\n", registers[i].name, cfg);
 444        }
 445}
 446
 447static void s5pcsis_start_stream(struct csis_state *state)
 448{
 449        s5pcsis_reset(state);
 450        s5pcsis_set_params(state);
 451        s5pcsis_system_enable(state, true);
 452        s5pcsis_enable_interrupts(state, true);
 453}
 454
 455static void s5pcsis_stop_stream(struct csis_state *state)
 456{
 457        s5pcsis_enable_interrupts(state, false);
 458        s5pcsis_system_enable(state, false);
 459}
 460
 461static void s5pcsis_clear_counters(struct csis_state *state)
 462{
 463        unsigned long flags;
 464        int i;
 465
 466        spin_lock_irqsave(&state->slock, flags);
 467        for (i = 0; i < S5PCSIS_NUM_EVENTS; i++)
 468                state->events[i].counter = 0;
 469        spin_unlock_irqrestore(&state->slock, flags);
 470}
 471
 472static void s5pcsis_log_counters(struct csis_state *state, bool non_errors)
 473{
 474        int i = non_errors ? S5PCSIS_NUM_EVENTS : S5PCSIS_NUM_EVENTS - 4;
 475        unsigned long flags;
 476
 477        spin_lock_irqsave(&state->slock, flags);
 478
 479        for (i--; i >= 0; i--) {
 480                if (state->events[i].counter > 0 || debug)
 481                        v4l2_info(&state->sd, "%s events: %d\n",
 482                                  state->events[i].name,
 483                                  state->events[i].counter);
 484        }
 485        spin_unlock_irqrestore(&state->slock, flags);
 486}
 487
 488/*
 489 * V4L2 subdev operations
 490 */
 491static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
 492{
 493        struct csis_state *state = sd_to_csis_state(sd);
 494        struct device *dev = &state->pdev->dev;
 495
 496        if (on)
 497                return pm_runtime_get_sync(dev);
 498
 499        return pm_runtime_put_sync(dev);
 500}
 501
 502static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
 503{
 504        struct csis_state *state = sd_to_csis_state(sd);
 505        int ret = 0;
 506
 507        v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
 508                 __func__, enable, state->flags);
 509
 510        if (enable) {
 511                s5pcsis_clear_counters(state);
 512                ret = pm_runtime_get_sync(&state->pdev->dev);
 513                if (ret && ret != 1)
 514                        return ret;
 515        }
 516
 517        mutex_lock(&state->lock);
 518        if (enable) {
 519                if (state->flags & ST_SUSPENDED) {
 520                        ret = -EBUSY;
 521                        goto unlock;
 522                }
 523                s5pcsis_start_stream(state);
 524                state->flags |= ST_STREAMING;
 525        } else {
 526                s5pcsis_stop_stream(state);
 527                state->flags &= ~ST_STREAMING;
 528                if (debug > 0)
 529                        s5pcsis_log_counters(state, true);
 530        }
 531unlock:
 532        mutex_unlock(&state->lock);
 533        if (!enable)
 534                pm_runtime_put(&state->pdev->dev);
 535
 536        return ret == 1 ? 0 : ret;
 537}
 538
 539static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
 540                                  struct v4l2_subdev_pad_config *cfg,
 541                                  struct v4l2_subdev_mbus_code_enum *code)
 542{
 543        if (code->index >= ARRAY_SIZE(s5pcsis_formats))
 544                return -EINVAL;
 545
 546        code->code = s5pcsis_formats[code->index].code;
 547        return 0;
 548}
 549
 550static struct csis_pix_format const *s5pcsis_try_format(
 551        struct v4l2_mbus_framefmt *mf)
 552{
 553        struct csis_pix_format const *csis_fmt;
 554
 555        csis_fmt = find_csis_format(mf);
 556        if (csis_fmt == NULL)
 557                csis_fmt = &s5pcsis_formats[0];
 558
 559        mf->code = csis_fmt->code;
 560        v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
 561                              csis_fmt->pix_width_alignment,
 562                              &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
 563                              0);
 564        return csis_fmt;
 565}
 566
 567static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
 568                struct csis_state *state, struct v4l2_subdev_pad_config *cfg,
 569                enum v4l2_subdev_format_whence which)
 570{
 571        if (which == V4L2_SUBDEV_FORMAT_TRY)
 572                return cfg ? v4l2_subdev_get_try_format(&state->sd, cfg, 0) : NULL;
 573
 574        return &state->format;
 575}
 576
 577static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
 578                           struct v4l2_subdev_format *fmt)
 579{
 580        struct csis_state *state = sd_to_csis_state(sd);
 581        struct csis_pix_format const *csis_fmt;
 582        struct v4l2_mbus_framefmt *mf;
 583
 584        mf = __s5pcsis_get_format(state, cfg, fmt->which);
 585
 586        if (fmt->pad == CSIS_PAD_SOURCE) {
 587                if (mf) {
 588                        mutex_lock(&state->lock);
 589                        fmt->format = *mf;
 590                        mutex_unlock(&state->lock);
 591                }
 592                return 0;
 593        }
 594        csis_fmt = s5pcsis_try_format(&fmt->format);
 595        if (mf) {
 596                mutex_lock(&state->lock);
 597                *mf = fmt->format;
 598                if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
 599                        state->csis_fmt = csis_fmt;
 600                mutex_unlock(&state->lock);
 601        }
 602        return 0;
 603}
 604
 605static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg,
 606                           struct v4l2_subdev_format *fmt)
 607{
 608        struct csis_state *state = sd_to_csis_state(sd);
 609        struct v4l2_mbus_framefmt *mf;
 610
 611        mf = __s5pcsis_get_format(state, cfg, fmt->which);
 612        if (!mf)
 613                return -EINVAL;
 614
 615        mutex_lock(&state->lock);
 616        fmt->format = *mf;
 617        mutex_unlock(&state->lock);
 618        return 0;
 619}
 620
 621static int s5pcsis_s_rx_buffer(struct v4l2_subdev *sd, void *buf,
 622                               unsigned int *size)
 623{
 624        struct csis_state *state = sd_to_csis_state(sd);
 625        unsigned long flags;
 626
 627        *size = min_t(unsigned int, *size, S5PCSIS_PKTDATA_SIZE);
 628
 629        spin_lock_irqsave(&state->slock, flags);
 630        state->pkt_buf.data = buf;
 631        state->pkt_buf.len = *size;
 632        spin_unlock_irqrestore(&state->slock, flags);
 633
 634        return 0;
 635}
 636
 637static int s5pcsis_log_status(struct v4l2_subdev *sd)
 638{
 639        struct csis_state *state = sd_to_csis_state(sd);
 640
 641        mutex_lock(&state->lock);
 642        s5pcsis_log_counters(state, true);
 643        if (debug && (state->flags & ST_POWERED))
 644                dump_regs(state, __func__);
 645        mutex_unlock(&state->lock);
 646        return 0;
 647}
 648
 649static const struct v4l2_subdev_core_ops s5pcsis_core_ops = {
 650        .s_power = s5pcsis_s_power,
 651        .log_status = s5pcsis_log_status,
 652};
 653
 654static const struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
 655        .enum_mbus_code = s5pcsis_enum_mbus_code,
 656        .get_fmt = s5pcsis_get_fmt,
 657        .set_fmt = s5pcsis_set_fmt,
 658};
 659
 660static const struct v4l2_subdev_video_ops s5pcsis_video_ops = {
 661        .s_rx_buffer = s5pcsis_s_rx_buffer,
 662        .s_stream = s5pcsis_s_stream,
 663};
 664
 665static const struct v4l2_subdev_ops s5pcsis_subdev_ops = {
 666        .core = &s5pcsis_core_ops,
 667        .pad = &s5pcsis_pad_ops,
 668        .video = &s5pcsis_video_ops,
 669};
 670
 671static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
 672{
 673        struct csis_state *state = dev_id;
 674        struct csis_pktbuf *pktbuf = &state->pkt_buf;
 675        unsigned long flags;
 676        u32 status;
 677
 678        status = s5pcsis_read(state, S5PCSIS_INTSRC);
 679        spin_lock_irqsave(&state->slock, flags);
 680
 681        if ((status & S5PCSIS_INTSRC_NON_IMAGE_DATA) && pktbuf->data) {
 682                u32 offset;
 683
 684                if (status & S5PCSIS_INTSRC_EVEN)
 685                        offset = S5PCSIS_PKTDATA_EVEN;
 686                else
 687                        offset = S5PCSIS_PKTDATA_ODD;
 688
 689                memcpy(pktbuf->data, (u8 __force *)state->regs + offset,
 690                       pktbuf->len);
 691                pktbuf->data = NULL;
 692                rmb();
 693        }
 694
 695        /* Update the event/error counters */
 696        if ((status & S5PCSIS_INTSRC_ERRORS) || debug) {
 697                int i;
 698                for (i = 0; i < S5PCSIS_NUM_EVENTS; i++) {
 699                        if (!(status & state->events[i].mask))
 700                                continue;
 701                        state->events[i].counter++;
 702                        v4l2_dbg(2, debug, &state->sd, "%s: %d\n",
 703                                 state->events[i].name,
 704                                 state->events[i].counter);
 705                }
 706                v4l2_dbg(2, debug, &state->sd, "status: %08x\n", status);
 707        }
 708        spin_unlock_irqrestore(&state->slock, flags);
 709
 710        s5pcsis_write(state, S5PCSIS_INTSRC, status);
 711        return IRQ_HANDLED;
 712}
 713
 714static int s5pcsis_parse_dt(struct platform_device *pdev,
 715                            struct csis_state *state)
 716{
 717        struct device_node *node = pdev->dev.of_node;
 718        struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
 719        int ret;
 720
 721        if (of_property_read_u32(node, "clock-frequency",
 722                                 &state->clk_frequency))
 723                state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ;
 724        if (of_property_read_u32(node, "bus-width",
 725                                 &state->max_num_lanes))
 726                return -EINVAL;
 727
 728        node = of_graph_get_next_endpoint(node, NULL);
 729        if (!node) {
 730                dev_err(&pdev->dev, "No port node at %pOF\n",
 731                                pdev->dev.of_node);
 732                return -EINVAL;
 733        }
 734        /* Get port node and validate MIPI-CSI channel id. */
 735        ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(node), &endpoint);
 736        if (ret)
 737                goto err;
 738
 739        state->index = endpoint.base.port - FIMC_INPUT_MIPI_CSI2_0;
 740        if (state->index >= CSIS_MAX_ENTITIES) {
 741                ret = -ENXIO;
 742                goto err;
 743        }
 744
 745        /* Get MIPI CSI-2 bus configuration from the endpoint node. */
 746        of_property_read_u32(node, "samsung,csis-hs-settle",
 747                                        &state->hs_settle);
 748        state->wclk_ext = of_property_read_bool(node,
 749                                        "samsung,csis-wclk");
 750
 751        state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes;
 752
 753err:
 754        of_node_put(node);
 755        return ret;
 756}
 757
 758static int s5pcsis_pm_resume(struct device *dev, bool runtime);
 759static const struct of_device_id s5pcsis_of_match[];
 760
 761static int s5pcsis_probe(struct platform_device *pdev)
 762{
 763        const struct of_device_id *of_id;
 764        const struct csis_drvdata *drv_data;
 765        struct device *dev = &pdev->dev;
 766        struct resource *mem_res;
 767        struct csis_state *state;
 768        int ret = -ENOMEM;
 769        int i;
 770
 771        state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL);
 772        if (!state)
 773                return -ENOMEM;
 774
 775        mutex_init(&state->lock);
 776        spin_lock_init(&state->slock);
 777        state->pdev = pdev;
 778
 779        of_id = of_match_node(s5pcsis_of_match, dev->of_node);
 780        if (WARN_ON(of_id == NULL))
 781                return -EINVAL;
 782
 783        drv_data = of_id->data;
 784        state->interrupt_mask = drv_data->interrupt_mask;
 785
 786        ret = s5pcsis_parse_dt(pdev, state);
 787        if (ret < 0)
 788                return ret;
 789
 790        if (state->num_lanes == 0 || state->num_lanes > state->max_num_lanes) {
 791                dev_err(dev, "Unsupported number of data lanes: %d (max. %d)\n",
 792                        state->num_lanes, state->max_num_lanes);
 793                return -EINVAL;
 794        }
 795
 796        state->phy = devm_phy_get(dev, "csis");
 797        if (IS_ERR(state->phy))
 798                return PTR_ERR(state->phy);
 799
 800        mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 801        state->regs = devm_ioremap_resource(dev, mem_res);
 802        if (IS_ERR(state->regs))
 803                return PTR_ERR(state->regs);
 804
 805        state->irq = platform_get_irq(pdev, 0);
 806        if (state->irq < 0) {
 807                dev_err(dev, "Failed to get irq\n");
 808                return state->irq;
 809        }
 810
 811        for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
 812                state->supplies[i].supply = csis_supply_name[i];
 813
 814        ret = devm_regulator_bulk_get(dev, CSIS_NUM_SUPPLIES,
 815                                 state->supplies);
 816        if (ret)
 817                return ret;
 818
 819        ret = s5pcsis_clk_get(state);
 820        if (ret < 0)
 821                return ret;
 822
 823        if (state->clk_frequency)
 824                ret = clk_set_rate(state->clock[CSIS_CLK_MUX],
 825                                   state->clk_frequency);
 826        else
 827                dev_WARN(dev, "No clock frequency specified!\n");
 828        if (ret < 0)
 829                goto e_clkput;
 830
 831        ret = clk_enable(state->clock[CSIS_CLK_MUX]);
 832        if (ret < 0)
 833                goto e_clkput;
 834
 835        ret = devm_request_irq(dev, state->irq, s5pcsis_irq_handler,
 836                               0, dev_name(dev), state);
 837        if (ret) {
 838                dev_err(dev, "Interrupt request failed\n");
 839                goto e_clkdis;
 840        }
 841
 842        v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
 843        state->sd.owner = THIS_MODULE;
 844        snprintf(state->sd.name, sizeof(state->sd.name), "%s.%d",
 845                 CSIS_SUBDEV_NAME, state->index);
 846        state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 847        state->csis_fmt = &s5pcsis_formats[0];
 848
 849        state->format.code = s5pcsis_formats[0].code;
 850        state->format.width = S5PCSIS_DEF_PIX_WIDTH;
 851        state->format.height = S5PCSIS_DEF_PIX_HEIGHT;
 852
 853        state->sd.entity.function = MEDIA_ENT_F_IO_V4L;
 854        state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 855        state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 856        ret = media_entity_pads_init(&state->sd.entity,
 857                                CSIS_PADS_NUM, state->pads);
 858        if (ret < 0)
 859                goto e_clkdis;
 860
 861        /* This allows to retrieve the platform device id by the host driver */
 862        v4l2_set_subdevdata(&state->sd, pdev);
 863
 864        /* .. and a pointer to the subdev. */
 865        platform_set_drvdata(pdev, &state->sd);
 866        memcpy(state->events, s5pcsis_events, sizeof(state->events));
 867
 868        pm_runtime_enable(dev);
 869        if (!pm_runtime_enabled(dev)) {
 870                ret = s5pcsis_pm_resume(dev, true);
 871                if (ret < 0)
 872                        goto e_m_ent;
 873        }
 874
 875        dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n",
 876                 state->num_lanes, state->hs_settle, state->wclk_ext,
 877                 state->clk_frequency);
 878        return 0;
 879
 880e_m_ent:
 881        media_entity_cleanup(&state->sd.entity);
 882e_clkdis:
 883        clk_disable(state->clock[CSIS_CLK_MUX]);
 884e_clkput:
 885        s5pcsis_clk_put(state);
 886        return ret;
 887}
 888
 889static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
 890{
 891        struct v4l2_subdev *sd = dev_get_drvdata(dev);
 892        struct csis_state *state = sd_to_csis_state(sd);
 893        int ret = 0;
 894
 895        v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
 896                 __func__, state->flags);
 897
 898        mutex_lock(&state->lock);
 899        if (state->flags & ST_POWERED) {
 900                s5pcsis_stop_stream(state);
 901                ret = phy_power_off(state->phy);
 902                if (ret)
 903                        goto unlock;
 904                ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
 905                                             state->supplies);
 906                if (ret)
 907                        goto unlock;
 908                clk_disable(state->clock[CSIS_CLK_GATE]);
 909                state->flags &= ~ST_POWERED;
 910                if (!runtime)
 911                        state->flags |= ST_SUSPENDED;
 912        }
 913 unlock:
 914        mutex_unlock(&state->lock);
 915        return ret ? -EAGAIN : 0;
 916}
 917
 918static int s5pcsis_pm_resume(struct device *dev, bool runtime)
 919{
 920        struct v4l2_subdev *sd = dev_get_drvdata(dev);
 921        struct csis_state *state = sd_to_csis_state(sd);
 922        int ret = 0;
 923
 924        v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
 925                 __func__, state->flags);
 926
 927        mutex_lock(&state->lock);
 928        if (!runtime && !(state->flags & ST_SUSPENDED))
 929                goto unlock;
 930
 931        if (!(state->flags & ST_POWERED)) {
 932                ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
 933                                            state->supplies);
 934                if (ret)
 935                        goto unlock;
 936                ret = phy_power_on(state->phy);
 937                if (!ret) {
 938                        state->flags |= ST_POWERED;
 939                } else {
 940                        regulator_bulk_disable(CSIS_NUM_SUPPLIES,
 941                                               state->supplies);
 942                        goto unlock;
 943                }
 944                clk_enable(state->clock[CSIS_CLK_GATE]);
 945        }
 946        if (state->flags & ST_STREAMING)
 947                s5pcsis_start_stream(state);
 948
 949        state->flags &= ~ST_SUSPENDED;
 950 unlock:
 951        mutex_unlock(&state->lock);
 952        return ret ? -EAGAIN : 0;
 953}
 954
 955#ifdef CONFIG_PM_SLEEP
 956static int s5pcsis_suspend(struct device *dev)
 957{
 958        return s5pcsis_pm_suspend(dev, false);
 959}
 960
 961static int s5pcsis_resume(struct device *dev)
 962{
 963        return s5pcsis_pm_resume(dev, false);
 964}
 965#endif
 966
 967#ifdef CONFIG_PM
 968static int s5pcsis_runtime_suspend(struct device *dev)
 969{
 970        return s5pcsis_pm_suspend(dev, true);
 971}
 972
 973static int s5pcsis_runtime_resume(struct device *dev)
 974{
 975        return s5pcsis_pm_resume(dev, true);
 976}
 977#endif
 978
 979static int s5pcsis_remove(struct platform_device *pdev)
 980{
 981        struct v4l2_subdev *sd = platform_get_drvdata(pdev);
 982        struct csis_state *state = sd_to_csis_state(sd);
 983
 984        pm_runtime_disable(&pdev->dev);
 985        s5pcsis_pm_suspend(&pdev->dev, true);
 986        clk_disable(state->clock[CSIS_CLK_MUX]);
 987        pm_runtime_set_suspended(&pdev->dev);
 988        s5pcsis_clk_put(state);
 989
 990        media_entity_cleanup(&state->sd.entity);
 991
 992        return 0;
 993}
 994
 995static const struct dev_pm_ops s5pcsis_pm_ops = {
 996        SET_RUNTIME_PM_OPS(s5pcsis_runtime_suspend, s5pcsis_runtime_resume,
 997                           NULL)
 998        SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
 999};
1000
1001static const struct csis_drvdata exynos4_csis_drvdata = {
1002        .interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
1003};
1004
1005static const struct csis_drvdata exynos5_csis_drvdata = {
1006        .interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
1007};
1008
1009static const struct of_device_id s5pcsis_of_match[] = {
1010        {
1011                .compatible = "samsung,s5pv210-csis",
1012                .data = &exynos4_csis_drvdata,
1013        }, {
1014                .compatible = "samsung,exynos4210-csis",
1015                .data = &exynos4_csis_drvdata,
1016        }, {
1017                .compatible = "samsung,exynos5250-csis",
1018                .data = &exynos5_csis_drvdata,
1019        },
1020        { /* sentinel */ },
1021};
1022MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
1023
1024static struct platform_driver s5pcsis_driver = {
1025        .probe          = s5pcsis_probe,
1026        .remove         = s5pcsis_remove,
1027        .driver         = {
1028                .of_match_table = s5pcsis_of_match,
1029                .name           = CSIS_DRIVER_NAME,
1030                .pm             = &s5pcsis_pm_ops,
1031        },
1032};
1033
1034module_platform_driver(s5pcsis_driver);
1035
1036MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
1037MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver driver");
1038MODULE_LICENSE("GPL");
1039