aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-12-08 10:14:45 -0500
committerThierry Reding <treding@nvidia.com>2015-01-27 04:14:52 -0500
commitca915b108a39081edff1206ec00ecdb4136408ac (patch)
treebe8c144ee09940e9dd31248e03c3114236e4909e /drivers/gpu/drm
parent07866963b675b358d82baf8df73dba545d967a1d (diff)
drm/tegra: dc: Store clock setup in atomic state
This allows the clock setup to be separated from the clock programming and better matches the expectations of the atomic modesetting where no code paths must fail during modeset. Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/tegra/dc.c71
-rw-r--r--drivers/gpu/drm/tegra/drm.h4
2 files changed, 72 insertions, 3 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 4fb9048b2f65..b905a4e2bdf9 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -41,6 +41,22 @@ static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane)
41 return container_of(plane, struct tegra_plane, base); 41 return container_of(plane, struct tegra_plane, base);
42} 42}
43 43
44struct tegra_dc_state {
45 struct drm_crtc_state base;
46
47 struct clk *clk;
48 unsigned long pclk;
49 unsigned int div;
50};
51
52static inline struct tegra_dc_state *to_dc_state(struct drm_crtc_state *state)
53{
54 if (state)
55 return container_of(state, struct tegra_dc_state, base);
56
57 return NULL;
58}
59
44static void tegra_dc_window_commit(struct tegra_dc *dc, unsigned int index) 60static void tegra_dc_window_commit(struct tegra_dc *dc, unsigned int index)
45{ 61{
46 u32 value = WIN_A_ACT_REQ << index; 62 u32 value = WIN_A_ACT_REQ << index;
@@ -1004,13 +1020,48 @@ static void tegra_dc_destroy(struct drm_crtc *crtc)
1004 drm_crtc_cleanup(crtc); 1020 drm_crtc_cleanup(crtc);
1005} 1021}
1006 1022
1023static void tegra_crtc_reset(struct drm_crtc *crtc)
1024{
1025 struct tegra_dc_state *state;
1026
1027 kfree(crtc->state);
1028 crtc->state = NULL;
1029
1030 state = kzalloc(sizeof(*state), GFP_KERNEL);
1031 if (state)
1032 crtc->state = &state->base;
1033}
1034
1035static struct drm_crtc_state *
1036tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
1037{
1038 struct tegra_dc_state *state = to_dc_state(crtc->state);
1039 struct tegra_dc_state *copy;
1040
1041 copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
1042 if (!copy)
1043 return NULL;
1044
1045 copy->base.mode_changed = false;
1046 copy->base.planes_changed = false;
1047 copy->base.event = NULL;
1048
1049 return &copy->base;
1050}
1051
1052static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc,
1053 struct drm_crtc_state *state)
1054{
1055 kfree(state);
1056}
1057
1007static const struct drm_crtc_funcs tegra_crtc_funcs = { 1058static const struct drm_crtc_funcs tegra_crtc_funcs = {
1008 .page_flip = tegra_dc_page_flip, 1059 .page_flip = tegra_dc_page_flip,
1009 .set_config = drm_crtc_helper_set_config, 1060 .set_config = drm_crtc_helper_set_config,
1010 .destroy = tegra_dc_destroy, 1061 .destroy = tegra_dc_destroy,
1011 .reset = drm_atomic_helper_crtc_reset, 1062 .reset = tegra_crtc_reset,
1012 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, 1063 .atomic_duplicate_state = tegra_crtc_atomic_duplicate_state,
1013 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, 1064 .atomic_destroy_state = tegra_crtc_atomic_destroy_state,
1014}; 1065};
1015 1066
1016static void tegra_dc_stop(struct tegra_dc *dc) 1067static void tegra_dc_stop(struct tegra_dc *dc)
@@ -1148,6 +1199,20 @@ int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent,
1148 return 0; 1199 return 0;
1149} 1200}
1150 1201
1202int tegra_dc_state_setup_clock(struct tegra_dc *dc,
1203 struct drm_crtc_state *crtc_state,
1204 struct clk *clk, unsigned long pclk,
1205 unsigned int div)
1206{
1207 struct tegra_dc_state *state = to_dc_state(crtc_state);
1208
1209 state->clk = clk;
1210 state->pclk = pclk;
1211 state->div = div;
1212
1213 return 0;
1214}
1215
1151static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc) 1216static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
1152{ 1217{
1153 struct drm_display_mode *mode = &crtc->state->adjusted_mode; 1218 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index bf1c47ec46b6..3db719de312f 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -180,6 +180,10 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
180void tegra_dc_commit(struct tegra_dc *dc); 180void tegra_dc_commit(struct tegra_dc *dc);
181int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent, 181int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent,
182 unsigned long pclk, unsigned int div); 182 unsigned long pclk, unsigned int div);
183int tegra_dc_state_setup_clock(struct tegra_dc *dc,
184 struct drm_crtc_state *crtc_state,
185 struct clk *clk, unsigned long pclk,
186 unsigned int div);
183 187
184struct tegra_output { 188struct tegra_output {
185 struct device_node *of_node; 189 struct device_node *of_node;