root/drivers/media/platform/exynos4-is/mipi-csis.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sd_to_csis_state
  2. find_csis_format
  3. s5pcsis_enable_interrupts
  4. s5pcsis_reset
  5. s5pcsis_system_enable
  6. __s5pcsis_set_format
  7. s5pcsis_set_hsync_settle
  8. s5pcsis_set_params
  9. s5pcsis_clk_put
  10. s5pcsis_clk_get
  11. dump_regs
  12. s5pcsis_start_stream
  13. s5pcsis_stop_stream
  14. s5pcsis_clear_counters
  15. s5pcsis_log_counters
  16. s5pcsis_s_power
  17. s5pcsis_s_stream
  18. s5pcsis_enum_mbus_code
  19. s5pcsis_try_format
  20. __s5pcsis_get_format
  21. s5pcsis_set_fmt
  22. s5pcsis_get_fmt
  23. s5pcsis_s_rx_buffer
  24. s5pcsis_log_status
  25. s5pcsis_irq_handler
  26. s5pcsis_parse_dt
  27. s5pcsis_probe
  28. s5pcsis_pm_suspend
  29. s5pcsis_pm_resume
  30. s5pcsis_suspend
  31. s5pcsis_resume
  32. s5pcsis_runtime_suspend
  33. s5pcsis_runtime_resume
  34. s5pcsis_remove

   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 
  35 static int debug;
  36 module_param(debug, int, 0644);
  37 MODULE_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          (1UL << 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      (1UL << 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      (1UL << 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 
 114 enum {
 115         CSIS_CLK_MUX,
 116         CSIS_CLK_GATE,
 117 };
 118 
 119 static 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 
 126 static 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 
 132 enum {
 133         ST_POWERED      = 1,
 134         ST_STREAMING    = 2,
 135         ST_SUSPENDED    = 4,
 136 };
 137 
 138 struct s5pcsis_event {
 139         u32 mask;
 140         const char * const name;
 141         unsigned int counter;
 142 };
 143 
 144 static 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 
 164 struct csis_pktbuf {
 165         u32 *data;
 166         unsigned int len;
 167 };
 168 
 169 struct 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  */
 200 struct 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  */
 236 struct csis_pix_format {
 237         unsigned int pix_width_alignment;
 238         u32 code;
 239         u32 fmt_reg;
 240         u8 data_alignment;
 241 };
 242 
 243 static 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 
 274 static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
 275 {
 276         return container_of(sdev, struct csis_state, sd);
 277 }
 278 
 279 static 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 
 290 static 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 
 300 static 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 
 308 static 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 */
 329 static 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 
 347 static 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 
 355 static 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 
 382 static 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 
 395 static 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;
 417 err:
 418         s5pcsis_clk_put(state);
 419         dev_err(dev, "failed to get clock: %s\n", csi_clock_name[i]);
 420         return ret;
 421 }
 422 
 423 static 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 
 447 static 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 
 455 static void s5pcsis_stop_stream(struct csis_state *state)
 456 {
 457         s5pcsis_enable_interrupts(state, false);
 458         s5pcsis_system_enable(state, false);
 459 }
 460 
 461 static 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 
 472 static 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  */
 491 static 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 
 502 static 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         }
 531 unlock:
 532         mutex_unlock(&state->lock);
 533         if (!enable)
 534                 pm_runtime_put(&state->pdev->dev);
 535 
 536         return ret == 1 ? 0 : ret;
 537 }
 538 
 539 static 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 
 550 static 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 
 567 static 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 
 577 static 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 
 605 static 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 
 621 static 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 
 637 static 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 
 649 static const struct v4l2_subdev_core_ops s5pcsis_core_ops = {
 650         .s_power = s5pcsis_s_power,
 651         .log_status = s5pcsis_log_status,
 652 };
 653 
 654 static 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 
 660 static 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 
 665 static 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 
 671 static 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 
 714 static 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 
 753 err:
 754         of_node_put(node);
 755         return ret;
 756 }
 757 
 758 static int s5pcsis_pm_resume(struct device *dev, bool runtime);
 759 static const struct of_device_id s5pcsis_of_match[];
 760 
 761 static 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                 return state->irq;
 808 
 809         for (i = 0; i < CSIS_NUM_SUPPLIES; i++)
 810                 state->supplies[i].supply = csis_supply_name[i];
 811 
 812         ret = devm_regulator_bulk_get(dev, CSIS_NUM_SUPPLIES,
 813                                  state->supplies);
 814         if (ret)
 815                 return ret;
 816 
 817         ret = s5pcsis_clk_get(state);
 818         if (ret < 0)
 819                 return ret;
 820 
 821         if (state->clk_frequency)
 822                 ret = clk_set_rate(state->clock[CSIS_CLK_MUX],
 823                                    state->clk_frequency);
 824         else
 825                 dev_WARN(dev, "No clock frequency specified!\n");
 826         if (ret < 0)
 827                 goto e_clkput;
 828 
 829         ret = clk_enable(state->clock[CSIS_CLK_MUX]);
 830         if (ret < 0)
 831                 goto e_clkput;
 832 
 833         ret = devm_request_irq(dev, state->irq, s5pcsis_irq_handler,
 834                                0, dev_name(dev), state);
 835         if (ret) {
 836                 dev_err(dev, "Interrupt request failed\n");
 837                 goto e_clkdis;
 838         }
 839 
 840         v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
 841         state->sd.owner = THIS_MODULE;
 842         snprintf(state->sd.name, sizeof(state->sd.name), "%s.%d",
 843                  CSIS_SUBDEV_NAME, state->index);
 844         state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
 845         state->csis_fmt = &s5pcsis_formats[0];
 846 
 847         state->format.code = s5pcsis_formats[0].code;
 848         state->format.width = S5PCSIS_DEF_PIX_WIDTH;
 849         state->format.height = S5PCSIS_DEF_PIX_HEIGHT;
 850 
 851         state->sd.entity.function = MEDIA_ENT_F_IO_V4L;
 852         state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
 853         state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
 854         ret = media_entity_pads_init(&state->sd.entity,
 855                                 CSIS_PADS_NUM, state->pads);
 856         if (ret < 0)
 857                 goto e_clkdis;
 858 
 859         /* This allows to retrieve the platform device id by the host driver */
 860         v4l2_set_subdevdata(&state->sd, pdev);
 861 
 862         /* .. and a pointer to the subdev. */
 863         platform_set_drvdata(pdev, &state->sd);
 864         memcpy(state->events, s5pcsis_events, sizeof(state->events));
 865 
 866         pm_runtime_enable(dev);
 867         if (!pm_runtime_enabled(dev)) {
 868                 ret = s5pcsis_pm_resume(dev, true);
 869                 if (ret < 0)
 870                         goto e_m_ent;
 871         }
 872 
 873         dev_info(&pdev->dev, "lanes: %d, hs_settle: %d, wclk: %d, freq: %u\n",
 874                  state->num_lanes, state->hs_settle, state->wclk_ext,
 875                  state->clk_frequency);
 876         return 0;
 877 
 878 e_m_ent:
 879         media_entity_cleanup(&state->sd.entity);
 880 e_clkdis:
 881         clk_disable(state->clock[CSIS_CLK_MUX]);
 882 e_clkput:
 883         s5pcsis_clk_put(state);
 884         return ret;
 885 }
 886 
 887 static int s5pcsis_pm_suspend(struct device *dev, bool runtime)
 888 {
 889         struct v4l2_subdev *sd = dev_get_drvdata(dev);
 890         struct csis_state *state = sd_to_csis_state(sd);
 891         int ret = 0;
 892 
 893         v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
 894                  __func__, state->flags);
 895 
 896         mutex_lock(&state->lock);
 897         if (state->flags & ST_POWERED) {
 898                 s5pcsis_stop_stream(state);
 899                 ret = phy_power_off(state->phy);
 900                 if (ret)
 901                         goto unlock;
 902                 ret = regulator_bulk_disable(CSIS_NUM_SUPPLIES,
 903                                              state->supplies);
 904                 if (ret)
 905                         goto unlock;
 906                 clk_disable(state->clock[CSIS_CLK_GATE]);
 907                 state->flags &= ~ST_POWERED;
 908                 if (!runtime)
 909                         state->flags |= ST_SUSPENDED;
 910         }
 911  unlock:
 912         mutex_unlock(&state->lock);
 913         return ret ? -EAGAIN : 0;
 914 }
 915 
 916 static int s5pcsis_pm_resume(struct device *dev, bool runtime)
 917 {
 918         struct v4l2_subdev *sd = dev_get_drvdata(dev);
 919         struct csis_state *state = sd_to_csis_state(sd);
 920         int ret = 0;
 921 
 922         v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
 923                  __func__, state->flags);
 924 
 925         mutex_lock(&state->lock);
 926         if (!runtime && !(state->flags & ST_SUSPENDED))
 927                 goto unlock;
 928 
 929         if (!(state->flags & ST_POWERED)) {
 930                 ret = regulator_bulk_enable(CSIS_NUM_SUPPLIES,
 931                                             state->supplies);
 932                 if (ret)
 933                         goto unlock;
 934                 ret = phy_power_on(state->phy);
 935                 if (!ret) {
 936                         state->flags |= ST_POWERED;
 937                 } else {
 938                         regulator_bulk_disable(CSIS_NUM_SUPPLIES,
 939                                                state->supplies);
 940                         goto unlock;
 941                 }
 942                 clk_enable(state->clock[CSIS_CLK_GATE]);
 943         }
 944         if (state->flags & ST_STREAMING)
 945                 s5pcsis_start_stream(state);
 946 
 947         state->flags &= ~ST_SUSPENDED;
 948  unlock:
 949         mutex_unlock(&state->lock);
 950         return ret ? -EAGAIN : 0;
 951 }
 952 
 953 #ifdef CONFIG_PM_SLEEP
 954 static int s5pcsis_suspend(struct device *dev)
 955 {
 956         return s5pcsis_pm_suspend(dev, false);
 957 }
 958 
 959 static int s5pcsis_resume(struct device *dev)
 960 {
 961         return s5pcsis_pm_resume(dev, false);
 962 }
 963 #endif
 964 
 965 #ifdef CONFIG_PM
 966 static int s5pcsis_runtime_suspend(struct device *dev)
 967 {
 968         return s5pcsis_pm_suspend(dev, true);
 969 }
 970 
 971 static int s5pcsis_runtime_resume(struct device *dev)
 972 {
 973         return s5pcsis_pm_resume(dev, true);
 974 }
 975 #endif
 976 
 977 static int s5pcsis_remove(struct platform_device *pdev)
 978 {
 979         struct v4l2_subdev *sd = platform_get_drvdata(pdev);
 980         struct csis_state *state = sd_to_csis_state(sd);
 981 
 982         pm_runtime_disable(&pdev->dev);
 983         s5pcsis_pm_suspend(&pdev->dev, true);
 984         clk_disable(state->clock[CSIS_CLK_MUX]);
 985         pm_runtime_set_suspended(&pdev->dev);
 986         s5pcsis_clk_put(state);
 987 
 988         media_entity_cleanup(&state->sd.entity);
 989 
 990         return 0;
 991 }
 992 
 993 static const struct dev_pm_ops s5pcsis_pm_ops = {
 994         SET_RUNTIME_PM_OPS(s5pcsis_runtime_suspend, s5pcsis_runtime_resume,
 995                            NULL)
 996         SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_suspend, s5pcsis_resume)
 997 };
 998 
 999 static const struct csis_drvdata exynos4_csis_drvdata = {
1000         .interrupt_mask = S5PCSIS_INTMSK_EXYNOS4_EN_ALL,
1001 };
1002 
1003 static const struct csis_drvdata exynos5_csis_drvdata = {
1004         .interrupt_mask = S5PCSIS_INTMSK_EXYNOS5_EN_ALL,
1005 };
1006 
1007 static const struct of_device_id s5pcsis_of_match[] = {
1008         {
1009                 .compatible = "samsung,s5pv210-csis",
1010                 .data = &exynos4_csis_drvdata,
1011         }, {
1012                 .compatible = "samsung,exynos4210-csis",
1013                 .data = &exynos4_csis_drvdata,
1014         }, {
1015                 .compatible = "samsung,exynos5250-csis",
1016                 .data = &exynos5_csis_drvdata,
1017         },
1018         { /* sentinel */ },
1019 };
1020 MODULE_DEVICE_TABLE(of, s5pcsis_of_match);
1021 
1022 static struct platform_driver s5pcsis_driver = {
1023         .probe          = s5pcsis_probe,
1024         .remove         = s5pcsis_remove,
1025         .driver         = {
1026                 .of_match_table = s5pcsis_of_match,
1027                 .name           = CSIS_DRIVER_NAME,
1028                 .pm             = &s5pcsis_pm_ops,
1029         },
1030 };
1031 
1032 module_platform_driver(s5pcsis_driver);
1033 
1034 MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
1035 MODULE_DESCRIPTION("Samsung S5P/EXYNOS SoC MIPI-CSI2 receiver driver");
1036 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */