aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c144
-rw-r--r--drivers/gpu/drm/tegra/dc.c99
-rw-r--r--drivers/gpu/drm/tegra/dc.h7
-rw-r--r--drivers/gpu/drm/tegra/drm.c18
-rw-r--r--drivers/gpu/drm/tegra/drm.h4
-rw-r--r--drivers/gpu/drm/tegra/hdmi.c4
-rw-r--r--drivers/gpu/drm/tegra/hdmi.h2
-rw-r--r--drivers/gpu/drm/tegra/sor.c202
-rw-r--r--drivers/gpu/host1x/syncpt.c6
-rw-r--r--include/drm/drm_atomic_helper.h14
-rw-r--r--include/linux/host1x.h1
-rw-r--r--include/uapi/drm/tegra_drm.h3
12 files changed, 421 insertions, 83 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index e67d4d69faf7..41c38edade74 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -2069,6 +2069,26 @@ void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
2069EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); 2069EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
2070 2070
2071/** 2071/**
2072 * __drm_atomic_helper_crtc_duplicate_state - copy atomic CRTC state
2073 * @crtc: CRTC object
2074 * @state: atomic CRTC state
2075 *
2076 * Copies atomic state from a CRTC's current state and resets inferred values.
2077 * This is useful for drivers that subclass the CRTC state.
2078 */
2079void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
2080 struct drm_crtc_state *state)
2081{
2082 memcpy(state, crtc->state, sizeof(*state));
2083
2084 state->mode_changed = false;
2085 state->active_changed = false;
2086 state->planes_changed = false;
2087 state->event = NULL;
2088}
2089EXPORT_SYMBOL(__drm_atomic_helper_crtc_duplicate_state);
2090
2091/**
2072 * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook 2092 * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
2073 * @crtc: drm CRTC 2093 * @crtc: drm CRTC
2074 * 2094 *
@@ -2083,20 +2103,35 @@ drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
2083 if (WARN_ON(!crtc->state)) 2103 if (WARN_ON(!crtc->state))
2084 return NULL; 2104 return NULL;
2085 2105
2086 state = kmemdup(crtc->state, sizeof(*crtc->state), GFP_KERNEL); 2106 state = kmalloc(sizeof(*state), GFP_KERNEL);
2087 2107 if (state)
2088 if (state) { 2108 __drm_atomic_helper_crtc_duplicate_state(crtc, state);
2089 state->mode_changed = false;
2090 state->active_changed = false;
2091 state->planes_changed = false;
2092 state->event = NULL;
2093 }
2094 2109
2095 return state; 2110 return state;
2096} 2111}
2097EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state); 2112EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
2098 2113
2099/** 2114/**
2115 * __drm_atomic_helper_crtc_destroy_state - release CRTC state
2116 * @crtc: CRTC object
2117 * @state: CRTC state object to release
2118 *
2119 * Releases all resources stored in the CRTC state without actually freeing
2120 * the memory of the CRTC state. This is useful for drivers that subclass the
2121 * CRTC state.
2122 */
2123void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
2124 struct drm_crtc_state *state)
2125{
2126 /*
2127 * This is currently a placeholder so that drivers that subclass the
2128 * state will automatically do the right thing if code is ever added
2129 * to this function.
2130 */
2131}
2132EXPORT_SYMBOL(__drm_atomic_helper_crtc_destroy_state);
2133
2134/**
2100 * drm_atomic_helper_crtc_destroy_state - default state destroy hook 2135 * drm_atomic_helper_crtc_destroy_state - default state destroy hook
2101 * @crtc: drm CRTC 2136 * @crtc: drm CRTC
2102 * @state: CRTC state object to release 2137 * @state: CRTC state object to release
@@ -2107,6 +2142,7 @@ EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
2107void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, 2142void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
2108 struct drm_crtc_state *state) 2143 struct drm_crtc_state *state)
2109{ 2144{
2145 __drm_atomic_helper_crtc_destroy_state(crtc, state);
2110 kfree(state); 2146 kfree(state);
2111} 2147}
2112EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state); 2148EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
@@ -2132,6 +2168,24 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane)
2132EXPORT_SYMBOL(drm_atomic_helper_plane_reset); 2168EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
2133 2169
2134/** 2170/**
2171 * __drm_atomic_helper_plane_duplicate_state - copy atomic plane state
2172 * @plane: plane object
2173 * @state: atomic plane state
2174 *
2175 * Copies atomic state from a plane's current state. This is useful for
2176 * drivers that subclass the plane state.
2177 */
2178void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
2179 struct drm_plane_state *state)
2180{
2181 memcpy(state, plane->state, sizeof(*state));
2182
2183 if (state->fb)
2184 drm_framebuffer_reference(state->fb);
2185}
2186EXPORT_SYMBOL(__drm_atomic_helper_plane_duplicate_state);
2187
2188/**
2135 * drm_atomic_helper_plane_duplicate_state - default state duplicate hook 2189 * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
2136 * @plane: drm plane 2190 * @plane: drm plane
2137 * 2191 *
@@ -2146,16 +2200,32 @@ drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
2146 if (WARN_ON(!plane->state)) 2200 if (WARN_ON(!plane->state))
2147 return NULL; 2201 return NULL;
2148 2202
2149 state = kmemdup(plane->state, sizeof(*plane->state), GFP_KERNEL); 2203 state = kmalloc(sizeof(*state), GFP_KERNEL);
2150 2204 if (state)
2151 if (state && state->fb) 2205 __drm_atomic_helper_plane_duplicate_state(plane, state);
2152 drm_framebuffer_reference(state->fb);
2153 2206
2154 return state; 2207 return state;
2155} 2208}
2156EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state); 2209EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
2157 2210
2158/** 2211/**
2212 * __drm_atomic_helper_plane_destroy_state - release plane state
2213 * @plane: plane object
2214 * @state: plane state object to release
2215 *
2216 * Releases all resources stored in the plane state without actually freeing
2217 * the memory of the plane state. This is useful for drivers that subclass the
2218 * plane state.
2219 */
2220void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
2221 struct drm_plane_state *state)
2222{
2223 if (state->fb)
2224 drm_framebuffer_unreference(state->fb);
2225}
2226EXPORT_SYMBOL(__drm_atomic_helper_plane_destroy_state);
2227
2228/**
2159 * drm_atomic_helper_plane_destroy_state - default state destroy hook 2229 * drm_atomic_helper_plane_destroy_state - default state destroy hook
2160 * @plane: drm plane 2230 * @plane: drm plane
2161 * @state: plane state object to release 2231 * @state: plane state object to release
@@ -2166,9 +2236,7 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
2166void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, 2236void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
2167 struct drm_plane_state *state) 2237 struct drm_plane_state *state)
2168{ 2238{
2169 if (state->fb) 2239 __drm_atomic_helper_plane_destroy_state(plane, state);
2170 drm_framebuffer_unreference(state->fb);
2171
2172 kfree(state); 2240 kfree(state);
2173} 2241}
2174EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); 2242EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
@@ -2192,6 +2260,22 @@ void drm_atomic_helper_connector_reset(struct drm_connector *connector)
2192EXPORT_SYMBOL(drm_atomic_helper_connector_reset); 2260EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
2193 2261
2194/** 2262/**
2263 * __drm_atomic_helper_connector_duplicate_state - copy atomic connector state
2264 * @connector: connector object
2265 * @state: atomic connector state
2266 *
2267 * Copies atomic state from a connector's current state. This is useful for
2268 * drivers that subclass the connector state.
2269 */
2270void
2271__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
2272 struct drm_connector_state *state)
2273{
2274 memcpy(state, connector->state, sizeof(*state));
2275}
2276EXPORT_SYMBOL(__drm_atomic_helper_connector_duplicate_state);
2277
2278/**
2195 * drm_atomic_helper_connector_duplicate_state - default state duplicate hook 2279 * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
2196 * @connector: drm connector 2280 * @connector: drm connector
2197 * 2281 *
@@ -2201,14 +2285,41 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
2201struct drm_connector_state * 2285struct drm_connector_state *
2202drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector) 2286drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
2203{ 2287{
2288 struct drm_connector_state *state;
2289
2204 if (WARN_ON(!connector->state)) 2290 if (WARN_ON(!connector->state))
2205 return NULL; 2291 return NULL;
2206 2292
2207 return kmemdup(connector->state, sizeof(*connector->state), GFP_KERNEL); 2293 state = kmalloc(sizeof(*state), GFP_KERNEL);
2294 if (state)
2295 __drm_atomic_helper_connector_duplicate_state(connector, state);
2296
2297 return state;
2208} 2298}
2209EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state); 2299EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
2210 2300
2211/** 2301/**
2302 * __drm_atomic_helper_connector_destroy_state - release connector state
2303 * @connector: connector object
2304 * @state: connector state object to release
2305 *
2306 * Releases all resources stored in the connector state without actually
2307 * freeing the memory of the connector state. This is useful for drivers that
2308 * subclass the connector state.
2309 */
2310void
2311__drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
2312 struct drm_connector_state *state)
2313{
2314 /*
2315 * This is currently a placeholder so that drivers that subclass the
2316 * state will automatically do the right thing if code is ever added
2317 * to this function.
2318 */
2319}
2320EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
2321
2322/**
2212 * drm_atomic_helper_connector_destroy_state - default state destroy hook 2323 * drm_atomic_helper_connector_destroy_state - default state destroy hook
2213 * @connector: drm connector 2324 * @connector: drm connector
2214 * @state: connector state object to release 2325 * @state: connector state object to release
@@ -2219,6 +2330,7 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
2219void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, 2330void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
2220 struct drm_connector_state *state) 2331 struct drm_connector_state *state)
2221{ 2332{
2333 __drm_atomic_helper_connector_destroy_state(connector, state);
2222 kfree(state); 2334 kfree(state);
2223} 2335}
2224EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state); 2336EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index b7f781573b15..a287e4fec865 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -425,8 +425,8 @@ static void tegra_plane_reset(struct drm_plane *plane)
425{ 425{
426 struct tegra_plane_state *state; 426 struct tegra_plane_state *state;
427 427
428 if (plane->state && plane->state->fb) 428 if (plane->state)
429 drm_framebuffer_unreference(plane->state->fb); 429 __drm_atomic_helper_plane_destroy_state(plane, plane->state);
430 430
431 kfree(plane->state); 431 kfree(plane->state);
432 plane->state = NULL; 432 plane->state = NULL;
@@ -443,12 +443,14 @@ static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_pla
443 struct tegra_plane_state *state = to_tegra_plane_state(plane->state); 443 struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
444 struct tegra_plane_state *copy; 444 struct tegra_plane_state *copy;
445 445
446 copy = kmemdup(state, sizeof(*state), GFP_KERNEL); 446 copy = kmalloc(sizeof(*copy), GFP_KERNEL);
447 if (!copy) 447 if (!copy)
448 return NULL; 448 return NULL;
449 449
450 if (copy->base.fb) 450 __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
451 drm_framebuffer_reference(copy->base.fb); 451 copy->tiling = state->tiling;
452 copy->format = state->format;
453 copy->swap = state->swap;
452 454
453 return &copy->base; 455 return &copy->base;
454} 456}
@@ -456,9 +458,7 @@ static struct drm_plane_state *tegra_plane_atomic_duplicate_state(struct drm_pla
456static void tegra_plane_atomic_destroy_state(struct drm_plane *plane, 458static void tegra_plane_atomic_destroy_state(struct drm_plane *plane,
457 struct drm_plane_state *state) 459 struct drm_plane_state *state)
458{ 460{
459 if (state->fb) 461 __drm_atomic_helper_plane_destroy_state(plane, state);
460 drm_framebuffer_unreference(state->fb);
461
462 kfree(state); 462 kfree(state);
463} 463}
464 464
@@ -908,6 +908,15 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
908 return 0; 908 return 0;
909} 909}
910 910
911u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc)
912{
913 if (dc->syncpt)
914 return host1x_syncpt_read(dc->syncpt);
915
916 /* fallback to software emulated VBLANK counter */
917 return drm_crtc_vblank_count(&dc->base);
918}
919
911void tegra_dc_enable_vblank(struct tegra_dc *dc) 920void tegra_dc_enable_vblank(struct tegra_dc *dc)
912{ 921{
913 unsigned long value, flags; 922 unsigned long value, flags;
@@ -995,6 +1004,9 @@ static void tegra_crtc_reset(struct drm_crtc *crtc)
995{ 1004{
996 struct tegra_dc_state *state; 1005 struct tegra_dc_state *state;
997 1006
1007 if (crtc->state)
1008 __drm_atomic_helper_crtc_destroy_state(crtc, crtc->state);
1009
998 kfree(crtc->state); 1010 kfree(crtc->state);
999 crtc->state = NULL; 1011 crtc->state = NULL;
1000 1012
@@ -1011,14 +1023,15 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
1011 struct tegra_dc_state *state = to_dc_state(crtc->state); 1023 struct tegra_dc_state *state = to_dc_state(crtc->state);
1012 struct tegra_dc_state *copy; 1024 struct tegra_dc_state *copy;
1013 1025
1014 copy = kmemdup(state, sizeof(*state), GFP_KERNEL); 1026 copy = kmalloc(sizeof(*copy), GFP_KERNEL);
1015 if (!copy) 1027 if (!copy)
1016 return NULL; 1028 return NULL;
1017 1029
1018 copy->base.mode_changed = false; 1030 __drm_atomic_helper_crtc_duplicate_state(crtc, &copy->base);
1019 copy->base.active_changed = false; 1031 copy->clk = state->clk;
1020 copy->base.planes_changed = false; 1032 copy->pclk = state->pclk;
1021 copy->base.event = NULL; 1033 copy->div = state->div;
1034 copy->planes = state->planes;
1022 1035
1023 return &copy->base; 1036 return &copy->base;
1024} 1037}
@@ -1026,6 +1039,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
1026static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc, 1039static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc,
1027 struct drm_crtc_state *state) 1040 struct drm_crtc_state *state)
1028{ 1041{
1042 __drm_atomic_helper_crtc_destroy_state(crtc, state);
1029 kfree(state); 1043 kfree(state);
1030} 1044}
1031 1045
@@ -1152,26 +1166,18 @@ static int tegra_dc_set_timings(struct tegra_dc *dc,
1152 return 0; 1166 return 0;
1153} 1167}
1154 1168
1155int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent, 1169/**
1156 unsigned long pclk, unsigned int div) 1170 * tegra_dc_state_setup_clock - check clock settings and store them in atomic
1157{ 1171 * state
1158 u32 value; 1172 * @dc: display controller
1159 int err; 1173 * @crtc_state: CRTC atomic state
1160 1174 * @clk: parent clock for display controller
1161 err = clk_set_parent(dc->clk, parent); 1175 * @pclk: pixel clock
1162 if (err < 0) { 1176 * @div: shift clock divider
1163 dev_err(dc->dev, "failed to set parent clock: %d\n", err); 1177 *
1164 return err; 1178 * Returns:
1165 } 1179 * 0 on success or a negative error-code on failure.
1166 1180 */
1167 DRM_DEBUG_KMS("rate: %lu, div: %u\n", clk_get_rate(dc->clk), div);
1168
1169 value = SHIFT_CLK_DIVIDER(div) | PIXEL_CLK_DIVIDER_PCD1;
1170 tegra_dc_writel(dc, value, DC_DISP_DISP_CLOCK_CONTROL);
1171
1172 return 0;
1173}
1174
1175int tegra_dc_state_setup_clock(struct tegra_dc *dc, 1181int tegra_dc_state_setup_clock(struct tegra_dc *dc,
1176 struct drm_crtc_state *crtc_state, 1182 struct drm_crtc_state *crtc_state,
1177 struct clk *clk, unsigned long pclk, 1183 struct clk *clk, unsigned long pclk,
@@ -1179,6 +1185,9 @@ int tegra_dc_state_setup_clock(struct tegra_dc *dc,
1179{ 1185{
1180 struct tegra_dc_state *state = to_dc_state(crtc_state); 1186 struct tegra_dc_state *state = to_dc_state(crtc_state);
1181 1187
1188 if (!clk_has_parent(dc->clk, clk))
1189 return -EINVAL;
1190
1182 state->clk = clk; 1191 state->clk = clk;
1183 state->pclk = pclk; 1192 state->pclk = pclk;
1184 state->div = div; 1193 state->div = div;
@@ -1294,9 +1303,7 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc)
1294static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = { 1303static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
1295 .disable = tegra_crtc_disable, 1304 .disable = tegra_crtc_disable,
1296 .mode_fixup = tegra_crtc_mode_fixup, 1305 .mode_fixup = tegra_crtc_mode_fixup,
1297 .mode_set = drm_helper_crtc_mode_set,
1298 .mode_set_nofb = tegra_crtc_mode_set_nofb, 1306 .mode_set_nofb = tegra_crtc_mode_set_nofb,
1299 .mode_set_base = drm_helper_crtc_mode_set_base,
1300 .prepare = tegra_crtc_prepare, 1307 .prepare = tegra_crtc_prepare,
1301 .commit = tegra_crtc_commit, 1308 .commit = tegra_crtc_commit,
1302 .atomic_check = tegra_crtc_atomic_check, 1309 .atomic_check = tegra_crtc_atomic_check,
@@ -1631,7 +1638,6 @@ static int tegra_dc_init(struct host1x_client *client)
1631 struct tegra_drm *tegra = drm->dev_private; 1638 struct tegra_drm *tegra = drm->dev_private;
1632 struct drm_plane *primary = NULL; 1639 struct drm_plane *primary = NULL;
1633 struct drm_plane *cursor = NULL; 1640 struct drm_plane *cursor = NULL;
1634 unsigned int syncpt;
1635 u32 value; 1641 u32 value;
1636 int err; 1642 int err;
1637 1643
@@ -1700,13 +1706,15 @@ static int tegra_dc_init(struct host1x_client *client)
1700 } 1706 }
1701 1707
1702 /* initialize display controller */ 1708 /* initialize display controller */
1703 if (dc->pipe) 1709 if (dc->syncpt) {
1704 syncpt = SYNCPT_VBLANK1; 1710 u32 syncpt = host1x_syncpt_id(dc->syncpt);
1705 else
1706 syncpt = SYNCPT_VBLANK0;
1707 1711
1708 tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); 1712 value = SYNCPT_CNTRL_NO_STALL;
1709 tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC); 1713 tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1714
1715 value = SYNCPT_VSYNC_ENABLE | syncpt;
1716 tegra_dc_writel(dc, value, DC_CMD_CONT_SYNCPT_VSYNC);
1717 }
1710 1718
1711 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT; 1719 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
1712 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE); 1720 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
@@ -1874,6 +1882,7 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc)
1874 1882
1875static int tegra_dc_probe(struct platform_device *pdev) 1883static int tegra_dc_probe(struct platform_device *pdev)
1876{ 1884{
1885 unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED;
1877 const struct of_device_id *id; 1886 const struct of_device_id *id;
1878 struct resource *regs; 1887 struct resource *regs;
1879 struct tegra_dc *dc; 1888 struct tegra_dc *dc;
@@ -1965,6 +1974,10 @@ static int tegra_dc_probe(struct platform_device *pdev)
1965 return err; 1974 return err;
1966 } 1975 }
1967 1976
1977 dc->syncpt = host1x_syncpt_request(&pdev->dev, flags);
1978 if (!dc->syncpt)
1979 dev_warn(&pdev->dev, "failed to allocate syncpoint\n");
1980
1968 platform_set_drvdata(pdev, dc); 1981 platform_set_drvdata(pdev, dc);
1969 1982
1970 return 0; 1983 return 0;
@@ -1975,6 +1988,8 @@ static int tegra_dc_remove(struct platform_device *pdev)
1975 struct tegra_dc *dc = platform_get_drvdata(pdev); 1988 struct tegra_dc *dc = platform_get_drvdata(pdev);
1976 int err; 1989 int err;
1977 1990
1991 host1x_syncpt_free(dc->syncpt);
1992
1978 err = host1x_client_unregister(&dc->client); 1993 err = host1x_client_unregister(&dc->client);
1979 if (err < 0) { 1994 if (err < 0) {
1980 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", 1995 dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index 705c93b00794..55792daabbb5 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -12,6 +12,8 @@
12 12
13#define DC_CMD_GENERAL_INCR_SYNCPT 0x000 13#define DC_CMD_GENERAL_INCR_SYNCPT 0x000
14#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001 14#define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001
15#define SYNCPT_CNTRL_NO_STALL (1 << 8)
16#define SYNCPT_CNTRL_SOFT_RESET (1 << 0)
15#define DC_CMD_GENERAL_INCR_SYNCPT_ERROR 0x002 17#define DC_CMD_GENERAL_INCR_SYNCPT_ERROR 0x002
16#define DC_CMD_WIN_A_INCR_SYNCPT 0x008 18#define DC_CMD_WIN_A_INCR_SYNCPT 0x008
17#define DC_CMD_WIN_A_INCR_SYNCPT_CNTRL 0x009 19#define DC_CMD_WIN_A_INCR_SYNCPT_CNTRL 0x009
@@ -23,6 +25,7 @@
23#define DC_CMD_WIN_C_INCR_SYNCPT_CNTRL 0x019 25#define DC_CMD_WIN_C_INCR_SYNCPT_CNTRL 0x019
24#define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a 26#define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a
25#define DC_CMD_CONT_SYNCPT_VSYNC 0x028 27#define DC_CMD_CONT_SYNCPT_VSYNC 0x028
28#define SYNCPT_VSYNC_ENABLE (1 << 8)
26#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 29#define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031
27#define DC_CMD_DISPLAY_COMMAND 0x032 30#define DC_CMD_DISPLAY_COMMAND 0x032
28#define DISP_CTRL_MODE_STOP (0 << 5) 31#define DISP_CTRL_MODE_STOP (0 << 5)
@@ -438,8 +441,4 @@
438#define DC_WINBUF_BD_UFLOW_STATUS 0xdca 441#define DC_WINBUF_BD_UFLOW_STATUS 0xdca
439#define DC_WINBUF_CD_UFLOW_STATUS 0xfca 442#define DC_WINBUF_CD_UFLOW_STATUS 0xfca
440 443
441/* synchronization points */
442#define SYNCPT_VBLANK0 26
443#define SYNCPT_VBLANK1 27
444
445#endif /* TEGRA_DC_H */ 444#endif /* TEGRA_DC_H */
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index 5f1880766110..1833abd7d3aa 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -172,6 +172,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
172 */ 172 */
173 drm->irq_enabled = true; 173 drm->irq_enabled = true;
174 174
175 /* syncpoints are used for full 32-bit hardware VBLANK counters */
176 drm->vblank_disable_immediate = true;
177 drm->max_vblank_count = 0xffffffff;
178
175 err = drm_vblank_init(drm, drm->mode_config.num_crtc); 179 err = drm_vblank_init(drm, drm->mode_config.num_crtc);
176 if (err < 0) 180 if (err < 0)
177 goto device; 181 goto device;
@@ -813,12 +817,12 @@ static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm,
813static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) 817static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe)
814{ 818{
815 struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); 819 struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
820 struct tegra_dc *dc = to_tegra_dc(crtc);
816 821
817 if (!crtc) 822 if (!crtc)
818 return 0; 823 return 0;
819 824
820 /* TODO: implement real hardware counter using syncpoints */ 825 return tegra_dc_get_vblank_counter(dc);
821 return drm_crtc_vblank_count(crtc);
822} 826}
823 827
824static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) 828static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)
@@ -879,8 +883,18 @@ static int tegra_debugfs_framebuffers(struct seq_file *s, void *data)
879 return 0; 883 return 0;
880} 884}
881 885
886static int tegra_debugfs_iova(struct seq_file *s, void *data)
887{
888 struct drm_info_node *node = (struct drm_info_node *)s->private;
889 struct drm_device *drm = node->minor->dev;
890 struct tegra_drm *tegra = drm->dev_private;
891
892 return drm_mm_dump_table(s, &tegra->mm);
893}
894
882static struct drm_info_list tegra_debugfs_list[] = { 895static struct drm_info_list tegra_debugfs_list[] = {
883 { "framebuffers", tegra_debugfs_framebuffers, 0 }, 896 { "framebuffers", tegra_debugfs_framebuffers, 0 },
897 { "iova", tegra_debugfs_iova, 0 },
884}; 898};
885 899
886static int tegra_debugfs_init(struct drm_minor *minor) 900static int tegra_debugfs_init(struct drm_minor *minor)
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/drm/tegra/drm.h
index 8cb2dfeaa957..659b2fcc986d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/drm/tegra/drm.h
@@ -106,6 +106,7 @@ struct tegra_output;
106 106
107struct tegra_dc { 107struct tegra_dc {
108 struct host1x_client client; 108 struct host1x_client client;
109 struct host1x_syncpt *syncpt;
109 struct device *dev; 110 struct device *dev;
110 spinlock_t lock; 111 spinlock_t lock;
111 112
@@ -180,12 +181,11 @@ struct tegra_dc_window {
180}; 181};
181 182
182/* from dc.c */ 183/* from dc.c */
184u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc);
183void tegra_dc_enable_vblank(struct tegra_dc *dc); 185void tegra_dc_enable_vblank(struct tegra_dc *dc);
184void tegra_dc_disable_vblank(struct tegra_dc *dc); 186void tegra_dc_disable_vblank(struct tegra_dc *dc);
185void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); 187void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
186void tegra_dc_commit(struct tegra_dc *dc); 188void tegra_dc_commit(struct tegra_dc *dc);
187int tegra_dc_setup_clock(struct tegra_dc *dc, struct clk *parent,
188 unsigned long pclk, unsigned int div);
189int tegra_dc_state_setup_clock(struct tegra_dc *dc, 189int tegra_dc_state_setup_clock(struct tegra_dc *dc,
190 struct drm_crtc_state *crtc_state, 190 struct drm_crtc_state *crtc_state,
191 struct clk *clk, unsigned long pclk, 191 struct clk *clk, unsigned long pclk,
diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c
index 7eaaee74a039..06ab1783bba1 100644
--- a/drivers/gpu/drm/tegra/hdmi.c
+++ b/drivers/gpu/drm/tegra/hdmi.c
@@ -952,7 +952,7 @@ static void tegra_hdmi_encoder_mode_set(struct drm_encoder *encoder,
952 } 952 }
953 953
954 tegra_hdmi_writel(hdmi, 954 tegra_hdmi_writel(hdmi,
955 SOR_SEQ_CTL_PU_PC(0) | 955 SOR_SEQ_PU_PC(0) |
956 SOR_SEQ_PU_PC_ALT(0) | 956 SOR_SEQ_PU_PC_ALT(0) |
957 SOR_SEQ_PD_PC(8) | 957 SOR_SEQ_PD_PC(8) |
958 SOR_SEQ_PD_PC_ALT(8), 958 SOR_SEQ_PD_PC_ALT(8),
@@ -1394,8 +1394,8 @@ static int tegra_hdmi_exit(struct host1x_client *client)
1394 1394
1395 tegra_output_exit(&hdmi->output); 1395 tegra_output_exit(&hdmi->output);
1396 1396
1397 clk_disable_unprepare(hdmi->clk);
1398 reset_control_assert(hdmi->rst); 1397 reset_control_assert(hdmi->rst);
1398 clk_disable_unprepare(hdmi->clk);
1399 1399
1400 regulator_disable(hdmi->vdd); 1400 regulator_disable(hdmi->vdd);
1401 regulator_disable(hdmi->pll); 1401 regulator_disable(hdmi->pll);
diff --git a/drivers/gpu/drm/tegra/hdmi.h b/drivers/gpu/drm/tegra/hdmi.h
index 919a19df4e1b..a882514389cd 100644
--- a/drivers/gpu/drm/tegra/hdmi.h
+++ b/drivers/gpu/drm/tegra/hdmi.h
@@ -201,7 +201,7 @@
201#define HDMI_NV_PDISP_SOR_CRCB 0x5d 201#define HDMI_NV_PDISP_SOR_CRCB 0x5d
202#define HDMI_NV_PDISP_SOR_BLANK 0x5e 202#define HDMI_NV_PDISP_SOR_BLANK 0x5e
203#define HDMI_NV_PDISP_SOR_SEQ_CTL 0x5f 203#define HDMI_NV_PDISP_SOR_SEQ_CTL 0x5f
204#define SOR_SEQ_CTL_PU_PC(x) (((x) & 0xf) << 0) 204#define SOR_SEQ_PU_PC(x) (((x) & 0xf) << 0)
205#define SOR_SEQ_PU_PC_ALT(x) (((x) & 0xf) << 4) 205#define SOR_SEQ_PU_PC_ALT(x) (((x) & 0xf) << 4)
206#define SOR_SEQ_PD_PC(x) (((x) & 0xf) << 8) 206#define SOR_SEQ_PD_PC(x) (((x) & 0xf) << 8)
207#define SOR_SEQ_PD_PC_ALT(x) (((x) & 0xf) << 12) 207#define SOR_SEQ_PD_PC_ALT(x) (((x) & 0xf) << 12)
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 2afe478ded3b..7591d8901f9a 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -41,6 +41,8 @@ struct tegra_sor {
41 struct mutex lock; 41 struct mutex lock;
42 bool enabled; 42 bool enabled;
43 43
44 struct drm_info_list *debugfs_files;
45 struct drm_minor *minor;
44 struct dentry *debugfs; 46 struct dentry *debugfs;
45}; 47};
46 48
@@ -68,13 +70,12 @@ static inline struct tegra_sor *to_sor(struct tegra_output *output)
68 return container_of(output, struct tegra_sor, output); 70 return container_of(output, struct tegra_sor, output);
69} 71}
70 72
71static inline unsigned long tegra_sor_readl(struct tegra_sor *sor, 73static inline u32 tegra_sor_readl(struct tegra_sor *sor, unsigned long offset)
72 unsigned long offset)
73{ 74{
74 return readl(sor->regs + (offset << 2)); 75 return readl(sor->regs + (offset << 2));
75} 76}
76 77
77static inline void tegra_sor_writel(struct tegra_sor *sor, unsigned long value, 78static inline void tegra_sor_writel(struct tegra_sor *sor, u32 value,
78 unsigned long offset) 79 unsigned long offset)
79{ 80{
80 writel(value, sor->regs + (offset << 2)); 81 writel(value, sor->regs + (offset << 2));
@@ -83,9 +84,9 @@ static inline void tegra_sor_writel(struct tegra_sor *sor, unsigned long value,
83static int tegra_sor_dp_train_fast(struct tegra_sor *sor, 84static int tegra_sor_dp_train_fast(struct tegra_sor *sor,
84 struct drm_dp_link *link) 85 struct drm_dp_link *link)
85{ 86{
86 unsigned long value;
87 unsigned int i; 87 unsigned int i;
88 u8 pattern; 88 u8 pattern;
89 u32 value;
89 int err; 90 int err;
90 91
91 /* setup lane parameters */ 92 /* setup lane parameters */
@@ -202,7 +203,7 @@ static void tegra_sor_update(struct tegra_sor *sor)
202 203
203static int tegra_sor_setup_pwm(struct tegra_sor *sor, unsigned long timeout) 204static int tegra_sor_setup_pwm(struct tegra_sor *sor, unsigned long timeout)
204{ 205{
205 unsigned long value; 206 u32 value;
206 207
207 value = tegra_sor_readl(sor, SOR_PWM_DIV); 208 value = tegra_sor_readl(sor, SOR_PWM_DIV);
208 value &= ~SOR_PWM_DIV_MASK; 209 value &= ~SOR_PWM_DIV_MASK;
@@ -281,7 +282,7 @@ static int tegra_sor_wakeup(struct tegra_sor *sor)
281 282
282static int tegra_sor_power_up(struct tegra_sor *sor, unsigned long timeout) 283static int tegra_sor_power_up(struct tegra_sor *sor, unsigned long timeout)
283{ 284{
284 unsigned long value; 285 u32 value;
285 286
286 value = tegra_sor_readl(sor, SOR_PWR); 287 value = tegra_sor_readl(sor, SOR_PWR);
287 value |= SOR_PWR_TRIGGER | SOR_PWR_NORMAL_STATE_PU; 288 value |= SOR_PWR_TRIGGER | SOR_PWR_NORMAL_STATE_PU;
@@ -674,38 +675,195 @@ static const struct file_operations tegra_sor_crc_fops = {
674 .release = tegra_sor_crc_release, 675 .release = tegra_sor_crc_release,
675}; 676};
676 677
678static int tegra_sor_show_regs(struct seq_file *s, void *data)
679{
680 struct drm_info_node *node = s->private;
681 struct tegra_sor *sor = node->info_ent->data;
682
683#define DUMP_REG(name) \
684 seq_printf(s, "%-38s %#05x %08x\n", #name, name, \
685 tegra_sor_readl(sor, name))
686
687 DUMP_REG(SOR_CTXSW);
688 DUMP_REG(SOR_SUPER_STATE_0);
689 DUMP_REG(SOR_SUPER_STATE_1);
690 DUMP_REG(SOR_STATE_0);
691 DUMP_REG(SOR_STATE_1);
692 DUMP_REG(SOR_HEAD_STATE_0(0));
693 DUMP_REG(SOR_HEAD_STATE_0(1));
694 DUMP_REG(SOR_HEAD_STATE_1(0));
695 DUMP_REG(SOR_HEAD_STATE_1(1));
696 DUMP_REG(SOR_HEAD_STATE_2(0));
697 DUMP_REG(SOR_HEAD_STATE_2(1));
698 DUMP_REG(SOR_HEAD_STATE_3(0));
699 DUMP_REG(SOR_HEAD_STATE_3(1));
700 DUMP_REG(SOR_HEAD_STATE_4(0));
701 DUMP_REG(SOR_HEAD_STATE_4(1));
702 DUMP_REG(SOR_HEAD_STATE_5(0));
703 DUMP_REG(SOR_HEAD_STATE_5(1));
704 DUMP_REG(SOR_CRC_CNTRL);
705 DUMP_REG(SOR_DP_DEBUG_MVID);
706 DUMP_REG(SOR_CLK_CNTRL);
707 DUMP_REG(SOR_CAP);
708 DUMP_REG(SOR_PWR);
709 DUMP_REG(SOR_TEST);
710 DUMP_REG(SOR_PLL_0);
711 DUMP_REG(SOR_PLL_1);
712 DUMP_REG(SOR_PLL_2);
713 DUMP_REG(SOR_PLL_3);
714 DUMP_REG(SOR_CSTM);
715 DUMP_REG(SOR_LVDS);
716 DUMP_REG(SOR_CRC_A);
717 DUMP_REG(SOR_CRC_B);
718 DUMP_REG(SOR_BLANK);
719 DUMP_REG(SOR_SEQ_CTL);
720 DUMP_REG(SOR_LANE_SEQ_CTL);
721 DUMP_REG(SOR_SEQ_INST(0));
722 DUMP_REG(SOR_SEQ_INST(1));
723 DUMP_REG(SOR_SEQ_INST(2));
724 DUMP_REG(SOR_SEQ_INST(3));
725 DUMP_REG(SOR_SEQ_INST(4));
726 DUMP_REG(SOR_SEQ_INST(5));
727 DUMP_REG(SOR_SEQ_INST(6));
728 DUMP_REG(SOR_SEQ_INST(7));
729 DUMP_REG(SOR_SEQ_INST(8));
730 DUMP_REG(SOR_SEQ_INST(9));
731 DUMP_REG(SOR_SEQ_INST(10));
732 DUMP_REG(SOR_SEQ_INST(11));
733 DUMP_REG(SOR_SEQ_INST(12));
734 DUMP_REG(SOR_SEQ_INST(13));
735 DUMP_REG(SOR_SEQ_INST(14));
736 DUMP_REG(SOR_SEQ_INST(15));
737 DUMP_REG(SOR_PWM_DIV);
738 DUMP_REG(SOR_PWM_CTL);
739 DUMP_REG(SOR_VCRC_A_0);
740 DUMP_REG(SOR_VCRC_A_1);
741 DUMP_REG(SOR_VCRC_B_0);
742 DUMP_REG(SOR_VCRC_B_1);
743 DUMP_REG(SOR_CCRC_A_0);
744 DUMP_REG(SOR_CCRC_A_1);
745 DUMP_REG(SOR_CCRC_B_0);
746 DUMP_REG(SOR_CCRC_B_1);
747 DUMP_REG(SOR_EDATA_A_0);
748 DUMP_REG(SOR_EDATA_A_1);
749 DUMP_REG(SOR_EDATA_B_0);
750 DUMP_REG(SOR_EDATA_B_1);
751 DUMP_REG(SOR_COUNT_A_0);
752 DUMP_REG(SOR_COUNT_A_1);
753 DUMP_REG(SOR_COUNT_B_0);
754 DUMP_REG(SOR_COUNT_B_1);
755 DUMP_REG(SOR_DEBUG_A_0);
756 DUMP_REG(SOR_DEBUG_A_1);
757 DUMP_REG(SOR_DEBUG_B_0);
758 DUMP_REG(SOR_DEBUG_B_1);
759 DUMP_REG(SOR_TRIG);
760 DUMP_REG(SOR_MSCHECK);
761 DUMP_REG(SOR_XBAR_CTRL);
762 DUMP_REG(SOR_XBAR_POL);
763 DUMP_REG(SOR_DP_LINKCTL_0);
764 DUMP_REG(SOR_DP_LINKCTL_1);
765 DUMP_REG(SOR_LANE_DRIVE_CURRENT_0);
766 DUMP_REG(SOR_LANE_DRIVE_CURRENT_1);
767 DUMP_REG(SOR_LANE4_DRIVE_CURRENT_0);
768 DUMP_REG(SOR_LANE4_DRIVE_CURRENT_1);
769 DUMP_REG(SOR_LANE_PREEMPHASIS_0);
770 DUMP_REG(SOR_LANE_PREEMPHASIS_1);
771 DUMP_REG(SOR_LANE4_PREEMPHASIS_0);
772 DUMP_REG(SOR_LANE4_PREEMPHASIS_1);
773 DUMP_REG(SOR_LANE_POST_CURSOR_0);
774 DUMP_REG(SOR_LANE_POST_CURSOR_1);
775 DUMP_REG(SOR_DP_CONFIG_0);
776 DUMP_REG(SOR_DP_CONFIG_1);
777 DUMP_REG(SOR_DP_MN_0);
778 DUMP_REG(SOR_DP_MN_1);
779 DUMP_REG(SOR_DP_PADCTL_0);
780 DUMP_REG(SOR_DP_PADCTL_1);
781 DUMP_REG(SOR_DP_DEBUG_0);
782 DUMP_REG(SOR_DP_DEBUG_1);
783 DUMP_REG(SOR_DP_SPARE_0);
784 DUMP_REG(SOR_DP_SPARE_1);
785 DUMP_REG(SOR_DP_AUDIO_CTRL);
786 DUMP_REG(SOR_DP_AUDIO_HBLANK_SYMBOLS);
787 DUMP_REG(SOR_DP_AUDIO_VBLANK_SYMBOLS);
788 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_HEADER);
789 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK_0);
790 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK_1);
791 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK_2);
792 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK_3);
793 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK_4);
794 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK_5);
795 DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK_6);
796 DUMP_REG(SOR_DP_TPG);
797 DUMP_REG(SOR_DP_TPG_CONFIG);
798 DUMP_REG(SOR_DP_LQ_CSTM_0);
799 DUMP_REG(SOR_DP_LQ_CSTM_1);
800 DUMP_REG(SOR_DP_LQ_CSTM_2);
801
802#undef DUMP_REG
803
804 return 0;
805}
806
807static const struct drm_info_list debugfs_files[] = {
808 { "regs", tegra_sor_show_regs, 0, NULL },
809};
810
677static int tegra_sor_debugfs_init(struct tegra_sor *sor, 811static int tegra_sor_debugfs_init(struct tegra_sor *sor,
678 struct drm_minor *minor) 812 struct drm_minor *minor)
679{ 813{
680 struct dentry *entry; 814 struct dentry *entry;
815 unsigned int i;
681 int err = 0; 816 int err = 0;
682 817
683 sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root); 818 sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root);
684 if (!sor->debugfs) 819 if (!sor->debugfs)
685 return -ENOMEM; 820 return -ENOMEM;
686 821
822 sor->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
823 GFP_KERNEL);
824 if (!sor->debugfs_files) {
825 err = -ENOMEM;
826 goto remove;
827 }
828
829 for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
830 sor->debugfs_files[i].data = sor;
831
832 err = drm_debugfs_create_files(sor->debugfs_files,
833 ARRAY_SIZE(debugfs_files),
834 sor->debugfs, minor);
835 if (err < 0)
836 goto free;
837
687 entry = debugfs_create_file("crc", 0644, sor->debugfs, sor, 838 entry = debugfs_create_file("crc", 0644, sor->debugfs, sor,
688 &tegra_sor_crc_fops); 839 &tegra_sor_crc_fops);
689 if (!entry) { 840 if (!entry) {
690 dev_err(sor->dev,
691 "cannot create /sys/kernel/debug/dri/%s/sor/crc\n",
692 minor->debugfs_root->d_name.name);
693 err = -ENOMEM; 841 err = -ENOMEM;
694 goto remove; 842 goto free;
695 } 843 }
696 844
697 return err; 845 return err;
698 846
847free:
848 kfree(sor->debugfs_files);
849 sor->debugfs_files = NULL;
699remove: 850remove:
700 debugfs_remove(sor->debugfs); 851 debugfs_remove_recursive(sor->debugfs);
701 sor->debugfs = NULL; 852 sor->debugfs = NULL;
702 return err; 853 return err;
703} 854}
704 855
705static void tegra_sor_debugfs_exit(struct tegra_sor *sor) 856static void tegra_sor_debugfs_exit(struct tegra_sor *sor)
706{ 857{
707 debugfs_remove_recursive(sor->debugfs); 858 drm_debugfs_remove_files(sor->debugfs_files, ARRAY_SIZE(debugfs_files),
859 sor->minor);
860 sor->minor = NULL;
861
862 kfree(sor->debugfs_files);
708 sor->debugfs = NULL; 863 sor->debugfs = NULL;
864
865 debugfs_remove_recursive(sor->debugfs);
866 sor->debugfs_files = NULL;
709} 867}
710 868
711static void tegra_sor_connector_dpms(struct drm_connector *connector, int mode) 869static void tegra_sor_connector_dpms(struct drm_connector *connector, int mode)
@@ -791,8 +949,8 @@ static void tegra_sor_encoder_mode_set(struct drm_encoder *encoder,
791 struct tegra_sor_config config; 949 struct tegra_sor_config config;
792 struct drm_dp_link link; 950 struct drm_dp_link link;
793 struct drm_dp_aux *aux; 951 struct drm_dp_aux *aux;
794 unsigned long value;
795 int err = 0; 952 int err = 0;
953 u32 value;
796 954
797 mutex_lock(&sor->lock); 955 mutex_lock(&sor->lock);
798 956
@@ -1354,12 +1512,30 @@ static int tegra_sor_init(struct host1x_client *client)
1354 } 1512 }
1355 } 1513 }
1356 1514
1515 /*
1516 * XXX: Remove this reset once proper hand-over from firmware to
1517 * kernel is possible.
1518 */
1519 err = reset_control_assert(sor->rst);
1520 if (err < 0) {
1521 dev_err(sor->dev, "failed to assert SOR reset: %d\n", err);
1522 return err;
1523 }
1524
1357 err = clk_prepare_enable(sor->clk); 1525 err = clk_prepare_enable(sor->clk);
1358 if (err < 0) { 1526 if (err < 0) {
1359 dev_err(sor->dev, "failed to enable clock: %d\n", err); 1527 dev_err(sor->dev, "failed to enable clock: %d\n", err);
1360 return err; 1528 return err;
1361 } 1529 }
1362 1530
1531 usleep_range(1000, 3000);
1532
1533 err = reset_control_deassert(sor->rst);
1534 if (err < 0) {
1535 dev_err(sor->dev, "failed to deassert SOR reset: %d\n", err);
1536 return err;
1537 }
1538
1363 err = clk_prepare_enable(sor->clk_safe); 1539 err = clk_prepare_enable(sor->clk_safe);
1364 if (err < 0) 1540 if (err < 0)
1365 return err; 1541 return err;
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index b10550ee1d89..6b7fdc1e2ed0 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -425,6 +425,12 @@ u32 host1x_syncpt_read_min(struct host1x_syncpt *sp)
425} 425}
426EXPORT_SYMBOL(host1x_syncpt_read_min); 426EXPORT_SYMBOL(host1x_syncpt_read_min);
427 427
428u32 host1x_syncpt_read(struct host1x_syncpt *sp)
429{
430 return host1x_syncpt_load(sp);
431}
432EXPORT_SYMBOL(host1x_syncpt_read);
433
428int host1x_syncpt_nb_pts(struct host1x *host) 434int host1x_syncpt_nb_pts(struct host1x *host)
429{ 435{
430 return host->info->nb_pts; 436 return host->info->nb_pts;
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index 829280b56874..d665781eb542 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -87,20 +87,34 @@ void drm_atomic_helper_connector_dpms(struct drm_connector *connector,
87 87
88/* default implementations for state handling */ 88/* default implementations for state handling */
89void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc); 89void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
90void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
91 struct drm_crtc_state *state);
90struct drm_crtc_state * 92struct drm_crtc_state *
91drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc); 93drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc);
94void __drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
95 struct drm_crtc_state *state);
92void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc, 96void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
93 struct drm_crtc_state *state); 97 struct drm_crtc_state *state);
94 98
95void drm_atomic_helper_plane_reset(struct drm_plane *plane); 99void drm_atomic_helper_plane_reset(struct drm_plane *plane);
100void __drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane,
101 struct drm_plane_state *state);
96struct drm_plane_state * 102struct drm_plane_state *
97drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane); 103drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane);
104void __drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
105 struct drm_plane_state *state);
98void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane, 106void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
99 struct drm_plane_state *state); 107 struct drm_plane_state *state);
100 108
101void drm_atomic_helper_connector_reset(struct drm_connector *connector); 109void drm_atomic_helper_connector_reset(struct drm_connector *connector);
110void
111__drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector,
112 struct drm_connector_state *state);
102struct drm_connector_state * 113struct drm_connector_state *
103drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector); 114drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector);
115void
116__drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
117 struct drm_connector_state *state);
104void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, 118void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
105 struct drm_connector_state *state); 119 struct drm_connector_state *state);
106 120
diff --git a/include/linux/host1x.h b/include/linux/host1x.h
index 464f33814a94..d2ba7d334039 100644
--- a/include/linux/host1x.h
+++ b/include/linux/host1x.h
@@ -135,6 +135,7 @@ struct host1x_syncpt *host1x_syncpt_get(struct host1x *host, u32 id);
135u32 host1x_syncpt_id(struct host1x_syncpt *sp); 135u32 host1x_syncpt_id(struct host1x_syncpt *sp);
136u32 host1x_syncpt_read_min(struct host1x_syncpt *sp); 136u32 host1x_syncpt_read_min(struct host1x_syncpt *sp);
137u32 host1x_syncpt_read_max(struct host1x_syncpt *sp); 137u32 host1x_syncpt_read_max(struct host1x_syncpt *sp);
138u32 host1x_syncpt_read(struct host1x_syncpt *sp);
138int host1x_syncpt_incr(struct host1x_syncpt *sp); 139int host1x_syncpt_incr(struct host1x_syncpt *sp);
139u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs); 140u32 host1x_syncpt_incr_max(struct host1x_syncpt *sp, u32 incrs);
140int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout, 141int host1x_syncpt_wait(struct host1x_syncpt *sp, u32 thresh, long timeout,
diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h
index c15d781ecc0f..5391780c2b05 100644
--- a/include/uapi/drm/tegra_drm.h
+++ b/include/uapi/drm/tegra_drm.h
@@ -36,7 +36,8 @@ struct drm_tegra_gem_create {
36 36
37struct drm_tegra_gem_mmap { 37struct drm_tegra_gem_mmap {
38 __u32 handle; 38 __u32 handle;
39 __u32 offset; 39 __u32 pad;
40 __u64 offset;
40}; 41};
41 42
42struct drm_tegra_syncpt_read { 43struct drm_tegra_syncpt_read {