File drivers/gpu/alga/amd/si/cp.c changed (mode: 100644) (index 6c24567..b970b72) |
10 |
10 |
#include <alga/rng_mng.h> |
#include <alga/rng_mng.h> |
11 |
11 |
#include <alga/timing.h> |
#include <alga/timing.h> |
12 |
12 |
#include <alga/pixel_fmts.h> |
#include <alga/pixel_fmts.h> |
13 |
|
#include <alga/amd/dce4/dce4.h> |
|
|
13 |
|
#include <alga/amd/dce6/dce6.h> |
14 |
14 |
|
|
15 |
15 |
#include "regs.h" |
#include "regs.h" |
16 |
16 |
|
|
|
20 |
20 |
#include "cp.h" |
#include "cp.h" |
21 |
21 |
#include "drv.h" |
#include "drv.h" |
22 |
22 |
|
|
23 |
|
void cp_stop(struct pci_dev *dev) |
|
|
23 |
|
void cps_engines_stop(struct pci_dev *dev) |
24 |
24 |
{ |
{ |
25 |
|
wr32(dev, CP_ME_HALT | CP_PFP_HALT, CP_ME_CTL); |
|
|
25 |
|
wr32(dev, CP_CE_HALT | CP_ME_HALT | CP_PFP_HALT, CP_ME_CTL); |
26 |
26 |
wr32(dev, 0, SCRATCH_UMSK); |
wr32(dev, 0, SCRATCH_UMSK); |
27 |
27 |
} |
} |
28 |
28 |
|
|
29 |
29 |
/* should be at the very beginning of the ring */ |
/* should be at the very beginning of the ring */ |
30 |
|
void cp_me_init(struct pci_dev *dev) |
|
31 |
|
{ |
|
32 |
|
struct dev_drv_data *dd; |
|
33 |
|
dd = pci_get_drvdata(dev); |
|
34 |
|
|
|
35 |
|
cp_wr(dev, PKT3(PKT3_ME_INIT, 6)); |
|
36 |
|
cp_wr(dev, 0x1); |
|
37 |
|
cp_wr(dev, 0x2); |
|
38 |
|
cp_wr(dev, dd->cfg.gpu_hw_ctxs_n_max - 1); |
|
39 |
|
cp_wr(dev, PKT3_ME_INIT_DEV_ID(1)); |
|
40 |
|
cp_wr(dev, 0); |
|
41 |
|
cp_wr(dev, 0); |
|
42 |
|
|
|
43 |
|
cp_commit(dev); |
|
44 |
|
wr32(dev, 0xff, CP_ME_CTL); /* XXX: specific to ME init? */ |
|
45 |
|
} |
|
|
30 |
|
//void cp_me_init(struct pci_dev *dev) |
|
31 |
|
//{ |
|
32 |
|
// struct dev_drv_data *dd; |
|
33 |
|
// dd = pci_get_drvdata(dev); |
|
34 |
|
// |
|
35 |
|
// cp_wr(dev, PKT3(PKT3_ME_INIT, 6)); |
|
36 |
|
// cp_wr(dev, 0x1); |
|
37 |
|
// cp_wr(dev, 0x2); |
|
38 |
|
// cp_wr(dev, dd->cfg.gpu_hw_ctxs_n_max - 1); |
|
39 |
|
// cp_wr(dev, PKT3_ME_INIT_DEV_ID(1)); |
|
40 |
|
// cp_wr(dev, 0); |
|
41 |
|
// cp_wr(dev, 0); |
|
42 |
|
// |
|
43 |
|
// cp_commit(dev); |
|
44 |
|
// wr32(dev, 0xff, CP_ME_CTL); /* XXX: specific to ME init? */ |
|
45 |
|
//} |
46 |
46 |
|
|
47 |
47 |
/* |
/* |
48 |
48 |
* o ring size is 2^CP_RING_LOG2_QWS(17) quadwords (256 * 4096 bytes) |
* o ring size is 2^CP_RING_LOG2_QWS(17) quadwords (256 * 4096 bytes) |
|
... |
... |
void cp_me_init(struct pci_dev *dev) |
51 |
51 |
*/ |
*/ |
52 |
52 |
#define WB_SCRATCH_OF 0 |
#define WB_SCRATCH_OF 0 |
53 |
53 |
#define WB_CP_RPTR_OF 1024 |
#define WB_CP_RPTR_OF 1024 |
54 |
|
void cp_init(struct pci_dev *dev) |
|
55 |
|
{ |
|
56 |
|
u32 cp_rb_ctl; |
|
57 |
|
u64 cp_rb_rptr_addr; |
|
58 |
|
u64 wb_scratch_addr; |
|
59 |
|
struct dev_drv_data *dd; |
|
60 |
|
|
|
61 |
|
/* some command processor base settings */ |
|
62 |
|
wr32(dev, SET(ROQ_IB_0_START, 0x16) | SET(ROQ_IB_1_START, 0x2b), |
|
63 |
|
CP_QUEUE_THRESHOLDS); |
|
64 |
|
wr32(dev, SET(MEQ_0_START, 0x30) | SET(MEQ_1_START, 0x60), |
|
65 |
|
CP_MEQ_THRESHOLDS); |
|
66 |
|
wr32(dev, 0, CP_PERFMON_CTL); |
|
67 |
|
|
|
68 |
|
/* reset cp; if cp is reset, then pa, sh, vgt also need to be reset */ |
|
69 |
|
wr32(dev, SOFT_RESET_CP | SOFT_RESET_PA | SOFT_RESET_SH |
|
70 |
|
| SOFT_RESET_VGT | SOFT_RESET_SX, GRBM_SOFT_RESET); |
|
71 |
|
rr32(dev, GRBM_SOFT_RESET); |
|
72 |
|
mdelay(15); |
|
73 |
|
wr32(dev, 0, GRBM_SOFT_RESET); |
|
74 |
|
rr32(dev, GRBM_SOFT_RESET); |
|
75 |
|
|
|
76 |
|
/* set ring buffer size */ |
|
77 |
|
cp_rb_ctl = SET(RB_BLK_LOG2_QWS, GPU_PAGE_LOG2_QWS) |
|
78 |
|
| SET(RB_BUF_LOG2_QWS, CP_RING_LOG2_QWS); |
|
79 |
|
#ifdef __BIG_ENDIAN |
|
80 |
|
cp_rb_ctl |= BUF_SWAP_32BIT; |
|
81 |
|
#endif |
|
82 |
|
wr32(dev, cp_rb_ctl, CP_RB_CTL); |
|
83 |
|
wr32(dev, 0x4, CP_SEM_WAIT_TIMER); |
|
84 |
|
|
|
85 |
|
wr32(dev, 0, CP_RB_WPTR_DELAY); |
|
86 |
|
|
|
87 |
|
wr32(dev, cp_rb_ctl | RB_RPTR_WR_ENA, CP_RB_CTL); |
|
88 |
|
wr32(dev, 0, CP_RB_RPTR_WR); |
|
89 |
|
wr32(dev, 0, CP_RB_WPTR); |
|
90 |
|
wr32(dev, 0, CP_RB_RPTR); |
|
91 |
|
|
|
92 |
|
dd = pci_get_drvdata(dev); |
|
93 |
|
|
|
94 |
|
/* set the wb address, 2 lower bits are for endianness */ |
|
95 |
|
cp_rb_rptr_addr = dd->ba.wb_map->gpu_addr + WB_CP_RPTR_OF; |
|
96 |
|
|
|
97 |
|
wr32(dev, cp_rb_rptr_addr & 0xfffffffc, CP_RB_RPTR_ADDR); |
|
98 |
|
wr32(dev, upper_32_bits(cp_rb_rptr_addr) & 0xff, CP_RB_RPTR_ADDR_HI); |
|
99 |
|
|
|
100 |
|
wb_scratch_addr = dd->ba.wb_map->gpu_addr + WB_SCRATCH_OF; |
|
101 |
|
/* |
|
102 |
|
* 256 bytes block index is ok because gpu address and chosen write back |
|
103 |
|
* page offset fit properly that required aligment |
|
104 |
|
*/ |
|
105 |
|
wr32(dev, (wb_scratch_addr >> 8) & 0xffffffff, SCRATCH_ADDR); |
|
106 |
|
|
|
107 |
|
wr32(dev, 0xff, SCRATCH_UMSK); |
|
108 |
|
|
|
109 |
|
mdelay(1); |
|
110 |
|
wr32(dev, cp_rb_ctl, CP_RB_CTL); |
|
111 |
|
|
|
112 |
|
/* 256 bytes aligned ok because it is GPU_PAGE_SZ aligned */ |
|
113 |
|
wr32(dev, dd->ba.cp_ring_map->gpu_addr >> 8, CP_RB_BASE); |
|
114 |
|
wr32(dev, (1 << 27) | (1 << 28), CP_DEBUG); /* ??? */ |
|
115 |
|
|
|
116 |
|
dd->cp0.rptr = 0; |
|
117 |
|
dd->cp0.wptr = 0; |
|
118 |
|
spin_lock_init(&dd->cp0.lock); |
|
119 |
|
} |
|
120 |
|
|
|
121 |
|
inline void cp_wr(struct pci_dev *dev, u32 v) |
|
122 |
|
{ |
|
123 |
|
struct dev_drv_data *dd; |
|
124 |
|
u32 *r; |
|
125 |
|
|
|
126 |
|
dd = pci_get_drvdata(dev); |
|
127 |
|
|
|
128 |
|
r = dd->ba.cp_ring_map->cpu_addr; |
|
129 |
|
r[dd->cp0.wptr++] = v; |
|
130 |
|
dd->cp0.wptr &= CP_RING_DW_MASK; |
|
131 |
|
} |
|
132 |
|
|
|
133 |
|
inline void cp_commit(struct pci_dev *dev) |
|
134 |
|
{ |
|
135 |
|
struct dev_drv_data *dd; |
|
136 |
|
u32 *r; |
|
137 |
|
|
|
138 |
|
dd = pci_get_drvdata(dev); |
|
139 |
|
|
|
140 |
|
/* match ring fetch size */ |
|
141 |
|
r = dd->ba.cp_ring_map->cpu_addr; |
|
142 |
|
while (dd->cp0.wptr & CP_RING_PFP_DW_MASK) |
|
143 |
|
r[dd->cp0.wptr++] = PKT2; |
|
144 |
|
|
|
145 |
|
wmb(); /* data write operations emitted before dma */ |
|
146 |
|
|
|
147 |
|
dd->cp0.wptr &= CP_RING_DW_MASK; |
|
148 |
|
wr32(dev, dd->cp0.wptr, CP_RB_WPTR); |
|
149 |
|
rr32(dev, CP_RB_WPTR); |
|
150 |
|
} |
|
|
54 |
|
//void cp_init(struct pci_dev *dev) |
|
55 |
|
//{ |
|
56 |
|
// u32 cp_rb_ctl; |
|
57 |
|
// u64 cp_rb_rptr_addr; |
|
58 |
|
// u64 wb_scratch_addr; |
|
59 |
|
// struct dev_drv_data *dd; |
|
60 |
|
// |
|
61 |
|
// /* some command processor base settings */ |
|
62 |
|
// wr32(dev, SET(ROQ_IB_0_START, 0x16) | SET(ROQ_IB_1_START, 0x2b), |
|
63 |
|
// CP_QUEUE_THRESHOLDS); |
|
64 |
|
// wr32(dev, SET(MEQ_0_START, 0x30) | SET(MEQ_1_START, 0x60), |
|
65 |
|
// CP_MEQ_THRESHOLDS); |
|
66 |
|
// wr32(dev, 0, CP_PERFMON_CTL); |
|
67 |
|
// |
|
68 |
|
// /* reset cp; if cp is reset, then pa, sh, vgt also need to be reset */ |
|
69 |
|
// wr32(dev, SOFT_RESET_CP | SOFT_RESET_PA | SOFT_RESET_SH |
|
70 |
|
// | SOFT_RESET_VGT | SOFT_RESET_SX, GRBM_SOFT_RESET); |
|
71 |
|
// rr32(dev, GRBM_SOFT_RESET); |
|
72 |
|
// mdelay(15); |
|
73 |
|
// wr32(dev, 0, GRBM_SOFT_RESET); |
|
74 |
|
// rr32(dev, GRBM_SOFT_RESET); |
|
75 |
|
// |
|
76 |
|
// /* set ring buffer size */ |
|
77 |
|
// cp_rb_ctl = SET(RB_BLK_LOG2_QWS, GPU_PAGE_LOG2_QWS) |
|
78 |
|
// | SET(RB_BUF_LOG2_QWS, CP_RING_LOG2_QWS); |
|
79 |
|
//#ifdef __BIG_ENDIAN |
|
80 |
|
// cp_rb_ctl |= BUF_SWAP_32BIT; |
|
81 |
|
//#endif |
|
82 |
|
// wr32(dev, cp_rb_ctl, CP_RB_CTL); |
|
83 |
|
// wr32(dev, 0x4, CP_SEM_WAIT_TIMER); |
|
84 |
|
// |
|
85 |
|
// wr32(dev, 0, CP_RB_WPTR_DELAY); |
|
86 |
|
// |
|
87 |
|
// wr32(dev, cp_rb_ctl | RB_RPTR_WR_ENA, CP_RB_CTL); |
|
88 |
|
// wr32(dev, 0, CP_RB_RPTR_WR); |
|
89 |
|
// wr32(dev, 0, CP_RB_WPTR); |
|
90 |
|
// wr32(dev, 0, CP_RB_RPTR); |
|
91 |
|
// |
|
92 |
|
// dd = pci_get_drvdata(dev); |
|
93 |
|
// |
|
94 |
|
// /* set the wb address, 2 lower bits are for endianness */ |
|
95 |
|
// cp_rb_rptr_addr = dd->ba.wb_map->gpu_addr + WB_CP_RPTR_OF; |
|
96 |
|
// |
|
97 |
|
// wr32(dev, cp_rb_rptr_addr & 0xfffffffc, CP_RB_RPTR_ADDR); |
|
98 |
|
// wr32(dev, upper_32_bits(cp_rb_rptr_addr) & 0xff, CP_RB_RPTR_ADDR_HI); |
|
99 |
|
// |
|
100 |
|
// wb_scratch_addr = dd->ba.wb_map->gpu_addr + WB_SCRATCH_OF; |
|
101 |
|
// /* |
|
102 |
|
// * 256 bytes block index is ok because gpu address and chosen write back |
|
103 |
|
// * page offset fit properly that required aligment |
|
104 |
|
// */ |
|
105 |
|
// wr32(dev, (wb_scratch_addr >> 8) & 0xffffffff, SCRATCH_ADDR); |
|
106 |
|
// |
|
107 |
|
// wr32(dev, 0xff, SCRATCH_UMSK); |
|
108 |
|
// |
|
109 |
|
// mdelay(1); |
|
110 |
|
// wr32(dev, cp_rb_ctl, CP_RB_CTL); |
|
111 |
|
// |
|
112 |
|
// /* 256 bytes aligned ok because it is GPU_PAGE_SZ aligned */ |
|
113 |
|
// wr32(dev, dd->ba.cp_ring_map->gpu_addr >> 8, CP_RB_BASE); |
|
114 |
|
// wr32(dev, (1 << 27) | (1 << 28), CP_DEBUG); /* ??? */ |
|
115 |
|
// |
|
116 |
|
// dd->cp0.rptr = 0; |
|
117 |
|
// dd->cp0.wptr = 0; |
|
118 |
|
// spin_lock_init(&dd->cp0.lock); |
|
119 |
|
//} |
|
120 |
|
|
|
121 |
|
//inline void cp_wr(struct pci_dev *dev, u32 v) |
|
122 |
|
//{ |
|
123 |
|
// struct dev_drv_data *dd; |
|
124 |
|
// u32 *r; |
|
125 |
|
// |
|
126 |
|
// dd = pci_get_drvdata(dev); |
|
127 |
|
// |
|
128 |
|
// r = dd->ba.cp_ring_map->cpu_addr; |
|
129 |
|
// r[dd->cp0.wptr++] = v; |
|
130 |
|
// dd->cp0.wptr &= CP_RING_DW_MASK; |
|
131 |
|
//} |
|
132 |
|
|
|
133 |
|
//inline void cp_commit(struct pci_dev *dev) |
|
134 |
|
//{ |
|
135 |
|
// struct dev_drv_data *dd; |
|
136 |
|
// u32 *r; |
|
137 |
|
// |
|
138 |
|
// dd = pci_get_drvdata(dev); |
|
139 |
|
// |
|
140 |
|
// /* match ring fetch size */ |
|
141 |
|
// r = dd->ba.cp_ring_map->cpu_addr; |
|
142 |
|
// while (dd->cp0.wptr & CP_RING_PFP_DW_MASK) |
|
143 |
|
// r[dd->cp0.wptr++] = PKT2; |
|
144 |
|
// |
|
145 |
|
// wmb(); /* data write operations emitted before dma */ |
|
146 |
|
// |
|
147 |
|
// dd->cp0.wptr &= CP_RING_DW_MASK; |
|
148 |
|
// wr32(dev, dd->cp0.wptr, CP_RB_WPTR); |
|
149 |
|
// rr32(dev, CP_RB_WPTR); |
|
150 |
|
//} |
File drivers/gpu/alga/amd/si/drv.c changed (mode: 100644) (index ec8709b..abf2ac6) |
31 |
31 |
|
|
32 |
32 |
#include "fops.h" |
#include "fops.h" |
33 |
33 |
|
|
34 |
|
static struct class *class; |
|
|
34 |
|
//static struct class *class; |
35 |
35 |
|
|
36 |
36 |
static struct atb_dev adev; |
static struct atb_dev adev; |
37 |
37 |
static struct dce6_dev ddev; |
static struct dce6_dev ddev; |
|
... |
... |
static void * __devinit rom_copy_get(struct pci_dev *dev) |
109 |
109 |
return rom_copy; |
return rom_copy; |
110 |
110 |
} |
} |
111 |
111 |
|
|
112 |
|
//static void intrs_reset(struct pci_dev *dev) |
|
113 |
|
//{ |
|
114 |
|
// struct dev_drv_data *dd; |
|
115 |
|
// dd = pci_get_drvdata(dev); |
|
116 |
|
// |
|
117 |
|
// /* works even if ucode is not loaded */ |
|
118 |
|
// wr32(dev, CNTX_BUSY_INT_ENA | CNTX_EMPTY_INT_ENA, CP_INT_CTL); |
|
119 |
|
// |
|
120 |
|
// wr32(dev, 0, GRBM_INT_CTL); |
|
121 |
|
// |
|
122 |
|
// dce6_intrs_reset(dd->dce); |
|
123 |
|
//} |
|
|
112 |
|
static void intrs_reset(struct pci_dev *dev) |
|
113 |
|
{ |
|
114 |
|
struct dev_drv_data *dd; |
|
115 |
|
dd = pci_get_drvdata(dev); |
|
116 |
|
|
|
117 |
|
/* works even if ucode is not loaded */ |
|
118 |
|
wr32(dev, CNTX_BUSY_INT_ENA | CNTX_EMPTY_INT_ENA, CP_INT_CTL_RING_0); |
|
119 |
|
wr32(dev, 0, CP_INT_CTL_RING_1); |
|
120 |
|
wr32(dev, 0, CP_INT_CTL_RING_2); |
|
121 |
|
|
|
122 |
|
wr32(dev, 0, GRBM_INT_CTL); |
|
123 |
|
|
|
124 |
|
dce6_intrs_reset(dd->dce); |
|
125 |
|
} |
124 |
126 |
|
|
125 |
127 |
|
|
126 |
128 |
//static int mc_wait_for_idle(struct pci_dev *dev) |
//static int mc_wait_for_idle(struct pci_dev *dev) |
|
... |
... |
static void cfg_init(struct pci_dev *dev) |
588 |
590 |
// udelay(50); |
// udelay(50); |
589 |
591 |
//} |
//} |
590 |
592 |
|
|
591 |
|
//static irqreturn_t irq_thd(int irq, void *dev_id) |
|
592 |
|
//{ |
|
593 |
|
// struct pci_dev *dev; |
|
594 |
|
// struct dev_drv_data *dd; |
|
595 |
|
// |
|
596 |
|
// dev = dev_id; |
|
597 |
|
// dd = pci_get_drvdata(dev); |
|
598 |
|
// |
|
599 |
|
// dce6_irqs_thd(dd->dce); |
|
600 |
|
// return IRQ_HANDLED; |
|
601 |
|
//} |
|
|
593 |
|
static irqreturn_t irq_thd(int irq, void *dev_id) |
|
594 |
|
{ |
|
595 |
|
struct pci_dev *dev; |
|
596 |
|
struct dev_drv_data *dd; |
602 |
597 |
|
|
603 |
|
//static irqreturn_t irq(int irq, void *dev_id) |
|
604 |
|
//{ |
|
605 |
|
// struct pci_dev *dev; |
|
606 |
|
// dev = dev_id; |
|
607 |
|
// /* TODO: should return IRQ_HANDLED in some cases ? */ |
|
608 |
|
// if (ih_parse(dev)) |
|
609 |
|
// return IRQ_WAKE_THREAD; |
|
610 |
|
// else |
|
611 |
|
// return IRQ_NONE; |
|
612 |
|
//} |
|
|
598 |
|
dev = dev_id; |
|
599 |
|
dd = pci_get_drvdata(dev); |
|
600 |
|
|
|
601 |
|
dce6_irqs_thd(dd->dce); |
|
602 |
|
return IRQ_HANDLED; |
|
603 |
|
} |
|
604 |
|
|
|
605 |
|
static irqreturn_t irq(int irq, void *dev_id) |
|
606 |
|
{ |
|
607 |
|
struct pci_dev *dev; |
|
608 |
|
dev = dev_id; |
|
609 |
|
/* TODO: should return IRQ_HANDLED in some cases ? */ |
|
610 |
|
if (ih_parse(dev)) |
|
611 |
|
return IRQ_WAKE_THREAD; |
|
612 |
|
else |
|
613 |
|
return IRQ_NONE; |
|
614 |
|
} |
613 |
615 |
|
|
614 |
616 |
/* override the memory configuration */ |
/* override the memory configuration */ |
615 |
|
//static void addr_cfg_compute(struct pci_dev *dev, u32 *addr_cfg, |
|
616 |
|
// unsigned *mem_row_sz_kb) |
|
617 |
|
//{ |
|
618 |
|
// struct dev_drv_data *dd; |
|
619 |
|
// u32 arb_ram_cfg; |
|
620 |
|
// unsigned cols_n; |
|
621 |
|
// |
|
622 |
|
// dd = pci_get_drvdata(dev); |
|
623 |
|
// |
|
624 |
|
// arb_ram_cfg = rd32(dev, MC_ARB_RAM_CFG); |
|
625 |
|
// cols_n = GET(MC_COLS_N, arb_ram_cfg); |
|
626 |
|
// |
|
627 |
|
// *mem_row_sz_kb = (4 *(1 << (8 + cols_n))) / 1024; |
|
628 |
|
// if (*mem_row_sz_kb > 4) |
|
629 |
|
// *mem_row_sz_kb = 4; |
|
630 |
|
// |
|
631 |
|
// *addr_cfg = dd->cfg.addr_best; |
|
632 |
|
// *addr_cfg &= ~ROW_SZ_MASK; |
|
633 |
|
// switch (*mem_row_sz_kb) { |
|
634 |
|
// case 1: |
|
635 |
|
// default: |
|
636 |
|
// *addr_cfg |= SET(ROW_SZ, 0); |
|
637 |
|
// break; |
|
638 |
|
// case 2: |
|
639 |
|
// *addr_cfg |= SET(ROW_SZ, 1); |
|
640 |
|
// break; |
|
641 |
|
// case 4: |
|
642 |
|
// *addr_cfg |= SET(ROW_SZ, 2); |
|
643 |
|
// break; |
|
644 |
|
// } |
|
645 |
|
//} |
|
|
617 |
|
static void addr_cfg_compute(struct pci_dev *dev, u32 *addr_cfg, |
|
618 |
|
unsigned *mem_row_sz_kb) |
|
619 |
|
{ |
|
620 |
|
struct dev_drv_data *dd; |
|
621 |
|
u32 arb_ram_cfg; |
|
622 |
|
unsigned cols_n; |
|
623 |
|
|
|
624 |
|
dd = pci_get_drvdata(dev); |
|
625 |
|
|
|
626 |
|
arb_ram_cfg = rr32(dev, MC_ARB_RAM_CFG); |
|
627 |
|
cols_n = GET(MC_COLS_N, arb_ram_cfg); |
|
628 |
|
|
|
629 |
|
*mem_row_sz_kb = (4 *(1 << (8 + cols_n))) / 1024; |
|
630 |
|
if (*mem_row_sz_kb > 4) |
|
631 |
|
*mem_row_sz_kb = 4; |
|
632 |
|
|
|
633 |
|
*addr_cfg = dd->cfg.addr_best; |
|
634 |
|
*addr_cfg &= ~ROW_SZ_MASK; |
|
635 |
|
switch (*mem_row_sz_kb) { |
|
636 |
|
case 1: |
|
637 |
|
default: |
|
638 |
|
*addr_cfg |= SET(ROW_SZ, 0); |
|
639 |
|
break; |
|
640 |
|
case 2: |
|
641 |
|
*addr_cfg |= SET(ROW_SZ, 1); |
|
642 |
|
break; |
|
643 |
|
case 4: |
|
644 |
|
*addr_cfg |= SET(ROW_SZ, 2); |
|
645 |
|
break; |
|
646 |
|
} |
|
647 |
|
} |
646 |
648 |
|
|
647 |
649 |
static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id) |
static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id) |
648 |
650 |
{ |
{ |
649 |
651 |
int err; |
int err; |
650 |
652 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
651 |
|
//u32 addr_cfg; |
|
|
653 |
|
u32 addr_cfg; |
|
654 |
|
unsigned mem_row_sz_kb; |
652 |
655 |
|
|
653 |
656 |
err = pci_enable_device(dev); |
err = pci_enable_device(dev); |
654 |
657 |
if (err) { |
if (err) { |
|
... |
... |
static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id) |
746 |
749 |
dev_info(&dev->dev, "already posted\n"); |
dev_info(&dev->dev, "already posted\n"); |
747 |
750 |
} |
} |
748 |
751 |
|
|
|
752 |
|
/* do some PCI-E bus magic */ |
749 |
753 |
wr32(dev, FB_RD_ENA | FB_WR_ENA, BIF_FB_ENA); |
wr32(dev, FB_RD_ENA | FB_WR_ENA, BIF_FB_ENA); |
750 |
754 |
|
|
751 |
|
///* claim back the 256k vga memory at vram beginning */ |
|
752 |
|
//dce6_vga_off(dd->dce); |
|
|
755 |
|
/* claim back the 256k vga memory at vram beginning */ |
|
756 |
|
dce6_vga_off(dd->dce); |
753 |
757 |
|
|
754 |
|
//addr_cfg_compute(dev, &addr_cfg, &mem_row_sz_kb); |
|
|
758 |
|
addr_cfg_compute(dev, &addr_cfg, &mem_row_sz_kb); |
755 |
759 |
|
|
756 |
|
///* CFG_MEM_SZ is now valid */ |
|
757 |
|
//dev_info(&dev->dev, "vram size is %uMB\n", rr32(dev, CFG_MEM_SZ)); |
|
|
760 |
|
/* CFG_MEM_SZ is now valid */ |
|
761 |
|
dev_info(&dev->dev, "vram size is %uMB\n", rr32(dev, CFG_MEM_SZ)); |
758 |
762 |
|
|
759 |
|
//rng_mng_init(&dd->vram.mng, 0, rr32(dev, CFG_MEM_SZ) * 1024 * 1024); |
|
|
763 |
|
rng_mng_init(&dd->vram.mng, 0, rr32(dev, CFG_MEM_SZ) * 1024 * 1024); |
760 |
764 |
|
|
761 |
|
//cp0_stop(dev); |
|
762 |
|
//cp1_stop(dev); |
|
763 |
|
//cp2_stop(dev); |
|
764 |
|
//ih_stop(dev); |
|
765 |
|
//intrs_reset(dev); |
|
|
765 |
|
cps_engines_stop(dev); |
|
766 |
|
ih_stop(dev); |
|
767 |
|
intrs_reset(dev); |
766 |
768 |
|
|
767 |
|
//err = request_threaded_irq(dev->irq, irq, irq_thd, 0, pci_name(dev), |
|
768 |
|
// (void*)dev); |
|
769 |
|
//if (err) { |
|
770 |
|
// dev_err(&dev->dev, "unable to request threaded irq\n"); |
|
771 |
|
// goto err_vram_mng_destroy; |
|
772 |
|
//} |
|
|
769 |
|
err = request_threaded_irq(dev->irq, irq, irq_thd, 0, pci_name(dev), |
|
770 |
|
(void*)dev); |
|
771 |
|
if (err) { |
|
772 |
|
dev_err(&dev->dev, "unable to request threaded irq\n"); |
|
773 |
|
goto err_vram_mng_destroy; |
|
774 |
|
} |
773 |
775 |
|
|
774 |
|
//err = ucode_load(dev); |
|
775 |
|
//if (err) |
|
776 |
|
// goto err_free_irq; |
|
|
776 |
|
err = ucode_load(dev); |
|
777 |
|
if (err) |
|
778 |
|
goto err_free_irq; |
777 |
779 |
|
|
778 |
780 |
///* quiet the memory requests before mc programming: dce then gpu */ |
///* quiet the memory requests before mc programming: dce then gpu */ |
779 |
781 |
///* TODO:dce6 still has mem_req? */ |
///* TODO:dce6 still has mem_req? */ |
|
... |
... |
static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id) |
844 |
846 |
//err_cdev_del: |
//err_cdev_del: |
845 |
847 |
// cdev_del(&dd->evergreen_cdev); |
// cdev_del(&dd->evergreen_cdev); |
846 |
848 |
// |
// |
847 |
|
//err_clr_master: |
|
|
849 |
|
err_clr_master: |
848 |
850 |
// pci_clear_master(dev); |
// pci_clear_master(dev); |
849 |
|
// cp_stop(dev); |
|
850 |
|
// ih_stop(dev); |
|
|
851 |
|
cps_engines_stop(dev); |
|
852 |
|
ih_stop(dev); |
851 |
853 |
// dce6_shutdown(dd->dce); |
// dce6_shutdown(dd->dce); |
852 |
854 |
// |
// |
853 |
855 |
//err_ba_unmap: |
//err_ba_unmap: |
|
... |
... |
static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id) |
856 |
858 |
//err_ba_shutdown: |
//err_ba_shutdown: |
857 |
859 |
// ba_shutdown(dev); |
// ba_shutdown(dev); |
858 |
860 |
// |
// |
859 |
|
//err_release_firmware: |
|
860 |
|
// ucode_release(dev); |
|
861 |
|
// |
|
862 |
|
//err_free_irq: |
|
863 |
|
// free_irq(dev->irq, (void*)dev); |
|
864 |
|
// |
|
865 |
|
//err_vram_mng_destroy: |
|
866 |
|
// rng_mng_destroy(&dd->vram.mng); |
|
|
861 |
|
err_release_firmware: |
|
862 |
|
ucode_release(dev); |
|
863 |
|
|
|
864 |
|
err_free_irq: |
|
865 |
|
free_irq(dev->irq, (void*)dev); |
|
866 |
|
|
|
867 |
|
err_vram_mng_destroy: |
|
868 |
|
rng_mng_destroy(&dd->vram.mng); |
867 |
869 |
|
|
868 |
870 |
err_dce_free: |
err_dce_free: |
869 |
871 |
kfree(dd->dce); |
kfree(dd->dce); |
|
... |
... |
static void __devexit remove(struct pci_dev *dev) |
906 |
908 |
//cdev_del(&dd->evergreen_cdev); |
//cdev_del(&dd->evergreen_cdev); |
907 |
909 |
|
|
908 |
910 |
//pci_clear_master(dev); |
//pci_clear_master(dev); |
909 |
|
//cp_stop(dev); |
|
910 |
|
//ih_stop(dev); |
|
|
911 |
|
cps_engines_stop(dev); |
|
912 |
|
ih_stop(dev); |
911 |
913 |
//dce6_shutdown(dd->dce); |
//dce6_shutdown(dd->dce); |
912 |
914 |
kfree(dd->dce); |
kfree(dd->dce); |
913 |
|
//free_irq(dev->irq, (void*)dev); |
|
|
915 |
|
free_irq(dev->irq, (void*)dev); |
914 |
916 |
|
|
915 |
917 |
//ba_unmap(dev); |
//ba_unmap(dev); |
916 |
918 |
|
|
|
... |
... |
static void __devexit remove(struct pci_dev *dev) |
918 |
920 |
|
|
919 |
921 |
ucode_release(dev); |
ucode_release(dev); |
920 |
922 |
|
|
921 |
|
//rng_mng_destroy(&dd->vram.mng); |
|
|
923 |
|
rng_mng_destroy(&dd->vram.mng); |
922 |
924 |
atb_cleanup(dd->atb); |
atb_cleanup(dd->atb); |
923 |
925 |
kfree(dd->atb); |
kfree(dd->atb); |
924 |
926 |
kfree(adev.rom); |
kfree(adev.rom); |
|
... |
... |
static const struct dev_pm_ops pm_ops; |
938 |
940 |
/* FIXME: hardcoded for now */ |
/* FIXME: hardcoded for now */ |
939 |
941 |
static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = |
static DEFINE_PCI_DEVICE_TABLE(pci_tbl) = |
940 |
942 |
{ |
{ |
941 |
|
{PCI_VENDOR_ID_ATI, 0x254d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TAHITI}, |
|
|
943 |
|
{PCI_VENDOR_ID_ATI, 0x6798, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TAHITI}, |
942 |
944 |
{} |
{} |
943 |
945 |
}; |
}; |
944 |
946 |
MODULE_DEVICE_TABLE(pci, pci_tbl); |
MODULE_DEVICE_TABLE(pci, pci_tbl); |
|
... |
... |
static int __init init(void) |
956 |
958 |
{ |
{ |
957 |
959 |
int r; |
int r; |
958 |
960 |
|
|
959 |
|
class = class_create(THIS_MODULE, "si"); |
|
960 |
|
if (IS_ERR(class)) |
|
961 |
|
return PTR_ERR(class); |
|
|
961 |
|
//class = class_create(THIS_MODULE, "si"); |
|
962 |
|
//if (IS_ERR(class)) |
|
963 |
|
// return PTR_ERR(class); |
962 |
964 |
|
|
963 |
|
r = alloc_chrdev_region(&devt, 0, 1, pci_driver.name); |
|
964 |
|
if (r < 0) { |
|
965 |
|
printk(KERN_ERR "%s:cannot allocate major/minor range\n", |
|
966 |
|
pci_driver.name); |
|
967 |
|
goto class_destroy; |
|
968 |
|
} |
|
969 |
|
|
|
|
965 |
|
//r = alloc_chrdev_region(&devt, 0, 1, pci_driver.name); |
|
966 |
|
//if (r < 0) { |
|
967 |
|
// printk(KERN_ERR "%s:cannot allocate major/minor range\n", |
|
968 |
|
// pci_driver.name); |
|
969 |
|
// goto class_destroy; |
|
970 |
|
//} |
|
971 |
|
// |
970 |
972 |
r = pci_register_driver(&pci_driver); |
r = pci_register_driver(&pci_driver); |
971 |
973 |
if (r != 0) { |
if (r != 0) { |
972 |
974 |
printk(KERN_ERR "%s:cannot register PCI driver\n", |
printk(KERN_ERR "%s:cannot register PCI driver\n", |
|
... |
... |
static int __init init(void) |
976 |
978 |
return 0; |
return 0; |
977 |
979 |
|
|
978 |
980 |
chrdev_region_unregister: |
chrdev_region_unregister: |
979 |
|
unregister_chrdev_region(devt, 1); |
|
980 |
|
|
|
981 |
|
class_destroy: |
|
982 |
|
class_destroy(class); |
|
|
981 |
|
// unregister_chrdev_region(devt, 1); |
|
982 |
|
// |
|
983 |
|
//class_destroy: |
|
984 |
|
// class_destroy(class); |
983 |
985 |
return r; |
return r; |
984 |
986 |
} |
} |
985 |
987 |
|
|
986 |
988 |
static void __exit cleanup(void) |
static void __exit cleanup(void) |
987 |
989 |
{ |
{ |
988 |
990 |
pci_unregister_driver(&pci_driver); |
pci_unregister_driver(&pci_driver); |
989 |
|
unregister_chrdev_region(devt, 1); |
|
990 |
|
class_destroy(class); |
|
|
991 |
|
// unregister_chrdev_region(devt, 1); |
|
992 |
|
// class_destroy(class); |
991 |
993 |
} |
} |
992 |
994 |
|
|
993 |
995 |
module_init(init); |
module_init(init); |
File drivers/gpu/alga/amd/si/ih.c changed (mode: 100644) (index e0026d9..716f9ff) |
10 |
10 |
#include <alga/rng_mng.h> |
#include <alga/rng_mng.h> |
11 |
11 |
#include <alga/timing.h> |
#include <alga/timing.h> |
12 |
12 |
#include <alga/pixel_fmts.h> |
#include <alga/pixel_fmts.h> |
13 |
|
#include <alga/amd/dce4/dce4.h> |
|
|
13 |
|
#include <alga/amd/dce6/dce6.h> |
14 |
14 |
|
|
15 |
15 |
#include "regs.h" |
#include "regs.h" |
16 |
16 |
|
|
|
20 |
20 |
#include "cp.h" |
#include "cp.h" |
21 |
21 |
#include "drv.h" |
#include "drv.h" |
22 |
22 |
|
|
23 |
|
void ih_start(struct pci_dev *dev) |
|
24 |
|
{ |
|
25 |
|
u32 ih_ctl; |
|
26 |
|
u32 ih_rb_ctl; |
|
27 |
|
|
|
28 |
|
ih_ctl = rr32(dev, IH_CTL); |
|
29 |
|
ih_rb_ctl = rr32(dev, IH_RB_CTL); |
|
30 |
|
|
|
31 |
|
ih_ctl |= ENA_INTR; |
|
32 |
|
ih_rb_ctl |= IH_RB_ENA; |
|
33 |
|
wr32(dev, ih_ctl, IH_CTL); |
|
34 |
|
wr32(dev, ih_rb_ctl, IH_RB_CTL); |
|
35 |
|
} |
|
|
23 |
|
//void ih_start(struct pci_dev *dev) |
|
24 |
|
//{ |
|
25 |
|
// u32 ih_ctl; |
|
26 |
|
// u32 ih_rb_ctl; |
|
27 |
|
// |
|
28 |
|
// ih_ctl = rr32(dev, IH_CTL); |
|
29 |
|
// ih_rb_ctl = rr32(dev, IH_RB_CTL); |
|
30 |
|
// |
|
31 |
|
// ih_ctl |= ENA_INTR; |
|
32 |
|
// ih_rb_ctl |= IH_RB_ENA; |
|
33 |
|
// wr32(dev, ih_ctl, IH_CTL); |
|
34 |
|
// wr32(dev, ih_rb_ctl, IH_RB_CTL); |
|
35 |
|
//} |
36 |
36 |
|
|
37 |
37 |
void ih_stop(struct pci_dev *dev) |
void ih_stop(struct pci_dev *dev) |
38 |
38 |
{ |
{ |
|
... |
... |
void ih_stop(struct pci_dev *dev) |
52 |
52 |
|
|
53 |
53 |
/* ih ring size is 2^IH_RING_LOG2_DWS(=14) dwords or 4096 vectors of 16 bytes */ |
/* ih ring size is 2^IH_RING_LOG2_DWS(=14) dwords or 4096 vectors of 16 bytes */ |
54 |
54 |
#define WB_IH_WPTR_OF 2048 |
#define WB_IH_WPTR_OF 2048 |
55 |
|
void ih_init(struct pci_dev *dev) |
|
56 |
|
{ |
|
57 |
|
struct dev_drv_data *dd; |
|
58 |
|
u32 intr_ctl; |
|
59 |
|
u32 ih_rb_ctl; |
|
60 |
|
u32 ih_ctl; |
|
61 |
|
|
|
62 |
|
dd = pci_get_drvdata(dev); |
|
63 |
|
|
|
64 |
|
/* |
|
65 |
|
* setup interrupt control |
|
66 |
|
* set dummy read address to ring address |
|
67 |
|
* 256 bytes block index |
|
68 |
|
*/ |
|
69 |
|
wr32(dev, dd->ba.ih_ring_map->gpu_addr >> 8, INTR_CTL2); |
|
70 |
|
|
|
71 |
|
intr_ctl = rr32(dev, INTR_CTL); |
|
72 |
|
/* |
|
73 |
|
* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled |
|
74 |
|
* without msi |
|
75 |
|
* IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_ENA |
|
76 |
|
*/ |
|
77 |
|
intr_ctl &= ~IH_DUMMY_RD_OVERRIDE; /* GPU should disable dummy read */ |
|
78 |
|
|
|
79 |
|
/* IH_REQ_NONSNOOP_ENA=1 if ring is in non-cacheable mem, e.g. vram */ |
|
80 |
|
intr_ctl &= ~IH_REQ_NONSNOOP_ENA; /* we are in bus aperture */ |
|
81 |
|
wr32(dev, intr_ctl, INTR_CTL); |
|
82 |
|
|
|
83 |
|
/* 256 bytes block index */ |
|
84 |
|
wr32(dev, dd->ba.ih_ring_map->gpu_addr >> 8, IH_RB_BASE); |
|
85 |
|
|
|
86 |
|
ih_rb_ctl = (IH_WPTR_OVERFLOW_ENA | IH_WPTR_OVERFLOW_CLR |
|
87 |
|
| SET(IH_IB_LOG2_DWS, IH_RING_LOG2_DWS) |
|
88 |
|
| IH_WPTR_WRITEBACK_ENA); |
|
89 |
|
|
|
90 |
|
wr32(dev, (dd->ba.wb_map->gpu_addr + WB_IH_WPTR_OF) & 0xfffffffc, |
|
91 |
|
IH_RB_WPTR_ADDR_LO); |
|
92 |
|
wr32(dev, upper_32_bits(dd->ba.wb_map->gpu_addr + WB_IH_WPTR_OF) & 0xff, |
|
93 |
|
IH_RB_WPTR_ADDR_HI); |
|
94 |
|
wr32(dev, ih_rb_ctl, IH_RB_CTL); |
|
95 |
|
|
|
96 |
|
wr32(dev, 0, IH_RB_RPTR); |
|
97 |
|
wr32(dev, 0, IH_RB_WPTR); |
|
98 |
|
|
|
99 |
|
/* default settings for IH_CTL (disabled at first) */ |
|
100 |
|
ih_ctl = SET(MC_WR_REQ_CREDIT, 0x10) | SET(MC_WR_CLEAN_CNT, 0x10) |
|
101 |
|
| RPTR_REARM; |
|
102 |
|
wr32(dev, ih_ctl, IH_CTL); |
|
103 |
|
|
|
104 |
|
dd->ih.rp = 0; |
|
105 |
|
spin_lock_init(&dd->ih.lock); |
|
106 |
|
}; |
|
|
55 |
|
//void ih_init(struct pci_dev *dev) |
|
56 |
|
//{ |
|
57 |
|
// struct dev_drv_data *dd; |
|
58 |
|
// u32 intr_ctl; |
|
59 |
|
// u32 ih_rb_ctl; |
|
60 |
|
// u32 ih_ctl; |
|
61 |
|
// |
|
62 |
|
// dd = pci_get_drvdata(dev); |
|
63 |
|
// |
|
64 |
|
// /* |
|
65 |
|
// * setup interrupt control |
|
66 |
|
// * set dummy read address to ring address |
|
67 |
|
// * 256 bytes block index |
|
68 |
|
// */ |
|
69 |
|
// wr32(dev, dd->ba.ih_ring_map->gpu_addr >> 8, INTR_CTL2); |
|
70 |
|
// |
|
71 |
|
// intr_ctl = rr32(dev, INTR_CTL); |
|
72 |
|
// /* |
|
73 |
|
// * IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled |
|
74 |
|
// * without msi |
|
75 |
|
// * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_ENA |
|
76 |
|
// */ |
|
77 |
|
// intr_ctl &= ~IH_DUMMY_RD_OVERRIDE; /* GPU should disable dummy read */ |
|
78 |
|
// |
|
79 |
|
// /* IH_REQ_NONSNOOP_ENA=1 if ring is in non-cacheable mem, e.g. vram */ |
|
80 |
|
// intr_ctl &= ~IH_REQ_NONSNOOP_ENA; /* we are in bus aperture */ |
|
81 |
|
// wr32(dev, intr_ctl, INTR_CTL); |
|
82 |
|
// |
|
83 |
|
// /* 256 bytes block index */ |
|
84 |
|
// wr32(dev, dd->ba.ih_ring_map->gpu_addr >> 8, IH_RB_BASE); |
|
85 |
|
// |
|
86 |
|
// ih_rb_ctl = (IH_WPTR_OVERFLOW_ENA | IH_WPTR_OVERFLOW_CLR |
|
87 |
|
// | SET(IH_IB_LOG2_DWS, IH_RING_LOG2_DWS) |
|
88 |
|
// | IH_WPTR_WRITEBACK_ENA); |
|
89 |
|
// |
|
90 |
|
// wr32(dev, (dd->ba.wb_map->gpu_addr + WB_IH_WPTR_OF) & 0xfffffffc, |
|
91 |
|
// IH_RB_WPTR_ADDR_LO); |
|
92 |
|
// wr32(dev, upper_32_bits(dd->ba.wb_map->gpu_addr + WB_IH_WPTR_OF) & 0xff, |
|
93 |
|
// IH_RB_WPTR_ADDR_HI); |
|
94 |
|
// wr32(dev, ih_rb_ctl, IH_RB_CTL); |
|
95 |
|
// |
|
96 |
|
// wr32(dev, 0, IH_RB_RPTR); |
|
97 |
|
// wr32(dev, 0, IH_RB_WPTR); |
|
98 |
|
// |
|
99 |
|
// /* default settings for IH_CTL (disabled at first) */ |
|
100 |
|
// ih_ctl = SET(MC_WR_REQ_CREDIT, 0x10) | SET(MC_WR_CLEAN_CNT, 0x10) |
|
101 |
|
// | RPTR_REARM; |
|
102 |
|
// wr32(dev, ih_ctl, IH_CTL); |
|
103 |
|
// |
|
104 |
|
// dd->ih.rp = 0; |
|
105 |
|
// spin_lock_init(&dd->ih.lock); |
|
106 |
|
//}; |
107 |
107 |
|
|
108 |
108 |
#define VECTOR_SZ 16 |
#define VECTOR_SZ 16 |
109 |
109 |
#define VECTOR_ID_D0 1 |
#define VECTOR_ID_D0 1 |
|
... |
... |
void ih_init(struct pci_dev *dev) |
115 |
115 |
#define Dx_VBLANK 0 |
#define Dx_VBLANK 0 |
116 |
116 |
#define VECTOR_ID_HPD 42 |
#define VECTOR_ID_HPD 42 |
117 |
117 |
|
|
|
118 |
|
/* |
|
119 |
|
* Each ring entry is 128 bits: |
|
120 |
|
* [7:0] - interrupt source id |
|
121 |
|
* [31:8] - reserved |
|
122 |
|
* [59:32] - interrupt source data |
|
123 |
|
* [63:60] - reserved |
|
124 |
|
* [71:64] - RINGID |
|
125 |
|
* [79:72] - VMID |
|
126 |
|
* [127:80] - reserved |
|
127 |
|
*/ |
118 |
128 |
static void vector(struct pci_dev *dev, u32 id, u32 data, bool *irq_thd) |
static void vector(struct pci_dev *dev, u32 id, u32 data, bool *irq_thd) |
119 |
129 |
{ |
{ |
120 |
130 |
struct dev_drv_data *dd; |
struct dev_drv_data *dd; |
|
... |
... |
static void vector(struct pci_dev *dev, u32 id, u32 data, bool *irq_thd) |
122 |
132 |
|
|
123 |
133 |
switch (id) { |
switch (id) { |
124 |
134 |
case VECTOR_ID_HPD: |
case VECTOR_ID_HPD: |
125 |
|
dce4_hpd_irq(dd->dce, data); |
|
|
135 |
|
dce6_hpd_irq(dd->dce, data); |
126 |
136 |
*irq_thd = true; |
*irq_thd = true; |
127 |
137 |
break; |
break; |
128 |
138 |
case VECTOR_ID_D0: |
case VECTOR_ID_D0: |
|
... |
... |
static void vector(struct pci_dev *dev, u32 id, u32 data, bool *irq_thd) |
132 |
142 |
case VECTOR_ID_D4: |
case VECTOR_ID_D4: |
133 |
143 |
case VECTOR_ID_D5: |
case VECTOR_ID_D5: |
134 |
144 |
if (data == Dx_VBLANK) {/* only page flipping in vblank */ |
if (data == Dx_VBLANK) {/* only page flipping in vblank */ |
135 |
|
dce4_pf_irq(dd->dce, id - 1); |
|
|
145 |
|
dce6_pf_irq(dd->dce, id - 1); |
136 |
146 |
*irq_thd = true; |
*irq_thd = true; |
137 |
147 |
} |
} |
138 |
148 |
break; |
break; |
|
... |
... |
bool ih_parse(struct pci_dev *dev) |
190 |
200 |
if (rp == wp) |
if (rp == wp) |
191 |
201 |
break; |
break; |
192 |
202 |
|
|
193 |
|
dce4_irqs_ack(dd->dce); /* must ack dce irqs ourself... */ |
|
|
203 |
|
dce6_irqs_ack(dd->dce); /* must ack dce irqs ourself... */ |
194 |
204 |
|
|
195 |
205 |
do { |
do { |
196 |
206 |
u32 id; |
u32 id; |
File drivers/gpu/alga/amd/si/ucode.c changed (mode: 100644) (index 0b67076..06e0f32) |
3 |
3 |
Protected by GNU Affero GPL v3 with some exceptions. |
Protected by GNU Affero GPL v3 with some exceptions. |
4 |
4 |
See README at root of alga tree. |
See README at root of alga tree. |
5 |
5 |
*/ |
*/ |
|
6 |
|
#include <linux/module.h> |
6 |
7 |
#include <linux/pci.h> |
#include <linux/pci.h> |
7 |
8 |
#include <linux/firmware.h> |
#include <linux/firmware.h> |
8 |
9 |
#include <linux/cdev.h> |
#include <linux/cdev.h> |
|
10 |
11 |
#include <alga/rng_mng.h> |
#include <alga/rng_mng.h> |
11 |
12 |
#include <alga/timing.h> |
#include <alga/timing.h> |
12 |
13 |
#include <alga/pixel_fmts.h> |
#include <alga/pixel_fmts.h> |
13 |
|
#include <alga/amd/dce4/dce4.h> |
|
|
14 |
|
#include <alga/amd/dce6/dce6.h> |
14 |
15 |
|
|
15 |
16 |
#include "regs.h" |
#include "regs.h" |
16 |
17 |
|
|
|
... |
... |
int ucode_load(struct pci_dev *dev) |
155 |
156 |
dev_err(&dev->dev, "unable to load mc ucode:%s\n", fw_name); |
dev_err(&dev->dev, "unable to load mc ucode:%s\n", fw_name); |
156 |
157 |
goto out; |
goto out; |
157 |
158 |
} |
} |
158 |
|
if (dd->ucode.rlc->size != mc_req_sz) { |
|
|
159 |
|
if (dd->ucode.mc->size != mc_req_sz) { |
159 |
160 |
dev_err(&dev->dev, "bogus length %zu in mc firmware \"%s\"\n", |
dev_err(&dev->dev, "bogus length %zu in mc firmware \"%s\"\n", |
160 |
161 |
dd->ucode.mc->size, fw_name); |
dd->ucode.mc->size, fw_name); |
161 |
162 |
err = -EINVAL; |
err = -EINVAL; |
|
... |
... |
out: |
177 |
178 |
return err; |
return err; |
178 |
179 |
} |
} |
179 |
180 |
|
|
180 |
|
void ucode_rlc_program(struct pci_dev *dev) |
|
181 |
|
{ |
|
182 |
|
u32 i; |
|
183 |
|
const __be32 *fw_data; |
|
184 |
|
struct dev_drv_data *dd; |
|
185 |
|
|
|
186 |
|
dd = pci_get_drvdata(dev); |
|
187 |
|
|
|
188 |
|
wr32(dev, 0, RLC_CTL); |
|
189 |
|
|
|
190 |
|
wr32(dev, 0, RLC_HB_BASE); |
|
191 |
|
wr32(dev, 0, RLC_HB_CTL); |
|
192 |
|
wr32(dev, 0, RLC_HB_RPTR); |
|
193 |
|
wr32(dev, 0, RLC_HB_WPTR); |
|
194 |
|
wr32(dev, 0, RLC_HB_WPTR_LSB_ADDR); |
|
195 |
|
wr32(dev, 0, RLC_HB_WPTR_MSB_ADDR); |
|
196 |
|
wr32(dev, 0, RLC_MC_CTL); |
|
197 |
|
wr32(dev, 0, RLC_UCODE_CTL); |
|
198 |
|
|
|
199 |
|
fw_data = (const __be32 *)dd->ucode.rlc->data; |
|
200 |
|
for (i = 0; i < RLC_DWS; ++i) { |
|
201 |
|
wr32(dev, i, RLC_UCODE_ADDR); |
|
202 |
|
wr32(dev, be32_to_cpup(fw_data++), RLC_UCODE_DATA); |
|
203 |
|
} |
|
204 |
|
wr32(dev, 0, RLC_UCODE_ADDR); |
|
205 |
|
|
|
206 |
|
wr32(dev, RLC_ENA, RLC_CTL); |
|
207 |
|
} |
|
208 |
|
|
|
209 |
|
void ucode_cp_program(struct pci_dev *dev) |
|
210 |
|
{ |
|
211 |
|
struct dev_drv_data *dd; |
|
212 |
|
u32 cp_rb_ctl; |
|
213 |
|
const __be32 *fw_data; |
|
214 |
|
int i; |
|
215 |
|
|
|
216 |
|
dd = pci_get_drvdata(dev); |
|
217 |
|
|
|
218 |
|
/* XXX: rb size values for ucode programming */ |
|
219 |
|
cp_rb_ctl = RB_NO_UPDATE | SET(RB_BLK_LOG2_QWS, 15) |
|
220 |
|
| SET(RB_BUF_LOG2_QWS, 3); |
|
221 |
|
#ifdef __BIG_ENDIAN |
|
222 |
|
cp_rb_ctl |= BUF_SWAP_32BIT; |
|
223 |
|
#endif |
|
224 |
|
wr32(dev, cp_rb_ctl, CP_RB_CTL); |
|
225 |
|
|
|
226 |
|
fw_data = (const __be32 *)dd->ucode.pfp->data; |
|
227 |
|
wr32(dev, 0,CP_PFP_UCODE_ADDR); |
|
228 |
|
for (i = 0; i < PFP_DWS; ++i) |
|
229 |
|
wr32(dev, be32_to_cpup(fw_data++), CP_PFP_UCODE_DATA); |
|
230 |
|
wr32(dev, 0, CP_PFP_UCODE_ADDR); |
|
231 |
|
|
|
232 |
|
fw_data = (const __be32 *)dd->ucode.me->data; |
|
233 |
|
wr32(dev, 0, CP_ME_RAM_WADDR); |
|
234 |
|
for (i = 0; i < ME_DWS; ++i) |
|
235 |
|
wr32(dev, be32_to_cpup(fw_data++), CP_ME_RAM_DATA); |
|
236 |
|
wr32(dev, 0, CP_PFP_UCODE_ADDR); |
|
237 |
|
wr32(dev, 0, CP_ME_RAM_WADDR); |
|
238 |
|
wr32(dev, 0, CP_ME_RAM_RADDR); |
|
239 |
|
} |
|
|
181 |
|
//void ucode_rlc_program(struct pci_dev *dev) |
|
182 |
|
//{ |
|
183 |
|
// u32 i; |
|
184 |
|
// const __be32 *fw_data; |
|
185 |
|
// struct dev_drv_data *dd; |
|
186 |
|
// |
|
187 |
|
// dd = pci_get_drvdata(dev); |
|
188 |
|
// |
|
189 |
|
// wr32(dev, 0, RLC_CTL); |
|
190 |
|
// |
|
191 |
|
// wr32(dev, 0, RLC_HB_BASE); |
|
192 |
|
// wr32(dev, 0, RLC_HB_CTL); |
|
193 |
|
// wr32(dev, 0, RLC_HB_RPTR); |
|
194 |
|
// wr32(dev, 0, RLC_HB_WPTR); |
|
195 |
|
// wr32(dev, 0, RLC_HB_WPTR_LSB_ADDR); |
|
196 |
|
// wr32(dev, 0, RLC_HB_WPTR_MSB_ADDR); |
|
197 |
|
// wr32(dev, 0, RLC_MC_CTL); |
|
198 |
|
// wr32(dev, 0, RLC_UCODE_CTL); |
|
199 |
|
// |
|
200 |
|
// fw_data = (const __be32 *)dd->ucode.rlc->data; |
|
201 |
|
// for (i = 0; i < RLC_DWS; ++i) { |
|
202 |
|
// wr32(dev, i, RLC_UCODE_ADDR); |
|
203 |
|
// wr32(dev, be32_to_cpup(fw_data++), RLC_UCODE_DATA); |
|
204 |
|
// } |
|
205 |
|
// wr32(dev, 0, RLC_UCODE_ADDR); |
|
206 |
|
// |
|
207 |
|
// wr32(dev, RLC_ENA, RLC_CTL); |
|
208 |
|
//} |
|
209 |
|
|
|
210 |
|
//void ucode_cp_program(struct pci_dev *dev) |
|
211 |
|
//{ |
|
212 |
|
// struct dev_drv_data *dd; |
|
213 |
|
// u32 cp_rb_ctl; |
|
214 |
|
// const __be32 *fw_data; |
|
215 |
|
// int i; |
|
216 |
|
// |
|
217 |
|
// dd = pci_get_drvdata(dev); |
|
218 |
|
// |
|
219 |
|
// /* XXX: rb size values for ucode programming */ |
|
220 |
|
// cp_rb_ctl = RB_NO_UPDATE | SET(RB_BLK_LOG2_QWS, 15) |
|
221 |
|
// | SET(RB_BUF_LOG2_QWS, 3); |
|
222 |
|
//#ifdef __BIG_ENDIAN |
|
223 |
|
// cp_rb_ctl |= BUF_SWAP_32BIT; |
|
224 |
|
//#endif |
|
225 |
|
// wr32(dev, cp_rb_ctl, CP_RB_CTL); |
|
226 |
|
// |
|
227 |
|
// fw_data = (const __be32 *)dd->ucode.pfp->data; |
|
228 |
|
// wr32(dev, 0,CP_PFP_UCODE_ADDR); |
|
229 |
|
// for (i = 0; i < PFP_DWS; ++i) |
|
230 |
|
// wr32(dev, be32_to_cpup(fw_data++), CP_PFP_UCODE_DATA); |
|
231 |
|
// wr32(dev, 0, CP_PFP_UCODE_ADDR); |
|
232 |
|
// |
|
233 |
|
// fw_data = (const __be32 *)dd->ucode.me->data; |
|
234 |
|
// wr32(dev, 0, CP_ME_RAM_WADDR); |
|
235 |
|
// for (i = 0; i < ME_DWS; ++i) |
|
236 |
|
// wr32(dev, be32_to_cpup(fw_data++), CP_ME_RAM_DATA); |
|
237 |
|
// wr32(dev, 0, CP_PFP_UCODE_ADDR); |
|
238 |
|
// wr32(dev, 0, CP_ME_RAM_WADDR); |
|
239 |
|
// wr32(dev, 0, CP_ME_RAM_RADDR); |
|
240 |
|
//} |
240 |
241 |
|
|
241 |
242 |
#define TAHITI_IO_MC_REGS_SZ 36 |
#define TAHITI_IO_MC_REGS_SZ 36 |
242 |
243 |
|
|
|
... |
... |
static const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SZ][2] = { |
357 |
358 |
{0x0000009f, 0x00a37400} |
{0x0000009f, 0x00a37400} |
358 |
359 |
}; |
}; |
359 |
360 |
|
|
360 |
|
void ucode_mc_program(struct pci_dev *dev) |
|
361 |
|
{ |
|
362 |
|
const __be32 *fw_data; |
|
363 |
|
u32 running; |
|
364 |
|
u32 blackout; |
|
365 |
|
u32 *io_mc_regs; |
|
366 |
|
unsigned i; |
|
367 |
|
unsigned ucode_dws; |
|
368 |
|
unsigned regs_sz; |
|
369 |
|
struct dev_drv_data *dd; |
|
370 |
|
|
|
371 |
|
dd = pci_get_drvdata(dev); |
|
372 |
|
|
|
373 |
|
switch (dd->family) { |
|
374 |
|
case CHIP_TAHITI: |
|
375 |
|
io_mc_regs = (u32 *)&tahiti_io_mc_regs[0][0]; |
|
376 |
|
regs_sz = ARRAY_SIZE(tahiti_io_mc_regs) / 2; |
|
377 |
|
ucode_dws = MC_DWS; |
|
378 |
|
break; |
|
379 |
|
case CHIP_PITCAIRN: |
|
380 |
|
io_mc_regs = (u32 *)&pitcairn_io_mc_regs[0][0]; |
|
381 |
|
regs_sz = ARRAY_SIZE(pitcairn_io_mc_regs) / 2; |
|
382 |
|
ucode_dws = MC_DWS; |
|
383 |
|
break; |
|
384 |
|
case CHIP_VERDE: |
|
385 |
|
io_mc_regs = (u32 *)&verde_io_mc_regs[0][0]; |
|
386 |
|
regs_sz = ARRAY_SIZE(verde_io_mc_regs) / 2; |
|
387 |
|
ucode_dws = MC_DWS; |
|
388 |
|
break; |
|
389 |
|
} |
|
390 |
|
|
|
391 |
|
running = rr32(dev, MC_SEQ_SUP_CTL) & RUN_MASK; |
|
392 |
|
blackout = 0; |
|
393 |
|
|
|
394 |
|
if (running == 0) { |
|
395 |
|
/* this is a reminder */ |
|
396 |
|
if (running) { |
|
397 |
|
blackout = rr32(dev, MC_SHARED_BLACKOUT_CTL); |
|
398 |
|
wr32(dev, blackout | 1, MC_SHARED_BLACKOUT_CTL); |
|
399 |
|
} |
|
400 |
|
|
|
401 |
|
/* reset the engine and set to writable */ |
|
402 |
|
wr32(dev, 0x00000008, MC_SEQ_SUP_CTL); |
|
403 |
|
wr32(dev, 0x00000010, MC_SEQ_SUP_CTL); |
|
404 |
|
|
|
405 |
|
/* load mc io regs */ |
|
406 |
|
for (i = 0; i < regs_sz; ++i) { |
|
407 |
|
wr32(dev, io_mc_regs[i * 2], MC_SEQ_IO_DBG_IDX); |
|
408 |
|
wr32(dev, io_mc_regs[i * 2 + 1], MC_SEQ_IO_DBG_DATA); |
|
409 |
|
} |
|
410 |
|
/* load the mc ucode */ |
|
411 |
|
fw_data = (const __be32 *)dd->ucode.mc->data; |
|
412 |
|
for (i = 0; i < ucode_dws; ++i) |
|
413 |
|
wr32(dev, be32_to_cpup(fw_data++), MC_SEQ_SUP_PGM); |
|
414 |
|
|
|
415 |
|
/* put the engine back into the active state */ |
|
416 |
|
wr32(dev, 0x00000008, MC_SEQ_SUP_CTL); |
|
417 |
|
wr32(dev, 0x00000004, MC_SEQ_SUP_CTL); |
|
418 |
|
wr32(dev, 0x00000001, MC_SEQ_SUP_CTL); |
|
419 |
|
|
|
420 |
|
/* wait for memory training to complete (100 ms timeout) */ |
|
421 |
|
for (i = 0; i < 100000; ++i) {/* memory pattern D0 */ |
|
422 |
|
if (rr32(dev, MC_SEQ_TRAIN_WAKEUP_CTL) & TRAIN_DONE_D0) |
|
423 |
|
break; |
|
424 |
|
udelay(1); |
|
425 |
|
} |
|
426 |
|
for (i = 0; i < 10000; ++i) {/* memory pattern D1 */ |
|
427 |
|
if (rr32(dev, MC_SEQ_TRAIN_WAKEUP_CTL) & TRAIN_DONE_D1) |
|
428 |
|
break; |
|
429 |
|
udelay(1); |
|
430 |
|
} |
|
431 |
|
|
|
432 |
|
/* this is a reminder */ |
|
433 |
|
if (running) |
|
434 |
|
wr32(dev, blackout, MC_SHARED_BLACKOUT_CTL); |
|
435 |
|
} |
|
436 |
|
} |
|
|
361 |
|
//void ucode_mc_program(struct pci_dev *dev) |
|
362 |
|
//{ |
|
363 |
|
// const __be32 *fw_data; |
|
364 |
|
// u32 running; |
|
365 |
|
// u32 blackout; |
|
366 |
|
// u32 *io_mc_regs; |
|
367 |
|
// unsigned i; |
|
368 |
|
// unsigned ucode_dws; |
|
369 |
|
// unsigned regs_sz; |
|
370 |
|
// struct dev_drv_data *dd; |
|
371 |
|
// |
|
372 |
|
// dd = pci_get_drvdata(dev); |
|
373 |
|
// |
|
374 |
|
// switch (dd->family) { |
|
375 |
|
// case CHIP_TAHITI: |
|
376 |
|
// io_mc_regs = (u32 *)&tahiti_io_mc_regs[0][0]; |
|
377 |
|
// regs_sz = ARRAY_SIZE(tahiti_io_mc_regs) / 2; |
|
378 |
|
// ucode_dws = MC_DWS; |
|
379 |
|
// break; |
|
380 |
|
// case CHIP_PITCAIRN: |
|
381 |
|
// io_mc_regs = (u32 *)&pitcairn_io_mc_regs[0][0]; |
|
382 |
|
// regs_sz = ARRAY_SIZE(pitcairn_io_mc_regs) / 2; |
|
383 |
|
// ucode_dws = MC_DWS; |
|
384 |
|
// break; |
|
385 |
|
// case CHIP_VERDE: |
|
386 |
|
// io_mc_regs = (u32 *)&verde_io_mc_regs[0][0]; |
|
387 |
|
// regs_sz = ARRAY_SIZE(verde_io_mc_regs) / 2; |
|
388 |
|
// ucode_dws = MC_DWS; |
|
389 |
|
// break; |
|
390 |
|
// } |
|
391 |
|
// |
|
392 |
|
// running = rr32(dev, MC_SEQ_SUP_CTL) & RUN_MASK; |
|
393 |
|
// blackout = 0; |
|
394 |
|
// |
|
395 |
|
// if (running == 0) { |
|
396 |
|
// /* this is a reminder */ |
|
397 |
|
// if (running) { |
|
398 |
|
// blackout = rr32(dev, MC_SHARED_BLACKOUT_CTL); |
|
399 |
|
// wr32(dev, blackout | 1, MC_SHARED_BLACKOUT_CTL); |
|
400 |
|
// } |
|
401 |
|
// |
|
402 |
|
// /* reset the engine and set to writable */ |
|
403 |
|
// wr32(dev, 0x00000008, MC_SEQ_SUP_CTL); |
|
404 |
|
// wr32(dev, 0x00000010, MC_SEQ_SUP_CTL); |
|
405 |
|
// |
|
406 |
|
// /* load mc io regs */ |
|
407 |
|
// for (i = 0; i < regs_sz; ++i) { |
|
408 |
|
// wr32(dev, io_mc_regs[i * 2], MC_SEQ_IO_DBG_IDX); |
|
409 |
|
// wr32(dev, io_mc_regs[i * 2 + 1], MC_SEQ_IO_DBG_DATA); |
|
410 |
|
// } |
|
411 |
|
// /* load the mc ucode */ |
|
412 |
|
// fw_data = (const __be32 *)dd->ucode.mc->data; |
|
413 |
|
// for (i = 0; i < ucode_dws; ++i) |
|
414 |
|
// wr32(dev, be32_to_cpup(fw_data++), MC_SEQ_SUP_PGM); |
|
415 |
|
// |
|
416 |
|
// /* put the engine back into the active state */ |
|
417 |
|
// wr32(dev, 0x00000008, MC_SEQ_SUP_CTL); |
|
418 |
|
// wr32(dev, 0x00000004, MC_SEQ_SUP_CTL); |
|
419 |
|
// wr32(dev, 0x00000001, MC_SEQ_SUP_CTL); |
|
420 |
|
// |
|
421 |
|
// /* wait for memory training to complete (100 ms timeout) */ |
|
422 |
|
// for (i = 0; i < 100000; ++i) {/* memory pattern D0 */ |
|
423 |
|
// if (rr32(dev, MC_SEQ_TRAIN_WAKEUP_CTL) & TRAIN_DONE_D0) |
|
424 |
|
// break; |
|
425 |
|
// udelay(1); |
|
426 |
|
// } |
|
427 |
|
// for (i = 0; i < 10000; ++i) {/* memory pattern D1 */ |
|
428 |
|
// if (rr32(dev, MC_SEQ_TRAIN_WAKEUP_CTL) & TRAIN_DONE_D1) |
|
429 |
|
// break; |
|
430 |
|
// udelay(1); |
|
431 |
|
// } |
|
432 |
|
// |
|
433 |
|
// /* this is a reminder */ |
|
434 |
|
// if (running) |
|
435 |
|
// wr32(dev, blackout, MC_SHARED_BLACKOUT_CTL); |
|
436 |
|
// } |
|
437 |
|
//} |