diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv10_graph.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nv10_graph.c | 212 |
1 files changed, 113 insertions, 99 deletions
diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 8c92edb7bbcd..0930c6cb88e0 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c | |||
@@ -28,10 +28,9 @@ | |||
28 | #include "nouveau_drv.h" | 28 | #include "nouveau_drv.h" |
29 | #include "nouveau_util.h" | 29 | #include "nouveau_util.h" |
30 | 30 | ||
31 | static int nv10_graph_register(struct drm_device *); | 31 | struct nv10_graph_engine { |
32 | static void nv10_graph_isr(struct drm_device *); | 32 | struct nouveau_exec_engine base; |
33 | 33 | }; | |
34 | #define NV10_FIFO_NUMBER 32 | ||
35 | 34 | ||
36 | struct pipe_state { | 35 | struct pipe_state { |
37 | uint32_t pipe_0x0000[0x040/4]; | 36 | uint32_t pipe_0x0000[0x040/4]; |
@@ -414,9 +413,9 @@ struct graph_state { | |||
414 | 413 | ||
415 | static void nv10_graph_save_pipe(struct nouveau_channel *chan) | 414 | static void nv10_graph_save_pipe(struct nouveau_channel *chan) |
416 | { | 415 | { |
417 | struct drm_device *dev = chan->dev; | 416 | struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; |
418 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; | ||
419 | struct pipe_state *pipe = &pgraph_ctx->pipe_state; | 417 | struct pipe_state *pipe = &pgraph_ctx->pipe_state; |
418 | struct drm_device *dev = chan->dev; | ||
420 | 419 | ||
421 | PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); | 420 | PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400); |
422 | PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); | 421 | PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200); |
@@ -432,9 +431,9 @@ static void nv10_graph_save_pipe(struct nouveau_channel *chan) | |||
432 | 431 | ||
433 | static void nv10_graph_load_pipe(struct nouveau_channel *chan) | 432 | static void nv10_graph_load_pipe(struct nouveau_channel *chan) |
434 | { | 433 | { |
435 | struct drm_device *dev = chan->dev; | 434 | struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; |
436 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; | ||
437 | struct pipe_state *pipe = &pgraph_ctx->pipe_state; | 435 | struct pipe_state *pipe = &pgraph_ctx->pipe_state; |
436 | struct drm_device *dev = chan->dev; | ||
438 | uint32_t xfmode0, xfmode1; | 437 | uint32_t xfmode0, xfmode1; |
439 | int i; | 438 | int i; |
440 | 439 | ||
@@ -482,9 +481,9 @@ static void nv10_graph_load_pipe(struct nouveau_channel *chan) | |||
482 | 481 | ||
483 | static void nv10_graph_create_pipe(struct nouveau_channel *chan) | 482 | static void nv10_graph_create_pipe(struct nouveau_channel *chan) |
484 | { | 483 | { |
485 | struct drm_device *dev = chan->dev; | 484 | struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; |
486 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; | ||
487 | struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; | 485 | struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state; |
486 | struct drm_device *dev = chan->dev; | ||
488 | uint32_t *fifo_pipe_state_addr; | 487 | uint32_t *fifo_pipe_state_addr; |
489 | int i; | 488 | int i; |
490 | #define PIPE_INIT(addr) \ | 489 | #define PIPE_INIT(addr) \ |
@@ -661,8 +660,6 @@ static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan, | |||
661 | uint32_t inst) | 660 | uint32_t inst) |
662 | { | 661 | { |
663 | struct drm_device *dev = chan->dev; | 662 | struct drm_device *dev = chan->dev; |
664 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
665 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
666 | uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4]; | 663 | uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4]; |
667 | uint32_t ctx_user, ctx_switch[5]; | 664 | uint32_t ctx_user, ctx_switch[5]; |
668 | int i, subchan = -1; | 665 | int i, subchan = -1; |
@@ -711,8 +708,8 @@ static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan, | |||
711 | 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c); | 708 | 0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c); |
712 | nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst); | 709 | nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst); |
713 | nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); | 710 | nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000); |
714 | pgraph->fifo_access(dev, true); | 711 | nv04_graph_fifo_access(dev, true); |
715 | pgraph->fifo_access(dev, false); | 712 | nv04_graph_fifo_access(dev, false); |
716 | 713 | ||
717 | /* Restore the FIFO state */ | 714 | /* Restore the FIFO state */ |
718 | for (i = 0; i < ARRAY_SIZE(fifo); i++) | 715 | for (i = 0; i < ARRAY_SIZE(fifo); i++) |
@@ -729,11 +726,12 @@ static void nv10_graph_load_dma_vtxbuf(struct nouveau_channel *chan, | |||
729 | nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user); | 726 | nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user); |
730 | } | 727 | } |
731 | 728 | ||
732 | int nv10_graph_load_context(struct nouveau_channel *chan) | 729 | static int |
730 | nv10_graph_load_context(struct nouveau_channel *chan) | ||
733 | { | 731 | { |
734 | struct drm_device *dev = chan->dev; | 732 | struct drm_device *dev = chan->dev; |
735 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 733 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
736 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; | 734 | struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR]; |
737 | uint32_t tmp; | 735 | uint32_t tmp; |
738 | int i; | 736 | int i; |
739 | 737 | ||
@@ -757,21 +755,20 @@ int nv10_graph_load_context(struct nouveau_channel *chan) | |||
757 | return 0; | 755 | return 0; |
758 | } | 756 | } |
759 | 757 | ||
760 | int | 758 | static int |
761 | nv10_graph_unload_context(struct drm_device *dev) | 759 | nv10_graph_unload_context(struct drm_device *dev) |
762 | { | 760 | { |
763 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 761 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
764 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | ||
765 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; | 762 | struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; |
766 | struct nouveau_channel *chan; | 763 | struct nouveau_channel *chan; |
767 | struct graph_state *ctx; | 764 | struct graph_state *ctx; |
768 | uint32_t tmp; | 765 | uint32_t tmp; |
769 | int i; | 766 | int i; |
770 | 767 | ||
771 | chan = pgraph->channel(dev); | 768 | chan = nv10_graph_channel(dev); |
772 | if (!chan) | 769 | if (!chan) |
773 | return 0; | 770 | return 0; |
774 | ctx = chan->pgraph_ctx; | 771 | ctx = chan->engctx[NVOBJ_ENGINE_GR]; |
775 | 772 | ||
776 | for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) | 773 | for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) |
777 | ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]); | 774 | ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]); |
@@ -805,7 +802,7 @@ nv10_graph_context_switch(struct drm_device *dev) | |||
805 | /* Load context for next channel */ | 802 | /* Load context for next channel */ |
806 | chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; | 803 | chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; |
807 | chan = dev_priv->channels.ptr[chid]; | 804 | chan = dev_priv->channels.ptr[chid]; |
808 | if (chan && chan->pgraph_ctx) | 805 | if (chan && chan->engctx[NVOBJ_ENGINE_GR]) |
809 | nv10_graph_load_context(chan); | 806 | nv10_graph_load_context(chan); |
810 | } | 807 | } |
811 | 808 | ||
@@ -836,7 +833,8 @@ nv10_graph_channel(struct drm_device *dev) | |||
836 | return dev_priv->channels.ptr[chid]; | 833 | return dev_priv->channels.ptr[chid]; |
837 | } | 834 | } |
838 | 835 | ||
839 | int nv10_graph_create_context(struct nouveau_channel *chan) | 836 | static int |
837 | nv10_graph_context_new(struct nouveau_channel *chan, int engine) | ||
840 | { | 838 | { |
841 | struct drm_device *dev = chan->dev; | 839 | struct drm_device *dev = chan->dev; |
842 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 840 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
@@ -844,11 +842,10 @@ int nv10_graph_create_context(struct nouveau_channel *chan) | |||
844 | 842 | ||
845 | NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id); | 843 | NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id); |
846 | 844 | ||
847 | chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), | 845 | pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL); |
848 | GFP_KERNEL); | ||
849 | if (pgraph_ctx == NULL) | 846 | if (pgraph_ctx == NULL) |
850 | return -ENOMEM; | 847 | return -ENOMEM; |
851 | 848 | chan->engctx[engine] = pgraph_ctx; | |
852 | 849 | ||
853 | NV_WRITE_CTX(0x00400e88, 0x08000000); | 850 | NV_WRITE_CTX(0x00400e88, 0x08000000); |
854 | NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); | 851 | NV_WRITE_CTX(0x00400e9c, 0x4b7fffff); |
@@ -873,30 +870,30 @@ int nv10_graph_create_context(struct nouveau_channel *chan) | |||
873 | return 0; | 870 | return 0; |
874 | } | 871 | } |
875 | 872 | ||
876 | void nv10_graph_destroy_context(struct nouveau_channel *chan) | 873 | static void |
874 | nv10_graph_context_del(struct nouveau_channel *chan, int engine) | ||
877 | { | 875 | { |
878 | struct drm_device *dev = chan->dev; | 876 | struct drm_device *dev = chan->dev; |
879 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 877 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
880 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; | 878 | struct graph_state *pgraph_ctx = chan->engctx[engine]; |
881 | struct graph_state *pgraph_ctx = chan->pgraph_ctx; | ||
882 | unsigned long flags; | 879 | unsigned long flags; |
883 | 880 | ||
884 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 881 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
885 | pgraph->fifo_access(dev, false); | 882 | nv04_graph_fifo_access(dev, false); |
886 | 883 | ||
887 | /* Unload the context if it's the currently active one */ | 884 | /* Unload the context if it's the currently active one */ |
888 | if (pgraph->channel(dev) == chan) | 885 | if (nv10_graph_channel(dev) == chan) |
889 | pgraph->unload_context(dev); | 886 | nv10_graph_unload_context(dev); |
887 | |||
888 | nv04_graph_fifo_access(dev, true); | ||
889 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
890 | 890 | ||
891 | /* Free the context resources */ | 891 | /* Free the context resources */ |
892 | chan->engctx[engine] = NULL; | ||
892 | kfree(pgraph_ctx); | 893 | kfree(pgraph_ctx); |
893 | chan->pgraph_ctx = NULL; | ||
894 | |||
895 | pgraph->fifo_access(dev, true); | ||
896 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
897 | } | 894 | } |
898 | 895 | ||
899 | void | 896 | static void |
900 | nv10_graph_set_tile_region(struct drm_device *dev, int i) | 897 | nv10_graph_set_tile_region(struct drm_device *dev, int i) |
901 | { | 898 | { |
902 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 899 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
@@ -907,22 +904,18 @@ nv10_graph_set_tile_region(struct drm_device *dev, int i) | |||
907 | nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr); | 904 | nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr); |
908 | } | 905 | } |
909 | 906 | ||
910 | int nv10_graph_init(struct drm_device *dev) | 907 | static int |
908 | nv10_graph_init(struct drm_device *dev, int engine) | ||
911 | { | 909 | { |
912 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 910 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
913 | uint32_t tmp; | 911 | u32 tmp; |
914 | int ret, i; | 912 | int i; |
915 | 913 | ||
916 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & | 914 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & |
917 | ~NV_PMC_ENABLE_PGRAPH); | 915 | ~NV_PMC_ENABLE_PGRAPH); |
918 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | | 916 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | |
919 | NV_PMC_ENABLE_PGRAPH); | 917 | NV_PMC_ENABLE_PGRAPH); |
920 | 918 | ||
921 | ret = nv10_graph_register(dev); | ||
922 | if (ret) | ||
923 | return ret; | ||
924 | |||
925 | nouveau_irq_register(dev, 12, nv10_graph_isr); | ||
926 | nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); | 919 | nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); |
927 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); | 920 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); |
928 | 921 | ||
@@ -963,18 +956,20 @@ int nv10_graph_init(struct drm_device *dev) | |||
963 | return 0; | 956 | return 0; |
964 | } | 957 | } |
965 | 958 | ||
966 | void nv10_graph_takedown(struct drm_device *dev) | 959 | static int |
960 | nv10_graph_fini(struct drm_device *dev, int engine) | ||
967 | { | 961 | { |
962 | nv10_graph_unload_context(dev); | ||
968 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); | 963 | nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); |
969 | nouveau_irq_unregister(dev, 12); | 964 | return 0; |
970 | } | 965 | } |
971 | 966 | ||
972 | static int | 967 | static int |
973 | nv17_graph_mthd_lma_window(struct nouveau_channel *chan, | 968 | nv17_graph_mthd_lma_window(struct nouveau_channel *chan, |
974 | u32 class, u32 mthd, u32 data) | 969 | u32 class, u32 mthd, u32 data) |
975 | { | 970 | { |
971 | struct graph_state *ctx = chan->engctx[NVOBJ_ENGINE_GR]; | ||
976 | struct drm_device *dev = chan->dev; | 972 | struct drm_device *dev = chan->dev; |
977 | struct graph_state *ctx = chan->pgraph_ctx; | ||
978 | struct pipe_state *pipe = &ctx->pipe_state; | 973 | struct pipe_state *pipe = &ctx->pipe_state; |
979 | uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; | 974 | uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; |
980 | uint32_t xfmode0, xfmode1; | 975 | uint32_t xfmode0, xfmode1; |
@@ -1061,64 +1056,13 @@ nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, | |||
1061 | return 0; | 1056 | return 0; |
1062 | } | 1057 | } |
1063 | 1058 | ||
1064 | static int | ||
1065 | nv10_graph_register(struct drm_device *dev) | ||
1066 | { | ||
1067 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1068 | |||
1069 | if (dev_priv->engine.graph.registered) | ||
1070 | return 0; | ||
1071 | |||
1072 | NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ | ||
1073 | NVOBJ_CLASS(dev, 0x0030, GR); /* null */ | ||
1074 | NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ | ||
1075 | NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ | ||
1076 | NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */ | ||
1077 | NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ | ||
1078 | NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ | ||
1079 | NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ | ||
1080 | NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ | ||
1081 | NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ | ||
1082 | NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ | ||
1083 | NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ | ||
1084 | NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ | ||
1085 | NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ | ||
1086 | NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */ | ||
1087 | NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */ | ||
1088 | NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */ | ||
1089 | NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */ | ||
1090 | |||
1091 | /* celcius */ | ||
1092 | if (dev_priv->chipset <= 0x10) { | ||
1093 | NVOBJ_CLASS(dev, 0x0056, GR); | ||
1094 | } else | ||
1095 | if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) { | ||
1096 | NVOBJ_CLASS(dev, 0x0096, GR); | ||
1097 | } else { | ||
1098 | NVOBJ_CLASS(dev, 0x0099, GR); | ||
1099 | NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window); | ||
1100 | NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window); | ||
1101 | NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window); | ||
1102 | NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window); | ||
1103 | NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable); | ||
1104 | } | ||
1105 | |||
1106 | /* nvsw */ | ||
1107 | NVOBJ_CLASS(dev, 0x506e, SW); | ||
1108 | NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); | ||
1109 | |||
1110 | dev_priv->engine.graph.registered = true; | ||
1111 | return 0; | ||
1112 | } | ||
1113 | |||
1114 | struct nouveau_bitfield nv10_graph_intr[] = { | 1059 | struct nouveau_bitfield nv10_graph_intr[] = { |
1115 | { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, | 1060 | { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, |
1116 | { NV_PGRAPH_INTR_ERROR, "ERROR" }, | 1061 | { NV_PGRAPH_INTR_ERROR, "ERROR" }, |
1117 | {} | 1062 | {} |
1118 | }; | 1063 | }; |
1119 | 1064 | ||
1120 | struct nouveau_bitfield nv10_graph_nstatus[] = | 1065 | struct nouveau_bitfield nv10_graph_nstatus[] = { |
1121 | { | ||
1122 | { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, | 1066 | { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, |
1123 | { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, | 1067 | { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, |
1124 | { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, | 1068 | { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, |
@@ -1173,3 +1117,73 @@ nv10_graph_isr(struct drm_device *dev) | |||
1173 | } | 1117 | } |
1174 | } | 1118 | } |
1175 | } | 1119 | } |
1120 | |||
1121 | static void | ||
1122 | nv10_graph_destroy(struct drm_device *dev, int engine) | ||
1123 | { | ||
1124 | struct nv10_graph_engine *pgraph = nv_engine(dev, engine); | ||
1125 | |||
1126 | nouveau_irq_unregister(dev, 12); | ||
1127 | kfree(pgraph); | ||
1128 | } | ||
1129 | |||
1130 | int | ||
1131 | nv10_graph_create(struct drm_device *dev) | ||
1132 | { | ||
1133 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1134 | struct nv10_graph_engine *pgraph; | ||
1135 | |||
1136 | pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL); | ||
1137 | if (!pgraph) | ||
1138 | return -ENOMEM; | ||
1139 | |||
1140 | pgraph->base.destroy = nv10_graph_destroy; | ||
1141 | pgraph->base.init = nv10_graph_init; | ||
1142 | pgraph->base.fini = nv10_graph_fini; | ||
1143 | pgraph->base.context_new = nv10_graph_context_new; | ||
1144 | pgraph->base.context_del = nv10_graph_context_del; | ||
1145 | pgraph->base.object_new = nv04_graph_object_new; | ||
1146 | pgraph->base.set_tile_region = nv10_graph_set_tile_region; | ||
1147 | |||
1148 | NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base); | ||
1149 | nouveau_irq_register(dev, 12, nv10_graph_isr); | ||
1150 | |||
1151 | /* nvsw */ | ||
1152 | NVOBJ_CLASS(dev, 0x506e, SW); | ||
1153 | NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); | ||
1154 | |||
1155 | NVOBJ_CLASS(dev, 0x0030, GR); /* null */ | ||
1156 | NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ | ||
1157 | NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ | ||
1158 | NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */ | ||
1159 | NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ | ||
1160 | NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ | ||
1161 | NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ | ||
1162 | NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ | ||
1163 | NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ | ||
1164 | NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ | ||
1165 | NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ | ||
1166 | NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ | ||
1167 | NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ | ||
1168 | NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */ | ||
1169 | NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */ | ||
1170 | NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */ | ||
1171 | NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */ | ||
1172 | |||
1173 | /* celcius */ | ||
1174 | if (dev_priv->chipset <= 0x10) { | ||
1175 | NVOBJ_CLASS(dev, 0x0056, GR); | ||
1176 | } else | ||
1177 | if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) { | ||
1178 | NVOBJ_CLASS(dev, 0x0096, GR); | ||
1179 | } else { | ||
1180 | NVOBJ_CLASS(dev, 0x0099, GR); | ||
1181 | NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window); | ||
1182 | NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window); | ||
1183 | NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window); | ||
1184 | NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window); | ||
1185 | NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable); | ||
1186 | } | ||
1187 | |||
1188 | return 0; | ||
1189 | } | ||