Lines Matching refs:state
293 static void s5pcsis_enable_interrupts(struct csis_state *state, bool on) in s5pcsis_enable_interrupts() argument
295 u32 val = s5pcsis_read(state, S5PCSIS_INTMSK); in s5pcsis_enable_interrupts()
297 val |= state->interrupt_mask; in s5pcsis_enable_interrupts()
299 val &= ~state->interrupt_mask; in s5pcsis_enable_interrupts()
300 s5pcsis_write(state, S5PCSIS_INTMSK, val); in s5pcsis_enable_interrupts()
303 static void s5pcsis_reset(struct csis_state *state) in s5pcsis_reset() argument
305 u32 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_reset()
307 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET); in s5pcsis_reset()
311 static void s5pcsis_system_enable(struct csis_state *state, int on) in s5pcsis_system_enable() argument
315 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_system_enable()
320 s5pcsis_write(state, S5PCSIS_CTRL, val); in s5pcsis_system_enable()
322 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL); in s5pcsis_system_enable()
325 mask = (1 << (state->num_lanes + 1)) - 1; in s5pcsis_system_enable()
328 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val); in s5pcsis_system_enable()
332 static void __s5pcsis_set_format(struct csis_state *state) in __s5pcsis_set_format() argument
334 struct v4l2_mbus_framefmt *mf = &state->format; in __s5pcsis_set_format()
337 v4l2_dbg(1, debug, &state->sd, "fmt: %#x, %d x %d\n", in __s5pcsis_set_format()
341 val = s5pcsis_read(state, S5PCSIS_CONFIG); in __s5pcsis_set_format()
342 val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg; in __s5pcsis_set_format()
343 s5pcsis_write(state, S5PCSIS_CONFIG, val); in __s5pcsis_set_format()
347 s5pcsis_write(state, S5PCSIS_RESOL, val); in __s5pcsis_set_format()
350 static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle) in s5pcsis_set_hsync_settle() argument
352 u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL); in s5pcsis_set_hsync_settle()
355 s5pcsis_write(state, S5PCSIS_DPHYCTRL, val); in s5pcsis_set_hsync_settle()
358 static void s5pcsis_set_params(struct csis_state *state) in s5pcsis_set_params() argument
362 val = s5pcsis_read(state, S5PCSIS_CONFIG); in s5pcsis_set_params()
363 val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (state->num_lanes - 1); in s5pcsis_set_params()
364 s5pcsis_write(state, S5PCSIS_CONFIG, val); in s5pcsis_set_params()
366 __s5pcsis_set_format(state); in s5pcsis_set_params()
367 s5pcsis_set_hsync_settle(state, state->hs_settle); in s5pcsis_set_params()
369 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_set_params()
370 if (state->csis_fmt->data_alignment == 32) in s5pcsis_set_params()
376 if (state->wclk_ext) in s5pcsis_set_params()
378 s5pcsis_write(state, S5PCSIS_CTRL, val); in s5pcsis_set_params()
381 val = s5pcsis_read(state, S5PCSIS_CTRL); in s5pcsis_set_params()
382 s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW); in s5pcsis_set_params()
385 static void s5pcsis_clk_put(struct csis_state *state) in s5pcsis_clk_put() argument
390 if (IS_ERR(state->clock[i])) in s5pcsis_clk_put()
392 clk_unprepare(state->clock[i]); in s5pcsis_clk_put()
393 clk_put(state->clock[i]); in s5pcsis_clk_put()
394 state->clock[i] = ERR_PTR(-EINVAL); in s5pcsis_clk_put()
398 static int s5pcsis_clk_get(struct csis_state *state) in s5pcsis_clk_get() argument
400 struct device *dev = &state->pdev->dev; in s5pcsis_clk_get()
404 state->clock[i] = ERR_PTR(-EINVAL); in s5pcsis_clk_get()
407 state->clock[i] = clk_get(dev, csi_clock_name[i]); in s5pcsis_clk_get()
408 if (IS_ERR(state->clock[i])) { in s5pcsis_clk_get()
409 ret = PTR_ERR(state->clock[i]); in s5pcsis_clk_get()
412 ret = clk_prepare(state->clock[i]); in s5pcsis_clk_get()
414 clk_put(state->clock[i]); in s5pcsis_clk_get()
415 state->clock[i] = ERR_PTR(-EINVAL); in s5pcsis_clk_get()
421 s5pcsis_clk_put(state); in s5pcsis_clk_get()
426 static void dump_regs(struct csis_state *state, const char *label) in dump_regs() argument
442 v4l2_info(&state->sd, "--- %s ---\n", label); in dump_regs()
445 u32 cfg = s5pcsis_read(state, registers[i].offset); in dump_regs()
446 v4l2_info(&state->sd, "%10s: 0x%08x\n", registers[i].name, cfg); in dump_regs()
450 static void s5pcsis_start_stream(struct csis_state *state) in s5pcsis_start_stream() argument
452 s5pcsis_reset(state); in s5pcsis_start_stream()
453 s5pcsis_set_params(state); in s5pcsis_start_stream()
454 s5pcsis_system_enable(state, true); in s5pcsis_start_stream()
455 s5pcsis_enable_interrupts(state, true); in s5pcsis_start_stream()
458 static void s5pcsis_stop_stream(struct csis_state *state) in s5pcsis_stop_stream() argument
460 s5pcsis_enable_interrupts(state, false); in s5pcsis_stop_stream()
461 s5pcsis_system_enable(state, false); in s5pcsis_stop_stream()
464 static void s5pcsis_clear_counters(struct csis_state *state) in s5pcsis_clear_counters() argument
469 spin_lock_irqsave(&state->slock, flags); in s5pcsis_clear_counters()
471 state->events[i].counter = 0; in s5pcsis_clear_counters()
472 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_clear_counters()
475 static void s5pcsis_log_counters(struct csis_state *state, bool non_errors) in s5pcsis_log_counters() argument
480 spin_lock_irqsave(&state->slock, flags); in s5pcsis_log_counters()
483 if (state->events[i].counter > 0 || debug) in s5pcsis_log_counters()
484 v4l2_info(&state->sd, "%s events: %d\n", in s5pcsis_log_counters()
485 state->events[i].name, in s5pcsis_log_counters()
486 state->events[i].counter); in s5pcsis_log_counters()
488 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_log_counters()
496 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_s_power() local
497 struct device *dev = &state->pdev->dev; in s5pcsis_s_power()
507 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_s_stream() local
511 __func__, enable, state->flags); in s5pcsis_s_stream()
514 s5pcsis_clear_counters(state); in s5pcsis_s_stream()
515 ret = pm_runtime_get_sync(&state->pdev->dev); in s5pcsis_s_stream()
520 mutex_lock(&state->lock); in s5pcsis_s_stream()
522 if (state->flags & ST_SUSPENDED) { in s5pcsis_s_stream()
526 s5pcsis_start_stream(state); in s5pcsis_s_stream()
527 state->flags |= ST_STREAMING; in s5pcsis_s_stream()
529 s5pcsis_stop_stream(state); in s5pcsis_s_stream()
530 state->flags &= ~ST_STREAMING; in s5pcsis_s_stream()
532 s5pcsis_log_counters(state, true); in s5pcsis_s_stream()
535 mutex_unlock(&state->lock); in s5pcsis_s_stream()
537 pm_runtime_put(&state->pdev->dev); in s5pcsis_s_stream()
571 struct csis_state *state, struct v4l2_subdev_pad_config *cfg, in __s5pcsis_get_format() argument
575 return cfg ? v4l2_subdev_get_try_format(&state->sd, cfg, 0) : NULL; in __s5pcsis_get_format()
577 return &state->format; in __s5pcsis_get_format()
583 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_set_fmt() local
587 mf = __s5pcsis_get_format(state, cfg, fmt->which); in s5pcsis_set_fmt()
591 mutex_lock(&state->lock); in s5pcsis_set_fmt()
593 mutex_unlock(&state->lock); in s5pcsis_set_fmt()
599 mutex_lock(&state->lock); in s5pcsis_set_fmt()
602 state->csis_fmt = csis_fmt; in s5pcsis_set_fmt()
603 mutex_unlock(&state->lock); in s5pcsis_set_fmt()
611 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_get_fmt() local
614 mf = __s5pcsis_get_format(state, cfg, fmt->which); in s5pcsis_get_fmt()
618 mutex_lock(&state->lock); in s5pcsis_get_fmt()
620 mutex_unlock(&state->lock); in s5pcsis_get_fmt()
627 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_s_rx_buffer() local
632 spin_lock_irqsave(&state->slock, flags); in s5pcsis_s_rx_buffer()
633 state->pkt_buf.data = buf; in s5pcsis_s_rx_buffer()
634 state->pkt_buf.len = *size; in s5pcsis_s_rx_buffer()
635 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_s_rx_buffer()
642 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_log_status() local
644 mutex_lock(&state->lock); in s5pcsis_log_status()
645 s5pcsis_log_counters(state, true); in s5pcsis_log_status()
646 if (debug && (state->flags & ST_POWERED)) in s5pcsis_log_status()
647 dump_regs(state, __func__); in s5pcsis_log_status()
648 mutex_unlock(&state->lock); in s5pcsis_log_status()
693 struct csis_state *state = dev_id; in s5pcsis_irq_handler() local
694 struct csis_pktbuf *pktbuf = &state->pkt_buf; in s5pcsis_irq_handler()
698 status = s5pcsis_read(state, S5PCSIS_INTSRC); in s5pcsis_irq_handler()
699 spin_lock_irqsave(&state->slock, flags); in s5pcsis_irq_handler()
709 memcpy(pktbuf->data, state->regs + offset, pktbuf->len); in s5pcsis_irq_handler()
718 if (!(status & state->events[i].mask)) in s5pcsis_irq_handler()
720 state->events[i].counter++; in s5pcsis_irq_handler()
721 v4l2_dbg(2, debug, &state->sd, "%s: %d\n", in s5pcsis_irq_handler()
722 state->events[i].name, in s5pcsis_irq_handler()
723 state->events[i].counter); in s5pcsis_irq_handler()
725 v4l2_dbg(2, debug, &state->sd, "status: %08x\n", status); in s5pcsis_irq_handler()
727 spin_unlock_irqrestore(&state->slock, flags); in s5pcsis_irq_handler()
729 s5pcsis_write(state, S5PCSIS_INTSRC, status); in s5pcsis_irq_handler()
734 struct csis_state *state) in s5pcsis_parse_dt() argument
740 &state->clk_frequency)) in s5pcsis_parse_dt()
741 state->clk_frequency = DEFAULT_SCLK_CSIS_FREQ; in s5pcsis_parse_dt()
743 &state->max_num_lanes)) in s5pcsis_parse_dt()
755 state->index = endpoint.base.port - FIMC_INPUT_MIPI_CSI2_0; in s5pcsis_parse_dt()
756 if (state->index >= CSIS_MAX_ENTITIES) in s5pcsis_parse_dt()
761 &state->hs_settle); in s5pcsis_parse_dt()
762 state->wclk_ext = of_property_read_bool(node, in s5pcsis_parse_dt()
765 state->num_lanes = endpoint.bus.mipi_csi2.num_data_lanes; in s5pcsis_parse_dt()
780 struct csis_state *state; in s5pcsis_probe() local
784 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); in s5pcsis_probe()
785 if (!state) in s5pcsis_probe()
788 mutex_init(&state->lock); in s5pcsis_probe()
789 spin_lock_init(&state->slock); in s5pcsis_probe()
790 state->pdev = pdev; in s5pcsis_probe()
797 state->interrupt_mask = drv_data->interrupt_mask; in s5pcsis_probe()
799 ret = s5pcsis_parse_dt(pdev, state); in s5pcsis_probe()
803 if (state->num_lanes == 0 || state->num_lanes > state->max_num_lanes) { in s5pcsis_probe()
805 state->num_lanes, state->max_num_lanes); in s5pcsis_probe()
809 state->phy = devm_phy_get(dev, "csis"); in s5pcsis_probe()
810 if (IS_ERR(state->phy)) in s5pcsis_probe()
811 return PTR_ERR(state->phy); in s5pcsis_probe()
814 state->regs = devm_ioremap_resource(dev, mem_res); in s5pcsis_probe()
815 if (IS_ERR(state->regs)) in s5pcsis_probe()
816 return PTR_ERR(state->regs); in s5pcsis_probe()
818 state->irq = platform_get_irq(pdev, 0); in s5pcsis_probe()
819 if (state->irq < 0) { in s5pcsis_probe()
821 return state->irq; in s5pcsis_probe()
825 state->supplies[i].supply = csis_supply_name[i]; in s5pcsis_probe()
828 state->supplies); in s5pcsis_probe()
832 ret = s5pcsis_clk_get(state); in s5pcsis_probe()
836 if (state->clk_frequency) in s5pcsis_probe()
837 ret = clk_set_rate(state->clock[CSIS_CLK_MUX], in s5pcsis_probe()
838 state->clk_frequency); in s5pcsis_probe()
844 ret = clk_enable(state->clock[CSIS_CLK_MUX]); in s5pcsis_probe()
848 ret = devm_request_irq(dev, state->irq, s5pcsis_irq_handler, in s5pcsis_probe()
849 0, dev_name(dev), state); in s5pcsis_probe()
855 v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops); in s5pcsis_probe()
856 state->sd.owner = THIS_MODULE; in s5pcsis_probe()
857 snprintf(state->sd.name, sizeof(state->sd.name), "%s.%d", in s5pcsis_probe()
858 CSIS_SUBDEV_NAME, state->index); in s5pcsis_probe()
859 state->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in s5pcsis_probe()
860 state->csis_fmt = &s5pcsis_formats[0]; in s5pcsis_probe()
862 state->format.code = s5pcsis_formats[0].code; in s5pcsis_probe()
863 state->format.width = S5PCSIS_DEF_PIX_WIDTH; in s5pcsis_probe()
864 state->format.height = S5PCSIS_DEF_PIX_HEIGHT; in s5pcsis_probe()
866 state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in s5pcsis_probe()
867 state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in s5pcsis_probe()
868 ret = media_entity_init(&state->sd.entity, in s5pcsis_probe()
869 CSIS_PADS_NUM, state->pads, 0); in s5pcsis_probe()
874 v4l2_set_subdevdata(&state->sd, pdev); in s5pcsis_probe()
877 platform_set_drvdata(pdev, &state->sd); in s5pcsis_probe()
878 memcpy(state->events, s5pcsis_events, sizeof(state->events)); in s5pcsis_probe()
888 state->num_lanes, state->hs_settle, state->wclk_ext, in s5pcsis_probe()
889 state->clk_frequency); in s5pcsis_probe()
893 media_entity_cleanup(&state->sd.entity); in s5pcsis_probe()
895 clk_disable(state->clock[CSIS_CLK_MUX]); in s5pcsis_probe()
897 s5pcsis_clk_put(state); in s5pcsis_probe()
905 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_pm_suspend() local
909 __func__, state->flags); in s5pcsis_pm_suspend()
911 mutex_lock(&state->lock); in s5pcsis_pm_suspend()
912 if (state->flags & ST_POWERED) { in s5pcsis_pm_suspend()
913 s5pcsis_stop_stream(state); in s5pcsis_pm_suspend()
914 ret = phy_power_off(state->phy); in s5pcsis_pm_suspend()
918 state->supplies); in s5pcsis_pm_suspend()
921 clk_disable(state->clock[CSIS_CLK_GATE]); in s5pcsis_pm_suspend()
922 state->flags &= ~ST_POWERED; in s5pcsis_pm_suspend()
924 state->flags |= ST_SUSPENDED; in s5pcsis_pm_suspend()
927 mutex_unlock(&state->lock); in s5pcsis_pm_suspend()
935 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_pm_resume() local
939 __func__, state->flags); in s5pcsis_pm_resume()
941 mutex_lock(&state->lock); in s5pcsis_pm_resume()
942 if (!runtime && !(state->flags & ST_SUSPENDED)) in s5pcsis_pm_resume()
945 if (!(state->flags & ST_POWERED)) { in s5pcsis_pm_resume()
947 state->supplies); in s5pcsis_pm_resume()
950 ret = phy_power_on(state->phy); in s5pcsis_pm_resume()
952 state->flags |= ST_POWERED; in s5pcsis_pm_resume()
955 state->supplies); in s5pcsis_pm_resume()
958 clk_enable(state->clock[CSIS_CLK_GATE]); in s5pcsis_pm_resume()
960 if (state->flags & ST_STREAMING) in s5pcsis_pm_resume()
961 s5pcsis_start_stream(state); in s5pcsis_pm_resume()
963 state->flags &= ~ST_SUSPENDED; in s5pcsis_pm_resume()
965 mutex_unlock(&state->lock); in s5pcsis_pm_resume()
996 struct csis_state *state = sd_to_csis_state(sd); in s5pcsis_remove() local
1000 clk_disable(state->clock[CSIS_CLK_MUX]); in s5pcsis_remove()
1002 s5pcsis_clk_put(state); in s5pcsis_remove()
1004 media_entity_cleanup(&state->sd.entity); in s5pcsis_remove()