Merge branch 'topic/oss' into for-linus
[pandora-kernel.git] / drivers / gpu / drm / radeon / rs600.c
1 /*
2  * Copyright 2008 Advanced Micro Devices, Inc.
3  * Copyright 2008 Red Hat Inc.
4  * Copyright 2009 Jerome Glisse.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Dave Airlie
25  *          Alex Deucher
26  *          Jerome Glisse
27  */
28 #include "drmP.h"
29 #include "radeon_reg.h"
30 #include "radeon.h"
31
32 /* rs600 depends on : */
33 void r100_hdp_reset(struct radeon_device *rdev);
34 int r100_gui_wait_for_idle(struct radeon_device *rdev);
35 int r300_mc_wait_for_idle(struct radeon_device *rdev);
36 void r420_pipes_init(struct radeon_device *rdev);
37
38 /* This files gather functions specifics to :
39  * rs600
40  *
41  * Some of these functions might be used by newer ASICs.
42  */
43 void rs600_gpu_init(struct radeon_device *rdev);
44 int rs600_mc_wait_for_idle(struct radeon_device *rdev);
45 void rs600_disable_vga(struct radeon_device *rdev);
46
47
48 /*
49  * GART.
50  */
51 void rs600_gart_tlb_flush(struct radeon_device *rdev)
52 {
53         uint32_t tmp;
54
55         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
56         tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
57         WREG32_MC(RS600_MC_PT0_CNTL, tmp);
58
59         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
60         tmp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE;
61         WREG32_MC(RS600_MC_PT0_CNTL, tmp);
62
63         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
64         tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
65         WREG32_MC(RS600_MC_PT0_CNTL, tmp);
66         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
67 }
68
69 int rs600_gart_enable(struct radeon_device *rdev)
70 {
71         uint32_t tmp;
72         int i;
73         int r;
74
75         /* Initialize common gart structure */
76         r = radeon_gart_init(rdev);
77         if (r) {
78                 return r;
79         }
80         rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
81         r = radeon_gart_table_vram_alloc(rdev);
82         if (r) {
83                 return r;
84         }
85         /* FIXME: setup default page */
86         WREG32_MC(RS600_MC_PT0_CNTL,
87                  (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
88                   RS600_EFFECTIVE_L2_QUEUE_SIZE(6)));
89         for (i = 0; i < 19; i++) {
90                 WREG32_MC(RS600_MC_PT0_CLIENT0_CNTL + i,
91                          (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE |
92                           RS600_SYSTEM_ACCESS_MODE_IN_SYS |
93                           RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE |
94                           RS600_EFFECTIVE_L1_CACHE_SIZE(3) |
95                           RS600_ENABLE_FRAGMENT_PROCESSING |
96                           RS600_EFFECTIVE_L1_QUEUE_SIZE(3)));
97         }
98
99         /* System context map to GART space */
100         WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_location);
101         tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
102         WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, tmp);
103
104         /* enable first context */
105         WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_location);
106         tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1;
107         WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, tmp);
108         WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL,
109                  (RS600_ENABLE_PAGE_TABLE | RS600_PAGE_TABLE_TYPE_FLAT));
110         /* disable all other contexts */
111         for (i = 1; i < 8; i++) {
112                 WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL + i, 0);
113         }
114
115         /* setup the page table */
116         WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
117                  rdev->gart.table_addr);
118         WREG32_MC(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
119
120         /* enable page tables */
121         tmp = RREG32_MC(RS600_MC_PT0_CNTL);
122         WREG32_MC(RS600_MC_PT0_CNTL, (tmp | RS600_ENABLE_PT));
123         tmp = RREG32_MC(RS600_MC_CNTL1);
124         WREG32_MC(RS600_MC_CNTL1, (tmp | RS600_ENABLE_PAGE_TABLES));
125         rs600_gart_tlb_flush(rdev);
126         rdev->gart.ready = true;
127         return 0;
128 }
129
130 void rs600_gart_disable(struct radeon_device *rdev)
131 {
132         uint32_t tmp;
133
134         /* FIXME: disable out of gart access */
135         WREG32_MC(RS600_MC_PT0_CNTL, 0);
136         tmp = RREG32_MC(RS600_MC_CNTL1);
137         tmp &= ~RS600_ENABLE_PAGE_TABLES;
138         WREG32_MC(RS600_MC_CNTL1, tmp);
139         radeon_object_kunmap(rdev->gart.table.vram.robj);
140         radeon_object_unpin(rdev->gart.table.vram.robj);
141 }
142
143 #define R600_PTE_VALID     (1 << 0)
144 #define R600_PTE_SYSTEM    (1 << 1)
145 #define R600_PTE_SNOOPED   (1 << 2)
146 #define R600_PTE_READABLE  (1 << 5)
147 #define R600_PTE_WRITEABLE (1 << 6)
148
149 int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr)
150 {
151         void __iomem *ptr = (void *)rdev->gart.table.vram.ptr;
152
153         if (i < 0 || i > rdev->gart.num_gpu_pages) {
154                 return -EINVAL;
155         }
156         addr = addr & 0xFFFFFFFFFFFFF000ULL;
157         addr |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
158         addr |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
159         writeq(addr, ((void __iomem *)ptr) + (i * 8));
160         return 0;
161 }
162
163
164 /*
165  * MC.
166  */
167 void rs600_mc_disable_clients(struct radeon_device *rdev)
168 {
169         unsigned tmp;
170
171         if (r100_gui_wait_for_idle(rdev)) {
172                 printk(KERN_WARNING "Failed to wait GUI idle while "
173                        "programming pipes. Bad things might happen.\n");
174         }
175
176         tmp = RREG32(AVIVO_D1VGA_CONTROL);
177         WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
178         tmp = RREG32(AVIVO_D2VGA_CONTROL);
179         WREG32(AVIVO_D2VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE);
180
181         tmp = RREG32(AVIVO_D1CRTC_CONTROL);
182         WREG32(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
183         tmp = RREG32(AVIVO_D2CRTC_CONTROL);
184         WREG32(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN);
185
186         /* make sure all previous write got through */
187         tmp = RREG32(AVIVO_D2CRTC_CONTROL);
188
189         mdelay(1);
190 }
191
192 int rs600_mc_init(struct radeon_device *rdev)
193 {
194         uint32_t tmp;
195         int r;
196
197         if (r100_debugfs_rbbm_init(rdev)) {
198                 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
199         }
200
201         rs600_gpu_init(rdev);
202         rs600_gart_disable(rdev);
203
204         /* Setup GPU memory space */
205         rdev->mc.vram_location = 0xFFFFFFFFUL;
206         rdev->mc.gtt_location = 0xFFFFFFFFUL;
207         r = radeon_mc_setup(rdev);
208         if (r) {
209                 return r;
210         }
211
212         /* Program GPU memory space */
213         /* Enable bus master */
214         tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
215         WREG32(RADEON_BUS_CNTL, tmp);
216         /* FIXME: What does AGP means for such chipset ? */
217         WREG32_MC(RS600_MC_AGP_LOCATION, 0x0FFFFFFF);
218         /* FIXME: are this AGP reg in indirect MC range ? */
219         WREG32_MC(RS600_MC_AGP_BASE, 0);
220         WREG32_MC(RS600_MC_AGP_BASE_2, 0);
221         rs600_mc_disable_clients(rdev);
222         if (rs600_mc_wait_for_idle(rdev)) {
223                 printk(KERN_WARNING "Failed to wait MC idle while "
224                        "programming pipes. Bad things might happen.\n");
225         }
226         tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
227         tmp = REG_SET(RS600_MC_FB_TOP, tmp >> 16);
228         tmp |= REG_SET(RS600_MC_FB_START, rdev->mc.vram_location >> 16);
229         WREG32_MC(RS600_MC_FB_LOCATION, tmp);
230         WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
231         return 0;
232 }
233
234 void rs600_mc_fini(struct radeon_device *rdev)
235 {
236         rs600_gart_disable(rdev);
237         radeon_gart_table_vram_free(rdev);
238         radeon_gart_fini(rdev);
239 }
240
241
242 /*
243  * Interrupts
244  */
245 int rs600_irq_set(struct radeon_device *rdev)
246 {
247         uint32_t tmp = 0;
248         uint32_t mode_int = 0;
249
250         if (rdev->irq.sw_int) {
251                 tmp |= RADEON_SW_INT_ENABLE;
252         }
253         if (rdev->irq.crtc_vblank_int[0]) {
254                 tmp |= AVIVO_DISPLAY_INT_STATUS;
255                 mode_int |= AVIVO_D1MODE_INT_MASK;
256         }
257         if (rdev->irq.crtc_vblank_int[1]) {
258                 tmp |= AVIVO_DISPLAY_INT_STATUS;
259                 mode_int |= AVIVO_D2MODE_INT_MASK;
260         }
261         WREG32(RADEON_GEN_INT_CNTL, tmp);
262         WREG32(AVIVO_DxMODE_INT_MASK, mode_int);
263         return 0;
264 }
265
266 static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int)
267 {
268         uint32_t irqs = RREG32(RADEON_GEN_INT_STATUS);
269         uint32_t irq_mask = RADEON_SW_INT_TEST;
270
271         if (irqs & AVIVO_DISPLAY_INT_STATUS) {
272                 *r500_disp_int = RREG32(AVIVO_DISP_INTERRUPT_STATUS);
273                 if (*r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) {
274                         WREG32(AVIVO_D1MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK);
275                 }
276                 if (*r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) {
277                         WREG32(AVIVO_D2MODE_VBLANK_STATUS, AVIVO_VBLANK_ACK);
278                 }
279         } else {
280                 *r500_disp_int = 0;
281         }
282
283         if (irqs) {
284                 WREG32(RADEON_GEN_INT_STATUS, irqs);
285         }
286         return irqs & irq_mask;
287 }
288
289 int rs600_irq_process(struct radeon_device *rdev)
290 {
291         uint32_t status;
292         uint32_t r500_disp_int;
293
294         status = rs600_irq_ack(rdev, &r500_disp_int);
295         if (!status && !r500_disp_int) {
296                 return IRQ_NONE;
297         }
298         while (status || r500_disp_int) {
299                 /* SW interrupt */
300                 if (status & RADEON_SW_INT_TEST) {
301                         radeon_fence_process(rdev);
302                 }
303                 /* Vertical blank interrupts */
304                 if (r500_disp_int & AVIVO_D1_VBLANK_INTERRUPT) {
305                         drm_handle_vblank(rdev->ddev, 0);
306                 }
307                 if (r500_disp_int & AVIVO_D2_VBLANK_INTERRUPT) {
308                         drm_handle_vblank(rdev->ddev, 1);
309                 }
310                 status = rs600_irq_ack(rdev, &r500_disp_int);
311         }
312         return IRQ_HANDLED;
313 }
314
315 u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc)
316 {
317         if (crtc == 0)
318                 return RREG32(AVIVO_D1CRTC_FRAME_COUNT);
319         else
320                 return RREG32(AVIVO_D2CRTC_FRAME_COUNT);
321 }
322
323
324 /*
325  * Global GPU functions
326  */
327 void rs600_disable_vga(struct radeon_device *rdev)
328 {
329         unsigned tmp;
330
331         WREG32(0x330, 0);
332         WREG32(0x338, 0);
333         tmp = RREG32(0x300);
334         tmp &= ~(3 << 16);
335         WREG32(0x300, tmp);
336         WREG32(0x308, (1 << 8));
337         WREG32(0x310, rdev->mc.vram_location);
338         WREG32(0x594, 0);
339 }
340
341 int rs600_mc_wait_for_idle(struct radeon_device *rdev)
342 {
343         unsigned i;
344         uint32_t tmp;
345
346         for (i = 0; i < rdev->usec_timeout; i++) {
347                 /* read MC_STATUS */
348                 tmp = RREG32_MC(RS600_MC_STATUS);
349                 if (tmp & RS600_MC_STATUS_IDLE) {
350                         return 0;
351                 }
352                 DRM_UDELAY(1);
353         }
354         return -1;
355 }
356
357 void rs600_errata(struct radeon_device *rdev)
358 {
359         rdev->pll_errata = 0;
360 }
361
362 void rs600_gpu_init(struct radeon_device *rdev)
363 {
364         /* FIXME: HDP same place on rs600 ? */
365         r100_hdp_reset(rdev);
366         rs600_disable_vga(rdev);
367         /* FIXME: is this correct ? */
368         r420_pipes_init(rdev);
369         if (rs600_mc_wait_for_idle(rdev)) {
370                 printk(KERN_WARNING "Failed to wait MC idle while "
371                        "programming pipes. Bad things might happen.\n");
372         }
373 }
374
375
376 /*
377  * VRAM info.
378  */
379 void rs600_vram_info(struct radeon_device *rdev)
380 {
381         /* FIXME: to do or is these values sane ? */
382         rdev->mc.vram_is_ddr = true;
383         rdev->mc.vram_width = 128;
384 }
385
386 void rs600_bandwidth_update(struct radeon_device *rdev)
387 {
388         /* FIXME: implement, should this be like rs690 ? */
389 }
390
391
392 /*
393  * Indirect registers accessor
394  */
395 uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg)
396 {
397         uint32_t r;
398
399         WREG32(RS600_MC_INDEX,
400                ((reg & RS600_MC_ADDR_MASK) | RS600_MC_IND_CITF_ARB0));
401         r = RREG32(RS600_MC_DATA);
402         return r;
403 }
404
405 void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
406 {
407         WREG32(RS600_MC_INDEX,
408                 RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 |
409                 ((reg) & RS600_MC_ADDR_MASK));
410         WREG32(RS600_MC_DATA, v);
411 }
412
413 static const unsigned rs600_reg_safe_bm[219] = {
414         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
415         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
416         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
417         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
418         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
419         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
420         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
421         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
422         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
423         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
424         0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
425         0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
426         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
427         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
428         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
429         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
430         0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
431         0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
432         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
433         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
434         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
435         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
436         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
437         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
438         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
439         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
440         0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
441         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
442         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
443         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
444         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
445         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
446         0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
447         0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF,
448         0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
449         0x00000000, 0x0000C100, 0x00000000, 0x00000000,
450         0x00000000, 0x00000000, 0x00000000, 0x00000000,
451         0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
452         0x00000000, 0x00000000, 0x00000000, 0x00000000,
453         0x0003FC01, 0xFFFFFCF8, 0xFF800B19, 0xFFFFFFFF,
454         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
455         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
456         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
457         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
458         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
459         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
460         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
461         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
462         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
463         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
464         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
465         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
466         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
467         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
468         0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
469 };
470
471 int rs600_init(struct radeon_device *rdev)
472 {
473         rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm;
474         rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm);
475         return 0;
476 }