Lines Matching full:state
175 * struct csis_state - the driver's internal state data structure
188 * @flags: the state variable for power and streaming control
290 static void s5pcsis_enable_interrupts(struct csis_state *state, bool on) in s5pcsis_enable_interrupts() argument
292 u32 val = s5pcsis_read(state, S5PCSIS_INTMSK); in s5pcsis_enable_interrupts()
294 val |= state->interrupt_mask; in s5pcsis_enable_interrupts()
296 val &= ~state->interrupt_mask; in s5pcsis_enable_interrupts()
297 s5pcsis_write(state, S5PCSIS_INTMSK, val); in s5pcsis_enable_interrupts()
300 static void s5pcsis_reset(struct csis_state *state) in s5pcsis_reset() argument
302 u32 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_reset()
304 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET); in s5pcsis_reset()
308 static void s5pcsis_system_enable(struct csis_state *state, int on) in s5pcsis_system_enable() argument
312 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_system_enable()
317 s5pcsis_write(state, S5PCSIS_CTRL, val); in s5pcsis_system_enable()
319 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL); in s5pcsis_system_enable()
322 mask = (1 << (state->num_lanes + 1)) - 1; in s5pcsis_system_enable()
325 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val); in s5pcsis_system_enable()
328 /* Called with the state.lock mutex held */
329 static void __s5pcsis_set_format(struct csis_state *state) in __s5pcsis_set_format() argument
331 struct v4l2_mbus_framefmt *mf = &state->format; in __s5pcsis_set_format()
334 v4l2_dbg(1, debug, &state->sd, "fmt: %#x, %d x %d\n", in __s5pcsis_set_format()
338 val = s5pcsis_read(state, S5PCSIS_CONFIG); in __s5pcsis_set_format()
339 val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg; in __s5pcsis_set_format()
340 s5pcsis_write(state, S5PCSIS_CONFIG, val); in __s5pcsis_set_format()
344 s5pcsis_write(state, S5PCSIS_RESOL, val); in __s5pcsis_set_format()
347 static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle) in s5pcsis_set_hsync_settle() argument
349 u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL); in s5pcsis_set_hsync_settle()
352 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val); in s5pcsis_set_hsync_settle()
355 static void s5pcsis_set_params(struct csis_state *state) in s5pcsis_set_params() argument
359 val = s5pcsis_read(state, S5PCSIS_CONFIG); in s5pcsis_set_params()
360 val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (state->num_lanes - 1); in s5pcsis_set_params()
361 s5pcsis_write(state, S5PCSIS_CONFIG, val); in s5pcsis_set_params()
363 __s5pcsis_set_format(state); in s5pcsis_set_params()
364 s5pcsis_set_hsync_settle(state, state->hs_settle); in s5pcsis_set_params()
366 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_set_params()
367 if (state->csis_fmt->data_alignment == 32) in s5pcsis_set_params()
373 if (state->wclk_ext) in s5pcsis_set_params()
375 s5pcsis_write(state, S5PCSIS_CTRL, val); in s5pcsis_set_params()
378 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_set_params()
379 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW); in s5pcsis_set_params()
382 static void s5pcsis_clk_put(struct csis_state *state) in s5pcsis_clk_put() argument
387 if (IS_ERR(state->clock[i])) in s5pcsis_clk_put()
389 clk_unprepare(state->clock[i]); in s5pcsis_clk_put()
390 clk_put(state->clock[i]); in s5pcsis_clk_put()
391 state->clock[i] = ERR_PTR(-EINVAL); in s5pcsis_clk_put()
395 static int s5pcsis_clk_get(struct csis_state *state) in s5pcsis_clk_get() argument
397 struct device *dev = &state->pdev->dev; in s5pcsis_clk_get()
401 state->clock[i] = ERR_PTR(-EINVAL); in s5pcsis_clk_get()
404 state->clock[i] = clk_get(dev, csi_clock_name[i]); in s5pcsis_clk_get()
405 if (IS_ERR(state->clock[i])) { in s5pcsis_clk_get()
406 ret = PTR_ERR(state->clock[i]); in s5pcsis_clk_get()
409 ret = clk_prepare(state->clock[i]); in s5pcsis_clk_get()
411 clk_put(state->clock[i]); in s5pcsis_clk_get()
412 state->clock[i] = ERR_PTR(-EINVAL); in s5pcsis_clk_get()
418 s5pcsis_clk_put(state); in s5pcsis_clk_get()
423 static void dump_regs(struct csis_state *state, const char *label) in dump_regs() argument
439 v4l2_info(&state->sd, "--- %s ---\n", label); in dump_regs()
442 u32 cfg = s5pcsis_read(state, registers[i].offset); in dump_regs()
443 v4l2_info(&state->sd, "%10s: 0x%08x\n", registers[i].name, cfg); in dump_regs()
447 static void s5pcsis_start_stream(struct csis_state *state) in s5pcsis_start_stream() argument
449 s5pcsis_reset(state); in s5pcsis_start_stream()
450 s5pcsis_set_params(state); in s5pcsis_start_stream()
451 s5pcsis_system_enable(state, true); in s5pcsis_start_stream()
452 s5pcsis_enable_interrupts(state, true); in s5pcsis_start_stream()
455 static void s5pcsis_stop_stream(struct csis_state *state) in s5pcsis_stop_stream() argument
457 s5pcsis_enable_interrupts(state, false); in s5pcsis_stop_stream()
458 s5pcsis_system_enable(state, false); in s5pcsis_stop_stream()
461 static void s5pcsis_clear_counters(struct csis_state *state) in s5pcsis_clear_counters() argument
466 spin_lock_irqsave(&state->slock, flags); in s5pcsis_clear_counters()
468 state->events[i].counter = 0; in s5pcsis_clear_counters()
469 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_clear_counters()
472 static void s5pcsis_log_counters(struct csis_state *state, bool non_errors) in s5pcsis_log_counters() argument
477 spin_lock_irqsave(&state->slock, flags); in s5pcsis_log_counters()
480 if (state->events[i].counter > 0 || debug) in s5pcsis_log_counters()
481 v4l2_info(&state->sd, "%s events: %d\n", in s5pcsis_log_counters()
482 state->events[i].name, in s5pcsis_log_counters()
483 state->events[i].counter); in s5pcsis_log_counters()
485 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_log_counters()
493 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_s_power() local
494 struct device *dev = &state->pdev->dev; in s5pcsis_s_power()
504 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_s_stream() local
507 v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n", in s5pcsis_s_stream()
508 __func__, enable, state->flags); in s5pcsis_s_stream()
511 s5pcsis_clear_counters(state); in s5pcsis_s_stream()
512 ret = pm_runtime_get_sync(&state->pdev->dev); in s5pcsis_s_stream()
517 mutex_lock(&state->lock); in s5pcsis_s_stream()
519 if (state->flags & ST_SUSPENDED) { in s5pcsis_s_stream()
523 s5pcsis_start_stream(state); in s5pcsis_s_stream()
524 state->flags |= ST_STREAMING; in s5pcsis_s_stream()
526 s5pcsis_stop_stream(state); in s5pcsis_s_stream()
527 state->flags &= ~ST_STREAMING; in s5pcsis_s_stream()
529 s5pcsis_log_counters(state, true); in s5pcsis_s_stream()
532 mutex_unlock(&state->lock); in s5pcsis_s_stream()
534 pm_runtime_put(&state->pdev->dev); in s5pcsis_s_stream()
568 struct csis_state *state, struct v4l2_subdev_pad_config *cfg, in __s5pcsis_get_format() argument
572 return cfg ? v4l2_subdev_get_try_format(&state->sd, cfg, 0) : NULL; in __s5pcsis_get_format()
574 return &state->format; in __s5pcsis_get_format()
580 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_set_fmt() local
584 mf = __s5pcsis_get_format(state, cfg, fmt->which); in s5pcsis_set_fmt()
588 mutex_lock(&state->lock); in s5pcsis_set_fmt()
590 mutex_unlock(&state->lock); in s5pcsis_set_fmt()
596 mutex_lock(&state->lock); in s5pcsis_set_fmt()
599 state->csis_fmt = csis_fmt; in s5pcsis_set_fmt()
600 mutex_unlock(&state->lock); in s5pcsis_set_fmt()
608 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_get_fmt() local
611 mf = __s5pcsis_get_format(state, cfg, fmt->which); in s5pcsis_get_fmt()
615 mutex_lock(&state->lock); in s5pcsis_get_fmt()
617 mutex_unlock(&state->lock); in s5pcsis_get_fmt()
624 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_s_rx_buffer() local
629 spin_lock_irqsave(&state->slock, flags); in s5pcsis_s_rx_buffer()
630 state->pkt_buf.data = buf; in s5pcsis_s_rx_buffer()
631 state->pkt_buf.len = *size; in s5pcsis_s_rx_buffer()
632 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_s_rx_buffer()
639 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_log_status() local
641 mutex_lock(&state->lock); in s5pcsis_log_status()
642 s5pcsis_log_counters(state, true); in s5pcsis_log_status()
643 if (debug && (state->flags & ST_POWERED)) in s5pcsis_log_status()
644 dump_regs(state, __func__); in s5pcsis_log_status()
645 mutex_unlock(&state->lock); in s5pcsis_log_status()
673 struct csis_state *state = dev_id; in s5pcsis_irq_handler() local
674 struct csis_pktbuf *pktbuf = &state->pkt_buf; in s5pcsis_irq_handler()
678 status = s5pcsis_read(state, S5PCSIS_INTSRC); in s5pcsis_irq_handler()
679 spin_lock_irqsave(&state->slock, flags); in s5pcsis_irq_handler()
689 memcpy(pktbuf->data, (u8 __force *)state->regs + offset, in s5pcsis_irq_handler()
699 if (!(status & state->events[i].mask)) in s5pcsis_irq_handler()
701 state->events[i].counter++; in s5pcsis_irq_handler()
702 v4l2_dbg(2, debug, &state->sd, "%s: %d\n", in s5pcsis_irq_handler()
703 state->events[i].name, in s5pcsis_irq_handler()
704 state->events[i].counter); in s5pcsis_irq_handler()
706 v4l2_dbg(2, debug, &state->sd, "status: %08x\n", status); in s5pcsis_irq_handler()
708 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_irq_handler()
710 s5pcsis_write(state, S5PCSIS_INTSRC, status); in s5pcsis_irq_handler()
715 struct csis_state *state) in s5pcsis_parse_dt() argument
722 &state->clk_frequency)) in s5pcsis_parse_dt()
723 state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; in s5pcsis_parse_dt()
725 &state->max_num_lanes)) in s5pcsis_parse_dt()
739 state->index = endpoint.base.port - FIMC_INPUT_MIPI_CSI2_0; in s5pcsis_parse_dt()
740 if (state->index >= CSIS_MAX_ENTITIES) { in s5pcsis_parse_dt()
747 &state->hs_settle); in s5pcsis_parse_dt()
748 state->wclk_ext = of_property_read_bool(node, in s5pcsis_parse_dt()
751 state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes; in s5pcsis_parse_dt()
767 struct csis_state *state; in s5pcsis_probe() local
771 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); in s5pcsis_probe()
772 if (!state) in s5pcsis_probe()
775 mutex_init(&state->lock); in s5pcsis_probe()
776 spin_lock_init(&state->slock); in s5pcsis_probe()
777 state->pdev = pdev; in s5pcsis_probe()
784 state->interrupt_mask = drv_data->interrupt_mask; in s5pcsis_probe()
786 ret = s5pcsis_parse_dt(pdev, state); in s5pcsis_probe()
790 if (state->num_lanes == 0 || state->num_lanes > state->max_num_lanes) { in s5pcsis_probe()
792 state->num_lanes, state->max_num_lanes); in s5pcsis_probe()
796 state->phy = devm_phy_get(dev, "csis"); in s5pcsis_probe()
797 if (IS_ERR(state->phy)) in s5pcsis_probe()
798 return PTR_ERR(state->phy); in s5pcsis_probe()
801 state->regs = devm_ioremap_resource(dev, mem_res); in s5pcsis_probe()
802 if (IS_ERR(state->regs)) in s5pcsis_probe()
803 return PTR_ERR(state->regs); in s5pcsis_probe()
805 state->irq = platform_get_irq(pdev, 0); in s5pcsis_probe()
806 if (state->irq < 0) in s5pcsis_probe()
807 return state->irq; in s5pcsis_probe()
810 state->supplies[i].supply = csis_supply_name[i]; in s5pcsis_probe()
813 state->supplies); in s5pcsis_probe()
817 ret = s5pcsis_clk_get(state); in s5pcsis_probe()
821 if (state->clk_frequency) in s5pcsis_probe()
822 ret = clk_set_rate(state->clock[CSIS_CLK_MUX], in s5pcsis_probe()
823 state->clk_frequency); in s5pcsis_probe()
829 ret = clk_enable(state->clock[CSIS_CLK_MUX]); in s5pcsis_probe()
833 ret = devm_request_irq(dev, state->irq, s5pcsis_irq_handler, in s5pcsis_probe()
834 0, dev_name(dev), state); in s5pcsis_probe()
840 v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops); in s5pcsis_probe()
841 state->sd.owner = THIS_MODULE; in s5pcsis_probe()
842 snprintf(state->sd.name, sizeof(state->sd.name), "%s.%d", in s5pcsis_probe()
843 CSIS_SUBDEV_NAME, state->index); in s5pcsis_probe()
844 state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in s5pcsis_probe()
845 state->csis_fmt = &s5pcsis_formats[0]; in s5pcsis_probe()
847 state->format.code = s5pcsis_formats[0].code; in s5pcsis_probe()
848 state->format.width = S5PCSIS_DEF_PIX_WIDTH; in s5pcsis_probe()
849 state->format.height = S5PCSIS_DEF_PIX_HEIGHT; in s5pcsis_probe()
851 state->sd.entity.function = MEDIA_ENT_F_IO_V4L; in s5pcsis_probe()
852 state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in s5pcsis_probe()
853 state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in s5pcsis_probe()
854 ret = media_entity_pads_init(&state->sd.entity, in s5pcsis_probe()
855 CSIS_PADS_NUM, state->pads); in s5pcsis_probe()
860 v4l2_set_subdevdata(&state->sd, pdev); in s5pcsis_probe()
863 platform_set_drvdata(pdev, &state->sd); in s5pcsis_probe()
864 memcpy(state->events, s5pcsis_events, sizeof(state->events)); in s5pcsis_probe()
874 state->num_lanes, state->hs_settle, state->wclk_ext, in s5pcsis_probe()
875 state->clk_frequency); in s5pcsis_probe()
879 media_entity_cleanup(&state->sd.entity); in s5pcsis_probe()
881 clk_disable(state->clock[CSIS_CLK_MUX]); in s5pcsis_probe()
883 s5pcsis_clk_put(state); in s5pcsis_probe()
890 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_pm_suspend() local
894 __func__, state->flags); in s5pcsis_pm_suspend()
896 mutex_lock(&state->lock); in s5pcsis_pm_suspend()
897 if (state->flags & ST_POWERED) { in s5pcsis_pm_suspend()
898 s5pcsis_stop_stream(state); in s5pcsis_pm_suspend()
899 ret = phy_power_off(state->phy); in s5pcsis_pm_suspend()
903 state->supplies); in s5pcsis_pm_suspend()
906 clk_disable(state->clock[CSIS_CLK_GATE]); in s5pcsis_pm_suspend()
907 state->flags &= ~ST_POWERED; in s5pcsis_pm_suspend()
909 state->flags |= ST_SUSPENDED; in s5pcsis_pm_suspend()
912 mutex_unlock(&state->lock); in s5pcsis_pm_suspend()
919 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_pm_resume() local
923 __func__, state->flags); in s5pcsis_pm_resume()
925 mutex_lock(&state->lock); in s5pcsis_pm_resume()
926 if (!runtime && !(state->flags & ST_SUSPENDED)) in s5pcsis_pm_resume()
929 if (!(state->flags & ST_POWERED)) { in s5pcsis_pm_resume()
931 state->supplies); in s5pcsis_pm_resume()
934 ret = phy_power_on(state->phy); in s5pcsis_pm_resume()
936 state->flags |= ST_POWERED; in s5pcsis_pm_resume()
939 state->supplies); in s5pcsis_pm_resume()
942 clk_enable(state->clock[CSIS_CLK_GATE]); in s5pcsis_pm_resume()
944 if (state->flags & ST_STREAMING) in s5pcsis_pm_resume()
945 s5pcsis_start_stream(state); in s5pcsis_pm_resume()
947 state->flags &= ~ST_SUSPENDED; in s5pcsis_pm_resume()
949 mutex_unlock(&state->lock); in s5pcsis_pm_resume()
980 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_remove() local
984 clk_disable(state->clock[CSIS_CLK_MUX]); in s5pcsis_remove()
986 s5pcsis_clk_put(state); in s5pcsis_remove()
988 media_entity_cleanup(&state->sd.entity); in s5pcsis_remove()