struct xilinx_cresample *cresample;
struct xilinx_rgb2yuv *rgb2yuv;
struct clk *pixel_clock;
+ bool pixel_clock_enabled;
struct xilinx_vtc *vtc;
struct xilinx_drm_plane_manager *plane_manager;
int dpms;
long diff;
int ret;
+ if (crtc->pixel_clock_enabled) {
+ clk_disable_unprepare(crtc->pixel_clock);
+ crtc->pixel_clock_enabled = false;
+ }
+
/* set pixel clock */
ret = clk_set_rate(crtc->pixel_clock, adjusted_mode->clock * 1000);
if (ret) {
DRM_DEBUG_KMS("actual pixel clock rate(%d) is off by %ld\n",
adjusted_mode->clock, diff);
+ if (!crtc->pixel_clock_enabled) {
+ ret = clk_prepare_enable(crtc->pixel_clock);
+ if (ret) {
+ DRM_ERROR("failed to enable a pixel clock\n");
+ crtc->pixel_clock_enabled = false;
+ return ret;
+ }
+ }
+ crtc->pixel_clock_enabled = true;
+
if (crtc->vtc) {
/* set video timing */
vm.hactive = adjusted_mode->hdisplay;
if (crtc->dp_sub)
xilinx_drm_dp_sub_put(crtc->dp_sub);
- clk_disable_unprepare(crtc->pixel_clock);
+ if (crtc->pixel_clock_enabled) {
+ clk_disable_unprepare(crtc->pixel_clock);
+ crtc->pixel_clock_enabled = false;
+ }
xilinx_drm_plane_remove_manager(crtc->plane_manager);
}
ret = clk_prepare_enable(crtc->pixel_clock);
if (ret) {
- DRM_DEBUG_KMS("failed to prepare/enable clock\n");
+ DRM_ERROR("failed to enable a pixel clock\n");
+ crtc->pixel_clock_enabled = false;
goto err_plane;
}
+ crtc->pixel_clock_enabled = true;
sub_node = of_parse_phandle(drm->dev->of_node, "xlnx,vtc", 0);
if (sub_node) {
if (IS_ERR(crtc->vtc)) {
DRM_ERROR("failed to probe video timing controller\n");
ret = PTR_ERR(crtc->vtc);
- goto err_plane;
+ goto err_pixel_clk;
}
}
ret = PTR_ERR(crtc->dp_sub);
if (ret != -EPROBE_DEFER)
DRM_ERROR("failed to get a dp_sub\n");
- goto err_plane;
+ goto err_pixel_clk;
}
crtc->dpms = DRM_MODE_DPMS_OFF;
NULL, &xilinx_drm_crtc_funcs, NULL);
if (ret) {
DRM_ERROR("failed to initialize crtc\n");
- goto err_plane;
+ goto err_pixel_clk;
}
drm_crtc_helper_add(&crtc->base, &xilinx_drm_crtc_helper_funcs);
return &crtc->base;
+err_pixel_clk:
+ if (crtc->pixel_clock_enabled) {
+ clk_disable_unprepare(crtc->pixel_clock);
+ crtc->pixel_clock_enabled = false;
+ }
err_plane:
xilinx_drm_plane_remove_manager(crtc->plane_manager);
return ERR_PTR(ret);