diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-02-08 20:57:45 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-02-24 15:45:08 -0500 |
commit | 45c4e0aae96c6354bf5131a282a74fe38d032de3 (patch) | |
tree | 2e2aa98a865bbb364f22a16516c0b750d453d97c | |
parent | 292deb7a3b6b03df664b8f5024a351d3389543ae (diff) |
drm/nv50-nvc0: precalculate some fb state when creating them
Just a cleanup, to avoid duplicating parts of nv50_crtc.c's code in
the page flipping routines.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fb.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_crtc.c | 61 |
3 files changed, 61 insertions, 55 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 505c6bfb4d75..3a30d822dec1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "nouveau_hw.h" | 32 | #include "nouveau_hw.h" |
33 | #include "nouveau_crtc.h" | 33 | #include "nouveau_crtc.h" |
34 | #include "nouveau_dma.h" | 34 | #include "nouveau_dma.h" |
35 | #include "nv50_display.h" | ||
35 | 36 | ||
36 | static void | 37 | static void |
37 | nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) | 38 | nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) |
@@ -61,18 +62,59 @@ static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { | |||
61 | }; | 62 | }; |
62 | 63 | ||
63 | int | 64 | int |
64 | nouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb, | 65 | nouveau_framebuffer_init(struct drm_device *dev, |
65 | struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo) | 66 | struct nouveau_framebuffer *nv_fb, |
67 | struct drm_mode_fb_cmd *mode_cmd, | ||
68 | struct nouveau_bo *nvbo) | ||
66 | { | 69 | { |
70 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
71 | struct drm_framebuffer *fb = &nv_fb->base; | ||
67 | int ret; | 72 | int ret; |
68 | 73 | ||
69 | ret = drm_framebuffer_init(dev, &nouveau_fb->base, &nouveau_framebuffer_funcs); | 74 | ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); |
70 | if (ret) { | 75 | if (ret) { |
71 | return ret; | 76 | return ret; |
72 | } | 77 | } |
73 | 78 | ||
74 | drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd); | 79 | drm_helper_mode_fill_fb_struct(fb, mode_cmd); |
75 | nouveau_fb->nvbo = nvbo; | 80 | nv_fb->nvbo = nvbo; |
81 | |||
82 | if (dev_priv->card_type >= NV_50) { | ||
83 | u32 tile_flags = nouveau_bo_tile_layout(nvbo); | ||
84 | if (tile_flags == 0x7a00 || | ||
85 | tile_flags == 0xfe00) | ||
86 | nv_fb->r_dma = NvEvoFB32; | ||
87 | else | ||
88 | if (tile_flags == 0x7000) | ||
89 | nv_fb->r_dma = NvEvoFB16; | ||
90 | else | ||
91 | nv_fb->r_dma = NvEvoVRAM_LP; | ||
92 | |||
93 | switch (fb->depth) { | ||
94 | case 8: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_8; break; | ||
95 | case 15: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_15; break; | ||
96 | case 16: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_16; break; | ||
97 | case 24: | ||
98 | case 32: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_24; break; | ||
99 | case 30: nv_fb->r_format = NV50_EVO_CRTC_FB_DEPTH_30; break; | ||
100 | default: | ||
101 | NV_ERROR(dev, "unknown depth %d\n", fb->depth); | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | |||
105 | if (dev_priv->chipset == 0x50) | ||
106 | nv_fb->r_format |= (tile_flags << 8); | ||
107 | |||
108 | if (!tile_flags) | ||
109 | nv_fb->r_pitch = 0x00100000 | fb->pitch; | ||
110 | else { | ||
111 | u32 mode = nvbo->tile_mode; | ||
112 | if (dev_priv->card_type >= NV_C0) | ||
113 | mode >>= 4; | ||
114 | nv_fb->r_pitch = ((fb->pitch / 4) << 4) | mode; | ||
115 | } | ||
116 | } | ||
117 | |||
76 | return 0; | 118 | return 0; |
77 | } | 119 | } |
78 | 120 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_fb.h b/drivers/gpu/drm/nouveau/nouveau_fb.h index d432134b71e0..a3a88ad00f86 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fb.h +++ b/drivers/gpu/drm/nouveau/nouveau_fb.h | |||
@@ -30,6 +30,9 @@ | |||
30 | struct nouveau_framebuffer { | 30 | struct nouveau_framebuffer { |
31 | struct drm_framebuffer base; | 31 | struct drm_framebuffer base; |
32 | struct nouveau_bo *nvbo; | 32 | struct nouveau_bo *nvbo; |
33 | u32 r_dma; | ||
34 | u32 r_format; | ||
35 | u32 r_pitch; | ||
33 | }; | 36 | }; |
34 | 37 | ||
35 | static inline struct nouveau_framebuffer * | 38 | static inline struct nouveau_framebuffer * |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index a94aff57cc06..308af1db8381 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -522,7 +522,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
522 | struct nouveau_channel *evo = nv50_display(dev)->master; | 522 | struct nouveau_channel *evo = nv50_display(dev)->master; |
523 | struct drm_framebuffer *drm_fb = nv_crtc->base.fb; | 523 | struct drm_framebuffer *drm_fb = nv_crtc->base.fb; |
524 | struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); | 524 | struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); |
525 | int ret, format; | 525 | int ret; |
526 | 526 | ||
527 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); | 527 | NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); |
528 | 528 | ||
@@ -548,28 +548,6 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
548 | } | 548 | } |
549 | } | 549 | } |
550 | 550 | ||
551 | switch (drm_fb->depth) { | ||
552 | case 8: | ||
553 | format = NV50_EVO_CRTC_FB_DEPTH_8; | ||
554 | break; | ||
555 | case 15: | ||
556 | format = NV50_EVO_CRTC_FB_DEPTH_15; | ||
557 | break; | ||
558 | case 16: | ||
559 | format = NV50_EVO_CRTC_FB_DEPTH_16; | ||
560 | break; | ||
561 | case 24: | ||
562 | case 32: | ||
563 | format = NV50_EVO_CRTC_FB_DEPTH_24; | ||
564 | break; | ||
565 | case 30: | ||
566 | format = NV50_EVO_CRTC_FB_DEPTH_30; | ||
567 | break; | ||
568 | default: | ||
569 | NV_ERROR(dev, "unknown depth %d\n", drm_fb->depth); | ||
570 | return -EINVAL; | ||
571 | } | ||
572 | |||
573 | nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT; | 551 | nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT; |
574 | nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); | 552 | nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); |
575 | nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; | 553 | nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; |
@@ -579,14 +557,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
579 | return ret; | 557 | return ret; |
580 | 558 | ||
581 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); | 559 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); |
582 | if (nv_crtc->fb.tile_flags == 0x7a00 || | 560 | OUT_RING (evo, fb->r_dma); |
583 | nv_crtc->fb.tile_flags == 0xfe00) | ||
584 | OUT_RING(evo, NvEvoFB32); | ||
585 | else | ||
586 | if (nv_crtc->fb.tile_flags == 0x7000) | ||
587 | OUT_RING(evo, NvEvoFB16); | ||
588 | else | ||
589 | OUT_RING(evo, NvEvoVRAM_LP); | ||
590 | } | 561 | } |
591 | 562 | ||
592 | ret = RING_SPACE(evo, 12); | 563 | ret = RING_SPACE(evo, 12); |
@@ -594,30 +565,20 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
594 | return ret; | 565 | return ret; |
595 | 566 | ||
596 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5); | 567 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_OFFSET), 5); |
597 | OUT_RING(evo, nv_crtc->fb.offset >> 8); | 568 | OUT_RING (evo, nv_crtc->fb.offset >> 8); |
598 | OUT_RING(evo, 0); | 569 | OUT_RING (evo, 0); |
599 | OUT_RING(evo, (drm_fb->height << 16) | drm_fb->width); | 570 | OUT_RING (evo, (drm_fb->height << 16) | drm_fb->width); |
600 | if (!nv_crtc->fb.tile_flags) { | 571 | OUT_RING (evo, fb->r_pitch); |
601 | OUT_RING(evo, drm_fb->pitch | (1 << 20)); | 572 | OUT_RING (evo, fb->r_format); |
602 | } else { | ||
603 | u32 tile_mode = fb->nvbo->tile_mode; | ||
604 | if (dev_priv->card_type >= NV_C0) | ||
605 | tile_mode >>= 4; | ||
606 | OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode); | ||
607 | } | ||
608 | if (dev_priv->chipset == 0x50) | ||
609 | OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format); | ||
610 | else | ||
611 | OUT_RING(evo, format); | ||
612 | 573 | ||
613 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1); | 574 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, CLUT_MODE), 1); |
614 | OUT_RING(evo, fb->base.depth == 8 ? | 575 | OUT_RING (evo, fb->base.depth == 8 ? |
615 | NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); | 576 | NV50_EVO_CRTC_CLUT_MODE_OFF : NV50_EVO_CRTC_CLUT_MODE_ON); |
616 | 577 | ||
617 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); | 578 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, COLOR_CTRL), 1); |
618 | OUT_RING(evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR); | 579 | OUT_RING (evo, NV50_EVO_CRTC_COLOR_CTRL_COLOR); |
619 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); | 580 | BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_POS), 1); |
620 | OUT_RING(evo, (y << 16) | x); | 581 | OUT_RING (evo, (y << 16) | x); |
621 | 582 | ||
622 | if (nv_crtc->lut.depth != fb->base.depth) { | 583 | if (nv_crtc->lut.depth != fb->base.depth) { |
623 | nv_crtc->lut.depth = fb->base.depth; | 584 | nv_crtc->lut.depth = fb->base.depth; |