aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2014-12-22 17:24:26 -0500
committerDave Airlie <airlied@redhat.com>2014-12-22 17:24:26 -0500
commitfc556fb64e3a4cdc6b764079a98e3cfb85d89c1f (patch)
tree4ee704df2b9952943f4f4fc4db3704549fbe97b1 /drivers
parenta548a838a1f770a55ec3e750f36ba281d7f4ab2e (diff)
parent93396d0f9c027654eb09151d2e22fe78a39feedb (diff)
Merge tag 'drm/tegra/for-3.19-rc1-fixes' of git://people.freedesktop.org/~tagr/linux into drm-fixes
drm/tegra: Fixes for v3.19-rc1 This is a set of fixes for two regressions and one bug in the IOMMU mapping code. It turns out that all of these issues turn up primarily on Tegra30 hardware. The IOMMU mapping bug only manifests on buffers that aren't multiples of the page size. I happened to be testing HDMI with 1080p while writing the code and framebuffers for that happen to fit exactly within 2025 pages of 4 KiB each. One of the regressions is caused by the IOMMU code allocating pages from shmem which can have associated cache lines. If the pages aren't flushed then these cache lines may be flushed later on and cause framebuffer corruption. I'm not sure why I didn't see this before. Perhaps the board that I was using had enough RAM so that the pages shmem would hand out had a better chance of being unused. Or maybe I didn't look too closely. The fix for this is to fake up an SG table so that it can be passed to the DMA API. Ideally this would use drm_clflush_*(), but implementing that for ARM causes DRM to fail to build as a module since some of the low-level cache maintenance functions aren't exported. Hopefully we can get a suitable API exported on ARM for the next release. The second regression is caused by a mismatch between the hardware pipe number and the CRTC's DRM index. These were used inconsistently, which could cause one code location to call drm_vblank_get() with a different pipe than the corresponding drm_vblank_put(), thereby causing the reference count to become unbalanced. Alexandre also reported a possible race condition related to this, which this series also fixes. * tag 'drm/tegra/for-3.19-rc1-fixes' of git://people.freedesktop.org/~tagr/linux: drm/tegra: dc: Select root window for event dispatch drm/tegra: gem: Use the proper size for GEM objects drm/tegra: gem: Flush buffer objects upon allocation drm/tegra: dc: Fix a potential race on page-flip completion drm/tegra: dc: Consistently use the same pipe drm/irq: Add drm_crtc_vblank_count() drm/irq: Add drm_crtc_handle_vblank() drm/irq: Add drm_crtc_send_vblank_event()
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_irq.c60
-rw-r--r--drivers/gpu/drm/tegra/dc.c48
-rw-r--r--drivers/gpu/drm/tegra/drm.c16
-rw-r--r--drivers/gpu/drm/tegra/gem.c52
4 files changed, 146 insertions, 30 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index f5a5f18efa5b..4d79dad9d44f 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -830,6 +830,8 @@ drm_get_last_vbltimestamp(struct drm_device *dev, int crtc,
830 * vblank events since the system was booted, including lost events due to 830 * vblank events since the system was booted, including lost events due to
831 * modesetting activity. 831 * modesetting activity.
832 * 832 *
833 * This is the legacy version of drm_crtc_vblank_count().
834 *
833 * Returns: 835 * Returns:
834 * The software vblank counter. 836 * The software vblank counter.
835 */ 837 */
@@ -844,6 +846,25 @@ u32 drm_vblank_count(struct drm_device *dev, int crtc)
844EXPORT_SYMBOL(drm_vblank_count); 846EXPORT_SYMBOL(drm_vblank_count);
845 847
846/** 848/**
849 * drm_crtc_vblank_count - retrieve "cooked" vblank counter value
850 * @crtc: which counter to retrieve
851 *
852 * Fetches the "cooked" vblank count value that represents the number of
853 * vblank events since the system was booted, including lost events due to
854 * modesetting activity.
855 *
856 * This is the native KMS version of drm_vblank_count().
857 *
858 * Returns:
859 * The software vblank counter.
860 */
861u32 drm_crtc_vblank_count(struct drm_crtc *crtc)
862{
863 return drm_vblank_count(crtc->dev, drm_crtc_index(crtc));
864}
865EXPORT_SYMBOL(drm_crtc_vblank_count);
866
867/**
847 * drm_vblank_count_and_time - retrieve "cooked" vblank counter value 868 * drm_vblank_count_and_time - retrieve "cooked" vblank counter value
848 * and the system timestamp corresponding to that vblank counter value. 869 * and the system timestamp corresponding to that vblank counter value.
849 * 870 *
@@ -904,6 +925,8 @@ static void send_vblank_event(struct drm_device *dev,
904 * 925 *
905 * Updates sequence # and timestamp on event, and sends it to userspace. 926 * Updates sequence # and timestamp on event, and sends it to userspace.
906 * Caller must hold event lock. 927 * Caller must hold event lock.
928 *
929 * This is the legacy version of drm_crtc_send_vblank_event().
907 */ 930 */
908void drm_send_vblank_event(struct drm_device *dev, int crtc, 931void drm_send_vblank_event(struct drm_device *dev, int crtc,
909 struct drm_pending_vblank_event *e) 932 struct drm_pending_vblank_event *e)
@@ -923,6 +946,23 @@ void drm_send_vblank_event(struct drm_device *dev, int crtc,
923EXPORT_SYMBOL(drm_send_vblank_event); 946EXPORT_SYMBOL(drm_send_vblank_event);
924 947
925/** 948/**
949 * drm_crtc_send_vblank_event - helper to send vblank event after pageflip
950 * @crtc: the source CRTC of the vblank event
951 * @e: the event to send
952 *
953 * Updates sequence # and timestamp on event, and sends it to userspace.
954 * Caller must hold event lock.
955 *
956 * This is the native KMS version of drm_send_vblank_event().
957 */
958void drm_crtc_send_vblank_event(struct drm_crtc *crtc,
959 struct drm_pending_vblank_event *e)
960{
961 drm_send_vblank_event(crtc->dev, drm_crtc_index(crtc), e);
962}
963EXPORT_SYMBOL(drm_crtc_send_vblank_event);
964
965/**
926 * drm_vblank_enable - enable the vblank interrupt on a CRTC 966 * drm_vblank_enable - enable the vblank interrupt on a CRTC
927 * @dev: DRM device 967 * @dev: DRM device
928 * @crtc: CRTC in question 968 * @crtc: CRTC in question
@@ -1594,6 +1634,8 @@ static void drm_handle_vblank_events(struct drm_device *dev, int crtc)
1594 * 1634 *
1595 * Drivers should call this routine in their vblank interrupt handlers to 1635 * Drivers should call this routine in their vblank interrupt handlers to
1596 * update the vblank counter and send any signals that may be pending. 1636 * update the vblank counter and send any signals that may be pending.
1637 *
1638 * This is the legacy version of drm_crtc_handle_vblank().
1597 */ 1639 */
1598bool drm_handle_vblank(struct drm_device *dev, int crtc) 1640bool drm_handle_vblank(struct drm_device *dev, int crtc)
1599{ 1641{
@@ -1670,3 +1712,21 @@ bool drm_handle_vblank(struct drm_device *dev, int crtc)
1670 return true; 1712 return true;
1671} 1713}
1672EXPORT_SYMBOL(drm_handle_vblank); 1714EXPORT_SYMBOL(drm_handle_vblank);
1715
1716/**
1717 * drm_crtc_handle_vblank - handle a vblank event
1718 * @crtc: where this event occurred
1719 *
1720 * Drivers should call this routine in their vblank interrupt handlers to
1721 * update the vblank counter and send any signals that may be pending.
1722 *
1723 * This is the native KMS version of drm_handle_vblank().
1724 *
1725 * Returns:
1726 * True if the event was successfully handled, false on failure.
1727 */
1728bool drm_crtc_handle_vblank(struct drm_crtc *crtc)
1729{
1730 return drm_handle_vblank(crtc->dev, drm_crtc_index(crtc));
1731}
1732EXPORT_SYMBOL(drm_crtc_handle_vblank);
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 3367960286a6..978993fa3a36 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -168,7 +168,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
168 const struct tegra_dc_window *window) 168 const struct tegra_dc_window *window)
169{ 169{
170 unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp; 170 unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
171 unsigned long value; 171 unsigned long value, flags;
172 bool yuv, planar; 172 bool yuv, planar;
173 173
174 /* 174 /*
@@ -181,6 +181,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
181 else 181 else
182 bpp = planar ? 1 : 2; 182 bpp = planar ? 1 : 2;
183 183
184 spin_lock_irqsave(&dc->lock, flags);
185
184 value = WINDOW_A_SELECT << index; 186 value = WINDOW_A_SELECT << index;
185 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); 187 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
186 188
@@ -273,6 +275,7 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
273 275
274 case TEGRA_BO_TILING_MODE_BLOCK: 276 case TEGRA_BO_TILING_MODE_BLOCK:
275 DRM_ERROR("hardware doesn't support block linear mode\n"); 277 DRM_ERROR("hardware doesn't support block linear mode\n");
278 spin_unlock_irqrestore(&dc->lock, flags);
276 return -EINVAL; 279 return -EINVAL;
277 } 280 }
278 281
@@ -331,6 +334,8 @@ static int tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
331 334
332 tegra_dc_window_commit(dc, index); 335 tegra_dc_window_commit(dc, index);
333 336
337 spin_unlock_irqrestore(&dc->lock, flags);
338
334 return 0; 339 return 0;
335} 340}
336 341
@@ -338,11 +343,14 @@ static int tegra_window_plane_disable(struct drm_plane *plane)
338{ 343{
339 struct tegra_dc *dc = to_tegra_dc(plane->crtc); 344 struct tegra_dc *dc = to_tegra_dc(plane->crtc);
340 struct tegra_plane *p = to_tegra_plane(plane); 345 struct tegra_plane *p = to_tegra_plane(plane);
346 unsigned long flags;
341 u32 value; 347 u32 value;
342 348
343 if (!plane->crtc) 349 if (!plane->crtc)
344 return 0; 350 return 0;
345 351
352 spin_lock_irqsave(&dc->lock, flags);
353
346 value = WINDOW_A_SELECT << p->index; 354 value = WINDOW_A_SELECT << p->index;
347 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER); 355 tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
348 356
@@ -352,6 +360,8 @@ static int tegra_window_plane_disable(struct drm_plane *plane)
352 360
353 tegra_dc_window_commit(dc, p->index); 361 tegra_dc_window_commit(dc, p->index);
354 362
363 spin_unlock_irqrestore(&dc->lock, flags);
364
355 return 0; 365 return 0;
356} 366}
357 367
@@ -699,14 +709,16 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
699 struct tegra_bo *bo = tegra_fb_get_plane(fb, 0); 709 struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
700 unsigned int h_offset = 0, v_offset = 0; 710 unsigned int h_offset = 0, v_offset = 0;
701 struct tegra_bo_tiling tiling; 711 struct tegra_bo_tiling tiling;
712 unsigned long value, flags;
702 unsigned int format, swap; 713 unsigned int format, swap;
703 unsigned long value;
704 int err; 714 int err;
705 715
706 err = tegra_fb_get_tiling(fb, &tiling); 716 err = tegra_fb_get_tiling(fb, &tiling);
707 if (err < 0) 717 if (err < 0)
708 return err; 718 return err;
709 719
720 spin_lock_irqsave(&dc->lock, flags);
721
710 tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER); 722 tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
711 723
712 value = fb->offsets[0] + y * fb->pitches[0] + 724 value = fb->offsets[0] + y * fb->pitches[0] +
@@ -752,6 +764,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
752 764
753 case TEGRA_BO_TILING_MODE_BLOCK: 765 case TEGRA_BO_TILING_MODE_BLOCK:
754 DRM_ERROR("hardware doesn't support block linear mode\n"); 766 DRM_ERROR("hardware doesn't support block linear mode\n");
767 spin_unlock_irqrestore(&dc->lock, flags);
755 return -EINVAL; 768 return -EINVAL;
756 } 769 }
757 770
@@ -778,6 +791,8 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
778 tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL); 791 tegra_dc_writel(dc, value << 8, DC_CMD_STATE_CONTROL);
779 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL); 792 tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
780 793
794 spin_unlock_irqrestore(&dc->lock, flags);
795
781 return 0; 796 return 0;
782} 797}
783 798
@@ -814,23 +829,32 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
814 unsigned long flags, base; 829 unsigned long flags, base;
815 struct tegra_bo *bo; 830 struct tegra_bo *bo;
816 831
817 if (!dc->event) 832 spin_lock_irqsave(&drm->event_lock, flags);
833
834 if (!dc->event) {
835 spin_unlock_irqrestore(&drm->event_lock, flags);
818 return; 836 return;
837 }
819 838
820 bo = tegra_fb_get_plane(crtc->primary->fb, 0); 839 bo = tegra_fb_get_plane(crtc->primary->fb, 0);
821 840
841 spin_lock_irqsave(&dc->lock, flags);
842
822 /* check if new start address has been latched */ 843 /* check if new start address has been latched */
844 tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
823 tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS); 845 tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
824 base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR); 846 base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
825 tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS); 847 tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
826 848
849 spin_unlock_irqrestore(&dc->lock, flags);
850
827 if (base == bo->paddr + crtc->primary->fb->offsets[0]) { 851 if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
828 spin_lock_irqsave(&drm->event_lock, flags); 852 drm_crtc_send_vblank_event(crtc, dc->event);
829 drm_send_vblank_event(drm, dc->pipe, dc->event); 853 drm_crtc_vblank_put(crtc);
830 drm_vblank_put(drm, dc->pipe);
831 dc->event = NULL; 854 dc->event = NULL;
832 spin_unlock_irqrestore(&drm->event_lock, flags);
833 } 855 }
856
857 spin_unlock_irqrestore(&drm->event_lock, flags);
834} 858}
835 859
836void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) 860void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
@@ -843,7 +867,7 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
843 867
844 if (dc->event && dc->event->base.file_priv == file) { 868 if (dc->event && dc->event->base.file_priv == file) {
845 dc->event->base.destroy(&dc->event->base); 869 dc->event->base.destroy(&dc->event->base);
846 drm_vblank_put(drm, dc->pipe); 870 drm_crtc_vblank_put(crtc);
847 dc->event = NULL; 871 dc->event = NULL;
848 } 872 }
849 873
@@ -853,16 +877,16 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
853static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 877static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
854 struct drm_pending_vblank_event *event, uint32_t page_flip_flags) 878 struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
855{ 879{
880 unsigned int pipe = drm_crtc_index(crtc);
856 struct tegra_dc *dc = to_tegra_dc(crtc); 881 struct tegra_dc *dc = to_tegra_dc(crtc);
857 struct drm_device *drm = crtc->dev;
858 882
859 if (dc->event) 883 if (dc->event)
860 return -EBUSY; 884 return -EBUSY;
861 885
862 if (event) { 886 if (event) {
863 event->pipe = dc->pipe; 887 event->pipe = pipe;
864 dc->event = event; 888 dc->event = event;
865 drm_vblank_get(drm, dc->pipe); 889 drm_crtc_vblank_get(crtc);
866 } 890 }
867 891
868 tegra_dc_set_base(dc, 0, 0, fb); 892 tegra_dc_set_base(dc, 0, 0, fb);
@@ -1127,7 +1151,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
1127 /* 1151 /*
1128 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); 1152 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
1129 */ 1153 */
1130 drm_handle_vblank(dc->base.dev, dc->pipe); 1154 drm_crtc_handle_vblank(&dc->base);
1131 tegra_dc_finish_page_flip(dc); 1155 tegra_dc_finish_page_flip(dc);
1132 } 1156 }
1133 1157
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index e549afeece1f..d4f827593dfa 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -694,24 +694,28 @@ static const struct file_operations tegra_drm_fops = {
694 .llseek = noop_llseek, 694 .llseek = noop_llseek,
695}; 695};
696 696
697static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe) 697static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm,
698 unsigned int pipe)
698{ 699{
699 struct drm_crtc *crtc; 700 struct drm_crtc *crtc;
700 701
701 list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) { 702 list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) {
702 struct tegra_dc *dc = to_tegra_dc(crtc); 703 if (pipe == drm_crtc_index(crtc))
703
704 if (dc->pipe == pipe)
705 return crtc; 704 return crtc;
706 } 705 }
707 706
708 return NULL; 707 return NULL;
709} 708}
710 709
711static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc) 710static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe)
712{ 711{
712 struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
713
714 if (!crtc)
715 return 0;
716
713 /* TODO: implement real hardware counter using syncpoints */ 717 /* TODO: implement real hardware counter using syncpoints */
714 return drm_vblank_count(dev, crtc); 718 return drm_crtc_vblank_count(crtc);
715} 719}
716 720
717static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) 721static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)
diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c
index da32086cbeaf..8777b7f75791 100644
--- a/drivers/gpu/drm/tegra/gem.c
+++ b/drivers/gpu/drm/tegra/gem.c
@@ -216,32 +216,58 @@ static void tegra_bo_free(struct drm_device *drm, struct tegra_bo *bo)
216 } 216 }
217} 217}
218 218
219static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo, 219static int tegra_bo_get_pages(struct drm_device *drm, struct tegra_bo *bo)
220 size_t size)
221{ 220{
221 struct scatterlist *s;
222 struct sg_table *sgt;
223 unsigned int i;
224
222 bo->pages = drm_gem_get_pages(&bo->gem); 225 bo->pages = drm_gem_get_pages(&bo->gem);
223 if (IS_ERR(bo->pages)) 226 if (IS_ERR(bo->pages))
224 return PTR_ERR(bo->pages); 227 return PTR_ERR(bo->pages);
225 228
226 bo->num_pages = size >> PAGE_SHIFT; 229 bo->num_pages = bo->gem.size >> PAGE_SHIFT;
227 230
228 bo->sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages); 231 sgt = drm_prime_pages_to_sg(bo->pages, bo->num_pages);
229 if (IS_ERR(bo->sgt)) { 232 if (IS_ERR(sgt))
230 drm_gem_put_pages(&bo->gem, bo->pages, false, false); 233 goto put_pages;
231 return PTR_ERR(bo->sgt); 234
235 /*
236 * Fake up the SG table so that dma_map_sg() can be used to flush the
237 * pages associated with it. Note that this relies on the fact that
238 * the DMA API doesn't hook into IOMMU on Tegra, therefore mapping is
239 * only cache maintenance.
240 *
241 * TODO: Replace this by drm_clflash_sg() once it can be implemented
242 * without relying on symbols that are not exported.
243 */
244 for_each_sg(sgt->sgl, s, sgt->nents, i)
245 sg_dma_address(s) = sg_phys(s);
246
247 if (dma_map_sg(drm->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE) == 0) {
248 sgt = ERR_PTR(-ENOMEM);
249 goto release_sgt;
232 } 250 }
233 251
252 bo->sgt = sgt;
253
234 return 0; 254 return 0;
255
256release_sgt:
257 sg_free_table(sgt);
258 kfree(sgt);
259put_pages:
260 drm_gem_put_pages(&bo->gem, bo->pages, false, false);
261 return PTR_ERR(sgt);
235} 262}
236 263
237static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo, 264static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo)
238 size_t size)
239{ 265{
240 struct tegra_drm *tegra = drm->dev_private; 266 struct tegra_drm *tegra = drm->dev_private;
241 int err; 267 int err;
242 268
243 if (tegra->domain) { 269 if (tegra->domain) {
244 err = tegra_bo_get_pages(drm, bo, size); 270 err = tegra_bo_get_pages(drm, bo);
245 if (err < 0) 271 if (err < 0)
246 return err; 272 return err;
247 273
@@ -251,6 +277,8 @@ static int tegra_bo_alloc(struct drm_device *drm, struct tegra_bo *bo,
251 return err; 277 return err;
252 } 278 }
253 } else { 279 } else {
280 size_t size = bo->gem.size;
281
254 bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr, 282 bo->vaddr = dma_alloc_writecombine(drm->dev, size, &bo->paddr,
255 GFP_KERNEL | __GFP_NOWARN); 283 GFP_KERNEL | __GFP_NOWARN);
256 if (!bo->vaddr) { 284 if (!bo->vaddr) {
@@ -274,7 +302,7 @@ struct tegra_bo *tegra_bo_create(struct drm_device *drm, size_t size,
274 if (IS_ERR(bo)) 302 if (IS_ERR(bo))
275 return bo; 303 return bo;
276 304
277 err = tegra_bo_alloc(drm, bo, size); 305 err = tegra_bo_alloc(drm, bo);
278 if (err < 0) 306 if (err < 0)
279 goto release; 307 goto release;
280 308