Lines Matching full:csiphy
3 * camss-csiphy.c
5 * Qualcomm MSM Camera Subsystem - CSIPHY Module
22 #include "camss-csiphy.h"
139 * csiphy_set_clock_rates - Calculate and set clock rates on CSIPHY module
140 * @csiphy: CSIPHY device
142 static int csiphy_set_clock_rates(struct csiphy_device *csiphy) in csiphy_set_clock_rates() argument
144 struct device *dev = csiphy->camss->dev; in csiphy_set_clock_rates()
149 u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats, in csiphy_set_clock_rates()
150 csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); in csiphy_set_clock_rates()
151 u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data; in csiphy_set_clock_rates()
153 link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); in csiphy_set_clock_rates()
157 for (i = 0; i < csiphy->nclocks; i++) { in csiphy_set_clock_rates()
158 struct camss_clock *clock = &csiphy->clock[i]; in csiphy_set_clock_rates()
160 if (csiphy->rate_set[i]) { in csiphy_set_clock_rates()
172 "Pixel clock is too high for CSIPHY\n"); in csiphy_set_clock_rates()
177 /* set highest possible CSIPHY clock rate */ in csiphy_set_clock_rates()
188 csiphy->timer_clk_rate = round_rate; in csiphy_set_clock_rates()
190 ret = clk_set_rate(clock->clk, csiphy->timer_clk_rate); in csiphy_set_clock_rates()
202 * csiphy_set_power - Power on/off CSIPHY module
203 * @sd: CSIPHY V4L2 subdevice
210 struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); in csiphy_set_power() local
211 struct device *dev = csiphy->camss->dev; in csiphy_set_power()
220 ret = regulator_bulk_enable(csiphy->num_supplies, in csiphy_set_power()
221 csiphy->supplies); in csiphy_set_power()
227 ret = csiphy_set_clock_rates(csiphy); in csiphy_set_power()
229 regulator_bulk_disable(csiphy->num_supplies, in csiphy_set_power()
230 csiphy->supplies); in csiphy_set_power()
235 ret = camss_enable_clocks(csiphy->nclocks, csiphy->clock, dev); in csiphy_set_power()
237 regulator_bulk_disable(csiphy->num_supplies, in csiphy_set_power()
238 csiphy->supplies); in csiphy_set_power()
243 enable_irq(csiphy->irq); in csiphy_set_power()
245 csiphy->res->hw_ops->reset(csiphy); in csiphy_set_power()
247 csiphy->res->hw_ops->hw_version_read(csiphy, dev); in csiphy_set_power()
249 disable_irq(csiphy->irq); in csiphy_set_power()
251 camss_disable_clocks(csiphy->nclocks, csiphy->clock); in csiphy_set_power()
253 regulator_bulk_disable(csiphy->num_supplies, csiphy->supplies); in csiphy_set_power()
262 * csiphy_stream_on - Enable streaming on CSIPHY module
263 * @csiphy: CSIPHY device
265 * Helper function to enable streaming on CSIPHY module.
266 * Main configuration of CSIPHY module is also done here.
270 static int csiphy_stream_on(struct csiphy_device *csiphy) in csiphy_stream_on() argument
272 struct csiphy_config *cfg = &csiphy->cfg; in csiphy_stream_on()
274 u8 lane_mask = csiphy->res->hw_ops->get_lane_mask(&cfg->csi2->lane_cfg); in csiphy_stream_on()
275 u8 bpp = csiphy_get_bpp(csiphy->res->formats->formats, csiphy->res->formats->nformats, in csiphy_stream_on()
276 csiphy->fmt[MSM_CSIPHY_PAD_SINK].code); in csiphy_stream_on()
277 u8 num_lanes = csiphy->cfg.csi2->lane_cfg.num_data; in csiphy_stream_on()
280 link_freq = camss_get_link_freq(&csiphy->subdev.entity, bpp, num_lanes); in csiphy_stream_on()
283 dev_err(csiphy->camss->dev, in csiphy_stream_on()
288 if (csiphy->base_clk_mux) { in csiphy_stream_on()
289 val = readl_relaxed(csiphy->base_clk_mux); in csiphy_stream_on()
297 writel_relaxed(val, csiphy->base_clk_mux); in csiphy_stream_on()
303 csiphy->res->hw_ops->lanes_enable(csiphy, cfg, link_freq, lane_mask); in csiphy_stream_on()
309 * csiphy_stream_off - Disable streaming on CSIPHY module
310 * @csiphy: CSIPHY device
312 * Helper function to disable streaming on CSIPHY module
314 static void csiphy_stream_off(struct csiphy_device *csiphy) in csiphy_stream_off() argument
316 csiphy->res->hw_ops->lanes_disable(csiphy, &csiphy->cfg); in csiphy_stream_off()
321 * csiphy_set_stream - Enable/disable streaming on CSIPHY module
322 * @sd: CSIPHY V4L2 subdevice
329 struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); in csiphy_set_stream() local
333 ret = csiphy_stream_on(csiphy); in csiphy_set_stream()
335 csiphy_stream_off(csiphy); in csiphy_set_stream()
342 * @csiphy: CSIPHY device
350 __csiphy_get_format(struct csiphy_device *csiphy, in __csiphy_get_format() argument
358 return &csiphy->fmt[pad]; in __csiphy_get_format()
363 * @csiphy: CSIPHY device
369 static void csiphy_try_format(struct csiphy_device *csiphy, in csiphy_try_format() argument
381 for (i = 0; i < csiphy->res->formats->nformats; i++) in csiphy_try_format()
382 if (fmt->code == csiphy->res->formats->formats[i].code) in csiphy_try_format()
386 if (i >= csiphy->res->formats->nformats) in csiphy_try_format()
400 *fmt = *__csiphy_get_format(csiphy, sd_state, in csiphy_try_format()
410 * @sd: CSIPHY V4L2 subdevice
419 struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); in csiphy_enum_mbus_code() local
423 if (code->index >= csiphy->res->formats->nformats) in csiphy_enum_mbus_code()
426 code->code = csiphy->res->formats->formats[code->index].code; in csiphy_enum_mbus_code()
431 format = __csiphy_get_format(csiphy, sd_state, in csiphy_enum_mbus_code()
443 * @sd: CSIPHY V4L2 subdevice
452 struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); in csiphy_enum_frame_size() local
461 csiphy_try_format(csiphy, sd_state, fse->pad, &format, fse->which); in csiphy_enum_frame_size()
471 csiphy_try_format(csiphy, sd_state, fse->pad, &format, fse->which); in csiphy_enum_frame_size()
480 * @sd: CSIPHY V4L2 subdevice
490 struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); in csiphy_get_format() local
493 format = __csiphy_get_format(csiphy, sd_state, fmt->pad, fmt->which); in csiphy_get_format()
504 * @sd: CSIPHY V4L2 subdevice
514 struct csiphy_device *csiphy = v4l2_get_subdevdata(sd); in csiphy_set_format() local
517 format = __csiphy_get_format(csiphy, sd_state, fmt->pad, fmt->which); in csiphy_set_format()
521 csiphy_try_format(csiphy, sd_state, fmt->pad, &fmt->format, in csiphy_set_format()
527 format = __csiphy_get_format(csiphy, sd_state, in csiphy_set_format()
532 csiphy_try_format(csiphy, sd_state, MSM_CSIPHY_PAD_SRC, in csiphy_set_format()
542 * @sd: CSIPHY V4L2 subdevice
576 * msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources
577 * @csiphy: CSIPHY device
578 * @res: CSIPHY module resources table
579 * @id: CSIPHY module id
584 struct csiphy_device *csiphy, in msm_csiphy_subdev_init() argument
592 csiphy->camss = camss; in msm_csiphy_subdev_init()
593 csiphy->id = id; in msm_csiphy_subdev_init()
594 csiphy->cfg.combo_mode = 0; in msm_csiphy_subdev_init()
595 csiphy->res = &res->csiphy; in msm_csiphy_subdev_init()
599 csiphy->base = devm_platform_ioremap_resource_byname(pdev, res->reg[0]); in msm_csiphy_subdev_init()
600 if (IS_ERR(csiphy->base)) in msm_csiphy_subdev_init()
601 return PTR_ERR(csiphy->base); in msm_csiphy_subdev_init()
606 csiphy->base_clk_mux = in msm_csiphy_subdev_init()
608 if (IS_ERR(csiphy->base_clk_mux)) in msm_csiphy_subdev_init()
609 return PTR_ERR(csiphy->base_clk_mux); in msm_csiphy_subdev_init()
611 csiphy->base_clk_mux = NULL; in msm_csiphy_subdev_init()
620 csiphy->irq = ret; in msm_csiphy_subdev_init()
621 snprintf(csiphy->irq_name, sizeof(csiphy->irq_name), "%s_%s%d", in msm_csiphy_subdev_init()
622 dev_name(dev), MSM_CSIPHY_NAME, csiphy->id); in msm_csiphy_subdev_init()
624 ret = devm_request_irq(dev, csiphy->irq, csiphy->res->hw_ops->isr, in msm_csiphy_subdev_init()
626 csiphy->irq_name, csiphy); in msm_csiphy_subdev_init()
634 csiphy->nclocks = 0; in msm_csiphy_subdev_init()
635 while (res->clock[csiphy->nclocks]) in msm_csiphy_subdev_init()
636 csiphy->nclocks++; in msm_csiphy_subdev_init()
638 csiphy->clock = devm_kcalloc(dev, in msm_csiphy_subdev_init()
639 csiphy->nclocks, sizeof(*csiphy->clock), in msm_csiphy_subdev_init()
641 if (!csiphy->clock) in msm_csiphy_subdev_init()
644 csiphy->rate_set = devm_kcalloc(dev, in msm_csiphy_subdev_init()
645 csiphy->nclocks, in msm_csiphy_subdev_init()
646 sizeof(*csiphy->rate_set), in msm_csiphy_subdev_init()
648 if (!csiphy->rate_set) in msm_csiphy_subdev_init()
651 for (i = 0; i < csiphy->nclocks; i++) { in msm_csiphy_subdev_init()
652 struct camss_clock *clock = &csiphy->clock[i]; in msm_csiphy_subdev_init()
680 csiphy->rate_set[i] = csiphy_match_clock_name(clock->name, in msm_csiphy_subdev_init()
681 "csiphy%d_timer", k); in msm_csiphy_subdev_init()
682 if (csiphy->rate_set[i]) in msm_csiphy_subdev_init()
686 csiphy->rate_set[i] = csiphy_match_clock_name(clock->name, in msm_csiphy_subdev_init()
688 if (csiphy->rate_set[i]) in msm_csiphy_subdev_init()
692 csiphy->rate_set[i] = csiphy_match_clock_name(clock->name, "csiphy%d", k); in msm_csiphy_subdev_init()
693 if (csiphy->rate_set[i]) in msm_csiphy_subdev_init()
698 /* CSIPHY supplies */ in msm_csiphy_subdev_init()
701 csiphy->num_supplies++; in msm_csiphy_subdev_init()
704 if (csiphy->num_supplies) { in msm_csiphy_subdev_init()
705 csiphy->supplies = devm_kmalloc_array(camss->dev, in msm_csiphy_subdev_init()
706 csiphy->num_supplies, in msm_csiphy_subdev_init()
707 sizeof(*csiphy->supplies), in msm_csiphy_subdev_init()
709 if (!csiphy->supplies) in msm_csiphy_subdev_init()
713 for (i = 0; i < csiphy->num_supplies; i++) in msm_csiphy_subdev_init()
714 csiphy->supplies[i].supply = res->regulators[i]; in msm_csiphy_subdev_init()
716 ret = devm_regulator_bulk_get(camss->dev, csiphy->num_supplies, in msm_csiphy_subdev_init()
717 csiphy->supplies); in msm_csiphy_subdev_init()
722 * csiphy_link_setup - Setup CSIPHY connections
737 struct csiphy_device *csiphy; in csiphy_link_setup() local
744 csiphy = v4l2_get_subdevdata(sd); in csiphy_link_setup()
749 csiphy->cfg.csid_id = csid->id; in csiphy_link_setup()
786 * msm_csiphy_register_entity - Register subdev node for CSIPHY module
787 * @csiphy: CSIPHY device
792 int msm_csiphy_register_entity(struct csiphy_device *csiphy, in msm_csiphy_register_entity() argument
795 struct v4l2_subdev *sd = &csiphy->subdev; in msm_csiphy_register_entity()
796 struct media_pad *pads = csiphy->pads; in msm_csiphy_register_entity()
797 struct device *dev = csiphy->camss->dev; in msm_csiphy_register_entity()
804 MSM_CSIPHY_NAME, csiphy->id); in msm_csiphy_register_entity()
805 v4l2_set_subdevdata(sd, csiphy); in msm_csiphy_register_entity()
834 * msm_csiphy_unregister_entity - Unregister CSIPHY module subdev node
835 * @csiphy: CSIPHY device
837 void msm_csiphy_unregister_entity(struct csiphy_device *csiphy) in msm_csiphy_unregister_entity() argument
839 v4l2_device_unregister_subdev(&csiphy->subdev); in msm_csiphy_unregister_entity()
840 media_entity_cleanup(&csiphy->subdev.entity); in msm_csiphy_unregister_entity()