Lines Matching +full:csi +full:- +full:2
1 // SPDX-License-Identifier: GPL-2.0-only
3 * TI Camera Access Layer (CAL) - CAMERARX
5 * Copyright (c) 2015-2020 Texas Instruments Inc.
21 #include <media/v4l2-ctrls.h>
22 #include <media/v4l2-fwnode.h>
23 #include <media/v4l2-subdev.h>
28 /* ------------------------------------------------------------------
30 * ------------------------------------------------------------------
35 return ioread32(phy->base + offset); in camerarx_read()
40 iowrite32(val, phy->base + offset); in camerarx_write()
43 /* ------------------------------------------------------------------
45 * ------------------------------------------------------------------
53 ctrl = v4l2_ctrl_find(phy->sensor->ctrl_handler, V4L2_CID_PIXEL_RATE); in cal_camerarx_get_external_rate()
56 phy->sensor->name); in cal_camerarx_get_external_rate()
57 return -EPIPE; in cal_camerarx_get_external_rate()
68 u32 val = cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)); in cal_camerarx_lane_config()
72 &phy->endpoint.bus.mipi_csi2; in cal_camerarx_lane_config()
75 cal_set_field(&val, mipi_csi2->clock_lane + 1, lane_mask); in cal_camerarx_lane_config()
76 cal_set_field(&val, mipi_csi2->lane_polarities[0], polarity_mask); in cal_camerarx_lane_config()
77 for (lane = 0; lane < mipi_csi2->num_data_lanes; lane++) { in cal_camerarx_lane_config()
84 cal_set_field(&val, mipi_csi2->data_lanes[lane] + 1, lane_mask); in cal_camerarx_lane_config()
85 cal_set_field(&val, mipi_csi2->lane_polarities[lane + 1], in cal_camerarx_lane_config()
89 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), val); in cal_camerarx_lane_config()
91 phy->instance, val); in cal_camerarx_lane_config()
96 u32 num_lanes = phy->cal->data->camerarx[phy->instance].num_lanes; in cal_camerarx_enable()
98 regmap_field_write(phy->fields[F_CAMMODE], 0); in cal_camerarx_enable()
100 regmap_field_write(phy->fields[F_LANEENABLE], (1 << num_lanes) - 1); in cal_camerarx_enable()
102 if (phy->fields[F_CSI_MODE]) in cal_camerarx_enable()
103 regmap_field_write(phy->fields[F_CSI_MODE], 1); in cal_camerarx_enable()
104 regmap_field_write(phy->fields[F_CTRLCLKEN], 1); in cal_camerarx_enable()
109 regmap_field_write(phy->fields[F_CTRLCLKEN], 0); in cal_camerarx_disable()
126 &phy->endpoint.bus.mipi_csi2; in cal_camerarx_config()
127 u32 num_lanes = mipi_csi2->num_data_lanes; in cal_camerarx_config()
132 * CSI-2 is DDR and we only count used lanes. in cal_camerarx_config()
135 * / (2 * num_lanes) * fmt->bpp; in cal_camerarx_config()
137 csi2_ddrclk_khz = div_s64(external_rate * fmt->bpp, in cal_camerarx_config()
138 2 * num_lanes * 1000); in cal_camerarx_config()
156 phy_dbg(1, phy, "CSI2_%d_REG0 = 0x%08x\n", phy->instance, reg0); in cal_camerarx_config()
166 phy_dbg(1, phy, "CSI2_%d_REG1 = 0x%08x\n", phy->instance, reg1); in cal_camerarx_config()
178 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_power()
184 current_state = cal_read_field(phy->cal, in cal_camerarx_power()
185 CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_power()
205 if (cal_read_field(phy->cal, in cal_camerarx_wait_reset()
206 CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_wait_reset()
213 if (cal_read_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_wait_reset()
225 if (cal_read_field(phy->cal, in cal_camerarx_wait_stop_state()
226 CAL_CSI2_TIMING(phy->instance), in cal_camerarx_wait_stop_state()
232 if (cal_read_field(phy->cal, CAL_CSI2_TIMING(phy->instance), in cal_camerarx_wait_stop_state()
248 ret = v4l2_subdev_call(phy->sensor, core, s_power, 1); in cal_camerarx_start()
249 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) { in cal_camerarx_start()
255 * CSI-2 PHY Link Initialization Sequence, according to the DRA74xP / in cal_camerarx_start()
261 * 1. Configure all CSI-2 low level protocol registers to be ready to in cal_camerarx_start()
262 * receive signals/data from the CSI-2 PHY. in cal_camerarx_start()
264 * i.-v. Configure the lanes position and polarity. in cal_camerarx_start()
269 * vi.-vii. Configure D-PHY mode, enable the required lanes and in cal_camerarx_start()
275 * 2. CSI PHY and link initialization sequence. in cal_camerarx_start()
277 * a. Deassert the CSI-2 PHY reset. Do not wait for reset completion in cal_camerarx_start()
279 * CSI-2 HS clock. in cal_camerarx_start()
281 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_start()
284 phy_dbg(3, phy, "CAL_CSI2_COMPLEXIO_CFG(%d) = 0x%08x De-assert Complex IO Reset\n", in cal_camerarx_start()
285 phy->instance, in cal_camerarx_start()
286 cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance))); in cal_camerarx_start()
297 * The stop-state-counter is based on fclk cycles, and we always use in cal_camerarx_start()
298 * the x16 and x4 settings, so stop-state-timeout = in cal_camerarx_start()
299 * fclk-cycle * 16 * 4 * counter. in cal_camerarx_start()
301 * Stop-state-timeout must be more than 100us as per CSI-2 spec, so we in cal_camerarx_start()
304 sscounter = DIV_ROUND_UP(clk_get_rate(phy->cal->fclk), 10000 * 16 * 4); in cal_camerarx_start()
306 val = cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance)); in cal_camerarx_start()
311 cal_write(phy->cal, CAL_CSI2_TIMING(phy->instance), val); in cal_camerarx_start()
313 phy->instance, in cal_camerarx_start()
314 cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance))); in cal_camerarx_start()
317 cal_write_field(phy->cal, CAL_CSI2_TIMING(phy->instance), in cal_camerarx_start()
320 phy->instance, in cal_camerarx_start()
321 cal_read(phy->cal, CAL_CSI2_TIMING(phy->instance))); in cal_camerarx_start()
324 * c. Connect pull-down on CSI-2 PHY link (using pad control). in cal_camerarx_start()
331 * d. Power up the CSI-2 PHY. in cal_camerarx_start()
337 * Start the sensor to enable the CSI-2 HS clock. We can now wait for in cal_camerarx_start()
338 * CSI-2 PHY reset to complete. in cal_camerarx_start()
340 ret = v4l2_subdev_call(phy->sensor, video, s_stream, 1); in cal_camerarx_start()
342 v4l2_subdev_call(phy->sensor, core, s_power, 0); in cal_camerarx_start()
352 phy_dbg(1, phy, "CSI2_%u_REG1 = 0x%08x (bits 31-28 should be set)\n", in cal_camerarx_start()
353 phy->instance, camerarx_read(phy, CAL_CSI2_PHY_REG1)); in cal_camerarx_start()
356 * g. Disable pull-down on CSI-2 PHY link (using pad control). in cal_camerarx_start()
373 cal_write_field(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_stop()
379 if (cal_read_field(phy->cal, in cal_camerarx_stop()
380 CAL_CSI2_COMPLEXIO_CFG(phy->instance), in cal_camerarx_stop()
387 phy->instance, in cal_camerarx_stop()
388 cal_read(phy->cal, CAL_CSI2_COMPLEXIO_CFG(phy->instance)), i, in cal_camerarx_stop()
394 if (v4l2_subdev_call(phy->sensor, video, s_stream, 0)) in cal_camerarx_stop()
397 ret = v4l2_subdev_call(phy->sensor, core, s_power, 0); in cal_camerarx_stop()
398 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) in cal_camerarx_stop()
405 * Enabling CSI2 LDO shorts it to core supply. It is crucial the 2 CSI2
406 * LDOs on the device are disabled if CSI-2 module is powered on
411 * Errata does not apply when CSI-2 module is powered off
427 phy_dbg(1, phy, "CSI2_%d_REG10 = 0x%08x\n", phy->instance, reg10); in cal_camerarx_i913_errata()
445 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0), in cal_camerarx_enable_irqs()
446 CAL_HL_IRQ_CIO_MASK(phy->instance)); in cal_camerarx_enable_irqs()
447 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), in cal_camerarx_enable_irqs()
451 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(0), CAL_HL_IRQ_OCPO_ERR_MASK); in cal_camerarx_enable_irqs()
455 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance)); in cal_camerarx_enable_irqs()
456 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(1), val); in cal_camerarx_enable_irqs()
459 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance)); in cal_camerarx_enable_irqs()
460 cal_write(phy->cal, CAL_HL_IRQENABLE_SET(2), val); in cal_camerarx_enable_irqs()
462 cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(0), 0xFF000000); in cal_camerarx_enable_irqs()
470 cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(0), in cal_camerarx_disable_irqs()
471 CAL_HL_IRQ_CIO_MASK(phy->instance)); in cal_camerarx_disable_irqs()
472 cal_write(phy->cal, CAL_CSI2_COMPLEXIO_IRQENABLE(phy->instance), 0); in cal_camerarx_disable_irqs()
476 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance)); in cal_camerarx_disable_irqs()
477 cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(1), val); in cal_camerarx_disable_irqs()
480 cal_set_field(&val, 1, CAL_HL_IRQ_MASK(phy->instance)); in cal_camerarx_disable_irqs()
481 cal_write(phy->cal, CAL_HL_IRQENABLE_CLR(2), val); in cal_camerarx_disable_irqs()
483 cal_write(phy->cal, CAL_CSI2_VC_IRQENABLE(0), 0); in cal_camerarx_disable_irqs()
488 cal_write(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance), BIT(3)); in cal_camerarx_ppi_enable()
489 cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance), in cal_camerarx_ppi_enable()
495 cal_write_field(phy->cal, CAL_CSI2_PPI_CTRL(phy->instance), in cal_camerarx_ppi_disable()
505 if (!cal->data) in cal_camerarx_regmap_init()
506 return -EINVAL; in cal_camerarx_regmap_init()
508 phy_data = &cal->data->camerarx[phy->instance]; in cal_camerarx_regmap_init()
512 .reg = cal->syscon_camerrx_offset, in cal_camerarx_regmap_init()
513 .lsb = phy_data->fields[i].lsb, in cal_camerarx_regmap_init()
514 .msb = phy_data->fields[i].msb, in cal_camerarx_regmap_init()
521 phy->fields[i] = devm_regmap_field_alloc(cal->dev, in cal_camerarx_regmap_init()
522 cal->syscon_camerrx, in cal_camerarx_regmap_init()
524 if (IS_ERR(phy->fields[i])) { in cal_camerarx_regmap_init()
526 return PTR_ERR(phy->fields[i]); in cal_camerarx_regmap_init()
535 struct v4l2_fwnode_endpoint *endpoint = &phy->endpoint; in cal_camerarx_parse_dt()
537 char data_lanes[V4L2_FWNODE_CSI2_MAX_DATA_LANES * 2]; in cal_camerarx_parse_dt()
543 * instance, and parse its CSI-2-related properties. in cal_camerarx_parse_dt()
545 ep_node = of_graph_get_endpoint_by_regs(phy->cal->dev->of_node, in cal_camerarx_parse_dt()
546 phy->instance, 0); in cal_camerarx_parse_dt()
556 endpoint->bus_type = V4L2_MBUS_CSI2_DPHY; in cal_camerarx_parse_dt()
563 for (i = 0; i < endpoint->bus.mipi_csi2.num_data_lanes; i++) { in cal_camerarx_parse_dt()
564 unsigned int lane = endpoint->bus.mipi_csi2.data_lanes[i]; in cal_camerarx_parse_dt()
569 ret = -EINVAL; in cal_camerarx_parse_dt()
573 data_lanes[i*2] = '0' + lane; in cal_camerarx_parse_dt()
574 data_lanes[i*2+1] = ' '; in cal_camerarx_parse_dt()
577 data_lanes[i*2-1] = '\0'; in cal_camerarx_parse_dt()
580 "CSI-2 bus: clock lane <%u>, data lanes <%s>, flags 0x%08x\n", in cal_camerarx_parse_dt()
581 endpoint->bus.mipi_csi2.clock_lane, data_lanes, in cal_camerarx_parse_dt()
582 endpoint->bus.mipi_csi2.flags); in cal_camerarx_parse_dt()
585 phy->sensor_node = of_graph_get_remote_port_parent(ep_node); in cal_camerarx_parse_dt()
586 if (!phy->sensor_node) { in cal_camerarx_parse_dt()
588 ret = -EINVAL; in cal_camerarx_parse_dt()
592 phy_dbg(1, phy, "Found connected device %pOFn\n", phy->sensor_node); in cal_camerarx_parse_dt()
602 struct platform_device *pdev = to_platform_device(cal->dev); in cal_camerarx_create()
608 return ERR_PTR(-ENOMEM); in cal_camerarx_create()
610 phy->cal = cal; in cal_camerarx_create()
611 phy->instance = instance; in cal_camerarx_create()
613 phy->res = platform_get_resource_byname(pdev, IORESOURCE_MEM, in cal_camerarx_create()
617 phy->base = devm_ioremap_resource(cal->dev, phy->res); in cal_camerarx_create()
618 if (IS_ERR(phy->base)) { in cal_camerarx_create()
620 ret = PTR_ERR(phy->base); in cal_camerarx_create()
624 cal_dbg(1, cal, "ioresource %s at %pa - %pa\n", in cal_camerarx_create()
625 phy->res->name, &phy->res->start, &phy->res->end); in cal_camerarx_create()
647 of_node_put(phy->sensor_node); in cal_camerarx_destroy()