Commit 9b82f3e61758ed897200f0244b63a77c1791bcba

Authored by Geert Uytterhoeven
Committed by Paul Mackerras
1 parent 486936cd93

powerpc/ps3: Replace the flip_ctl logic in ps3av and ps3fb by a mutex

Introduce ps3_gpu_mutex to synchronizes GPU-related operations, like:
  - invoking the L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT command using the
    lv1_gpu_context_attribute() hypervisor call,
  - handling the PS3AV_CID_AVB_PARAM packet in the PS3 A/V Settings driver.

Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>

Showing 6 changed files with 14 additions and 38 deletions Inline Diff

arch/powerpc/include/asm/ps3.h
1 /* 1 /*
2 * PS3 platform declarations. 2 * PS3 platform declarations.
3 * 3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc. 4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp. 5 * Copyright 2006 Sony Corp.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21 #if !defined(_ASM_POWERPC_PS3_H) 21 #if !defined(_ASM_POWERPC_PS3_H)
22 #define _ASM_POWERPC_PS3_H 22 #define _ASM_POWERPC_PS3_H
23 23
24 #include <linux/init.h> 24 #include <linux/init.h>
25 #include <linux/types.h> 25 #include <linux/types.h>
26 #include <linux/device.h> 26 #include <linux/device.h>
27 #include "cell-pmu.h" 27 #include "cell-pmu.h"
28 28
29 union ps3_firmware_version { 29 union ps3_firmware_version {
30 u64 raw; 30 u64 raw;
31 struct { 31 struct {
32 u16 pad; 32 u16 pad;
33 u16 major; 33 u16 major;
34 u16 minor; 34 u16 minor;
35 u16 rev; 35 u16 rev;
36 }; 36 };
37 }; 37 };
38 38
39 void ps3_get_firmware_version(union ps3_firmware_version *v); 39 void ps3_get_firmware_version(union ps3_firmware_version *v);
40 int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev); 40 int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev);
41 41
42 /* 'Other OS' area */ 42 /* 'Other OS' area */
43 43
44 enum ps3_param_av_multi_out { 44 enum ps3_param_av_multi_out {
45 PS3_PARAM_AV_MULTI_OUT_NTSC = 0, 45 PS3_PARAM_AV_MULTI_OUT_NTSC = 0,
46 PS3_PARAM_AV_MULTI_OUT_PAL_RGB = 1, 46 PS3_PARAM_AV_MULTI_OUT_PAL_RGB = 1,
47 PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR = 2, 47 PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR = 2,
48 PS3_PARAM_AV_MULTI_OUT_SECAM = 3, 48 PS3_PARAM_AV_MULTI_OUT_SECAM = 3,
49 }; 49 };
50 50
51 enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void); 51 enum ps3_param_av_multi_out ps3_os_area_get_av_multi_out(void);
52 52
53 /* dma routines */ 53 /* dma routines */
54 54
55 enum ps3_dma_page_size { 55 enum ps3_dma_page_size {
56 PS3_DMA_4K = 12U, 56 PS3_DMA_4K = 12U,
57 PS3_DMA_64K = 16U, 57 PS3_DMA_64K = 16U,
58 PS3_DMA_1M = 20U, 58 PS3_DMA_1M = 20U,
59 PS3_DMA_16M = 24U, 59 PS3_DMA_16M = 24U,
60 }; 60 };
61 61
62 enum ps3_dma_region_type { 62 enum ps3_dma_region_type {
63 PS3_DMA_OTHER = 0, 63 PS3_DMA_OTHER = 0,
64 PS3_DMA_INTERNAL = 2, 64 PS3_DMA_INTERNAL = 2,
65 }; 65 };
66 66
67 struct ps3_dma_region_ops; 67 struct ps3_dma_region_ops;
68 68
69 /** 69 /**
70 * struct ps3_dma_region - A per device dma state variables structure 70 * struct ps3_dma_region - A per device dma state variables structure
71 * @did: The HV device id. 71 * @did: The HV device id.
72 * @page_size: The ioc pagesize. 72 * @page_size: The ioc pagesize.
73 * @region_type: The HV region type. 73 * @region_type: The HV region type.
74 * @bus_addr: The 'translated' bus address of the region. 74 * @bus_addr: The 'translated' bus address of the region.
75 * @len: The length in bytes of the region. 75 * @len: The length in bytes of the region.
76 * @offset: The offset from the start of memory of the region. 76 * @offset: The offset from the start of memory of the region.
77 * @ioid: The IOID of the device who owns this region 77 * @ioid: The IOID of the device who owns this region
78 * @chunk_list: Opaque variable used by the ioc page manager. 78 * @chunk_list: Opaque variable used by the ioc page manager.
79 * @region_ops: struct ps3_dma_region_ops - dma region operations 79 * @region_ops: struct ps3_dma_region_ops - dma region operations
80 */ 80 */
81 81
82 struct ps3_dma_region { 82 struct ps3_dma_region {
83 struct ps3_system_bus_device *dev; 83 struct ps3_system_bus_device *dev;
84 /* device variables */ 84 /* device variables */
85 const struct ps3_dma_region_ops *region_ops; 85 const struct ps3_dma_region_ops *region_ops;
86 unsigned char ioid; 86 unsigned char ioid;
87 enum ps3_dma_page_size page_size; 87 enum ps3_dma_page_size page_size;
88 enum ps3_dma_region_type region_type; 88 enum ps3_dma_region_type region_type;
89 unsigned long len; 89 unsigned long len;
90 unsigned long offset; 90 unsigned long offset;
91 91
92 /* driver variables (set by ps3_dma_region_create) */ 92 /* driver variables (set by ps3_dma_region_create) */
93 unsigned long bus_addr; 93 unsigned long bus_addr;
94 struct { 94 struct {
95 spinlock_t lock; 95 spinlock_t lock;
96 struct list_head head; 96 struct list_head head;
97 } chunk_list; 97 } chunk_list;
98 }; 98 };
99 99
100 struct ps3_dma_region_ops { 100 struct ps3_dma_region_ops {
101 int (*create)(struct ps3_dma_region *); 101 int (*create)(struct ps3_dma_region *);
102 int (*free)(struct ps3_dma_region *); 102 int (*free)(struct ps3_dma_region *);
103 int (*map)(struct ps3_dma_region *, 103 int (*map)(struct ps3_dma_region *,
104 unsigned long virt_addr, 104 unsigned long virt_addr,
105 unsigned long len, 105 unsigned long len,
106 unsigned long *bus_addr, 106 unsigned long *bus_addr,
107 u64 iopte_pp); 107 u64 iopte_pp);
108 int (*unmap)(struct ps3_dma_region *, 108 int (*unmap)(struct ps3_dma_region *,
109 unsigned long bus_addr, 109 unsigned long bus_addr,
110 unsigned long len); 110 unsigned long len);
111 }; 111 };
112 /** 112 /**
113 * struct ps3_dma_region_init - Helper to initialize structure variables 113 * struct ps3_dma_region_init - Helper to initialize structure variables
114 * 114 *
115 * Helper to properly initialize variables prior to calling 115 * Helper to properly initialize variables prior to calling
116 * ps3_system_bus_device_register. 116 * ps3_system_bus_device_register.
117 */ 117 */
118 118
119 struct ps3_system_bus_device; 119 struct ps3_system_bus_device;
120 120
121 int ps3_dma_region_init(struct ps3_system_bus_device *dev, 121 int ps3_dma_region_init(struct ps3_system_bus_device *dev,
122 struct ps3_dma_region *r, enum ps3_dma_page_size page_size, 122 struct ps3_dma_region *r, enum ps3_dma_page_size page_size,
123 enum ps3_dma_region_type region_type, void *addr, unsigned long len); 123 enum ps3_dma_region_type region_type, void *addr, unsigned long len);
124 int ps3_dma_region_create(struct ps3_dma_region *r); 124 int ps3_dma_region_create(struct ps3_dma_region *r);
125 int ps3_dma_region_free(struct ps3_dma_region *r); 125 int ps3_dma_region_free(struct ps3_dma_region *r);
126 int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr, 126 int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
127 unsigned long len, unsigned long *bus_addr, 127 unsigned long len, unsigned long *bus_addr,
128 u64 iopte_pp); 128 u64 iopte_pp);
129 int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr, 129 int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
130 unsigned long len); 130 unsigned long len);
131 131
132 /* mmio routines */ 132 /* mmio routines */
133 133
134 enum ps3_mmio_page_size { 134 enum ps3_mmio_page_size {
135 PS3_MMIO_4K = 12U, 135 PS3_MMIO_4K = 12U,
136 PS3_MMIO_64K = 16U 136 PS3_MMIO_64K = 16U
137 }; 137 };
138 138
139 struct ps3_mmio_region_ops; 139 struct ps3_mmio_region_ops;
140 /** 140 /**
141 * struct ps3_mmio_region - a per device mmio state variables structure 141 * struct ps3_mmio_region - a per device mmio state variables structure
142 * 142 *
143 * Current systems can be supported with a single region per device. 143 * Current systems can be supported with a single region per device.
144 */ 144 */
145 145
146 struct ps3_mmio_region { 146 struct ps3_mmio_region {
147 struct ps3_system_bus_device *dev; 147 struct ps3_system_bus_device *dev;
148 const struct ps3_mmio_region_ops *mmio_ops; 148 const struct ps3_mmio_region_ops *mmio_ops;
149 unsigned long bus_addr; 149 unsigned long bus_addr;
150 unsigned long len; 150 unsigned long len;
151 enum ps3_mmio_page_size page_size; 151 enum ps3_mmio_page_size page_size;
152 unsigned long lpar_addr; 152 unsigned long lpar_addr;
153 }; 153 };
154 154
155 struct ps3_mmio_region_ops { 155 struct ps3_mmio_region_ops {
156 int (*create)(struct ps3_mmio_region *); 156 int (*create)(struct ps3_mmio_region *);
157 int (*free)(struct ps3_mmio_region *); 157 int (*free)(struct ps3_mmio_region *);
158 }; 158 };
159 /** 159 /**
160 * struct ps3_mmio_region_init - Helper to initialize structure variables 160 * struct ps3_mmio_region_init - Helper to initialize structure variables
161 * 161 *
162 * Helper to properly initialize variables prior to calling 162 * Helper to properly initialize variables prior to calling
163 * ps3_system_bus_device_register. 163 * ps3_system_bus_device_register.
164 */ 164 */
165 165
166 int ps3_mmio_region_init(struct ps3_system_bus_device *dev, 166 int ps3_mmio_region_init(struct ps3_system_bus_device *dev,
167 struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len, 167 struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,
168 enum ps3_mmio_page_size page_size); 168 enum ps3_mmio_page_size page_size);
169 int ps3_mmio_region_create(struct ps3_mmio_region *r); 169 int ps3_mmio_region_create(struct ps3_mmio_region *r);
170 int ps3_free_mmio_region(struct ps3_mmio_region *r); 170 int ps3_free_mmio_region(struct ps3_mmio_region *r);
171 unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr); 171 unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr);
172 172
173 /* inrerrupt routines */ 173 /* inrerrupt routines */
174 174
175 enum ps3_cpu_binding { 175 enum ps3_cpu_binding {
176 PS3_BINDING_CPU_ANY = -1, 176 PS3_BINDING_CPU_ANY = -1,
177 PS3_BINDING_CPU_0 = 0, 177 PS3_BINDING_CPU_0 = 0,
178 PS3_BINDING_CPU_1 = 1, 178 PS3_BINDING_CPU_1 = 1,
179 }; 179 };
180 180
181 int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, 181 int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
182 unsigned int *virq); 182 unsigned int *virq);
183 int ps3_irq_plug_destroy(unsigned int virq); 183 int ps3_irq_plug_destroy(unsigned int virq);
184 int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq); 184 int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq);
185 int ps3_event_receive_port_destroy(unsigned int virq); 185 int ps3_event_receive_port_destroy(unsigned int virq);
186 int ps3_send_event_locally(unsigned int virq); 186 int ps3_send_event_locally(unsigned int virq);
187 187
188 int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id, 188 int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
189 unsigned int *virq); 189 unsigned int *virq);
190 int ps3_io_irq_destroy(unsigned int virq); 190 int ps3_io_irq_destroy(unsigned int virq);
191 int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp, 191 int ps3_vuart_irq_setup(enum ps3_cpu_binding cpu, void* virt_addr_bmp,
192 unsigned int *virq); 192 unsigned int *virq);
193 int ps3_vuart_irq_destroy(unsigned int virq); 193 int ps3_vuart_irq_destroy(unsigned int virq);
194 int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id, 194 int ps3_spe_irq_setup(enum ps3_cpu_binding cpu, unsigned long spe_id,
195 unsigned int class, unsigned int *virq); 195 unsigned int class, unsigned int *virq);
196 int ps3_spe_irq_destroy(unsigned int virq); 196 int ps3_spe_irq_destroy(unsigned int virq);
197 197
198 int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev, 198 int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
199 enum ps3_cpu_binding cpu, unsigned int *virq); 199 enum ps3_cpu_binding cpu, unsigned int *virq);
200 int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev, 200 int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
201 unsigned int virq); 201 unsigned int virq);
202 202
203 /* lv1 result codes */ 203 /* lv1 result codes */
204 204
205 enum lv1_result { 205 enum lv1_result {
206 LV1_SUCCESS = 0, 206 LV1_SUCCESS = 0,
207 /* not used -1 */ 207 /* not used -1 */
208 LV1_RESOURCE_SHORTAGE = -2, 208 LV1_RESOURCE_SHORTAGE = -2,
209 LV1_NO_PRIVILEGE = -3, 209 LV1_NO_PRIVILEGE = -3,
210 LV1_DENIED_BY_POLICY = -4, 210 LV1_DENIED_BY_POLICY = -4,
211 LV1_ACCESS_VIOLATION = -5, 211 LV1_ACCESS_VIOLATION = -5,
212 LV1_NO_ENTRY = -6, 212 LV1_NO_ENTRY = -6,
213 LV1_DUPLICATE_ENTRY = -7, 213 LV1_DUPLICATE_ENTRY = -7,
214 LV1_TYPE_MISMATCH = -8, 214 LV1_TYPE_MISMATCH = -8,
215 LV1_BUSY = -9, 215 LV1_BUSY = -9,
216 LV1_EMPTY = -10, 216 LV1_EMPTY = -10,
217 LV1_WRONG_STATE = -11, 217 LV1_WRONG_STATE = -11,
218 /* not used -12 */ 218 /* not used -12 */
219 LV1_NO_MATCH = -13, 219 LV1_NO_MATCH = -13,
220 LV1_ALREADY_CONNECTED = -14, 220 LV1_ALREADY_CONNECTED = -14,
221 LV1_UNSUPPORTED_PARAMETER_VALUE = -15, 221 LV1_UNSUPPORTED_PARAMETER_VALUE = -15,
222 LV1_CONDITION_NOT_SATISFIED = -16, 222 LV1_CONDITION_NOT_SATISFIED = -16,
223 LV1_ILLEGAL_PARAMETER_VALUE = -17, 223 LV1_ILLEGAL_PARAMETER_VALUE = -17,
224 LV1_BAD_OPTION = -18, 224 LV1_BAD_OPTION = -18,
225 LV1_IMPLEMENTATION_LIMITATION = -19, 225 LV1_IMPLEMENTATION_LIMITATION = -19,
226 LV1_NOT_IMPLEMENTED = -20, 226 LV1_NOT_IMPLEMENTED = -20,
227 LV1_INVALID_CLASS_ID = -21, 227 LV1_INVALID_CLASS_ID = -21,
228 LV1_CONSTRAINT_NOT_SATISFIED = -22, 228 LV1_CONSTRAINT_NOT_SATISFIED = -22,
229 LV1_ALIGNMENT_ERROR = -23, 229 LV1_ALIGNMENT_ERROR = -23,
230 LV1_HARDWARE_ERROR = -24, 230 LV1_HARDWARE_ERROR = -24,
231 LV1_INVALID_DATA_FORMAT = -25, 231 LV1_INVALID_DATA_FORMAT = -25,
232 LV1_INVALID_OPERATION = -26, 232 LV1_INVALID_OPERATION = -26,
233 LV1_INTERNAL_ERROR = -32768, 233 LV1_INTERNAL_ERROR = -32768,
234 }; 234 };
235 235
236 static inline const char* ps3_result(int result) 236 static inline const char* ps3_result(int result)
237 { 237 {
238 #if defined(DEBUG) 238 #if defined(DEBUG)
239 switch (result) { 239 switch (result) {
240 case LV1_SUCCESS: 240 case LV1_SUCCESS:
241 return "LV1_SUCCESS (0)"; 241 return "LV1_SUCCESS (0)";
242 case -1: 242 case -1:
243 return "** unknown result ** (-1)"; 243 return "** unknown result ** (-1)";
244 case LV1_RESOURCE_SHORTAGE: 244 case LV1_RESOURCE_SHORTAGE:
245 return "LV1_RESOURCE_SHORTAGE (-2)"; 245 return "LV1_RESOURCE_SHORTAGE (-2)";
246 case LV1_NO_PRIVILEGE: 246 case LV1_NO_PRIVILEGE:
247 return "LV1_NO_PRIVILEGE (-3)"; 247 return "LV1_NO_PRIVILEGE (-3)";
248 case LV1_DENIED_BY_POLICY: 248 case LV1_DENIED_BY_POLICY:
249 return "LV1_DENIED_BY_POLICY (-4)"; 249 return "LV1_DENIED_BY_POLICY (-4)";
250 case LV1_ACCESS_VIOLATION: 250 case LV1_ACCESS_VIOLATION:
251 return "LV1_ACCESS_VIOLATION (-5)"; 251 return "LV1_ACCESS_VIOLATION (-5)";
252 case LV1_NO_ENTRY: 252 case LV1_NO_ENTRY:
253 return "LV1_NO_ENTRY (-6)"; 253 return "LV1_NO_ENTRY (-6)";
254 case LV1_DUPLICATE_ENTRY: 254 case LV1_DUPLICATE_ENTRY:
255 return "LV1_DUPLICATE_ENTRY (-7)"; 255 return "LV1_DUPLICATE_ENTRY (-7)";
256 case LV1_TYPE_MISMATCH: 256 case LV1_TYPE_MISMATCH:
257 return "LV1_TYPE_MISMATCH (-8)"; 257 return "LV1_TYPE_MISMATCH (-8)";
258 case LV1_BUSY: 258 case LV1_BUSY:
259 return "LV1_BUSY (-9)"; 259 return "LV1_BUSY (-9)";
260 case LV1_EMPTY: 260 case LV1_EMPTY:
261 return "LV1_EMPTY (-10)"; 261 return "LV1_EMPTY (-10)";
262 case LV1_WRONG_STATE: 262 case LV1_WRONG_STATE:
263 return "LV1_WRONG_STATE (-11)"; 263 return "LV1_WRONG_STATE (-11)";
264 case -12: 264 case -12:
265 return "** unknown result ** (-12)"; 265 return "** unknown result ** (-12)";
266 case LV1_NO_MATCH: 266 case LV1_NO_MATCH:
267 return "LV1_NO_MATCH (-13)"; 267 return "LV1_NO_MATCH (-13)";
268 case LV1_ALREADY_CONNECTED: 268 case LV1_ALREADY_CONNECTED:
269 return "LV1_ALREADY_CONNECTED (-14)"; 269 return "LV1_ALREADY_CONNECTED (-14)";
270 case LV1_UNSUPPORTED_PARAMETER_VALUE: 270 case LV1_UNSUPPORTED_PARAMETER_VALUE:
271 return "LV1_UNSUPPORTED_PARAMETER_VALUE (-15)"; 271 return "LV1_UNSUPPORTED_PARAMETER_VALUE (-15)";
272 case LV1_CONDITION_NOT_SATISFIED: 272 case LV1_CONDITION_NOT_SATISFIED:
273 return "LV1_CONDITION_NOT_SATISFIED (-16)"; 273 return "LV1_CONDITION_NOT_SATISFIED (-16)";
274 case LV1_ILLEGAL_PARAMETER_VALUE: 274 case LV1_ILLEGAL_PARAMETER_VALUE:
275 return "LV1_ILLEGAL_PARAMETER_VALUE (-17)"; 275 return "LV1_ILLEGAL_PARAMETER_VALUE (-17)";
276 case LV1_BAD_OPTION: 276 case LV1_BAD_OPTION:
277 return "LV1_BAD_OPTION (-18)"; 277 return "LV1_BAD_OPTION (-18)";
278 case LV1_IMPLEMENTATION_LIMITATION: 278 case LV1_IMPLEMENTATION_LIMITATION:
279 return "LV1_IMPLEMENTATION_LIMITATION (-19)"; 279 return "LV1_IMPLEMENTATION_LIMITATION (-19)";
280 case LV1_NOT_IMPLEMENTED: 280 case LV1_NOT_IMPLEMENTED:
281 return "LV1_NOT_IMPLEMENTED (-20)"; 281 return "LV1_NOT_IMPLEMENTED (-20)";
282 case LV1_INVALID_CLASS_ID: 282 case LV1_INVALID_CLASS_ID:
283 return "LV1_INVALID_CLASS_ID (-21)"; 283 return "LV1_INVALID_CLASS_ID (-21)";
284 case LV1_CONSTRAINT_NOT_SATISFIED: 284 case LV1_CONSTRAINT_NOT_SATISFIED:
285 return "LV1_CONSTRAINT_NOT_SATISFIED (-22)"; 285 return "LV1_CONSTRAINT_NOT_SATISFIED (-22)";
286 case LV1_ALIGNMENT_ERROR: 286 case LV1_ALIGNMENT_ERROR:
287 return "LV1_ALIGNMENT_ERROR (-23)"; 287 return "LV1_ALIGNMENT_ERROR (-23)";
288 case LV1_HARDWARE_ERROR: 288 case LV1_HARDWARE_ERROR:
289 return "LV1_HARDWARE_ERROR (-24)"; 289 return "LV1_HARDWARE_ERROR (-24)";
290 case LV1_INVALID_DATA_FORMAT: 290 case LV1_INVALID_DATA_FORMAT:
291 return "LV1_INVALID_DATA_FORMAT (-25)"; 291 return "LV1_INVALID_DATA_FORMAT (-25)";
292 case LV1_INVALID_OPERATION: 292 case LV1_INVALID_OPERATION:
293 return "LV1_INVALID_OPERATION (-26)"; 293 return "LV1_INVALID_OPERATION (-26)";
294 case LV1_INTERNAL_ERROR: 294 case LV1_INTERNAL_ERROR:
295 return "LV1_INTERNAL_ERROR (-32768)"; 295 return "LV1_INTERNAL_ERROR (-32768)";
296 default: 296 default:
297 BUG(); 297 BUG();
298 return "** unknown result **"; 298 return "** unknown result **";
299 }; 299 };
300 #else 300 #else
301 return ""; 301 return "";
302 #endif 302 #endif
303 } 303 }
304 304
305 /* system bus routines */ 305 /* system bus routines */
306 306
307 enum ps3_match_id { 307 enum ps3_match_id {
308 PS3_MATCH_ID_EHCI = 1, 308 PS3_MATCH_ID_EHCI = 1,
309 PS3_MATCH_ID_OHCI = 2, 309 PS3_MATCH_ID_OHCI = 2,
310 PS3_MATCH_ID_GELIC = 3, 310 PS3_MATCH_ID_GELIC = 3,
311 PS3_MATCH_ID_AV_SETTINGS = 4, 311 PS3_MATCH_ID_AV_SETTINGS = 4,
312 PS3_MATCH_ID_SYSTEM_MANAGER = 5, 312 PS3_MATCH_ID_SYSTEM_MANAGER = 5,
313 PS3_MATCH_ID_STOR_DISK = 6, 313 PS3_MATCH_ID_STOR_DISK = 6,
314 PS3_MATCH_ID_STOR_ROM = 7, 314 PS3_MATCH_ID_STOR_ROM = 7,
315 PS3_MATCH_ID_STOR_FLASH = 8, 315 PS3_MATCH_ID_STOR_FLASH = 8,
316 PS3_MATCH_ID_SOUND = 9, 316 PS3_MATCH_ID_SOUND = 9,
317 PS3_MATCH_ID_GRAPHICS = 10, 317 PS3_MATCH_ID_GRAPHICS = 10,
318 PS3_MATCH_ID_LPM = 11, 318 PS3_MATCH_ID_LPM = 11,
319 }; 319 };
320 320
321 #define PS3_MODULE_ALIAS_EHCI "ps3:1" 321 #define PS3_MODULE_ALIAS_EHCI "ps3:1"
322 #define PS3_MODULE_ALIAS_OHCI "ps3:2" 322 #define PS3_MODULE_ALIAS_OHCI "ps3:2"
323 #define PS3_MODULE_ALIAS_GELIC "ps3:3" 323 #define PS3_MODULE_ALIAS_GELIC "ps3:3"
324 #define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4" 324 #define PS3_MODULE_ALIAS_AV_SETTINGS "ps3:4"
325 #define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5" 325 #define PS3_MODULE_ALIAS_SYSTEM_MANAGER "ps3:5"
326 #define PS3_MODULE_ALIAS_STOR_DISK "ps3:6" 326 #define PS3_MODULE_ALIAS_STOR_DISK "ps3:6"
327 #define PS3_MODULE_ALIAS_STOR_ROM "ps3:7" 327 #define PS3_MODULE_ALIAS_STOR_ROM "ps3:7"
328 #define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8" 328 #define PS3_MODULE_ALIAS_STOR_FLASH "ps3:8"
329 #define PS3_MODULE_ALIAS_SOUND "ps3:9" 329 #define PS3_MODULE_ALIAS_SOUND "ps3:9"
330 #define PS3_MODULE_ALIAS_GRAPHICS "ps3:10" 330 #define PS3_MODULE_ALIAS_GRAPHICS "ps3:10"
331 #define PS3_MODULE_ALIAS_LPM "ps3:11" 331 #define PS3_MODULE_ALIAS_LPM "ps3:11"
332 332
333 enum ps3_system_bus_device_type { 333 enum ps3_system_bus_device_type {
334 PS3_DEVICE_TYPE_IOC0 = 1, 334 PS3_DEVICE_TYPE_IOC0 = 1,
335 PS3_DEVICE_TYPE_SB, 335 PS3_DEVICE_TYPE_SB,
336 PS3_DEVICE_TYPE_VUART, 336 PS3_DEVICE_TYPE_VUART,
337 PS3_DEVICE_TYPE_LPM, 337 PS3_DEVICE_TYPE_LPM,
338 }; 338 };
339 339
340 enum ps3_match_sub_id { 340 enum ps3_match_sub_id {
341 /* for PS3_MATCH_ID_GRAPHICS */ 341 /* for PS3_MATCH_ID_GRAPHICS */
342 PS3_MATCH_SUB_ID_FB = 1, 342 PS3_MATCH_SUB_ID_FB = 1,
343 }; 343 };
344 344
345 /** 345 /**
346 * struct ps3_system_bus_device - a device on the system bus 346 * struct ps3_system_bus_device - a device on the system bus
347 */ 347 */
348 348
349 struct ps3_system_bus_device { 349 struct ps3_system_bus_device {
350 enum ps3_match_id match_id; 350 enum ps3_match_id match_id;
351 enum ps3_match_sub_id match_sub_id; 351 enum ps3_match_sub_id match_sub_id;
352 enum ps3_system_bus_device_type dev_type; 352 enum ps3_system_bus_device_type dev_type;
353 353
354 u64 bus_id; /* SB */ 354 u64 bus_id; /* SB */
355 u64 dev_id; /* SB */ 355 u64 dev_id; /* SB */
356 unsigned int interrupt_id; /* SB */ 356 unsigned int interrupt_id; /* SB */
357 struct ps3_dma_region *d_region; /* SB, IOC0 */ 357 struct ps3_dma_region *d_region; /* SB, IOC0 */
358 struct ps3_mmio_region *m_region; /* SB, IOC0*/ 358 struct ps3_mmio_region *m_region; /* SB, IOC0*/
359 unsigned int port_number; /* VUART */ 359 unsigned int port_number; /* VUART */
360 struct { /* LPM */ 360 struct { /* LPM */
361 u64 node_id; 361 u64 node_id;
362 u64 pu_id; 362 u64 pu_id;
363 u64 rights; 363 u64 rights;
364 } lpm; 364 } lpm;
365 365
366 /* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */ 366 /* struct iommu_table *iommu_table; -- waiting for BenH's cleanups */
367 struct device core; 367 struct device core;
368 void *driver_priv; /* private driver variables */ 368 void *driver_priv; /* private driver variables */
369 }; 369 };
370 370
371 int ps3_open_hv_device(struct ps3_system_bus_device *dev); 371 int ps3_open_hv_device(struct ps3_system_bus_device *dev);
372 int ps3_close_hv_device(struct ps3_system_bus_device *dev); 372 int ps3_close_hv_device(struct ps3_system_bus_device *dev);
373 373
374 /** 374 /**
375 * struct ps3_system_bus_driver - a driver for a device on the system bus 375 * struct ps3_system_bus_driver - a driver for a device on the system bus
376 */ 376 */
377 377
378 struct ps3_system_bus_driver { 378 struct ps3_system_bus_driver {
379 enum ps3_match_id match_id; 379 enum ps3_match_id match_id;
380 enum ps3_match_sub_id match_sub_id; 380 enum ps3_match_sub_id match_sub_id;
381 struct device_driver core; 381 struct device_driver core;
382 int (*probe)(struct ps3_system_bus_device *); 382 int (*probe)(struct ps3_system_bus_device *);
383 int (*remove)(struct ps3_system_bus_device *); 383 int (*remove)(struct ps3_system_bus_device *);
384 int (*shutdown)(struct ps3_system_bus_device *); 384 int (*shutdown)(struct ps3_system_bus_device *);
385 /* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */ 385 /* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */
386 /* int (*resume)(struct ps3_system_bus_device *); */ 386 /* int (*resume)(struct ps3_system_bus_device *); */
387 }; 387 };
388 388
389 int ps3_system_bus_device_register(struct ps3_system_bus_device *dev); 389 int ps3_system_bus_device_register(struct ps3_system_bus_device *dev);
390 int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv); 390 int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv);
391 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv); 391 void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv);
392 392
393 static inline struct ps3_system_bus_driver *ps3_drv_to_system_bus_drv( 393 static inline struct ps3_system_bus_driver *ps3_drv_to_system_bus_drv(
394 struct device_driver *_drv) 394 struct device_driver *_drv)
395 { 395 {
396 return container_of(_drv, struct ps3_system_bus_driver, core); 396 return container_of(_drv, struct ps3_system_bus_driver, core);
397 } 397 }
398 static inline struct ps3_system_bus_device *ps3_dev_to_system_bus_dev( 398 static inline struct ps3_system_bus_device *ps3_dev_to_system_bus_dev(
399 struct device *_dev) 399 struct device *_dev)
400 { 400 {
401 return container_of(_dev, struct ps3_system_bus_device, core); 401 return container_of(_dev, struct ps3_system_bus_device, core);
402 } 402 }
403 static inline struct ps3_system_bus_driver * 403 static inline struct ps3_system_bus_driver *
404 ps3_system_bus_dev_to_system_bus_drv(struct ps3_system_bus_device *_dev) 404 ps3_system_bus_dev_to_system_bus_drv(struct ps3_system_bus_device *_dev)
405 { 405 {
406 BUG_ON(!_dev); 406 BUG_ON(!_dev);
407 BUG_ON(!_dev->core.driver); 407 BUG_ON(!_dev->core.driver);
408 return ps3_drv_to_system_bus_drv(_dev->core.driver); 408 return ps3_drv_to_system_bus_drv(_dev->core.driver);
409 } 409 }
410 410
411 /** 411 /**
412 * ps3_system_bus_set_drvdata - 412 * ps3_system_bus_set_drvdata -
413 * @dev: device structure 413 * @dev: device structure
414 * @data: Data to set 414 * @data: Data to set
415 */ 415 */
416 416
417 static inline void ps3_system_bus_set_driver_data( 417 static inline void ps3_system_bus_set_driver_data(
418 struct ps3_system_bus_device *dev, void *data) 418 struct ps3_system_bus_device *dev, void *data)
419 { 419 {
420 dev->core.driver_data = data; 420 dev->core.driver_data = data;
421 } 421 }
422 static inline void *ps3_system_bus_get_driver_data( 422 static inline void *ps3_system_bus_get_driver_data(
423 struct ps3_system_bus_device *dev) 423 struct ps3_system_bus_device *dev)
424 { 424 {
425 return dev->core.driver_data; 425 return dev->core.driver_data;
426 } 426 }
427 427
428 /* These two need global scope for get_dma_ops(). */ 428 /* These two need global scope for get_dma_ops(). */
429 429
430 extern struct bus_type ps3_system_bus_type; 430 extern struct bus_type ps3_system_bus_type;
431 431
432 /* system manager */ 432 /* system manager */
433 433
434 struct ps3_sys_manager_ops { 434 struct ps3_sys_manager_ops {
435 struct ps3_system_bus_device *dev; 435 struct ps3_system_bus_device *dev;
436 void (*power_off)(struct ps3_system_bus_device *dev); 436 void (*power_off)(struct ps3_system_bus_device *dev);
437 void (*restart)(struct ps3_system_bus_device *dev); 437 void (*restart)(struct ps3_system_bus_device *dev);
438 }; 438 };
439 439
440 void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops); 440 void ps3_sys_manager_register_ops(const struct ps3_sys_manager_ops *ops);
441 void __noreturn ps3_sys_manager_power_off(void); 441 void __noreturn ps3_sys_manager_power_off(void);
442 void __noreturn ps3_sys_manager_restart(void); 442 void __noreturn ps3_sys_manager_restart(void);
443 void __noreturn ps3_sys_manager_halt(void); 443 void __noreturn ps3_sys_manager_halt(void);
444 int ps3_sys_manager_get_wol(void); 444 int ps3_sys_manager_get_wol(void);
445 void ps3_sys_manager_set_wol(int state); 445 void ps3_sys_manager_set_wol(int state);
446 446
447 struct ps3_prealloc { 447 struct ps3_prealloc {
448 const char *name; 448 const char *name;
449 void *address; 449 void *address;
450 unsigned long size; 450 unsigned long size;
451 unsigned long align; 451 unsigned long align;
452 }; 452 };
453 453
454 extern struct ps3_prealloc ps3fb_videomemory; 454 extern struct ps3_prealloc ps3fb_videomemory;
455 extern struct ps3_prealloc ps3flash_bounce_buffer; 455 extern struct ps3_prealloc ps3flash_bounce_buffer;
456 456
457 /* logical performance monitor */ 457 /* logical performance monitor */
458 458
459 /** 459 /**
460 * enum ps3_lpm_rights - Rigths granted by the system policy module. 460 * enum ps3_lpm_rights - Rigths granted by the system policy module.
461 * 461 *
462 * @PS3_LPM_RIGHTS_USE_LPM: The right to use the lpm. 462 * @PS3_LPM_RIGHTS_USE_LPM: The right to use the lpm.
463 * @PS3_LPM_RIGHTS_USE_TB: The right to use the internal trace buffer. 463 * @PS3_LPM_RIGHTS_USE_TB: The right to use the internal trace buffer.
464 */ 464 */
465 465
466 enum ps3_lpm_rights { 466 enum ps3_lpm_rights {
467 PS3_LPM_RIGHTS_USE_LPM = 0x001, 467 PS3_LPM_RIGHTS_USE_LPM = 0x001,
468 PS3_LPM_RIGHTS_USE_TB = 0x100, 468 PS3_LPM_RIGHTS_USE_TB = 0x100,
469 }; 469 };
470 470
471 /** 471 /**
472 * enum ps3_lpm_tb_type - Type of trace buffer lv1 should use. 472 * enum ps3_lpm_tb_type - Type of trace buffer lv1 should use.
473 * 473 *
474 * @PS3_LPM_TB_TYPE_NONE: Do not use a trace buffer. 474 * @PS3_LPM_TB_TYPE_NONE: Do not use a trace buffer.
475 * @PS3_LPM_RIGHTS_USE_TB: Use the lv1 internal trace buffer. Must have 475 * @PS3_LPM_RIGHTS_USE_TB: Use the lv1 internal trace buffer. Must have
476 * rights @PS3_LPM_RIGHTS_USE_TB. 476 * rights @PS3_LPM_RIGHTS_USE_TB.
477 */ 477 */
478 478
479 enum ps3_lpm_tb_type { 479 enum ps3_lpm_tb_type {
480 PS3_LPM_TB_TYPE_NONE = 0, 480 PS3_LPM_TB_TYPE_NONE = 0,
481 PS3_LPM_TB_TYPE_INTERNAL = 1, 481 PS3_LPM_TB_TYPE_INTERNAL = 1,
482 }; 482 };
483 483
484 int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache, 484 int ps3_lpm_open(enum ps3_lpm_tb_type tb_type, void *tb_cache,
485 u64 tb_cache_size); 485 u64 tb_cache_size);
486 int ps3_lpm_close(void); 486 int ps3_lpm_close(void);
487 int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count, 487 int ps3_lpm_copy_tb(unsigned long offset, void *buf, unsigned long count,
488 unsigned long *bytes_copied); 488 unsigned long *bytes_copied);
489 int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf, 489 int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
490 unsigned long count, unsigned long *bytes_copied); 490 unsigned long count, unsigned long *bytes_copied);
491 void ps3_set_bookmark(u64 bookmark); 491 void ps3_set_bookmark(u64 bookmark);
492 void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id); 492 void ps3_set_pm_bookmark(u64 tag, u64 incident, u64 th_id);
493 int ps3_set_signal(u64 rtas_signal_group, u8 signal_bit, u16 sub_unit, 493 int ps3_set_signal(u64 rtas_signal_group, u8 signal_bit, u16 sub_unit,
494 u8 bus_word); 494 u8 bus_word);
495 495
496 u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr); 496 u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr);
497 void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val); 497 void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val);
498 u32 ps3_read_ctr(u32 cpu, u32 ctr); 498 u32 ps3_read_ctr(u32 cpu, u32 ctr);
499 void ps3_write_ctr(u32 cpu, u32 ctr, u32 val); 499 void ps3_write_ctr(u32 cpu, u32 ctr, u32 val);
500 500
501 u32 ps3_read_pm07_control(u32 cpu, u32 ctr); 501 u32 ps3_read_pm07_control(u32 cpu, u32 ctr);
502 void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val); 502 void ps3_write_pm07_control(u32 cpu, u32 ctr, u32 val);
503 u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg); 503 u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg);
504 void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val); 504 void ps3_write_pm(u32 cpu, enum pm_reg_name reg, u32 val);
505 505
506 u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr); 506 u32 ps3_get_ctr_size(u32 cpu, u32 phys_ctr);
507 void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size); 507 void ps3_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size);
508 508
509 void ps3_enable_pm(u32 cpu); 509 void ps3_enable_pm(u32 cpu);
510 void ps3_disable_pm(u32 cpu); 510 void ps3_disable_pm(u32 cpu);
511 void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask); 511 void ps3_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask);
512 void ps3_disable_pm_interrupts(u32 cpu); 512 void ps3_disable_pm_interrupts(u32 cpu);
513 513
514 u32 ps3_get_and_clear_pm_interrupts(u32 cpu); 514 u32 ps3_get_and_clear_pm_interrupts(u32 cpu);
515 void ps3_sync_irq(int node); 515 void ps3_sync_irq(int node);
516 u32 ps3_get_hw_thread_id(int cpu); 516 u32 ps3_get_hw_thread_id(int cpu);
517 u64 ps3_get_spe_id(void *arg); 517 u64 ps3_get_spe_id(void *arg);
518 518
519 /* mutex synchronizing GPU accesses and video mode changes */
520 extern struct mutex ps3_gpu_mutex;
521
519 #endif 522 #endif
520 523
arch/powerpc/include/asm/ps3av.h
1 /* 1 /*
2 * PS3 AV backend support. 2 * PS3 AV backend support.
3 * 3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc. 4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp. 5 * Copyright 2007 Sony Corp.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21 #ifndef _ASM_POWERPC_PS3AV_H_ 21 #ifndef _ASM_POWERPC_PS3AV_H_
22 #define _ASM_POWERPC_PS3AV_H_ 22 #define _ASM_POWERPC_PS3AV_H_
23 23
24 /** command for ioctl() **/ 24 /** command for ioctl() **/
25 #define PS3AV_VERSION 0x205 /* version of ps3av command */ 25 #define PS3AV_VERSION 0x205 /* version of ps3av command */
26 26
27 #define PS3AV_CID_AV_INIT 0x00000001 27 #define PS3AV_CID_AV_INIT 0x00000001
28 #define PS3AV_CID_AV_FIN 0x00000002 28 #define PS3AV_CID_AV_FIN 0x00000002
29 #define PS3AV_CID_AV_GET_HW_CONF 0x00000003 29 #define PS3AV_CID_AV_GET_HW_CONF 0x00000003
30 #define PS3AV_CID_AV_GET_MONITOR_INFO 0x00000004 30 #define PS3AV_CID_AV_GET_MONITOR_INFO 0x00000004
31 #define PS3AV_CID_AV_ENABLE_EVENT 0x00000006 31 #define PS3AV_CID_AV_ENABLE_EVENT 0x00000006
32 #define PS3AV_CID_AV_DISABLE_EVENT 0x00000007 32 #define PS3AV_CID_AV_DISABLE_EVENT 0x00000007
33 #define PS3AV_CID_AV_TV_MUTE 0x0000000a 33 #define PS3AV_CID_AV_TV_MUTE 0x0000000a
34 34
35 #define PS3AV_CID_AV_VIDEO_CS 0x00010001 35 #define PS3AV_CID_AV_VIDEO_CS 0x00010001
36 #define PS3AV_CID_AV_VIDEO_MUTE 0x00010002 36 #define PS3AV_CID_AV_VIDEO_MUTE 0x00010002
37 #define PS3AV_CID_AV_VIDEO_DISABLE_SIG 0x00010003 37 #define PS3AV_CID_AV_VIDEO_DISABLE_SIG 0x00010003
38 #define PS3AV_CID_AV_AUDIO_PARAM 0x00020001 38 #define PS3AV_CID_AV_AUDIO_PARAM 0x00020001
39 #define PS3AV_CID_AV_AUDIO_MUTE 0x00020002 39 #define PS3AV_CID_AV_AUDIO_MUTE 0x00020002
40 #define PS3AV_CID_AV_HDMI_MODE 0x00040001 40 #define PS3AV_CID_AV_HDMI_MODE 0x00040001
41 41
42 #define PS3AV_CID_VIDEO_INIT 0x01000001 42 #define PS3AV_CID_VIDEO_INIT 0x01000001
43 #define PS3AV_CID_VIDEO_MODE 0x01000002 43 #define PS3AV_CID_VIDEO_MODE 0x01000002
44 #define PS3AV_CID_VIDEO_FORMAT 0x01000004 44 #define PS3AV_CID_VIDEO_FORMAT 0x01000004
45 #define PS3AV_CID_VIDEO_PITCH 0x01000005 45 #define PS3AV_CID_VIDEO_PITCH 0x01000005
46 46
47 #define PS3AV_CID_AUDIO_INIT 0x02000001 47 #define PS3AV_CID_AUDIO_INIT 0x02000001
48 #define PS3AV_CID_AUDIO_MODE 0x02000002 48 #define PS3AV_CID_AUDIO_MODE 0x02000002
49 #define PS3AV_CID_AUDIO_MUTE 0x02000003 49 #define PS3AV_CID_AUDIO_MUTE 0x02000003
50 #define PS3AV_CID_AUDIO_ACTIVE 0x02000004 50 #define PS3AV_CID_AUDIO_ACTIVE 0x02000004
51 #define PS3AV_CID_AUDIO_INACTIVE 0x02000005 51 #define PS3AV_CID_AUDIO_INACTIVE 0x02000005
52 #define PS3AV_CID_AUDIO_SPDIF_BIT 0x02000006 52 #define PS3AV_CID_AUDIO_SPDIF_BIT 0x02000006
53 #define PS3AV_CID_AUDIO_CTRL 0x02000007 53 #define PS3AV_CID_AUDIO_CTRL 0x02000007
54 54
55 #define PS3AV_CID_EVENT_UNPLUGGED 0x10000001 55 #define PS3AV_CID_EVENT_UNPLUGGED 0x10000001
56 #define PS3AV_CID_EVENT_PLUGGED 0x10000002 56 #define PS3AV_CID_EVENT_PLUGGED 0x10000002
57 #define PS3AV_CID_EVENT_HDCP_DONE 0x10000003 57 #define PS3AV_CID_EVENT_HDCP_DONE 0x10000003
58 #define PS3AV_CID_EVENT_HDCP_FAIL 0x10000004 58 #define PS3AV_CID_EVENT_HDCP_FAIL 0x10000004
59 #define PS3AV_CID_EVENT_HDCP_AUTH 0x10000005 59 #define PS3AV_CID_EVENT_HDCP_AUTH 0x10000005
60 #define PS3AV_CID_EVENT_HDCP_ERROR 0x10000006 60 #define PS3AV_CID_EVENT_HDCP_ERROR 0x10000006
61 61
62 #define PS3AV_CID_AVB_PARAM 0x04000001 62 #define PS3AV_CID_AVB_PARAM 0x04000001
63 63
64 /* max backend ports */ 64 /* max backend ports */
65 #define PS3AV_HDMI_MAX 2 /* HDMI_0 HDMI_1 */ 65 #define PS3AV_HDMI_MAX 2 /* HDMI_0 HDMI_1 */
66 #define PS3AV_AVMULTI_MAX 1 /* AVMULTI_0 */ 66 #define PS3AV_AVMULTI_MAX 1 /* AVMULTI_0 */
67 #define PS3AV_AV_PORT_MAX (PS3AV_HDMI_MAX + PS3AV_AVMULTI_MAX) 67 #define PS3AV_AV_PORT_MAX (PS3AV_HDMI_MAX + PS3AV_AVMULTI_MAX)
68 #define PS3AV_OPT_PORT_MAX 1 /* SPDIF0 */ 68 #define PS3AV_OPT_PORT_MAX 1 /* SPDIF0 */
69 #define PS3AV_HEAD_MAX 2 /* HEAD_A HEAD_B */ 69 #define PS3AV_HEAD_MAX 2 /* HEAD_A HEAD_B */
70 70
71 /* num of pkt for PS3AV_CID_AVB_PARAM */ 71 /* num of pkt for PS3AV_CID_AVB_PARAM */
72 #define PS3AV_AVB_NUM_VIDEO PS3AV_HEAD_MAX 72 #define PS3AV_AVB_NUM_VIDEO PS3AV_HEAD_MAX
73 #define PS3AV_AVB_NUM_AUDIO 0 /* not supported */ 73 #define PS3AV_AVB_NUM_AUDIO 0 /* not supported */
74 #define PS3AV_AVB_NUM_AV_VIDEO PS3AV_AV_PORT_MAX 74 #define PS3AV_AVB_NUM_AV_VIDEO PS3AV_AV_PORT_MAX
75 #define PS3AV_AVB_NUM_AV_AUDIO PS3AV_HDMI_MAX 75 #define PS3AV_AVB_NUM_AV_AUDIO PS3AV_HDMI_MAX
76 76
77 #define PS3AV_MUTE_PORT_MAX 1 /* num of ports in mute pkt */ 77 #define PS3AV_MUTE_PORT_MAX 1 /* num of ports in mute pkt */
78 78
79 /* event_bit */ 79 /* event_bit */
80 #define PS3AV_CMD_EVENT_BIT_UNPLUGGED (1 << 0) 80 #define PS3AV_CMD_EVENT_BIT_UNPLUGGED (1 << 0)
81 #define PS3AV_CMD_EVENT_BIT_PLUGGED (1 << 1) 81 #define PS3AV_CMD_EVENT_BIT_PLUGGED (1 << 1)
82 #define PS3AV_CMD_EVENT_BIT_HDCP_DONE (1 << 2) 82 #define PS3AV_CMD_EVENT_BIT_HDCP_DONE (1 << 2)
83 #define PS3AV_CMD_EVENT_BIT_HDCP_FAIL (1 << 3) 83 #define PS3AV_CMD_EVENT_BIT_HDCP_FAIL (1 << 3)
84 #define PS3AV_CMD_EVENT_BIT_HDCP_REAUTH (1 << 4) 84 #define PS3AV_CMD_EVENT_BIT_HDCP_REAUTH (1 << 4)
85 #define PS3AV_CMD_EVENT_BIT_HDCP_TOPOLOGY (1 << 5) 85 #define PS3AV_CMD_EVENT_BIT_HDCP_TOPOLOGY (1 << 5)
86 86
87 /* common params */ 87 /* common params */
88 /* mute */ 88 /* mute */
89 #define PS3AV_CMD_MUTE_OFF 0x0000 89 #define PS3AV_CMD_MUTE_OFF 0x0000
90 #define PS3AV_CMD_MUTE_ON 0x0001 90 #define PS3AV_CMD_MUTE_ON 0x0001
91 /* avport */ 91 /* avport */
92 #define PS3AV_CMD_AVPORT_HDMI_0 0x0000 92 #define PS3AV_CMD_AVPORT_HDMI_0 0x0000
93 #define PS3AV_CMD_AVPORT_HDMI_1 0x0001 93 #define PS3AV_CMD_AVPORT_HDMI_1 0x0001
94 #define PS3AV_CMD_AVPORT_AVMULTI_0 0x0010 94 #define PS3AV_CMD_AVPORT_AVMULTI_0 0x0010
95 #define PS3AV_CMD_AVPORT_SPDIF_0 0x0020 95 #define PS3AV_CMD_AVPORT_SPDIF_0 0x0020
96 #define PS3AV_CMD_AVPORT_SPDIF_1 0x0021 96 #define PS3AV_CMD_AVPORT_SPDIF_1 0x0021
97 97
98 /* for av backend */ 98 /* for av backend */
99 /* av_mclk */ 99 /* av_mclk */
100 #define PS3AV_CMD_AV_MCLK_128 0x0000 100 #define PS3AV_CMD_AV_MCLK_128 0x0000
101 #define PS3AV_CMD_AV_MCLK_256 0x0001 101 #define PS3AV_CMD_AV_MCLK_256 0x0001
102 #define PS3AV_CMD_AV_MCLK_512 0x0003 102 #define PS3AV_CMD_AV_MCLK_512 0x0003
103 /* av_inputlen */ 103 /* av_inputlen */
104 #define PS3AV_CMD_AV_INPUTLEN_16 0x02 104 #define PS3AV_CMD_AV_INPUTLEN_16 0x02
105 #define PS3AV_CMD_AV_INPUTLEN_20 0x0a 105 #define PS3AV_CMD_AV_INPUTLEN_20 0x0a
106 #define PS3AV_CMD_AV_INPUTLEN_24 0x0b 106 #define PS3AV_CMD_AV_INPUTLEN_24 0x0b
107 /* alayout */ 107 /* alayout */
108 #define PS3AV_CMD_AV_LAYOUT_32 (1 << 0) 108 #define PS3AV_CMD_AV_LAYOUT_32 (1 << 0)
109 #define PS3AV_CMD_AV_LAYOUT_44 (1 << 1) 109 #define PS3AV_CMD_AV_LAYOUT_44 (1 << 1)
110 #define PS3AV_CMD_AV_LAYOUT_48 (1 << 2) 110 #define PS3AV_CMD_AV_LAYOUT_48 (1 << 2)
111 #define PS3AV_CMD_AV_LAYOUT_88 (1 << 3) 111 #define PS3AV_CMD_AV_LAYOUT_88 (1 << 3)
112 #define PS3AV_CMD_AV_LAYOUT_96 (1 << 4) 112 #define PS3AV_CMD_AV_LAYOUT_96 (1 << 4)
113 #define PS3AV_CMD_AV_LAYOUT_176 (1 << 5) 113 #define PS3AV_CMD_AV_LAYOUT_176 (1 << 5)
114 #define PS3AV_CMD_AV_LAYOUT_192 (1 << 6) 114 #define PS3AV_CMD_AV_LAYOUT_192 (1 << 6)
115 /* hdmi_mode */ 115 /* hdmi_mode */
116 #define PS3AV_CMD_AV_HDMI_MODE_NORMAL 0xff 116 #define PS3AV_CMD_AV_HDMI_MODE_NORMAL 0xff
117 #define PS3AV_CMD_AV_HDMI_HDCP_OFF 0x01 117 #define PS3AV_CMD_AV_HDMI_HDCP_OFF 0x01
118 #define PS3AV_CMD_AV_HDMI_EDID_PASS 0x80 118 #define PS3AV_CMD_AV_HDMI_EDID_PASS 0x80
119 #define PS3AV_CMD_AV_HDMI_DVI 0x40 119 #define PS3AV_CMD_AV_HDMI_DVI 0x40
120 120
121 /* for video module */ 121 /* for video module */
122 /* video_head */ 122 /* video_head */
123 #define PS3AV_CMD_VIDEO_HEAD_A 0x0000 123 #define PS3AV_CMD_VIDEO_HEAD_A 0x0000
124 #define PS3AV_CMD_VIDEO_HEAD_B 0x0001 124 #define PS3AV_CMD_VIDEO_HEAD_B 0x0001
125 /* video_cs_out video_cs_in */ 125 /* video_cs_out video_cs_in */
126 #define PS3AV_CMD_VIDEO_CS_NONE 0x0000 126 #define PS3AV_CMD_VIDEO_CS_NONE 0x0000
127 #define PS3AV_CMD_VIDEO_CS_RGB_8 0x0001 127 #define PS3AV_CMD_VIDEO_CS_RGB_8 0x0001
128 #define PS3AV_CMD_VIDEO_CS_YUV444_8 0x0002 128 #define PS3AV_CMD_VIDEO_CS_YUV444_8 0x0002
129 #define PS3AV_CMD_VIDEO_CS_YUV422_8 0x0003 129 #define PS3AV_CMD_VIDEO_CS_YUV422_8 0x0003
130 #define PS3AV_CMD_VIDEO_CS_XVYCC_8 0x0004 130 #define PS3AV_CMD_VIDEO_CS_XVYCC_8 0x0004
131 #define PS3AV_CMD_VIDEO_CS_RGB_10 0x0005 131 #define PS3AV_CMD_VIDEO_CS_RGB_10 0x0005
132 #define PS3AV_CMD_VIDEO_CS_YUV444_10 0x0006 132 #define PS3AV_CMD_VIDEO_CS_YUV444_10 0x0006
133 #define PS3AV_CMD_VIDEO_CS_YUV422_10 0x0007 133 #define PS3AV_CMD_VIDEO_CS_YUV422_10 0x0007
134 #define PS3AV_CMD_VIDEO_CS_XVYCC_10 0x0008 134 #define PS3AV_CMD_VIDEO_CS_XVYCC_10 0x0008
135 #define PS3AV_CMD_VIDEO_CS_RGB_12 0x0009 135 #define PS3AV_CMD_VIDEO_CS_RGB_12 0x0009
136 #define PS3AV_CMD_VIDEO_CS_YUV444_12 0x000a 136 #define PS3AV_CMD_VIDEO_CS_YUV444_12 0x000a
137 #define PS3AV_CMD_VIDEO_CS_YUV422_12 0x000b 137 #define PS3AV_CMD_VIDEO_CS_YUV422_12 0x000b
138 #define PS3AV_CMD_VIDEO_CS_XVYCC_12 0x000c 138 #define PS3AV_CMD_VIDEO_CS_XVYCC_12 0x000c
139 /* video_vid */ 139 /* video_vid */
140 #define PS3AV_CMD_VIDEO_VID_NONE 0x0000 140 #define PS3AV_CMD_VIDEO_VID_NONE 0x0000
141 #define PS3AV_CMD_VIDEO_VID_480I 0x0001 141 #define PS3AV_CMD_VIDEO_VID_480I 0x0001
142 #define PS3AV_CMD_VIDEO_VID_576I 0x0003 142 #define PS3AV_CMD_VIDEO_VID_576I 0x0003
143 #define PS3AV_CMD_VIDEO_VID_480P 0x0005 143 #define PS3AV_CMD_VIDEO_VID_480P 0x0005
144 #define PS3AV_CMD_VIDEO_VID_576P 0x0006 144 #define PS3AV_CMD_VIDEO_VID_576P 0x0006
145 #define PS3AV_CMD_VIDEO_VID_1080I_60HZ 0x0007 145 #define PS3AV_CMD_VIDEO_VID_1080I_60HZ 0x0007
146 #define PS3AV_CMD_VIDEO_VID_1080I_50HZ 0x0008 146 #define PS3AV_CMD_VIDEO_VID_1080I_50HZ 0x0008
147 #define PS3AV_CMD_VIDEO_VID_720P_60HZ 0x0009 147 #define PS3AV_CMD_VIDEO_VID_720P_60HZ 0x0009
148 #define PS3AV_CMD_VIDEO_VID_720P_50HZ 0x000a 148 #define PS3AV_CMD_VIDEO_VID_720P_50HZ 0x000a
149 #define PS3AV_CMD_VIDEO_VID_1080P_60HZ 0x000b 149 #define PS3AV_CMD_VIDEO_VID_1080P_60HZ 0x000b
150 #define PS3AV_CMD_VIDEO_VID_1080P_50HZ 0x000c 150 #define PS3AV_CMD_VIDEO_VID_1080P_50HZ 0x000c
151 #define PS3AV_CMD_VIDEO_VID_WXGA 0x000d 151 #define PS3AV_CMD_VIDEO_VID_WXGA 0x000d
152 #define PS3AV_CMD_VIDEO_VID_SXGA 0x000e 152 #define PS3AV_CMD_VIDEO_VID_SXGA 0x000e
153 #define PS3AV_CMD_VIDEO_VID_WUXGA 0x000f 153 #define PS3AV_CMD_VIDEO_VID_WUXGA 0x000f
154 #define PS3AV_CMD_VIDEO_VID_480I_A 0x0010 154 #define PS3AV_CMD_VIDEO_VID_480I_A 0x0010
155 /* video_format */ 155 /* video_format */
156 #define PS3AV_CMD_VIDEO_FORMAT_BLACK 0x0000 156 #define PS3AV_CMD_VIDEO_FORMAT_BLACK 0x0000
157 #define PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT 0x0007 157 #define PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT 0x0007
158 /* video_order */ 158 /* video_order */
159 #define PS3AV_CMD_VIDEO_ORDER_RGB 0x0000 159 #define PS3AV_CMD_VIDEO_ORDER_RGB 0x0000
160 #define PS3AV_CMD_VIDEO_ORDER_BGR 0x0001 160 #define PS3AV_CMD_VIDEO_ORDER_BGR 0x0001
161 /* video_fmt */ 161 /* video_fmt */
162 #define PS3AV_CMD_VIDEO_FMT_X8R8G8B8 0x0000 162 #define PS3AV_CMD_VIDEO_FMT_X8R8G8B8 0x0000
163 /* video_out_format */ 163 /* video_out_format */
164 #define PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT 0x0000 164 #define PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT 0x0000
165 /* video_cl_cnv */ 165 /* video_cl_cnv */
166 #define PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT 0x0000 166 #define PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT 0x0000
167 #define PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT 0x0010 167 #define PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT 0x0010
168 /* video_sync */ 168 /* video_sync */
169 #define PS3AV_CMD_VIDEO_SYNC_VSYNC 0x0001 169 #define PS3AV_CMD_VIDEO_SYNC_VSYNC 0x0001
170 #define PS3AV_CMD_VIDEO_SYNC_CSYNC 0x0004 170 #define PS3AV_CMD_VIDEO_SYNC_CSYNC 0x0004
171 #define PS3AV_CMD_VIDEO_SYNC_HSYNC 0x0010 171 #define PS3AV_CMD_VIDEO_SYNC_HSYNC 0x0010
172 172
173 /* for audio module */ 173 /* for audio module */
174 /* num_of_ch */ 174 /* num_of_ch */
175 #define PS3AV_CMD_AUDIO_NUM_OF_CH_2 0x0000 175 #define PS3AV_CMD_AUDIO_NUM_OF_CH_2 0x0000
176 #define PS3AV_CMD_AUDIO_NUM_OF_CH_3 0x0001 176 #define PS3AV_CMD_AUDIO_NUM_OF_CH_3 0x0001
177 #define PS3AV_CMD_AUDIO_NUM_OF_CH_4 0x0002 177 #define PS3AV_CMD_AUDIO_NUM_OF_CH_4 0x0002
178 #define PS3AV_CMD_AUDIO_NUM_OF_CH_5 0x0003 178 #define PS3AV_CMD_AUDIO_NUM_OF_CH_5 0x0003
179 #define PS3AV_CMD_AUDIO_NUM_OF_CH_6 0x0004 179 #define PS3AV_CMD_AUDIO_NUM_OF_CH_6 0x0004
180 #define PS3AV_CMD_AUDIO_NUM_OF_CH_7 0x0005 180 #define PS3AV_CMD_AUDIO_NUM_OF_CH_7 0x0005
181 #define PS3AV_CMD_AUDIO_NUM_OF_CH_8 0x0006 181 #define PS3AV_CMD_AUDIO_NUM_OF_CH_8 0x0006
182 /* audio_fs */ 182 /* audio_fs */
183 #define PS3AV_CMD_AUDIO_FS_32K 0x0001 183 #define PS3AV_CMD_AUDIO_FS_32K 0x0001
184 #define PS3AV_CMD_AUDIO_FS_44K 0x0002 184 #define PS3AV_CMD_AUDIO_FS_44K 0x0002
185 #define PS3AV_CMD_AUDIO_FS_48K 0x0003 185 #define PS3AV_CMD_AUDIO_FS_48K 0x0003
186 #define PS3AV_CMD_AUDIO_FS_88K 0x0004 186 #define PS3AV_CMD_AUDIO_FS_88K 0x0004
187 #define PS3AV_CMD_AUDIO_FS_96K 0x0005 187 #define PS3AV_CMD_AUDIO_FS_96K 0x0005
188 #define PS3AV_CMD_AUDIO_FS_176K 0x0006 188 #define PS3AV_CMD_AUDIO_FS_176K 0x0006
189 #define PS3AV_CMD_AUDIO_FS_192K 0x0007 189 #define PS3AV_CMD_AUDIO_FS_192K 0x0007
190 /* audio_word_bits */ 190 /* audio_word_bits */
191 #define PS3AV_CMD_AUDIO_WORD_BITS_16 0x0001 191 #define PS3AV_CMD_AUDIO_WORD_BITS_16 0x0001
192 #define PS3AV_CMD_AUDIO_WORD_BITS_20 0x0002 192 #define PS3AV_CMD_AUDIO_WORD_BITS_20 0x0002
193 #define PS3AV_CMD_AUDIO_WORD_BITS_24 0x0003 193 #define PS3AV_CMD_AUDIO_WORD_BITS_24 0x0003
194 /* audio_format */ 194 /* audio_format */
195 #define PS3AV_CMD_AUDIO_FORMAT_PCM 0x0001 195 #define PS3AV_CMD_AUDIO_FORMAT_PCM 0x0001
196 #define PS3AV_CMD_AUDIO_FORMAT_BITSTREAM 0x00ff 196 #define PS3AV_CMD_AUDIO_FORMAT_BITSTREAM 0x00ff
197 /* audio_source */ 197 /* audio_source */
198 #define PS3AV_CMD_AUDIO_SOURCE_SERIAL 0x0000 198 #define PS3AV_CMD_AUDIO_SOURCE_SERIAL 0x0000
199 #define PS3AV_CMD_AUDIO_SOURCE_SPDIF 0x0001 199 #define PS3AV_CMD_AUDIO_SOURCE_SPDIF 0x0001
200 /* audio_swap */ 200 /* audio_swap */
201 #define PS3AV_CMD_AUDIO_SWAP_0 0x0000 201 #define PS3AV_CMD_AUDIO_SWAP_0 0x0000
202 #define PS3AV_CMD_AUDIO_SWAP_1 0x0000 202 #define PS3AV_CMD_AUDIO_SWAP_1 0x0000
203 /* audio_map */ 203 /* audio_map */
204 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_0 0x0000 204 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_0 0x0000
205 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_1 0x0001 205 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_1 0x0001
206 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_2 0x0002 206 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_2 0x0002
207 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_3 0x0003 207 #define PS3AV_CMD_AUDIO_MAP_OUTPUT_3 0x0003
208 /* audio_layout */ 208 /* audio_layout */
209 #define PS3AV_CMD_AUDIO_LAYOUT_2CH 0x0000 209 #define PS3AV_CMD_AUDIO_LAYOUT_2CH 0x0000
210 #define PS3AV_CMD_AUDIO_LAYOUT_6CH 0x000b /* LREClr */ 210 #define PS3AV_CMD_AUDIO_LAYOUT_6CH 0x000b /* LREClr */
211 #define PS3AV_CMD_AUDIO_LAYOUT_8CH 0x001f /* LREClrXY */ 211 #define PS3AV_CMD_AUDIO_LAYOUT_8CH 0x001f /* LREClrXY */
212 /* audio_downmix */ 212 /* audio_downmix */
213 #define PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED 0x0000 213 #define PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED 0x0000
214 #define PS3AV_CMD_AUDIO_DOWNMIX_PROHIBITED 0x0001 214 #define PS3AV_CMD_AUDIO_DOWNMIX_PROHIBITED 0x0001
215 215
216 /* audio_port */ 216 /* audio_port */
217 #define PS3AV_CMD_AUDIO_PORT_HDMI_0 ( 1 << 0 ) 217 #define PS3AV_CMD_AUDIO_PORT_HDMI_0 ( 1 << 0 )
218 #define PS3AV_CMD_AUDIO_PORT_HDMI_1 ( 1 << 1 ) 218 #define PS3AV_CMD_AUDIO_PORT_HDMI_1 ( 1 << 1 )
219 #define PS3AV_CMD_AUDIO_PORT_AVMULTI_0 ( 1 << 10 ) 219 #define PS3AV_CMD_AUDIO_PORT_AVMULTI_0 ( 1 << 10 )
220 #define PS3AV_CMD_AUDIO_PORT_SPDIF_0 ( 1 << 20 ) 220 #define PS3AV_CMD_AUDIO_PORT_SPDIF_0 ( 1 << 20 )
221 #define PS3AV_CMD_AUDIO_PORT_SPDIF_1 ( 1 << 21 ) 221 #define PS3AV_CMD_AUDIO_PORT_SPDIF_1 ( 1 << 21 )
222 222
223 /* audio_ctrl_id */ 223 /* audio_ctrl_id */
224 #define PS3AV_CMD_AUDIO_CTRL_ID_DAC_RESET 0x0000 224 #define PS3AV_CMD_AUDIO_CTRL_ID_DAC_RESET 0x0000
225 #define PS3AV_CMD_AUDIO_CTRL_ID_DAC_DE_EMPHASIS 0x0001 225 #define PS3AV_CMD_AUDIO_CTRL_ID_DAC_DE_EMPHASIS 0x0001
226 #define PS3AV_CMD_AUDIO_CTRL_ID_AVCLK 0x0002 226 #define PS3AV_CMD_AUDIO_CTRL_ID_AVCLK 0x0002
227 /* audio_ctrl_data[0] reset */ 227 /* audio_ctrl_data[0] reset */
228 #define PS3AV_CMD_AUDIO_CTRL_RESET_NEGATE 0x0000 228 #define PS3AV_CMD_AUDIO_CTRL_RESET_NEGATE 0x0000
229 #define PS3AV_CMD_AUDIO_CTRL_RESET_ASSERT 0x0001 229 #define PS3AV_CMD_AUDIO_CTRL_RESET_ASSERT 0x0001
230 /* audio_ctrl_data[0] de-emphasis */ 230 /* audio_ctrl_data[0] de-emphasis */
231 #define PS3AV_CMD_AUDIO_CTRL_DE_EMPHASIS_OFF 0x0000 231 #define PS3AV_CMD_AUDIO_CTRL_DE_EMPHASIS_OFF 0x0000
232 #define PS3AV_CMD_AUDIO_CTRL_DE_EMPHASIS_ON 0x0001 232 #define PS3AV_CMD_AUDIO_CTRL_DE_EMPHASIS_ON 0x0001
233 /* audio_ctrl_data[0] avclk */ 233 /* audio_ctrl_data[0] avclk */
234 #define PS3AV_CMD_AUDIO_CTRL_AVCLK_22 0x0000 234 #define PS3AV_CMD_AUDIO_CTRL_AVCLK_22 0x0000
235 #define PS3AV_CMD_AUDIO_CTRL_AVCLK_18 0x0001 235 #define PS3AV_CMD_AUDIO_CTRL_AVCLK_18 0x0001
236 236
237 /* av_vid */ 237 /* av_vid */
238 /* do not use these params directly, use vid_video2av */ 238 /* do not use these params directly, use vid_video2av */
239 #define PS3AV_CMD_AV_VID_480I 0x0000 239 #define PS3AV_CMD_AV_VID_480I 0x0000
240 #define PS3AV_CMD_AV_VID_480P 0x0001 240 #define PS3AV_CMD_AV_VID_480P 0x0001
241 #define PS3AV_CMD_AV_VID_720P_60HZ 0x0002 241 #define PS3AV_CMD_AV_VID_720P_60HZ 0x0002
242 #define PS3AV_CMD_AV_VID_1080I_60HZ 0x0003 242 #define PS3AV_CMD_AV_VID_1080I_60HZ 0x0003
243 #define PS3AV_CMD_AV_VID_1080P_60HZ 0x0004 243 #define PS3AV_CMD_AV_VID_1080P_60HZ 0x0004
244 #define PS3AV_CMD_AV_VID_576I 0x0005 244 #define PS3AV_CMD_AV_VID_576I 0x0005
245 #define PS3AV_CMD_AV_VID_576P 0x0006 245 #define PS3AV_CMD_AV_VID_576P 0x0006
246 #define PS3AV_CMD_AV_VID_720P_50HZ 0x0007 246 #define PS3AV_CMD_AV_VID_720P_50HZ 0x0007
247 #define PS3AV_CMD_AV_VID_1080I_50HZ 0x0008 247 #define PS3AV_CMD_AV_VID_1080I_50HZ 0x0008
248 #define PS3AV_CMD_AV_VID_1080P_50HZ 0x0009 248 #define PS3AV_CMD_AV_VID_1080P_50HZ 0x0009
249 #define PS3AV_CMD_AV_VID_WXGA 0x000a 249 #define PS3AV_CMD_AV_VID_WXGA 0x000a
250 #define PS3AV_CMD_AV_VID_SXGA 0x000b 250 #define PS3AV_CMD_AV_VID_SXGA 0x000b
251 #define PS3AV_CMD_AV_VID_WUXGA 0x000c 251 #define PS3AV_CMD_AV_VID_WUXGA 0x000c
252 /* av_cs_out av_cs_in */ 252 /* av_cs_out av_cs_in */
253 /* use cs_video2av() */ 253 /* use cs_video2av() */
254 #define PS3AV_CMD_AV_CS_RGB_8 0x0000 254 #define PS3AV_CMD_AV_CS_RGB_8 0x0000
255 #define PS3AV_CMD_AV_CS_YUV444_8 0x0001 255 #define PS3AV_CMD_AV_CS_YUV444_8 0x0001
256 #define PS3AV_CMD_AV_CS_YUV422_8 0x0002 256 #define PS3AV_CMD_AV_CS_YUV422_8 0x0002
257 #define PS3AV_CMD_AV_CS_XVYCC_8 0x0003 257 #define PS3AV_CMD_AV_CS_XVYCC_8 0x0003
258 #define PS3AV_CMD_AV_CS_RGB_10 0x0004 258 #define PS3AV_CMD_AV_CS_RGB_10 0x0004
259 #define PS3AV_CMD_AV_CS_YUV444_10 0x0005 259 #define PS3AV_CMD_AV_CS_YUV444_10 0x0005
260 #define PS3AV_CMD_AV_CS_YUV422_10 0x0006 260 #define PS3AV_CMD_AV_CS_YUV422_10 0x0006
261 #define PS3AV_CMD_AV_CS_XVYCC_10 0x0007 261 #define PS3AV_CMD_AV_CS_XVYCC_10 0x0007
262 #define PS3AV_CMD_AV_CS_RGB_12 0x0008 262 #define PS3AV_CMD_AV_CS_RGB_12 0x0008
263 #define PS3AV_CMD_AV_CS_YUV444_12 0x0009 263 #define PS3AV_CMD_AV_CS_YUV444_12 0x0009
264 #define PS3AV_CMD_AV_CS_YUV422_12 0x000a 264 #define PS3AV_CMD_AV_CS_YUV422_12 0x000a
265 #define PS3AV_CMD_AV_CS_XVYCC_12 0x000b 265 #define PS3AV_CMD_AV_CS_XVYCC_12 0x000b
266 #define PS3AV_CMD_AV_CS_8 0x0000 266 #define PS3AV_CMD_AV_CS_8 0x0000
267 #define PS3AV_CMD_AV_CS_10 0x0001 267 #define PS3AV_CMD_AV_CS_10 0x0001
268 #define PS3AV_CMD_AV_CS_12 0x0002 268 #define PS3AV_CMD_AV_CS_12 0x0002
269 /* dither */ 269 /* dither */
270 #define PS3AV_CMD_AV_DITHER_OFF 0x0000 270 #define PS3AV_CMD_AV_DITHER_OFF 0x0000
271 #define PS3AV_CMD_AV_DITHER_ON 0x0001 271 #define PS3AV_CMD_AV_DITHER_ON 0x0001
272 #define PS3AV_CMD_AV_DITHER_8BIT 0x0000 272 #define PS3AV_CMD_AV_DITHER_8BIT 0x0000
273 #define PS3AV_CMD_AV_DITHER_10BIT 0x0002 273 #define PS3AV_CMD_AV_DITHER_10BIT 0x0002
274 #define PS3AV_CMD_AV_DITHER_12BIT 0x0004 274 #define PS3AV_CMD_AV_DITHER_12BIT 0x0004
275 /* super_white */ 275 /* super_white */
276 #define PS3AV_CMD_AV_SUPER_WHITE_OFF 0x0000 276 #define PS3AV_CMD_AV_SUPER_WHITE_OFF 0x0000
277 #define PS3AV_CMD_AV_SUPER_WHITE_ON 0x0001 277 #define PS3AV_CMD_AV_SUPER_WHITE_ON 0x0001
278 /* aspect */ 278 /* aspect */
279 #define PS3AV_CMD_AV_ASPECT_16_9 0x0000 279 #define PS3AV_CMD_AV_ASPECT_16_9 0x0000
280 #define PS3AV_CMD_AV_ASPECT_4_3 0x0001 280 #define PS3AV_CMD_AV_ASPECT_4_3 0x0001
281 /* video_cs_cnv() */ 281 /* video_cs_cnv() */
282 #define PS3AV_CMD_VIDEO_CS_RGB 0x0001 282 #define PS3AV_CMD_VIDEO_CS_RGB 0x0001
283 #define PS3AV_CMD_VIDEO_CS_YUV422 0x0002 283 #define PS3AV_CMD_VIDEO_CS_YUV422 0x0002
284 #define PS3AV_CMD_VIDEO_CS_YUV444 0x0003 284 #define PS3AV_CMD_VIDEO_CS_YUV444 0x0003
285 285
286 /* for broadcast automode */ 286 /* for broadcast automode */
287 #define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */ 287 #define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */
288 #define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */ 288 #define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */
289 #define PS3AV_RESBIT_1280x720P 0x0004 289 #define PS3AV_RESBIT_1280x720P 0x0004
290 #define PS3AV_RESBIT_1920x1080I 0x0008 290 #define PS3AV_RESBIT_1920x1080I 0x0008
291 #define PS3AV_RESBIT_1920x1080P 0x4000 291 #define PS3AV_RESBIT_1920x1080P 0x4000
292 #define PS3AV_RES_MASK_60 (PS3AV_RESBIT_720x480P \ 292 #define PS3AV_RES_MASK_60 (PS3AV_RESBIT_720x480P \
293 | PS3AV_RESBIT_1280x720P \ 293 | PS3AV_RESBIT_1280x720P \
294 | PS3AV_RESBIT_1920x1080I \ 294 | PS3AV_RESBIT_1920x1080I \
295 | PS3AV_RESBIT_1920x1080P) 295 | PS3AV_RESBIT_1920x1080P)
296 #define PS3AV_RES_MASK_50 (PS3AV_RESBIT_720x576P \ 296 #define PS3AV_RES_MASK_50 (PS3AV_RESBIT_720x576P \
297 | PS3AV_RESBIT_1280x720P \ 297 | PS3AV_RESBIT_1280x720P \
298 | PS3AV_RESBIT_1920x1080I \ 298 | PS3AV_RESBIT_1920x1080I \
299 | PS3AV_RESBIT_1920x1080P) 299 | PS3AV_RESBIT_1920x1080P)
300 300
301 /* for VESA automode */ 301 /* for VESA automode */
302 #define PS3AV_RESBIT_VGA 0x0001 302 #define PS3AV_RESBIT_VGA 0x0001
303 #define PS3AV_RESBIT_WXGA 0x0002 303 #define PS3AV_RESBIT_WXGA 0x0002
304 #define PS3AV_RESBIT_SXGA 0x0004 304 #define PS3AV_RESBIT_SXGA 0x0004
305 #define PS3AV_RESBIT_WUXGA 0x0008 305 #define PS3AV_RESBIT_WUXGA 0x0008
306 #define PS3AV_RES_MASK_VESA (PS3AV_RESBIT_WXGA |\ 306 #define PS3AV_RES_MASK_VESA (PS3AV_RESBIT_WXGA |\
307 PS3AV_RESBIT_SXGA |\ 307 PS3AV_RESBIT_SXGA |\
308 PS3AV_RESBIT_WUXGA) 308 PS3AV_RESBIT_WUXGA)
309 309
310 #define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */ 310 #define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */
311 #define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */ 311 #define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */
312 312
313 313
314 /* for video mode */ 314 /* for video mode */
315 enum ps3av_mode_num { 315 enum ps3av_mode_num {
316 PS3AV_MODE_AUTO = 0, 316 PS3AV_MODE_AUTO = 0,
317 PS3AV_MODE_480I = 1, 317 PS3AV_MODE_480I = 1,
318 PS3AV_MODE_480P = 2, 318 PS3AV_MODE_480P = 2,
319 PS3AV_MODE_720P60 = 3, 319 PS3AV_MODE_720P60 = 3,
320 PS3AV_MODE_1080I60 = 4, 320 PS3AV_MODE_1080I60 = 4,
321 PS3AV_MODE_1080P60 = 5, 321 PS3AV_MODE_1080P60 = 5,
322 PS3AV_MODE_576I = 6, 322 PS3AV_MODE_576I = 6,
323 PS3AV_MODE_576P = 7, 323 PS3AV_MODE_576P = 7,
324 PS3AV_MODE_720P50 = 8, 324 PS3AV_MODE_720P50 = 8,
325 PS3AV_MODE_1080I50 = 9, 325 PS3AV_MODE_1080I50 = 9,
326 PS3AV_MODE_1080P50 = 10, 326 PS3AV_MODE_1080P50 = 10,
327 PS3AV_MODE_WXGA = 11, 327 PS3AV_MODE_WXGA = 11,
328 PS3AV_MODE_SXGA = 12, 328 PS3AV_MODE_SXGA = 12,
329 PS3AV_MODE_WUXGA = 13, 329 PS3AV_MODE_WUXGA = 13,
330 }; 330 };
331 331
332 #define PS3AV_MODE_MASK 0x000F 332 #define PS3AV_MODE_MASK 0x000F
333 #define PS3AV_MODE_HDCP_OFF 0x1000 /* Retail PS3 product doesn't support this */ 333 #define PS3AV_MODE_HDCP_OFF 0x1000 /* Retail PS3 product doesn't support this */
334 #define PS3AV_MODE_DITHER 0x0800 334 #define PS3AV_MODE_DITHER 0x0800
335 #define PS3AV_MODE_COLOR 0x0400 335 #define PS3AV_MODE_COLOR 0x0400
336 #define PS3AV_MODE_WHITE 0x0200 336 #define PS3AV_MODE_WHITE 0x0200
337 #define PS3AV_MODE_FULL 0x0080 337 #define PS3AV_MODE_FULL 0x0080
338 #define PS3AV_MODE_DVI 0x0040 338 #define PS3AV_MODE_DVI 0x0040
339 #define PS3AV_MODE_RGB 0x0020 339 #define PS3AV_MODE_RGB 0x0020
340 340
341 341
342 #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60 PS3AV_MODE_480P 342 #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60 PS3AV_MODE_480P
343 #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60 PS3AV_MODE_480I 343 #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60 PS3AV_MODE_480I
344 #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50 PS3AV_MODE_576P 344 #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50 PS3AV_MODE_576P
345 #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50 PS3AV_MODE_576I 345 #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50 PS3AV_MODE_576I
346 346
347 #define PS3AV_REGION_60 0x01 347 #define PS3AV_REGION_60 0x01
348 #define PS3AV_REGION_50 0x02 348 #define PS3AV_REGION_50 0x02
349 #define PS3AV_REGION_RGB 0x10 349 #define PS3AV_REGION_RGB 0x10
350 350
351 #define get_status(buf) (((__u32 *)buf)[2]) 351 #define get_status(buf) (((__u32 *)buf)[2])
352 #define PS3AV_HDR_SIZE 4 /* version + size */ 352 #define PS3AV_HDR_SIZE 4 /* version + size */
353 353
354 354
355 /** command packet structure **/ 355 /** command packet structure **/
356 struct ps3av_send_hdr { 356 struct ps3av_send_hdr {
357 u16 version; 357 u16 version;
358 u16 size; /* size of command packet */ 358 u16 size; /* size of command packet */
359 u32 cid; /* command id */ 359 u32 cid; /* command id */
360 }; 360 };
361 361
362 struct ps3av_reply_hdr { 362 struct ps3av_reply_hdr {
363 u16 version; 363 u16 version;
364 u16 size; 364 u16 size;
365 u32 cid; 365 u32 cid;
366 u32 status; 366 u32 status;
367 }; 367 };
368 368
369 /* backend: initialization */ 369 /* backend: initialization */
370 struct ps3av_pkt_av_init { 370 struct ps3av_pkt_av_init {
371 struct ps3av_send_hdr send_hdr; 371 struct ps3av_send_hdr send_hdr;
372 u32 event_bit; 372 u32 event_bit;
373 }; 373 };
374 374
375 /* backend: finalize */ 375 /* backend: finalize */
376 struct ps3av_pkt_av_fin { 376 struct ps3av_pkt_av_fin {
377 struct ps3av_send_hdr send_hdr; 377 struct ps3av_send_hdr send_hdr;
378 /* recv */ 378 /* recv */
379 u32 reserved; 379 u32 reserved;
380 }; 380 };
381 381
382 /* backend: get port */ 382 /* backend: get port */
383 struct ps3av_pkt_av_get_hw_conf { 383 struct ps3av_pkt_av_get_hw_conf {
384 struct ps3av_send_hdr send_hdr; 384 struct ps3av_send_hdr send_hdr;
385 /* recv */ 385 /* recv */
386 u32 status; 386 u32 status;
387 u16 num_of_hdmi; /* out: number of hdmi */ 387 u16 num_of_hdmi; /* out: number of hdmi */
388 u16 num_of_avmulti; /* out: number of avmulti */ 388 u16 num_of_avmulti; /* out: number of avmulti */
389 u16 num_of_spdif; /* out: number of hdmi */ 389 u16 num_of_spdif; /* out: number of hdmi */
390 u16 reserved; 390 u16 reserved;
391 }; 391 };
392 392
393 /* backend: get monitor info */ 393 /* backend: get monitor info */
394 struct ps3av_info_resolution { 394 struct ps3av_info_resolution {
395 u32 res_bits; 395 u32 res_bits;
396 u32 native; 396 u32 native;
397 }; 397 };
398 398
399 struct ps3av_info_cs { 399 struct ps3av_info_cs {
400 u8 rgb; 400 u8 rgb;
401 u8 yuv444; 401 u8 yuv444;
402 u8 yuv422; 402 u8 yuv422;
403 u8 reserved; 403 u8 reserved;
404 }; 404 };
405 405
406 struct ps3av_info_color { 406 struct ps3av_info_color {
407 u16 red_x; 407 u16 red_x;
408 u16 red_y; 408 u16 red_y;
409 u16 green_x; 409 u16 green_x;
410 u16 green_y; 410 u16 green_y;
411 u16 blue_x; 411 u16 blue_x;
412 u16 blue_y; 412 u16 blue_y;
413 u16 white_x; 413 u16 white_x;
414 u16 white_y; 414 u16 white_y;
415 u32 gamma; 415 u32 gamma;
416 }; 416 };
417 417
418 struct ps3av_info_audio { 418 struct ps3av_info_audio {
419 u8 type; 419 u8 type;
420 u8 max_num_of_ch; 420 u8 max_num_of_ch;
421 u8 fs; 421 u8 fs;
422 u8 sbit; 422 u8 sbit;
423 }; 423 };
424 424
425 struct ps3av_info_monitor { 425 struct ps3av_info_monitor {
426 u8 avport; 426 u8 avport;
427 u8 monitor_id[10]; 427 u8 monitor_id[10];
428 u8 monitor_type; 428 u8 monitor_type;
429 u8 monitor_name[16]; 429 u8 monitor_name[16];
430 struct ps3av_info_resolution res_60; 430 struct ps3av_info_resolution res_60;
431 struct ps3av_info_resolution res_50; 431 struct ps3av_info_resolution res_50;
432 struct ps3av_info_resolution res_other; 432 struct ps3av_info_resolution res_other;
433 struct ps3av_info_resolution res_vesa; 433 struct ps3av_info_resolution res_vesa;
434 struct ps3av_info_cs cs; 434 struct ps3av_info_cs cs;
435 struct ps3av_info_color color; 435 struct ps3av_info_color color;
436 u8 supported_ai; 436 u8 supported_ai;
437 u8 speaker_info; 437 u8 speaker_info;
438 u8 num_of_audio_block; 438 u8 num_of_audio_block;
439 struct ps3av_info_audio audio[0]; /* 0 or more audio blocks */ 439 struct ps3av_info_audio audio[0]; /* 0 or more audio blocks */
440 u8 reserved[169]; 440 u8 reserved[169];
441 } __attribute__ ((packed)); 441 } __attribute__ ((packed));
442 442
443 struct ps3av_pkt_av_get_monitor_info { 443 struct ps3av_pkt_av_get_monitor_info {
444 struct ps3av_send_hdr send_hdr; 444 struct ps3av_send_hdr send_hdr;
445 u16 avport; /* in: avport */ 445 u16 avport; /* in: avport */
446 u16 reserved; 446 u16 reserved;
447 /* recv */ 447 /* recv */
448 struct ps3av_info_monitor info; /* out: monitor info */ 448 struct ps3av_info_monitor info; /* out: monitor info */
449 }; 449 };
450 450
451 /* backend: enable/disable event */ 451 /* backend: enable/disable event */
452 struct ps3av_pkt_av_event { 452 struct ps3av_pkt_av_event {
453 struct ps3av_send_hdr send_hdr; 453 struct ps3av_send_hdr send_hdr;
454 u32 event_bit; /* in */ 454 u32 event_bit; /* in */
455 }; 455 };
456 456
457 /* backend: video cs param */ 457 /* backend: video cs param */
458 struct ps3av_pkt_av_video_cs { 458 struct ps3av_pkt_av_video_cs {
459 struct ps3av_send_hdr send_hdr; 459 struct ps3av_send_hdr send_hdr;
460 u16 avport; /* in: avport */ 460 u16 avport; /* in: avport */
461 u16 av_vid; /* in: video resolution */ 461 u16 av_vid; /* in: video resolution */
462 u16 av_cs_out; /* in: output color space */ 462 u16 av_cs_out; /* in: output color space */
463 u16 av_cs_in; /* in: input color space */ 463 u16 av_cs_in; /* in: input color space */
464 u8 dither; /* in: dither bit length */ 464 u8 dither; /* in: dither bit length */
465 u8 bitlen_out; /* in: bit length */ 465 u8 bitlen_out; /* in: bit length */
466 u8 super_white; /* in: super white */ 466 u8 super_white; /* in: super white */
467 u8 aspect; /* in: aspect ratio */ 467 u8 aspect; /* in: aspect ratio */
468 }; 468 };
469 469
470 /* backend: video mute */ 470 /* backend: video mute */
471 struct ps3av_av_mute { 471 struct ps3av_av_mute {
472 u16 avport; /* in: avport */ 472 u16 avport; /* in: avport */
473 u16 mute; /* in: mute on/off */ 473 u16 mute; /* in: mute on/off */
474 }; 474 };
475 475
476 struct ps3av_pkt_av_video_mute { 476 struct ps3av_pkt_av_video_mute {
477 struct ps3av_send_hdr send_hdr; 477 struct ps3av_send_hdr send_hdr;
478 struct ps3av_av_mute mute[PS3AV_MUTE_PORT_MAX]; 478 struct ps3av_av_mute mute[PS3AV_MUTE_PORT_MAX];
479 }; 479 };
480 480
481 /* backend: video disable signal */ 481 /* backend: video disable signal */
482 struct ps3av_pkt_av_video_disable_sig { 482 struct ps3av_pkt_av_video_disable_sig {
483 struct ps3av_send_hdr send_hdr; 483 struct ps3av_send_hdr send_hdr;
484 u16 avport; /* in: avport */ 484 u16 avport; /* in: avport */
485 u16 reserved; 485 u16 reserved;
486 }; 486 };
487 487
488 /* backend: audio param */ 488 /* backend: audio param */
489 struct ps3av_audio_info_frame { 489 struct ps3av_audio_info_frame {
490 struct pb1_bit { 490 struct pb1_bit {
491 u8 ct:4; 491 u8 ct:4;
492 u8 rsv:1; 492 u8 rsv:1;
493 u8 cc:3; 493 u8 cc:3;
494 } pb1; 494 } pb1;
495 struct pb2_bit { 495 struct pb2_bit {
496 u8 rsv:3; 496 u8 rsv:3;
497 u8 sf:3; 497 u8 sf:3;
498 u8 ss:2; 498 u8 ss:2;
499 } pb2; 499 } pb2;
500 u8 pb3; 500 u8 pb3;
501 u8 pb4; 501 u8 pb4;
502 struct pb5_bit { 502 struct pb5_bit {
503 u8 dm:1; 503 u8 dm:1;
504 u8 lsv:4; 504 u8 lsv:4;
505 u8 rsv:3; 505 u8 rsv:3;
506 } pb5; 506 } pb5;
507 }; 507 };
508 508
509 struct ps3av_pkt_av_audio_param { 509 struct ps3av_pkt_av_audio_param {
510 struct ps3av_send_hdr send_hdr; 510 struct ps3av_send_hdr send_hdr;
511 u16 avport; /* in: avport */ 511 u16 avport; /* in: avport */
512 u16 reserved; 512 u16 reserved;
513 u8 mclk; /* in: audio mclk */ 513 u8 mclk; /* in: audio mclk */
514 u8 ns[3]; /* in: audio ns val */ 514 u8 ns[3]; /* in: audio ns val */
515 u8 enable; /* in: audio enable */ 515 u8 enable; /* in: audio enable */
516 u8 swaplr; /* in: audio swap */ 516 u8 swaplr; /* in: audio swap */
517 u8 fifomap; /* in: audio fifomap */ 517 u8 fifomap; /* in: audio fifomap */
518 u8 inputctrl; /* in: audio input ctrl */ 518 u8 inputctrl; /* in: audio input ctrl */
519 u8 inputlen; /* in: sample bit size */ 519 u8 inputlen; /* in: sample bit size */
520 u8 layout; /* in: speaker layout param */ 520 u8 layout; /* in: speaker layout param */
521 struct ps3av_audio_info_frame info; /* in: info */ 521 struct ps3av_audio_info_frame info; /* in: info */
522 u8 chstat[5]; /* in: ch stat */ 522 u8 chstat[5]; /* in: ch stat */
523 }; 523 };
524 524
525 /* backend: audio_mute */ 525 /* backend: audio_mute */
526 struct ps3av_pkt_av_audio_mute { 526 struct ps3av_pkt_av_audio_mute {
527 struct ps3av_send_hdr send_hdr; 527 struct ps3av_send_hdr send_hdr;
528 struct ps3av_av_mute mute[PS3AV_MUTE_PORT_MAX]; 528 struct ps3av_av_mute mute[PS3AV_MUTE_PORT_MAX];
529 }; 529 };
530 530
531 /* backend: hdmi_mode */ 531 /* backend: hdmi_mode */
532 struct ps3av_pkt_av_hdmi_mode { 532 struct ps3av_pkt_av_hdmi_mode {
533 struct ps3av_send_hdr send_hdr; 533 struct ps3av_send_hdr send_hdr;
534 u8 mode; /* in: hdmi_mode */ 534 u8 mode; /* in: hdmi_mode */
535 u8 reserved0; 535 u8 reserved0;
536 u8 reserved1; 536 u8 reserved1;
537 u8 reserved2; 537 u8 reserved2;
538 }; 538 };
539 539
540 /* backend: tv_mute */ 540 /* backend: tv_mute */
541 struct ps3av_pkt_av_tv_mute { 541 struct ps3av_pkt_av_tv_mute {
542 struct ps3av_send_hdr send_hdr; 542 struct ps3av_send_hdr send_hdr;
543 u16 avport; /* in: avport HDMI only */ 543 u16 avport; /* in: avport HDMI only */
544 u16 mute; /* in: mute */ 544 u16 mute; /* in: mute */
545 }; 545 };
546 546
547 /* video: initialize */ 547 /* video: initialize */
548 struct ps3av_pkt_video_init { 548 struct ps3av_pkt_video_init {
549 struct ps3av_send_hdr send_hdr; 549 struct ps3av_send_hdr send_hdr;
550 /* recv */ 550 /* recv */
551 u32 reserved; 551 u32 reserved;
552 }; 552 };
553 553
554 /* video: mode setting */ 554 /* video: mode setting */
555 struct ps3av_pkt_video_mode { 555 struct ps3av_pkt_video_mode {
556 struct ps3av_send_hdr send_hdr; 556 struct ps3av_send_hdr send_hdr;
557 u32 video_head; /* in: head */ 557 u32 video_head; /* in: head */
558 u32 reserved; 558 u32 reserved;
559 u32 video_vid; /* in: video resolution */ 559 u32 video_vid; /* in: video resolution */
560 u16 reserved1; 560 u16 reserved1;
561 u16 width; /* in: width in pixel */ 561 u16 width; /* in: width in pixel */
562 u16 reserved2; 562 u16 reserved2;
563 u16 height; /* in: height in pixel */ 563 u16 height; /* in: height in pixel */
564 u32 pitch; /* in: line size in byte */ 564 u32 pitch; /* in: line size in byte */
565 u32 video_out_format; /* in: out format */ 565 u32 video_out_format; /* in: out format */
566 u32 video_format; /* in: input frame buffer format */ 566 u32 video_format; /* in: input frame buffer format */
567 u8 reserved3; 567 u8 reserved3;
568 u8 video_cl_cnv; /* in: color conversion */ 568 u8 video_cl_cnv; /* in: color conversion */
569 u16 video_order; /* in: input RGB order */ 569 u16 video_order; /* in: input RGB order */
570 u32 reserved4; 570 u32 reserved4;
571 }; 571 };
572 572
573 /* video: format */ 573 /* video: format */
574 struct ps3av_pkt_video_format { 574 struct ps3av_pkt_video_format {
575 struct ps3av_send_hdr send_hdr; 575 struct ps3av_send_hdr send_hdr;
576 u32 video_head; /* in: head */ 576 u32 video_head; /* in: head */
577 u32 video_format; /* in: frame buffer format */ 577 u32 video_format; /* in: frame buffer format */
578 u8 reserved; 578 u8 reserved;
579 u8 video_cl_cnv; /* in: color conversion */ 579 u8 video_cl_cnv; /* in: color conversion */
580 u16 video_order; /* in: input RGB order */ 580 u16 video_order; /* in: input RGB order */
581 }; 581 };
582 582
583 /* video: pitch */ 583 /* video: pitch */
584 struct ps3av_pkt_video_pitch { 584 struct ps3av_pkt_video_pitch {
585 u16 version; 585 u16 version;
586 u16 size; /* size of command packet */ 586 u16 size; /* size of command packet */
587 u32 cid; /* command id */ 587 u32 cid; /* command id */
588 u32 video_head; /* in: head */ 588 u32 video_head; /* in: head */
589 u32 pitch; /* in: line size in byte */ 589 u32 pitch; /* in: line size in byte */
590 }; 590 };
591 591
592 /* audio: initialize */ 592 /* audio: initialize */
593 struct ps3av_pkt_audio_init { 593 struct ps3av_pkt_audio_init {
594 struct ps3av_send_hdr send_hdr; 594 struct ps3av_send_hdr send_hdr;
595 /* recv */ 595 /* recv */
596 u32 reserved; 596 u32 reserved;
597 }; 597 };
598 598
599 /* audio: mode setting */ 599 /* audio: mode setting */
600 struct ps3av_pkt_audio_mode { 600 struct ps3av_pkt_audio_mode {
601 struct ps3av_send_hdr send_hdr; 601 struct ps3av_send_hdr send_hdr;
602 u8 avport; /* in: avport */ 602 u8 avport; /* in: avport */
603 u8 reserved0[3]; 603 u8 reserved0[3];
604 u32 mask; /* in: mask */ 604 u32 mask; /* in: mask */
605 u32 audio_num_of_ch; /* in: number of ch */ 605 u32 audio_num_of_ch; /* in: number of ch */
606 u32 audio_fs; /* in: sampling freq */ 606 u32 audio_fs; /* in: sampling freq */
607 u32 audio_word_bits; /* in: sample bit size */ 607 u32 audio_word_bits; /* in: sample bit size */
608 u32 audio_format; /* in: audio output format */ 608 u32 audio_format; /* in: audio output format */
609 u32 audio_source; /* in: audio source */ 609 u32 audio_source; /* in: audio source */
610 u8 audio_enable[4]; /* in: audio enable */ 610 u8 audio_enable[4]; /* in: audio enable */
611 u8 audio_swap[4]; /* in: audio swap */ 611 u8 audio_swap[4]; /* in: audio swap */
612 u8 audio_map[4]; /* in: audio map */ 612 u8 audio_map[4]; /* in: audio map */
613 u32 audio_layout; /* in: speaker layout */ 613 u32 audio_layout; /* in: speaker layout */
614 u32 audio_downmix; /* in: audio downmix permission */ 614 u32 audio_downmix; /* in: audio downmix permission */
615 u32 audio_downmix_level; 615 u32 audio_downmix_level;
616 u8 audio_cs_info[8]; /* in: IEC channel status */ 616 u8 audio_cs_info[8]; /* in: IEC channel status */
617 }; 617 };
618 618
619 /* audio: mute */ 619 /* audio: mute */
620 struct ps3av_audio_mute { 620 struct ps3av_audio_mute {
621 u8 avport; /* in: opt_port optical */ 621 u8 avport; /* in: opt_port optical */
622 u8 reserved[3]; 622 u8 reserved[3];
623 u32 mute; /* in: mute */ 623 u32 mute; /* in: mute */
624 }; 624 };
625 625
626 struct ps3av_pkt_audio_mute { 626 struct ps3av_pkt_audio_mute {
627 struct ps3av_send_hdr send_hdr; 627 struct ps3av_send_hdr send_hdr;
628 struct ps3av_audio_mute mute[PS3AV_OPT_PORT_MAX]; 628 struct ps3av_audio_mute mute[PS3AV_OPT_PORT_MAX];
629 }; 629 };
630 630
631 /* audio: active/inactive */ 631 /* audio: active/inactive */
632 struct ps3av_pkt_audio_active { 632 struct ps3av_pkt_audio_active {
633 struct ps3av_send_hdr send_hdr; 633 struct ps3av_send_hdr send_hdr;
634 u32 audio_port; /* in: audio active/inactive port */ 634 u32 audio_port; /* in: audio active/inactive port */
635 }; 635 };
636 636
637 /* audio: SPDIF user bit */ 637 /* audio: SPDIF user bit */
638 struct ps3av_pkt_audio_spdif_bit { 638 struct ps3av_pkt_audio_spdif_bit {
639 u16 version; 639 u16 version;
640 u16 size; /* size of command packet */ 640 u16 size; /* size of command packet */
641 u32 cid; /* command id */ 641 u32 cid; /* command id */
642 u8 avport; /* in: avport SPDIF only */ 642 u8 avport; /* in: avport SPDIF only */
643 u8 reserved[3]; 643 u8 reserved[3];
644 u32 audio_port; /* in: SPDIF only */ 644 u32 audio_port; /* in: SPDIF only */
645 u32 spdif_bit_data[12]; /* in: user bit data */ 645 u32 spdif_bit_data[12]; /* in: user bit data */
646 }; 646 };
647 647
648 /* audio: audio control */ 648 /* audio: audio control */
649 struct ps3av_pkt_audio_ctrl { 649 struct ps3av_pkt_audio_ctrl {
650 u16 version; 650 u16 version;
651 u16 size; /* size of command packet */ 651 u16 size; /* size of command packet */
652 u32 cid; /* command id */ 652 u32 cid; /* command id */
653 u32 audio_ctrl_id; /* in: control id */ 653 u32 audio_ctrl_id; /* in: control id */
654 u32 audio_ctrl_data[4]; /* in: control data */ 654 u32 audio_ctrl_data[4]; /* in: control data */
655 }; 655 };
656 656
657 /* avb:param */ 657 /* avb:param */
658 #define PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE \ 658 #define PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE \
659 (PS3AV_AVB_NUM_VIDEO*sizeof(struct ps3av_pkt_video_mode) + \ 659 (PS3AV_AVB_NUM_VIDEO*sizeof(struct ps3av_pkt_video_mode) + \
660 PS3AV_AVB_NUM_AUDIO*sizeof(struct ps3av_pkt_audio_mode) + \ 660 PS3AV_AVB_NUM_AUDIO*sizeof(struct ps3av_pkt_audio_mode) + \
661 PS3AV_AVB_NUM_AV_VIDEO*sizeof(struct ps3av_pkt_av_video_cs) + \ 661 PS3AV_AVB_NUM_AV_VIDEO*sizeof(struct ps3av_pkt_av_video_cs) + \
662 PS3AV_AVB_NUM_AV_AUDIO*sizeof(struct ps3av_pkt_av_audio_param)) 662 PS3AV_AVB_NUM_AV_AUDIO*sizeof(struct ps3av_pkt_av_audio_param))
663 663
664 struct ps3av_pkt_avb_param { 664 struct ps3av_pkt_avb_param {
665 struct ps3av_send_hdr send_hdr; 665 struct ps3av_send_hdr send_hdr;
666 u16 num_of_video_pkt; 666 u16 num_of_video_pkt;
667 u16 num_of_audio_pkt; 667 u16 num_of_audio_pkt;
668 u16 num_of_av_video_pkt; 668 u16 num_of_av_video_pkt;
669 u16 num_of_av_audio_pkt; 669 u16 num_of_av_audio_pkt;
670 /* 670 /*
671 * The actual buffer layout depends on the fields above: 671 * The actual buffer layout depends on the fields above:
672 * 672 *
673 * struct ps3av_pkt_video_mode video[num_of_video_pkt]; 673 * struct ps3av_pkt_video_mode video[num_of_video_pkt];
674 * struct ps3av_pkt_audio_mode audio[num_of_audio_pkt]; 674 * struct ps3av_pkt_audio_mode audio[num_of_audio_pkt];
675 * struct ps3av_pkt_av_video_cs av_video[num_of_av_video_pkt]; 675 * struct ps3av_pkt_av_video_cs av_video[num_of_av_video_pkt];
676 * struct ps3av_pkt_av_audio_param av_audio[num_of_av_audio_pkt]; 676 * struct ps3av_pkt_av_audio_param av_audio[num_of_av_audio_pkt];
677 */ 677 */
678 u8 buf[PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE]; 678 u8 buf[PS3AV_PKT_AVB_PARAM_MAX_BUF_SIZE];
679 }; 679 };
680 680
681 /* channel status */ 681 /* channel status */
682 extern u8 ps3av_mode_cs_info[]; 682 extern u8 ps3av_mode_cs_info[];
683 683
684 /** command status **/ 684 /** command status **/
685 #define PS3AV_STATUS_SUCCESS 0x0000 /* success */ 685 #define PS3AV_STATUS_SUCCESS 0x0000 /* success */
686 #define PS3AV_STATUS_RECEIVE_VUART_ERROR 0x0001 /* receive vuart error */ 686 #define PS3AV_STATUS_RECEIVE_VUART_ERROR 0x0001 /* receive vuart error */
687 #define PS3AV_STATUS_SYSCON_COMMUNICATE_FAIL 0x0002 /* syscon communication error */ 687 #define PS3AV_STATUS_SYSCON_COMMUNICATE_FAIL 0x0002 /* syscon communication error */
688 #define PS3AV_STATUS_INVALID_COMMAND 0x0003 /* obsolete invalid CID */ 688 #define PS3AV_STATUS_INVALID_COMMAND 0x0003 /* obsolete invalid CID */
689 #define PS3AV_STATUS_INVALID_PORT 0x0004 /* invalid port number */ 689 #define PS3AV_STATUS_INVALID_PORT 0x0004 /* invalid port number */
690 #define PS3AV_STATUS_INVALID_VID 0x0005 /* invalid video format */ 690 #define PS3AV_STATUS_INVALID_VID 0x0005 /* invalid video format */
691 #define PS3AV_STATUS_INVALID_COLOR_SPACE 0x0006 /* invalid video colose space */ 691 #define PS3AV_STATUS_INVALID_COLOR_SPACE 0x0006 /* invalid video colose space */
692 #define PS3AV_STATUS_INVALID_FS 0x0007 /* invalid audio sampling freq */ 692 #define PS3AV_STATUS_INVALID_FS 0x0007 /* invalid audio sampling freq */
693 #define PS3AV_STATUS_INVALID_AUDIO_CH 0x0008 /* invalid audio channel number */ 693 #define PS3AV_STATUS_INVALID_AUDIO_CH 0x0008 /* invalid audio channel number */
694 #define PS3AV_STATUS_UNSUPPORTED_VERSION 0x0009 /* version mismatch */ 694 #define PS3AV_STATUS_UNSUPPORTED_VERSION 0x0009 /* version mismatch */
695 #define PS3AV_STATUS_INVALID_SAMPLE_SIZE 0x000a /* invalid audio sample bit size */ 695 #define PS3AV_STATUS_INVALID_SAMPLE_SIZE 0x000a /* invalid audio sample bit size */
696 #define PS3AV_STATUS_FAILURE 0x000b /* other failures */ 696 #define PS3AV_STATUS_FAILURE 0x000b /* other failures */
697 #define PS3AV_STATUS_UNSUPPORTED_COMMAND 0x000c /* unsupported cid */ 697 #define PS3AV_STATUS_UNSUPPORTED_COMMAND 0x000c /* unsupported cid */
698 #define PS3AV_STATUS_BUFFER_OVERFLOW 0x000d /* write buffer overflow */ 698 #define PS3AV_STATUS_BUFFER_OVERFLOW 0x000d /* write buffer overflow */
699 #define PS3AV_STATUS_INVALID_VIDEO_PARAM 0x000e /* invalid video param */ 699 #define PS3AV_STATUS_INVALID_VIDEO_PARAM 0x000e /* invalid video param */
700 #define PS3AV_STATUS_NO_SEL 0x000f /* not exist selector */ 700 #define PS3AV_STATUS_NO_SEL 0x000f /* not exist selector */
701 #define PS3AV_STATUS_INVALID_AV_PARAM 0x0010 /* invalid backend param */ 701 #define PS3AV_STATUS_INVALID_AV_PARAM 0x0010 /* invalid backend param */
702 #define PS3AV_STATUS_INVALID_AUDIO_PARAM 0x0011 /* invalid audio param */ 702 #define PS3AV_STATUS_INVALID_AUDIO_PARAM 0x0011 /* invalid audio param */
703 #define PS3AV_STATUS_UNSUPPORTED_HDMI_MODE 0x0012 /* unsupported hdmi mode */ 703 #define PS3AV_STATUS_UNSUPPORTED_HDMI_MODE 0x0012 /* unsupported hdmi mode */
704 #define PS3AV_STATUS_NO_SYNC_HEAD 0x0013 /* sync head failed */ 704 #define PS3AV_STATUS_NO_SYNC_HEAD 0x0013 /* sync head failed */
705 705
706 extern void ps3av_set_hdr(u32, u16, struct ps3av_send_hdr *); 706 extern void ps3av_set_hdr(u32, u16, struct ps3av_send_hdr *);
707 extern int ps3av_do_pkt(u32, u16, size_t, struct ps3av_send_hdr *); 707 extern int ps3av_do_pkt(u32, u16, size_t, struct ps3av_send_hdr *);
708 708
709 extern int ps3av_cmd_init(void); 709 extern int ps3av_cmd_init(void);
710 extern int ps3av_cmd_fin(void); 710 extern int ps3av_cmd_fin(void);
711 extern int ps3av_cmd_av_video_mute(int, u32 *, u32); 711 extern int ps3av_cmd_av_video_mute(int, u32 *, u32);
712 extern int ps3av_cmd_av_video_disable_sig(u32); 712 extern int ps3av_cmd_av_video_disable_sig(u32);
713 extern int ps3av_cmd_av_tv_mute(u32, u32); 713 extern int ps3av_cmd_av_tv_mute(u32, u32);
714 extern int ps3av_cmd_enable_event(void); 714 extern int ps3av_cmd_enable_event(void);
715 extern int ps3av_cmd_av_hdmi_mode(u8); 715 extern int ps3av_cmd_av_hdmi_mode(u8);
716 extern u32 ps3av_cmd_set_av_video_cs(void *, u32, int, int, int, u32); 716 extern u32 ps3av_cmd_set_av_video_cs(void *, u32, int, int, int, u32);
717 extern u32 ps3av_cmd_set_video_mode(void *, u32, int, int, u32); 717 extern u32 ps3av_cmd_set_video_mode(void *, u32, int, int, u32);
718 extern int ps3av_cmd_video_format_black(u32, u32, u32); 718 extern int ps3av_cmd_video_format_black(u32, u32, u32);
719 extern int ps3av_cmd_av_audio_mute(int, u32 *, u32); 719 extern int ps3av_cmd_av_audio_mute(int, u32 *, u32);
720 extern u32 ps3av_cmd_set_av_audio_param(void *, u32, 720 extern u32 ps3av_cmd_set_av_audio_param(void *, u32,
721 const struct ps3av_pkt_audio_mode *, 721 const struct ps3av_pkt_audio_mode *,
722 u32); 722 u32);
723 extern void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *, u32, u32, 723 extern void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *, u32, u32,
724 u32, u32, u32, u32); 724 u32, u32, u32, u32);
725 extern int ps3av_cmd_audio_mode(struct ps3av_pkt_audio_mode *); 725 extern int ps3av_cmd_audio_mode(struct ps3av_pkt_audio_mode *);
726 extern int ps3av_cmd_audio_mute(int, u32 *, u32); 726 extern int ps3av_cmd_audio_mute(int, u32 *, u32);
727 extern int ps3av_cmd_audio_active(int, u32); 727 extern int ps3av_cmd_audio_active(int, u32);
728 extern int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *, u32); 728 extern int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *, u32);
729 extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *); 729 extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *);
730 extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *, 730 extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *,
731 u32); 731 u32);
732 732
733 extern int ps3av_set_video_mode(u32); 733 extern int ps3av_set_video_mode(u32);
734 extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); 734 extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
735 extern int ps3av_get_auto_mode(void); 735 extern int ps3av_get_auto_mode(void);
736 extern int ps3av_get_mode(void); 736 extern int ps3av_get_mode(void);
737 extern int ps3av_video_mode2res(u32, u32 *, u32 *); 737 extern int ps3av_video_mode2res(u32, u32 *, u32 *);
738 extern int ps3av_video_mute(int); 738 extern int ps3av_video_mute(int);
739 extern int ps3av_audio_mute(int); 739 extern int ps3av_audio_mute(int);
740 extern int ps3av_audio_mute_analog(int); 740 extern int ps3av_audio_mute_analog(int);
741 extern int ps3av_dev_open(void); 741 extern int ps3av_dev_open(void);
742 extern int ps3av_dev_close(void); 742 extern int ps3av_dev_close(void);
743 extern void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
744 void *flip_data);
745 extern void ps3av_flip_ctl(int on);
746
747 #endif /* _ASM_POWERPC_PS3AV_H_ */ 743 #endif /* _ASM_POWERPC_PS3AV_H_ */
748 744
arch/powerpc/platforms/ps3/setup.c
1 /* 1 /*
2 * PS3 platform setup routines. 2 * PS3 platform setup routines.
3 * 3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc. 4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp. 5 * Copyright 2006 Sony Corp.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21 #include <linux/kernel.h> 21 #include <linux/kernel.h>
22 #include <linux/delay.h> 22 #include <linux/delay.h>
23 #include <linux/fs.h> 23 #include <linux/fs.h>
24 #include <linux/root_dev.h> 24 #include <linux/root_dev.h>
25 #include <linux/console.h> 25 #include <linux/console.h>
26 #include <linux/kexec.h> 26 #include <linux/kexec.h>
27 #include <linux/bootmem.h> 27 #include <linux/bootmem.h>
28 28
29 #include <asm/machdep.h> 29 #include <asm/machdep.h>
30 #include <asm/firmware.h> 30 #include <asm/firmware.h>
31 #include <asm/time.h> 31 #include <asm/time.h>
32 #include <asm/iommu.h> 32 #include <asm/iommu.h>
33 #include <asm/udbg.h> 33 #include <asm/udbg.h>
34 #include <asm/prom.h> 34 #include <asm/prom.h>
35 #include <asm/lv1call.h> 35 #include <asm/lv1call.h>
36 36
37 #include "platform.h" 37 #include "platform.h"
38 38
39 #if defined(DEBUG) 39 #if defined(DEBUG)
40 #define DBG udbg_printf 40 #define DBG udbg_printf
41 #else 41 #else
42 #define DBG pr_debug 42 #define DBG pr_debug
43 #endif 43 #endif
44 44
45 /* mutex synchronizing GPU accesses and video mode changes */
46 DEFINE_MUTEX(ps3_gpu_mutex);
47 EXPORT_SYMBOL_GPL(ps3_gpu_mutex);
48
45 #if !defined(CONFIG_SMP) 49 #if !defined(CONFIG_SMP)
46 static void smp_send_stop(void) {} 50 static void smp_send_stop(void) {}
47 #endif 51 #endif
48 52
49 static union ps3_firmware_version ps3_firmware_version; 53 static union ps3_firmware_version ps3_firmware_version;
50 54
51 void ps3_get_firmware_version(union ps3_firmware_version *v) 55 void ps3_get_firmware_version(union ps3_firmware_version *v)
52 { 56 {
53 *v = ps3_firmware_version; 57 *v = ps3_firmware_version;
54 } 58 }
55 EXPORT_SYMBOL_GPL(ps3_get_firmware_version); 59 EXPORT_SYMBOL_GPL(ps3_get_firmware_version);
56 60
57 int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev) 61 int ps3_compare_firmware_version(u16 major, u16 minor, u16 rev)
58 { 62 {
59 union ps3_firmware_version x; 63 union ps3_firmware_version x;
60 64
61 x.pad = 0; 65 x.pad = 0;
62 x.major = major; 66 x.major = major;
63 x.minor = minor; 67 x.minor = minor;
64 x.rev = rev; 68 x.rev = rev;
65 69
66 return (ps3_firmware_version.raw > x.raw) - 70 return (ps3_firmware_version.raw > x.raw) -
67 (ps3_firmware_version.raw < x.raw); 71 (ps3_firmware_version.raw < x.raw);
68 } 72 }
69 EXPORT_SYMBOL_GPL(ps3_compare_firmware_version); 73 EXPORT_SYMBOL_GPL(ps3_compare_firmware_version);
70 74
71 static void ps3_power_save(void) 75 static void ps3_power_save(void)
72 { 76 {
73 /* 77 /*
74 * lv1_pause() puts the PPE thread into inactive state until an 78 * lv1_pause() puts the PPE thread into inactive state until an
75 * irq on an unmasked plug exists. MSR[EE] has no effect. 79 * irq on an unmasked plug exists. MSR[EE] has no effect.
76 * flags: 0 = wake on DEC interrupt, 1 = ignore DEC interrupt. 80 * flags: 0 = wake on DEC interrupt, 1 = ignore DEC interrupt.
77 */ 81 */
78 82
79 lv1_pause(0); 83 lv1_pause(0);
80 } 84 }
81 85
82 static void ps3_restart(char *cmd) 86 static void ps3_restart(char *cmd)
83 { 87 {
84 DBG("%s:%d cmd '%s'\n", __func__, __LINE__, cmd); 88 DBG("%s:%d cmd '%s'\n", __func__, __LINE__, cmd);
85 89
86 smp_send_stop(); 90 smp_send_stop();
87 ps3_sys_manager_restart(); /* never returns */ 91 ps3_sys_manager_restart(); /* never returns */
88 } 92 }
89 93
90 static void ps3_power_off(void) 94 static void ps3_power_off(void)
91 { 95 {
92 DBG("%s:%d\n", __func__, __LINE__); 96 DBG("%s:%d\n", __func__, __LINE__);
93 97
94 smp_send_stop(); 98 smp_send_stop();
95 ps3_sys_manager_power_off(); /* never returns */ 99 ps3_sys_manager_power_off(); /* never returns */
96 } 100 }
97 101
98 static void ps3_halt(void) 102 static void ps3_halt(void)
99 { 103 {
100 DBG("%s:%d\n", __func__, __LINE__); 104 DBG("%s:%d\n", __func__, __LINE__);
101 105
102 smp_send_stop(); 106 smp_send_stop();
103 ps3_sys_manager_halt(); /* never returns */ 107 ps3_sys_manager_halt(); /* never returns */
104 } 108 }
105 109
106 static void ps3_panic(char *str) 110 static void ps3_panic(char *str)
107 { 111 {
108 DBG("%s:%d %s\n", __func__, __LINE__, str); 112 DBG("%s:%d %s\n", __func__, __LINE__, str);
109 113
110 smp_send_stop(); 114 smp_send_stop();
111 printk("\n"); 115 printk("\n");
112 printk(" System does not reboot automatically.\n"); 116 printk(" System does not reboot automatically.\n");
113 printk(" Please press POWER button.\n"); 117 printk(" Please press POWER button.\n");
114 printk("\n"); 118 printk("\n");
115 119
116 while(1) 120 while(1)
117 lv1_pause(1); 121 lv1_pause(1);
118 } 122 }
119 123
120 #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \ 124 #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) || \
121 defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) 125 defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
122 static void __init prealloc(struct ps3_prealloc *p) 126 static void __init prealloc(struct ps3_prealloc *p)
123 { 127 {
124 if (!p->size) 128 if (!p->size)
125 return; 129 return;
126 130
127 p->address = __alloc_bootmem(p->size, p->align, __pa(MAX_DMA_ADDRESS)); 131 p->address = __alloc_bootmem(p->size, p->align, __pa(MAX_DMA_ADDRESS));
128 if (!p->address) { 132 if (!p->address) {
129 printk(KERN_ERR "%s: Cannot allocate %s\n", __func__, 133 printk(KERN_ERR "%s: Cannot allocate %s\n", __func__,
130 p->name); 134 p->name);
131 return; 135 return;
132 } 136 }
133 137
134 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size, 138 printk(KERN_INFO "%s: %lu bytes at %p\n", p->name, p->size,
135 p->address); 139 p->address);
136 } 140 }
137 #endif 141 #endif
138 142
139 #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE) 143 #if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE)
140 struct ps3_prealloc ps3fb_videomemory = { 144 struct ps3_prealloc ps3fb_videomemory = {
141 .name = "ps3fb videomemory", 145 .name = "ps3fb videomemory",
142 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024, 146 .size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
143 .align = 1024*1024 /* the GPU requires 1 MiB alignment */ 147 .align = 1024*1024 /* the GPU requires 1 MiB alignment */
144 }; 148 };
145 EXPORT_SYMBOL_GPL(ps3fb_videomemory); 149 EXPORT_SYMBOL_GPL(ps3fb_videomemory);
146 #define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory) 150 #define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory)
147 151
148 static int __init early_parse_ps3fb(char *p) 152 static int __init early_parse_ps3fb(char *p)
149 { 153 {
150 if (!p) 154 if (!p)
151 return 1; 155 return 1;
152 156
153 ps3fb_videomemory.size = _ALIGN_UP(memparse(p, &p), 157 ps3fb_videomemory.size = _ALIGN_UP(memparse(p, &p),
154 ps3fb_videomemory.align); 158 ps3fb_videomemory.align);
155 return 0; 159 return 0;
156 } 160 }
157 early_param("ps3fb", early_parse_ps3fb); 161 early_param("ps3fb", early_parse_ps3fb);
158 #else 162 #else
159 #define prealloc_ps3fb_videomemory() do { } while (0) 163 #define prealloc_ps3fb_videomemory() do { } while (0)
160 #endif 164 #endif
161 165
162 #if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE) 166 #if defined(CONFIG_PS3_FLASH) || defined(CONFIG_PS3_FLASH_MODULE)
163 struct ps3_prealloc ps3flash_bounce_buffer = { 167 struct ps3_prealloc ps3flash_bounce_buffer = {
164 .name = "ps3flash bounce buffer", 168 .name = "ps3flash bounce buffer",
165 .size = 256*1024, 169 .size = 256*1024,
166 .align = 256*1024 170 .align = 256*1024
167 }; 171 };
168 EXPORT_SYMBOL_GPL(ps3flash_bounce_buffer); 172 EXPORT_SYMBOL_GPL(ps3flash_bounce_buffer);
169 #define prealloc_ps3flash_bounce_buffer() prealloc(&ps3flash_bounce_buffer) 173 #define prealloc_ps3flash_bounce_buffer() prealloc(&ps3flash_bounce_buffer)
170 174
171 static int __init early_parse_ps3flash(char *p) 175 static int __init early_parse_ps3flash(char *p)
172 { 176 {
173 if (!p) 177 if (!p)
174 return 1; 178 return 1;
175 179
176 if (!strcmp(p, "off")) 180 if (!strcmp(p, "off"))
177 ps3flash_bounce_buffer.size = 0; 181 ps3flash_bounce_buffer.size = 0;
178 182
179 return 0; 183 return 0;
180 } 184 }
181 early_param("ps3flash", early_parse_ps3flash); 185 early_param("ps3flash", early_parse_ps3flash);
182 #else 186 #else
183 #define prealloc_ps3flash_bounce_buffer() do { } while (0) 187 #define prealloc_ps3flash_bounce_buffer() do { } while (0)
184 #endif 188 #endif
185 189
186 static int ps3_set_dabr(u64 dabr) 190 static int ps3_set_dabr(u64 dabr)
187 { 191 {
188 enum {DABR_USER = 1, DABR_KERNEL = 2,}; 192 enum {DABR_USER = 1, DABR_KERNEL = 2,};
189 193
190 return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0; 194 return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0;
191 } 195 }
192 196
193 static void __init ps3_setup_arch(void) 197 static void __init ps3_setup_arch(void)
194 { 198 {
195 199
196 DBG(" -> %s:%d\n", __func__, __LINE__); 200 DBG(" -> %s:%d\n", __func__, __LINE__);
197 201
198 lv1_get_version_info(&ps3_firmware_version.raw); 202 lv1_get_version_info(&ps3_firmware_version.raw);
199 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n", 203 printk(KERN_INFO "PS3 firmware version %u.%u.%u\n",
200 ps3_firmware_version.major, ps3_firmware_version.minor, 204 ps3_firmware_version.major, ps3_firmware_version.minor,
201 ps3_firmware_version.rev); 205 ps3_firmware_version.rev);
202 206
203 ps3_spu_set_platform(); 207 ps3_spu_set_platform();
204 208
205 #ifdef CONFIG_SMP 209 #ifdef CONFIG_SMP
206 smp_init_ps3(); 210 smp_init_ps3();
207 #endif 211 #endif
208 212
209 #ifdef CONFIG_DUMMY_CONSOLE 213 #ifdef CONFIG_DUMMY_CONSOLE
210 conswitchp = &dummy_con; 214 conswitchp = &dummy_con;
211 #endif 215 #endif
212 216
213 prealloc_ps3fb_videomemory(); 217 prealloc_ps3fb_videomemory();
214 prealloc_ps3flash_bounce_buffer(); 218 prealloc_ps3flash_bounce_buffer();
215 219
216 ppc_md.power_save = ps3_power_save; 220 ppc_md.power_save = ps3_power_save;
217 ps3_os_area_init(); 221 ps3_os_area_init();
218 222
219 DBG(" <- %s:%d\n", __func__, __LINE__); 223 DBG(" <- %s:%d\n", __func__, __LINE__);
220 } 224 }
221 225
222 static void __init ps3_progress(char *s, unsigned short hex) 226 static void __init ps3_progress(char *s, unsigned short hex)
223 { 227 {
224 printk("*** %04x : %s\n", hex, s ? s : ""); 228 printk("*** %04x : %s\n", hex, s ? s : "");
225 } 229 }
226 230
227 static int __init ps3_probe(void) 231 static int __init ps3_probe(void)
228 { 232 {
229 unsigned long htab_size; 233 unsigned long htab_size;
230 unsigned long dt_root; 234 unsigned long dt_root;
231 235
232 DBG(" -> %s:%d\n", __func__, __LINE__); 236 DBG(" -> %s:%d\n", __func__, __LINE__);
233 237
234 dt_root = of_get_flat_dt_root(); 238 dt_root = of_get_flat_dt_root();
235 if (!of_flat_dt_is_compatible(dt_root, "sony,ps3")) 239 if (!of_flat_dt_is_compatible(dt_root, "sony,ps3"))
236 return 0; 240 return 0;
237 241
238 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE; 242 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
239 243
240 ps3_os_area_save_params(); 244 ps3_os_area_save_params();
241 ps3_mm_init(); 245 ps3_mm_init();
242 ps3_mm_vas_create(&htab_size); 246 ps3_mm_vas_create(&htab_size);
243 ps3_hpte_init(htab_size); 247 ps3_hpte_init(htab_size);
244 248
245 DBG(" <- %s:%d\n", __func__, __LINE__); 249 DBG(" <- %s:%d\n", __func__, __LINE__);
246 return 1; 250 return 1;
247 } 251 }
248 252
249 #if defined(CONFIG_KEXEC) 253 #if defined(CONFIG_KEXEC)
250 static void ps3_kexec_cpu_down(int crash_shutdown, int secondary) 254 static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
251 { 255 {
252 int cpu = smp_processor_id(); 256 int cpu = smp_processor_id();
253 257
254 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu); 258 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
255 259
256 ps3_smp_cleanup_cpu(cpu); 260 ps3_smp_cleanup_cpu(cpu);
257 ps3_shutdown_IRQ(cpu); 261 ps3_shutdown_IRQ(cpu);
258 262
259 DBG(" <- %s:%d\n", __func__, __LINE__); 263 DBG(" <- %s:%d\n", __func__, __LINE__);
260 } 264 }
261 #endif 265 #endif
262 266
263 define_machine(ps3) { 267 define_machine(ps3) {
264 .name = "PS3", 268 .name = "PS3",
265 .probe = ps3_probe, 269 .probe = ps3_probe,
266 .setup_arch = ps3_setup_arch, 270 .setup_arch = ps3_setup_arch,
267 .init_IRQ = ps3_init_IRQ, 271 .init_IRQ = ps3_init_IRQ,
268 .panic = ps3_panic, 272 .panic = ps3_panic,
269 .get_boot_time = ps3_get_boot_time, 273 .get_boot_time = ps3_get_boot_time,
270 .set_rtc_time = ps3_set_rtc_time, 274 .set_rtc_time = ps3_set_rtc_time,
271 .get_rtc_time = ps3_get_rtc_time, 275 .get_rtc_time = ps3_get_rtc_time,
272 .set_dabr = ps3_set_dabr, 276 .set_dabr = ps3_set_dabr,
273 .calibrate_decr = ps3_calibrate_decr, 277 .calibrate_decr = ps3_calibrate_decr,
274 .progress = ps3_progress, 278 .progress = ps3_progress,
275 .restart = ps3_restart, 279 .restart = ps3_restart,
276 .power_off = ps3_power_off, 280 .power_off = ps3_power_off,
277 .halt = ps3_halt, 281 .halt = ps3_halt,
278 #if defined(CONFIG_KEXEC) 282 #if defined(CONFIG_KEXEC)
279 .kexec_cpu_down = ps3_kexec_cpu_down, 283 .kexec_cpu_down = ps3_kexec_cpu_down,
280 .machine_kexec = default_machine_kexec, 284 .machine_kexec = default_machine_kexec,
281 .machine_kexec_prepare = default_machine_kexec_prepare, 285 .machine_kexec_prepare = default_machine_kexec_prepare,
282 .machine_crash_shutdown = default_machine_crash_shutdown, 286 .machine_crash_shutdown = default_machine_crash_shutdown,
283 #endif 287 #endif
284 }; 288 };
285 289
1 /* 1 /*
2 * PS3 AV backend support. 2 * PS3 AV backend support.
3 * 3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc. 4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 Sony Corp. 5 * Copyright 2007 Sony Corp.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21 #include <linux/kernel.h> 21 #include <linux/kernel.h>
22 #include <linux/module.h> 22 #include <linux/module.h>
23 #include <linux/delay.h> 23 #include <linux/delay.h>
24 #include <linux/notifier.h> 24 #include <linux/notifier.h>
25 #include <linux/ioctl.h> 25 #include <linux/ioctl.h>
26 #include <linux/fb.h> 26 #include <linux/fb.h>
27 27
28 #include <asm/firmware.h> 28 #include <asm/firmware.h>
29 #include <asm/ps3av.h> 29 #include <asm/ps3av.h>
30 #include <asm/ps3.h> 30 #include <asm/ps3.h>
31 31
32 #include "vuart.h" 32 #include "vuart.h"
33 33
34 #define BUFSIZE 4096 /* vuart buf size */ 34 #define BUFSIZE 4096 /* vuart buf size */
35 #define PS3AV_BUF_SIZE 512 /* max packet size */ 35 #define PS3AV_BUF_SIZE 512 /* max packet size */
36 36
37 static int safe_mode; 37 static int safe_mode;
38 38
39 static int timeout = 5000; /* in msec ( 5 sec ) */ 39 static int timeout = 5000; /* in msec ( 5 sec ) */
40 module_param(timeout, int, 0644); 40 module_param(timeout, int, 0644);
41 41
42 static struct ps3av { 42 static struct ps3av {
43 struct mutex mutex; 43 struct mutex mutex;
44 struct work_struct work; 44 struct work_struct work;
45 struct completion done; 45 struct completion done;
46 struct workqueue_struct *wq; 46 struct workqueue_struct *wq;
47 int open_count; 47 int open_count;
48 struct ps3_system_bus_device *dev; 48 struct ps3_system_bus_device *dev;
49 49
50 int region; 50 int region;
51 struct ps3av_pkt_av_get_hw_conf av_hw_conf; 51 struct ps3av_pkt_av_get_hw_conf av_hw_conf;
52 u32 av_port[PS3AV_AV_PORT_MAX + PS3AV_OPT_PORT_MAX]; 52 u32 av_port[PS3AV_AV_PORT_MAX + PS3AV_OPT_PORT_MAX];
53 u32 opt_port[PS3AV_OPT_PORT_MAX]; 53 u32 opt_port[PS3AV_OPT_PORT_MAX];
54 u32 head[PS3AV_HEAD_MAX]; 54 u32 head[PS3AV_HEAD_MAX];
55 u32 audio_port; 55 u32 audio_port;
56 int ps3av_mode; 56 int ps3av_mode;
57 int ps3av_mode_old; 57 int ps3av_mode_old;
58 union { 58 union {
59 struct ps3av_reply_hdr reply_hdr; 59 struct ps3av_reply_hdr reply_hdr;
60 u8 raw[PS3AV_BUF_SIZE]; 60 u8 raw[PS3AV_BUF_SIZE];
61 } recv_buf; 61 } recv_buf;
62 void (*flip_ctl)(int on, void *data);
63 void *flip_data;
64 } *ps3av; 62 } *ps3av;
65 63
66 /* color space */ 64 /* color space */
67 #define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8 65 #define YUV444 PS3AV_CMD_VIDEO_CS_YUV444_8
68 #define RGB8 PS3AV_CMD_VIDEO_CS_RGB_8 66 #define RGB8 PS3AV_CMD_VIDEO_CS_RGB_8
69 /* format */ 67 /* format */
70 #define XRGB PS3AV_CMD_VIDEO_FMT_X8R8G8B8 68 #define XRGB PS3AV_CMD_VIDEO_FMT_X8R8G8B8
71 /* aspect */ 69 /* aspect */
72 #define A_N PS3AV_CMD_AV_ASPECT_4_3 70 #define A_N PS3AV_CMD_AV_ASPECT_4_3
73 #define A_W PS3AV_CMD_AV_ASPECT_16_9 71 #define A_W PS3AV_CMD_AV_ASPECT_16_9
74 static const struct avset_video_mode { 72 static const struct avset_video_mode {
75 u32 cs; 73 u32 cs;
76 u32 fmt; 74 u32 fmt;
77 u32 vid; 75 u32 vid;
78 u32 aspect; 76 u32 aspect;
79 u32 x; 77 u32 x;
80 u32 y; 78 u32 y;
81 } video_mode_table[] = { 79 } video_mode_table[] = {
82 { 0, }, /* auto */ 80 { 0, }, /* auto */
83 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480}, 81 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480},
84 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480}, 82 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480},
85 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720}, 83 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720},
86 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080}, 84 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080},
87 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080}, 85 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080},
88 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576}, 86 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576},
89 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576}, 87 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576},
90 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720}, 88 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720},
91 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080}, 89 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080},
92 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080}, 90 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080},
93 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768}, 91 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768},
94 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024}, 92 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024},
95 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200}, 93 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200},
96 }; 94 };
97 95
98 /* supported CIDs */ 96 /* supported CIDs */
99 static u32 cmd_table[] = { 97 static u32 cmd_table[] = {
100 /* init */ 98 /* init */
101 PS3AV_CID_AV_INIT, 99 PS3AV_CID_AV_INIT,
102 PS3AV_CID_AV_FIN, 100 PS3AV_CID_AV_FIN,
103 PS3AV_CID_VIDEO_INIT, 101 PS3AV_CID_VIDEO_INIT,
104 PS3AV_CID_AUDIO_INIT, 102 PS3AV_CID_AUDIO_INIT,
105 103
106 /* set */ 104 /* set */
107 PS3AV_CID_AV_ENABLE_EVENT, 105 PS3AV_CID_AV_ENABLE_EVENT,
108 PS3AV_CID_AV_DISABLE_EVENT, 106 PS3AV_CID_AV_DISABLE_EVENT,
109 107
110 PS3AV_CID_AV_VIDEO_CS, 108 PS3AV_CID_AV_VIDEO_CS,
111 PS3AV_CID_AV_VIDEO_MUTE, 109 PS3AV_CID_AV_VIDEO_MUTE,
112 PS3AV_CID_AV_VIDEO_DISABLE_SIG, 110 PS3AV_CID_AV_VIDEO_DISABLE_SIG,
113 PS3AV_CID_AV_AUDIO_PARAM, 111 PS3AV_CID_AV_AUDIO_PARAM,
114 PS3AV_CID_AV_AUDIO_MUTE, 112 PS3AV_CID_AV_AUDIO_MUTE,
115 PS3AV_CID_AV_HDMI_MODE, 113 PS3AV_CID_AV_HDMI_MODE,
116 PS3AV_CID_AV_TV_MUTE, 114 PS3AV_CID_AV_TV_MUTE,
117 115
118 PS3AV_CID_VIDEO_MODE, 116 PS3AV_CID_VIDEO_MODE,
119 PS3AV_CID_VIDEO_FORMAT, 117 PS3AV_CID_VIDEO_FORMAT,
120 PS3AV_CID_VIDEO_PITCH, 118 PS3AV_CID_VIDEO_PITCH,
121 119
122 PS3AV_CID_AUDIO_MODE, 120 PS3AV_CID_AUDIO_MODE,
123 PS3AV_CID_AUDIO_MUTE, 121 PS3AV_CID_AUDIO_MUTE,
124 PS3AV_CID_AUDIO_ACTIVE, 122 PS3AV_CID_AUDIO_ACTIVE,
125 PS3AV_CID_AUDIO_INACTIVE, 123 PS3AV_CID_AUDIO_INACTIVE,
126 PS3AV_CID_AVB_PARAM, 124 PS3AV_CID_AVB_PARAM,
127 125
128 /* get */ 126 /* get */
129 PS3AV_CID_AV_GET_HW_CONF, 127 PS3AV_CID_AV_GET_HW_CONF,
130 PS3AV_CID_AV_GET_MONITOR_INFO, 128 PS3AV_CID_AV_GET_MONITOR_INFO,
131 129
132 /* event */ 130 /* event */
133 PS3AV_CID_EVENT_UNPLUGGED, 131 PS3AV_CID_EVENT_UNPLUGGED,
134 PS3AV_CID_EVENT_PLUGGED, 132 PS3AV_CID_EVENT_PLUGGED,
135 PS3AV_CID_EVENT_HDCP_DONE, 133 PS3AV_CID_EVENT_HDCP_DONE,
136 PS3AV_CID_EVENT_HDCP_FAIL, 134 PS3AV_CID_EVENT_HDCP_FAIL,
137 PS3AV_CID_EVENT_HDCP_AUTH, 135 PS3AV_CID_EVENT_HDCP_AUTH,
138 PS3AV_CID_EVENT_HDCP_ERROR, 136 PS3AV_CID_EVENT_HDCP_ERROR,
139 137
140 0 138 0
141 }; 139 };
142 140
143 #define PS3AV_EVENT_CMD_MASK 0x10000000 141 #define PS3AV_EVENT_CMD_MASK 0x10000000
144 #define PS3AV_EVENT_ID_MASK 0x0000ffff 142 #define PS3AV_EVENT_ID_MASK 0x0000ffff
145 #define PS3AV_CID_MASK 0xffffffff 143 #define PS3AV_CID_MASK 0xffffffff
146 #define PS3AV_REPLY_BIT 0x80000000 144 #define PS3AV_REPLY_BIT 0x80000000
147 145
148 #define ps3av_event_get_port_id(cid) ((cid >> 16) & 0xff) 146 #define ps3av_event_get_port_id(cid) ((cid >> 16) & 0xff)
149 147
150 static u32 *ps3av_search_cmd_table(u32 cid, u32 mask) 148 static u32 *ps3av_search_cmd_table(u32 cid, u32 mask)
151 { 149 {
152 u32 *table; 150 u32 *table;
153 int i; 151 int i;
154 152
155 table = cmd_table; 153 table = cmd_table;
156 for (i = 0;; table++, i++) { 154 for (i = 0;; table++, i++) {
157 if ((*table & mask) == (cid & mask)) 155 if ((*table & mask) == (cid & mask))
158 break; 156 break;
159 if (*table == 0) 157 if (*table == 0)
160 return NULL; 158 return NULL;
161 } 159 }
162 return table; 160 return table;
163 } 161 }
164 162
165 static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr) 163 static int ps3av_parse_event_packet(const struct ps3av_reply_hdr *hdr)
166 { 164 {
167 u32 *table; 165 u32 *table;
168 166
169 if (hdr->cid & PS3AV_EVENT_CMD_MASK) { 167 if (hdr->cid & PS3AV_EVENT_CMD_MASK) {
170 table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK); 168 table = ps3av_search_cmd_table(hdr->cid, PS3AV_EVENT_CMD_MASK);
171 if (table) 169 if (table)
172 dev_dbg(&ps3av->dev->core, 170 dev_dbg(&ps3av->dev->core,
173 "recv event packet cid:%08x port:0x%x size:%d\n", 171 "recv event packet cid:%08x port:0x%x size:%d\n",
174 hdr->cid, ps3av_event_get_port_id(hdr->cid), 172 hdr->cid, ps3av_event_get_port_id(hdr->cid),
175 hdr->size); 173 hdr->size);
176 else 174 else
177 printk(KERN_ERR 175 printk(KERN_ERR
178 "%s: failed event packet, cid:%08x size:%d\n", 176 "%s: failed event packet, cid:%08x size:%d\n",
179 __func__, hdr->cid, hdr->size); 177 __func__, hdr->cid, hdr->size);
180 return 1; /* receive event packet */ 178 return 1; /* receive event packet */
181 } 179 }
182 return 0; 180 return 0;
183 } 181 }
184 182
185 183
186 #define POLLING_INTERVAL 25 /* in msec */ 184 #define POLLING_INTERVAL 25 /* in msec */
187 185
188 static int ps3av_vuart_write(struct ps3_system_bus_device *dev, 186 static int ps3av_vuart_write(struct ps3_system_bus_device *dev,
189 const void *buf, unsigned long size) 187 const void *buf, unsigned long size)
190 { 188 {
191 int error; 189 int error;
192 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 190 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
193 error = ps3_vuart_write(dev, buf, size); 191 error = ps3_vuart_write(dev, buf, size);
194 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 192 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
195 return error ? error : size; 193 return error ? error : size;
196 } 194 }
197 195
198 static int ps3av_vuart_read(struct ps3_system_bus_device *dev, void *buf, 196 static int ps3av_vuart_read(struct ps3_system_bus_device *dev, void *buf,
199 unsigned long size, int timeout) 197 unsigned long size, int timeout)
200 { 198 {
201 int error; 199 int error;
202 int loopcnt = 0; 200 int loopcnt = 0;
203 201
204 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 202 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
205 timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL; 203 timeout = (timeout + POLLING_INTERVAL - 1) / POLLING_INTERVAL;
206 while (loopcnt++ <= timeout) { 204 while (loopcnt++ <= timeout) {
207 error = ps3_vuart_read(dev, buf, size); 205 error = ps3_vuart_read(dev, buf, size);
208 if (!error) 206 if (!error)
209 return size; 207 return size;
210 if (error != -EAGAIN) { 208 if (error != -EAGAIN) {
211 printk(KERN_ERR "%s: ps3_vuart_read failed %d\n", 209 printk(KERN_ERR "%s: ps3_vuart_read failed %d\n",
212 __func__, error); 210 __func__, error);
213 return error; 211 return error;
214 } 212 }
215 msleep(POLLING_INTERVAL); 213 msleep(POLLING_INTERVAL);
216 } 214 }
217 return -EWOULDBLOCK; 215 return -EWOULDBLOCK;
218 } 216 }
219 217
220 static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf, 218 static int ps3av_send_cmd_pkt(const struct ps3av_send_hdr *send_buf,
221 struct ps3av_reply_hdr *recv_buf, int write_len, 219 struct ps3av_reply_hdr *recv_buf, int write_len,
222 int read_len) 220 int read_len)
223 { 221 {
224 int res; 222 int res;
225 u32 cmd; 223 u32 cmd;
226 int event; 224 int event;
227 225
228 if (!ps3av) 226 if (!ps3av)
229 return -ENODEV; 227 return -ENODEV;
230 228
231 /* send pkt */ 229 /* send pkt */
232 res = ps3av_vuart_write(ps3av->dev, send_buf, write_len); 230 res = ps3av_vuart_write(ps3av->dev, send_buf, write_len);
233 if (res < 0) { 231 if (res < 0) {
234 dev_dbg(&ps3av->dev->core, 232 dev_dbg(&ps3av->dev->core,
235 "%s: ps3av_vuart_write() failed (result=%d)\n", 233 "%s: ps3av_vuart_write() failed (result=%d)\n",
236 __func__, res); 234 __func__, res);
237 return res; 235 return res;
238 } 236 }
239 237
240 /* recv pkt */ 238 /* recv pkt */
241 cmd = send_buf->cid; 239 cmd = send_buf->cid;
242 do { 240 do {
243 /* read header */ 241 /* read header */
244 res = ps3av_vuart_read(ps3av->dev, recv_buf, PS3AV_HDR_SIZE, 242 res = ps3av_vuart_read(ps3av->dev, recv_buf, PS3AV_HDR_SIZE,
245 timeout); 243 timeout);
246 if (res != PS3AV_HDR_SIZE) { 244 if (res != PS3AV_HDR_SIZE) {
247 dev_dbg(&ps3av->dev->core, 245 dev_dbg(&ps3av->dev->core,
248 "%s: ps3av_vuart_read() failed (result=%d)\n", 246 "%s: ps3av_vuart_read() failed (result=%d)\n",
249 __func__, res); 247 __func__, res);
250 return res; 248 return res;
251 } 249 }
252 250
253 /* read body */ 251 /* read body */
254 res = ps3av_vuart_read(ps3av->dev, &recv_buf->cid, 252 res = ps3av_vuart_read(ps3av->dev, &recv_buf->cid,
255 recv_buf->size, timeout); 253 recv_buf->size, timeout);
256 if (res < 0) { 254 if (res < 0) {
257 dev_dbg(&ps3av->dev->core, 255 dev_dbg(&ps3av->dev->core,
258 "%s: ps3av_vuart_read() failed (result=%d)\n", 256 "%s: ps3av_vuart_read() failed (result=%d)\n",
259 __func__, res); 257 __func__, res);
260 return res; 258 return res;
261 } 259 }
262 res += PS3AV_HDR_SIZE; /* total len */ 260 res += PS3AV_HDR_SIZE; /* total len */
263 event = ps3av_parse_event_packet(recv_buf); 261 event = ps3av_parse_event_packet(recv_buf);
264 /* ret > 0 event packet */ 262 /* ret > 0 event packet */
265 } while (event); 263 } while (event);
266 264
267 if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) { 265 if ((cmd | PS3AV_REPLY_BIT) != recv_buf->cid) {
268 dev_dbg(&ps3av->dev->core, "%s: reply err (result=%x)\n", 266 dev_dbg(&ps3av->dev->core, "%s: reply err (result=%x)\n",
269 __func__, recv_buf->cid); 267 __func__, recv_buf->cid);
270 return -EINVAL; 268 return -EINVAL;
271 } 269 }
272 270
273 return 0; 271 return 0;
274 } 272 }
275 273
276 static int ps3av_process_reply_packet(struct ps3av_send_hdr *cmd_buf, 274 static int ps3av_process_reply_packet(struct ps3av_send_hdr *cmd_buf,
277 const struct ps3av_reply_hdr *recv_buf, 275 const struct ps3av_reply_hdr *recv_buf,
278 int user_buf_size) 276 int user_buf_size)
279 { 277 {
280 int return_len; 278 int return_len;
281 279
282 if (recv_buf->version != PS3AV_VERSION) { 280 if (recv_buf->version != PS3AV_VERSION) {
283 dev_dbg(&ps3av->dev->core, "reply_packet invalid version:%x\n", 281 dev_dbg(&ps3av->dev->core, "reply_packet invalid version:%x\n",
284 recv_buf->version); 282 recv_buf->version);
285 return -EFAULT; 283 return -EFAULT;
286 } 284 }
287 return_len = recv_buf->size + PS3AV_HDR_SIZE; 285 return_len = recv_buf->size + PS3AV_HDR_SIZE;
288 if (return_len > user_buf_size) 286 if (return_len > user_buf_size)
289 return_len = user_buf_size; 287 return_len = user_buf_size;
290 memcpy(cmd_buf, recv_buf, return_len); 288 memcpy(cmd_buf, recv_buf, return_len);
291 return 0; /* success */ 289 return 0; /* success */
292 } 290 }
293 291
294 void ps3av_set_hdr(u32 cid, u16 size, struct ps3av_send_hdr *hdr) 292 void ps3av_set_hdr(u32 cid, u16 size, struct ps3av_send_hdr *hdr)
295 { 293 {
296 hdr->version = PS3AV_VERSION; 294 hdr->version = PS3AV_VERSION;
297 hdr->size = size - PS3AV_HDR_SIZE; 295 hdr->size = size - PS3AV_HDR_SIZE;
298 hdr->cid = cid; 296 hdr->cid = cid;
299 } 297 }
300 298
301 int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size, 299 int ps3av_do_pkt(u32 cid, u16 send_len, size_t usr_buf_size,
302 struct ps3av_send_hdr *buf) 300 struct ps3av_send_hdr *buf)
303 { 301 {
304 int res = 0; 302 int res = 0;
305 u32 *table; 303 u32 *table;
306 304
307 BUG_ON(!ps3av); 305 BUG_ON(!ps3av);
308 306
309 mutex_lock(&ps3av->mutex); 307 mutex_lock(&ps3av->mutex);
310 308
311 table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK); 309 table = ps3av_search_cmd_table(cid, PS3AV_CID_MASK);
312 BUG_ON(!table); 310 BUG_ON(!table);
313 BUG_ON(send_len < PS3AV_HDR_SIZE); 311 BUG_ON(send_len < PS3AV_HDR_SIZE);
314 BUG_ON(usr_buf_size < send_len); 312 BUG_ON(usr_buf_size < send_len);
315 BUG_ON(usr_buf_size > PS3AV_BUF_SIZE); 313 BUG_ON(usr_buf_size > PS3AV_BUF_SIZE);
316 314
317 /* create header */ 315 /* create header */
318 ps3av_set_hdr(cid, send_len, buf); 316 ps3av_set_hdr(cid, send_len, buf);
319 317
320 /* send packet via vuart */ 318 /* send packet via vuart */
321 res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len, 319 res = ps3av_send_cmd_pkt(buf, &ps3av->recv_buf.reply_hdr, send_len,
322 usr_buf_size); 320 usr_buf_size);
323 if (res < 0) { 321 if (res < 0) {
324 printk(KERN_ERR 322 printk(KERN_ERR
325 "%s: ps3av_send_cmd_pkt() failed (result=%d)\n", 323 "%s: ps3av_send_cmd_pkt() failed (result=%d)\n",
326 __func__, res); 324 __func__, res);
327 goto err; 325 goto err;
328 } 326 }
329 327
330 /* process reply packet */ 328 /* process reply packet */
331 res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr, 329 res = ps3av_process_reply_packet(buf, &ps3av->recv_buf.reply_hdr,
332 usr_buf_size); 330 usr_buf_size);
333 if (res < 0) { 331 if (res < 0) {
334 printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n", 332 printk(KERN_ERR "%s: put_return_status() failed (result=%d)\n",
335 __func__, res); 333 __func__, res);
336 goto err; 334 goto err;
337 } 335 }
338 336
339 mutex_unlock(&ps3av->mutex); 337 mutex_unlock(&ps3av->mutex);
340 return 0; 338 return 0;
341 339
342 err: 340 err:
343 mutex_unlock(&ps3av->mutex); 341 mutex_unlock(&ps3av->mutex);
344 printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res); 342 printk(KERN_ERR "%s: failed cid:%x res:%d\n", __func__, cid, res);
345 return res; 343 return res;
346 } 344 }
347 345
348 static int ps3av_set_av_video_mute(u32 mute) 346 static int ps3av_set_av_video_mute(u32 mute)
349 { 347 {
350 int i, num_of_av_port, res; 348 int i, num_of_av_port, res;
351 349
352 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + 350 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
353 ps3av->av_hw_conf.num_of_avmulti; 351 ps3av->av_hw_conf.num_of_avmulti;
354 /* video mute on */ 352 /* video mute on */
355 for (i = 0; i < num_of_av_port; i++) { 353 for (i = 0; i < num_of_av_port; i++) {
356 res = ps3av_cmd_av_video_mute(1, &ps3av->av_port[i], mute); 354 res = ps3av_cmd_av_video_mute(1, &ps3av->av_port[i], mute);
357 if (res < 0) 355 if (res < 0)
358 return -1; 356 return -1;
359 } 357 }
360 358
361 return 0; 359 return 0;
362 } 360 }
363 361
364 static int ps3av_set_video_disable_sig(void) 362 static int ps3av_set_video_disable_sig(void)
365 { 363 {
366 int i, num_of_hdmi_port, num_of_av_port, res; 364 int i, num_of_hdmi_port, num_of_av_port, res;
367 365
368 num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi; 366 num_of_hdmi_port = ps3av->av_hw_conf.num_of_hdmi;
369 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + 367 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
370 ps3av->av_hw_conf.num_of_avmulti; 368 ps3av->av_hw_conf.num_of_avmulti;
371 369
372 /* tv mute */ 370 /* tv mute */
373 for (i = 0; i < num_of_hdmi_port; i++) { 371 for (i = 0; i < num_of_hdmi_port; i++) {
374 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i], 372 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
375 PS3AV_CMD_MUTE_ON); 373 PS3AV_CMD_MUTE_ON);
376 if (res < 0) 374 if (res < 0)
377 return -1; 375 return -1;
378 } 376 }
379 msleep(100); 377 msleep(100);
380 378
381 /* video mute on */ 379 /* video mute on */
382 for (i = 0; i < num_of_av_port; i++) { 380 for (i = 0; i < num_of_av_port; i++) {
383 res = ps3av_cmd_av_video_disable_sig(ps3av->av_port[i]); 381 res = ps3av_cmd_av_video_disable_sig(ps3av->av_port[i]);
384 if (res < 0) 382 if (res < 0)
385 return -1; 383 return -1;
386 if (i < num_of_hdmi_port) { 384 if (i < num_of_hdmi_port) {
387 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i], 385 res = ps3av_cmd_av_tv_mute(ps3av->av_port[i],
388 PS3AV_CMD_MUTE_OFF); 386 PS3AV_CMD_MUTE_OFF);
389 if (res < 0) 387 if (res < 0)
390 return -1; 388 return -1;
391 } 389 }
392 } 390 }
393 msleep(300); 391 msleep(300);
394 392
395 return 0; 393 return 0;
396 } 394 }
397 395
398 static int ps3av_set_audio_mute(u32 mute) 396 static int ps3av_set_audio_mute(u32 mute)
399 { 397 {
400 int i, num_of_av_port, num_of_opt_port, res; 398 int i, num_of_av_port, num_of_opt_port, res;
401 399
402 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi + 400 num_of_av_port = ps3av->av_hw_conf.num_of_hdmi +
403 ps3av->av_hw_conf.num_of_avmulti; 401 ps3av->av_hw_conf.num_of_avmulti;
404 num_of_opt_port = ps3av->av_hw_conf.num_of_spdif; 402 num_of_opt_port = ps3av->av_hw_conf.num_of_spdif;
405 403
406 for (i = 0; i < num_of_av_port; i++) { 404 for (i = 0; i < num_of_av_port; i++) {
407 res = ps3av_cmd_av_audio_mute(1, &ps3av->av_port[i], mute); 405 res = ps3av_cmd_av_audio_mute(1, &ps3av->av_port[i], mute);
408 if (res < 0) 406 if (res < 0)
409 return -1; 407 return -1;
410 } 408 }
411 for (i = 0; i < num_of_opt_port; i++) { 409 for (i = 0; i < num_of_opt_port; i++) {
412 res = ps3av_cmd_audio_mute(1, &ps3av->opt_port[i], mute); 410 res = ps3av_cmd_audio_mute(1, &ps3av->opt_port[i], mute);
413 if (res < 0) 411 if (res < 0)
414 return -1; 412 return -1;
415 } 413 }
416 414
417 return 0; 415 return 0;
418 } 416 }
419 417
420 int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source) 418 int ps3av_set_audio_mode(u32 ch, u32 fs, u32 word_bits, u32 format, u32 source)
421 { 419 {
422 struct ps3av_pkt_avb_param avb_param; 420 struct ps3av_pkt_avb_param avb_param;
423 int i, num_of_audio, vid, res; 421 int i, num_of_audio, vid, res;
424 struct ps3av_pkt_audio_mode audio_mode; 422 struct ps3av_pkt_audio_mode audio_mode;
425 u32 len = 0; 423 u32 len = 0;
426 424
427 num_of_audio = ps3av->av_hw_conf.num_of_hdmi + 425 num_of_audio = ps3av->av_hw_conf.num_of_hdmi +
428 ps3av->av_hw_conf.num_of_avmulti + 426 ps3av->av_hw_conf.num_of_avmulti +
429 ps3av->av_hw_conf.num_of_spdif; 427 ps3av->av_hw_conf.num_of_spdif;
430 428
431 avb_param.num_of_video_pkt = 0; 429 avb_param.num_of_video_pkt = 0;
432 avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */ 430 avb_param.num_of_audio_pkt = PS3AV_AVB_NUM_AUDIO; /* always 0 */
433 avb_param.num_of_av_video_pkt = 0; 431 avb_param.num_of_av_video_pkt = 0;
434 avb_param.num_of_av_audio_pkt = ps3av->av_hw_conf.num_of_hdmi; 432 avb_param.num_of_av_audio_pkt = ps3av->av_hw_conf.num_of_hdmi;
435 433
436 vid = video_mode_table[ps3av->ps3av_mode].vid; 434 vid = video_mode_table[ps3av->ps3av_mode].vid;
437 435
438 /* audio mute */ 436 /* audio mute */
439 ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON); 437 ps3av_set_audio_mute(PS3AV_CMD_MUTE_ON);
440 438
441 /* audio inactive */ 439 /* audio inactive */
442 res = ps3av_cmd_audio_active(0, ps3av->audio_port); 440 res = ps3av_cmd_audio_active(0, ps3av->audio_port);
443 if (res < 0) 441 if (res < 0)
444 dev_dbg(&ps3av->dev->core, 442 dev_dbg(&ps3av->dev->core,
445 "ps3av_cmd_audio_active OFF failed\n"); 443 "ps3av_cmd_audio_active OFF failed\n");
446 444
447 /* audio_pkt */ 445 /* audio_pkt */
448 for (i = 0; i < num_of_audio; i++) { 446 for (i = 0; i < num_of_audio; i++) {
449 ps3av_cmd_set_audio_mode(&audio_mode, ps3av->av_port[i], ch, 447 ps3av_cmd_set_audio_mode(&audio_mode, ps3av->av_port[i], ch,
450 fs, word_bits, format, source); 448 fs, word_bits, format, source);
451 if (i < ps3av->av_hw_conf.num_of_hdmi) { 449 if (i < ps3av->av_hw_conf.num_of_hdmi) {
452 /* hdmi only */ 450 /* hdmi only */
453 len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len], 451 len += ps3av_cmd_set_av_audio_param(&avb_param.buf[len],
454 ps3av->av_port[i], 452 ps3av->av_port[i],
455 &audio_mode, vid); 453 &audio_mode, vid);
456 } 454 }
457 /* audio_mode pkt should be sent separately */ 455 /* audio_mode pkt should be sent separately */
458 res = ps3av_cmd_audio_mode(&audio_mode); 456 res = ps3av_cmd_audio_mode(&audio_mode);
459 if (res < 0) 457 if (res < 0)
460 dev_dbg(&ps3av->dev->core, 458 dev_dbg(&ps3av->dev->core,
461 "ps3av_cmd_audio_mode failed, port:%x\n", i); 459 "ps3av_cmd_audio_mode failed, port:%x\n", i);
462 } 460 }
463 461
464 /* send command using avb pkt */ 462 /* send command using avb pkt */
465 len += offsetof(struct ps3av_pkt_avb_param, buf); 463 len += offsetof(struct ps3av_pkt_avb_param, buf);
466 res = ps3av_cmd_avb_param(&avb_param, len); 464 res = ps3av_cmd_avb_param(&avb_param, len);
467 if (res < 0) 465 if (res < 0)
468 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); 466 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
469 467
470 /* audio mute */ 468 /* audio mute */
471 ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF); 469 ps3av_set_audio_mute(PS3AV_CMD_MUTE_OFF);
472 470
473 /* audio active */ 471 /* audio active */
474 res = ps3av_cmd_audio_active(1, ps3av->audio_port); 472 res = ps3av_cmd_audio_active(1, ps3av->audio_port);
475 if (res < 0) 473 if (res < 0)
476 dev_dbg(&ps3av->dev->core, 474 dev_dbg(&ps3av->dev->core,
477 "ps3av_cmd_audio_active ON failed\n"); 475 "ps3av_cmd_audio_active ON failed\n");
478 476
479 return 0; 477 return 0;
480 } 478 }
481 479
482 EXPORT_SYMBOL_GPL(ps3av_set_audio_mode); 480 EXPORT_SYMBOL_GPL(ps3av_set_audio_mode);
483 481
484 static int ps3av_set_videomode(void) 482 static int ps3av_set_videomode(void)
485 { 483 {
486 /* av video mute */ 484 /* av video mute */
487 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON); 485 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_ON);
488 486
489 /* wake up ps3avd to do the actual video mode setting */ 487 /* wake up ps3avd to do the actual video mode setting */
490 queue_work(ps3av->wq, &ps3av->work); 488 queue_work(ps3av->wq, &ps3av->work);
491 489
492 return 0; 490 return 0;
493 } 491 }
494 492
495 static void ps3av_set_videomode_packet(u32 id) 493 static void ps3av_set_videomode_packet(u32 id)
496 { 494 {
497 struct ps3av_pkt_avb_param avb_param; 495 struct ps3av_pkt_avb_param avb_param;
498 unsigned int i; 496 unsigned int i;
499 u32 len = 0, av_video_cs; 497 u32 len = 0, av_video_cs;
500 const struct avset_video_mode *video_mode; 498 const struct avset_video_mode *video_mode;
501 int res; 499 int res;
502 500
503 video_mode = &video_mode_table[id & PS3AV_MODE_MASK]; 501 video_mode = &video_mode_table[id & PS3AV_MODE_MASK];
504 502
505 avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */ 503 avb_param.num_of_video_pkt = PS3AV_AVB_NUM_VIDEO; /* num of head */
506 avb_param.num_of_audio_pkt = 0; 504 avb_param.num_of_audio_pkt = 0;
507 avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi + 505 avb_param.num_of_av_video_pkt = ps3av->av_hw_conf.num_of_hdmi +
508 ps3av->av_hw_conf.num_of_avmulti; 506 ps3av->av_hw_conf.num_of_avmulti;
509 avb_param.num_of_av_audio_pkt = 0; 507 avb_param.num_of_av_audio_pkt = 0;
510 508
511 /* video_pkt */ 509 /* video_pkt */
512 for (i = 0; i < avb_param.num_of_video_pkt; i++) 510 for (i = 0; i < avb_param.num_of_video_pkt; i++)
513 len += ps3av_cmd_set_video_mode(&avb_param.buf[len], 511 len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
514 ps3av->head[i], video_mode->vid, 512 ps3av->head[i], video_mode->vid,
515 video_mode->fmt, id); 513 video_mode->fmt, id);
516 /* av_video_pkt */ 514 /* av_video_pkt */
517 for (i = 0; i < avb_param.num_of_av_video_pkt; i++) { 515 for (i = 0; i < avb_param.num_of_av_video_pkt; i++) {
518 if (id & PS3AV_MODE_DVI || id & PS3AV_MODE_RGB) 516 if (id & PS3AV_MODE_DVI || id & PS3AV_MODE_RGB)
519 av_video_cs = RGB8; 517 av_video_cs = RGB8;
520 else 518 else
521 av_video_cs = video_mode->cs; 519 av_video_cs = video_mode->cs;
522 #ifndef PS3AV_HDMI_YUV 520 #ifndef PS3AV_HDMI_YUV
523 if (ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 || 521 if (ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_0 ||
524 ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_1) 522 ps3av->av_port[i] == PS3AV_CMD_AVPORT_HDMI_1)
525 av_video_cs = RGB8; /* use RGB for HDMI */ 523 av_video_cs = RGB8; /* use RGB for HDMI */
526 #endif 524 #endif
527 len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len], 525 len += ps3av_cmd_set_av_video_cs(&avb_param.buf[len],
528 ps3av->av_port[i], 526 ps3av->av_port[i],
529 video_mode->vid, av_video_cs, 527 video_mode->vid, av_video_cs,
530 video_mode->aspect, id); 528 video_mode->aspect, id);
531 } 529 }
532 /* send command using avb pkt */ 530 /* send command using avb pkt */
533 len += offsetof(struct ps3av_pkt_avb_param, buf); 531 len += offsetof(struct ps3av_pkt_avb_param, buf);
534 res = ps3av_cmd_avb_param(&avb_param, len); 532 res = ps3av_cmd_avb_param(&avb_param, len);
535 if (res == PS3AV_STATUS_NO_SYNC_HEAD) 533 if (res == PS3AV_STATUS_NO_SYNC_HEAD)
536 printk(KERN_WARNING 534 printk(KERN_WARNING
537 "%s: Command failed. Please try your request again. \n", 535 "%s: Command failed. Please try your request again. \n",
538 __func__); 536 __func__);
539 else if (res) 537 else if (res)
540 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); 538 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
541 } 539 }
542 540
543 static void ps3av_set_videomode_cont(u32 id, u32 old_id) 541 static void ps3av_set_videomode_cont(u32 id, u32 old_id)
544 { 542 {
545 static int vesa; 543 static int vesa;
546 int res; 544 int res;
547 545
548 /* video signal off */ 546 /* video signal off */
549 ps3av_set_video_disable_sig(); 547 ps3av_set_video_disable_sig();
550 548
551 /* 549 /*
552 * AV backend needs non-VESA mode setting at least one time 550 * AV backend needs non-VESA mode setting at least one time
553 * when VESA mode is used. 551 * when VESA mode is used.
554 */ 552 */
555 if (vesa == 0 && (id & PS3AV_MODE_MASK) >= PS3AV_MODE_WXGA) { 553 if (vesa == 0 && (id & PS3AV_MODE_MASK) >= PS3AV_MODE_WXGA) {
556 /* vesa mode */ 554 /* vesa mode */
557 ps3av_set_videomode_packet(PS3AV_MODE_480P); 555 ps3av_set_videomode_packet(PS3AV_MODE_480P);
558 } 556 }
559 vesa = 1; 557 vesa = 1;
560 558
561 /* Retail PS3 product doesn't support this */ 559 /* Retail PS3 product doesn't support this */
562 if (id & PS3AV_MODE_HDCP_OFF) { 560 if (id & PS3AV_MODE_HDCP_OFF) {
563 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF); 561 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
564 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 562 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
565 dev_dbg(&ps3av->dev->core, "Not supported\n"); 563 dev_dbg(&ps3av->dev->core, "Not supported\n");
566 else if (res) 564 else if (res)
567 dev_dbg(&ps3av->dev->core, 565 dev_dbg(&ps3av->dev->core,
568 "ps3av_cmd_av_hdmi_mode failed\n"); 566 "ps3av_cmd_av_hdmi_mode failed\n");
569 } else if (old_id & PS3AV_MODE_HDCP_OFF) { 567 } else if (old_id & PS3AV_MODE_HDCP_OFF) {
570 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL); 568 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
571 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 569 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
572 dev_dbg(&ps3av->dev->core, 570 dev_dbg(&ps3av->dev->core,
573 "ps3av_cmd_av_hdmi_mode failed\n"); 571 "ps3av_cmd_av_hdmi_mode failed\n");
574 } 572 }
575 573
576 ps3av_set_videomode_packet(id); 574 ps3av_set_videomode_packet(id);
577 575
578 msleep(1500); 576 msleep(1500);
579 /* av video mute */ 577 /* av video mute */
580 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_OFF); 578 ps3av_set_av_video_mute(PS3AV_CMD_MUTE_OFF);
581 } 579 }
582 580
583 static void ps3avd(struct work_struct *work) 581 static void ps3avd(struct work_struct *work)
584 { 582 {
585 ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old); 583 ps3av_set_videomode_cont(ps3av->ps3av_mode, ps3av->ps3av_mode_old);
586 complete(&ps3av->done); 584 complete(&ps3av->done);
587 } 585 }
588 586
589 #define SHIFT_50 0 587 #define SHIFT_50 0
590 #define SHIFT_60 4 588 #define SHIFT_60 4
591 #define SHIFT_VESA 8 589 #define SHIFT_VESA 8
592 590
593 static const struct { 591 static const struct {
594 unsigned mask : 19; 592 unsigned mask : 19;
595 unsigned id : 4; 593 unsigned id : 4;
596 } ps3av_preferred_modes[] = { 594 } ps3av_preferred_modes[] = {
597 { PS3AV_RESBIT_WUXGA << SHIFT_VESA, PS3AV_MODE_WUXGA }, 595 { PS3AV_RESBIT_WUXGA << SHIFT_VESA, PS3AV_MODE_WUXGA },
598 { PS3AV_RESBIT_1920x1080P << SHIFT_60, PS3AV_MODE_1080P60 }, 596 { PS3AV_RESBIT_1920x1080P << SHIFT_60, PS3AV_MODE_1080P60 },
599 { PS3AV_RESBIT_1920x1080P << SHIFT_50, PS3AV_MODE_1080P50 }, 597 { PS3AV_RESBIT_1920x1080P << SHIFT_50, PS3AV_MODE_1080P50 },
600 { PS3AV_RESBIT_1920x1080I << SHIFT_60, PS3AV_MODE_1080I60 }, 598 { PS3AV_RESBIT_1920x1080I << SHIFT_60, PS3AV_MODE_1080I60 },
601 { PS3AV_RESBIT_1920x1080I << SHIFT_50, PS3AV_MODE_1080I50 }, 599 { PS3AV_RESBIT_1920x1080I << SHIFT_50, PS3AV_MODE_1080I50 },
602 { PS3AV_RESBIT_SXGA << SHIFT_VESA, PS3AV_MODE_SXGA }, 600 { PS3AV_RESBIT_SXGA << SHIFT_VESA, PS3AV_MODE_SXGA },
603 { PS3AV_RESBIT_WXGA << SHIFT_VESA, PS3AV_MODE_WXGA }, 601 { PS3AV_RESBIT_WXGA << SHIFT_VESA, PS3AV_MODE_WXGA },
604 { PS3AV_RESBIT_1280x720P << SHIFT_60, PS3AV_MODE_720P60 }, 602 { PS3AV_RESBIT_1280x720P << SHIFT_60, PS3AV_MODE_720P60 },
605 { PS3AV_RESBIT_1280x720P << SHIFT_50, PS3AV_MODE_720P50 }, 603 { PS3AV_RESBIT_1280x720P << SHIFT_50, PS3AV_MODE_720P50 },
606 { PS3AV_RESBIT_720x480P << SHIFT_60, PS3AV_MODE_480P }, 604 { PS3AV_RESBIT_720x480P << SHIFT_60, PS3AV_MODE_480P },
607 { PS3AV_RESBIT_720x576P << SHIFT_50, PS3AV_MODE_576P }, 605 { PS3AV_RESBIT_720x576P << SHIFT_50, PS3AV_MODE_576P },
608 }; 606 };
609 607
610 static enum ps3av_mode_num ps3av_resbit2id(u32 res_50, u32 res_60, 608 static enum ps3av_mode_num ps3av_resbit2id(u32 res_50, u32 res_60,
611 u32 res_vesa) 609 u32 res_vesa)
612 { 610 {
613 unsigned int i; 611 unsigned int i;
614 u32 res_all; 612 u32 res_all;
615 613
616 /* 614 /*
617 * We mask off the resolution bits we care about and combine the 615 * We mask off the resolution bits we care about and combine the
618 * results in one bitfield, so make sure there's no overlap 616 * results in one bitfield, so make sure there's no overlap
619 */ 617 */
620 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 & 618 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
621 PS3AV_RES_MASK_60 << SHIFT_60); 619 PS3AV_RES_MASK_60 << SHIFT_60);
622 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 & 620 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
623 PS3AV_RES_MASK_VESA << SHIFT_VESA); 621 PS3AV_RES_MASK_VESA << SHIFT_VESA);
624 BUILD_BUG_ON(PS3AV_RES_MASK_60 << SHIFT_60 & 622 BUILD_BUG_ON(PS3AV_RES_MASK_60 << SHIFT_60 &
625 PS3AV_RES_MASK_VESA << SHIFT_VESA); 623 PS3AV_RES_MASK_VESA << SHIFT_VESA);
626 res_all = (res_50 & PS3AV_RES_MASK_50) << SHIFT_50 | 624 res_all = (res_50 & PS3AV_RES_MASK_50) << SHIFT_50 |
627 (res_60 & PS3AV_RES_MASK_60) << SHIFT_60 | 625 (res_60 & PS3AV_RES_MASK_60) << SHIFT_60 |
628 (res_vesa & PS3AV_RES_MASK_VESA) << SHIFT_VESA; 626 (res_vesa & PS3AV_RES_MASK_VESA) << SHIFT_VESA;
629 627
630 if (!res_all) 628 if (!res_all)
631 return 0; 629 return 0;
632 630
633 for (i = 0; i < ARRAY_SIZE(ps3av_preferred_modes); i++) 631 for (i = 0; i < ARRAY_SIZE(ps3av_preferred_modes); i++)
634 if (res_all & ps3av_preferred_modes[i].mask) 632 if (res_all & ps3av_preferred_modes[i].mask)
635 return ps3av_preferred_modes[i].id; 633 return ps3av_preferred_modes[i].id;
636 634
637 return 0; 635 return 0;
638 } 636 }
639 637
640 static enum ps3av_mode_num ps3av_hdmi_get_id(struct ps3av_info_monitor *info) 638 static enum ps3av_mode_num ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
641 { 639 {
642 enum ps3av_mode_num id; 640 enum ps3av_mode_num id;
643 641
644 if (safe_mode) 642 if (safe_mode)
645 return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60; 643 return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
646 644
647 /* check native resolution */ 645 /* check native resolution */
648 id = ps3av_resbit2id(info->res_50.native, info->res_60.native, 646 id = ps3av_resbit2id(info->res_50.native, info->res_60.native,
649 info->res_vesa.native); 647 info->res_vesa.native);
650 if (id) { 648 if (id) {
651 pr_debug("%s: Using native mode %d\n", __func__, id); 649 pr_debug("%s: Using native mode %d\n", __func__, id);
652 return id; 650 return id;
653 } 651 }
654 652
655 /* check supported resolutions */ 653 /* check supported resolutions */
656 id = ps3av_resbit2id(info->res_50.res_bits, info->res_60.res_bits, 654 id = ps3av_resbit2id(info->res_50.res_bits, info->res_60.res_bits,
657 info->res_vesa.res_bits); 655 info->res_vesa.res_bits);
658 if (id) { 656 if (id) {
659 pr_debug("%s: Using supported mode %d\n", __func__, id); 657 pr_debug("%s: Using supported mode %d\n", __func__, id);
660 return id; 658 return id;
661 } 659 }
662 660
663 if (ps3av->region & PS3AV_REGION_60) 661 if (ps3av->region & PS3AV_REGION_60)
664 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60; 662 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
665 else 663 else
666 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50; 664 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50;
667 pr_debug("%s: Using default mode %d\n", __func__, id); 665 pr_debug("%s: Using default mode %d\n", __func__, id);
668 return id; 666 return id;
669 } 667 }
670 668
671 static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info) 669 static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
672 { 670 {
673 const struct ps3av_info_monitor *info = &monitor_info->info; 671 const struct ps3av_info_monitor *info = &monitor_info->info;
674 const struct ps3av_info_audio *audio = info->audio; 672 const struct ps3av_info_audio *audio = info->audio;
675 char id[sizeof(info->monitor_id)*3+1]; 673 char id[sizeof(info->monitor_id)*3+1];
676 int i; 674 int i;
677 675
678 pr_debug("Monitor Info: size %u\n", monitor_info->send_hdr.size); 676 pr_debug("Monitor Info: size %u\n", monitor_info->send_hdr.size);
679 677
680 pr_debug("avport: %02x\n", info->avport); 678 pr_debug("avport: %02x\n", info->avport);
681 for (i = 0; i < sizeof(info->monitor_id); i++) 679 for (i = 0; i < sizeof(info->monitor_id); i++)
682 sprintf(&id[i*3], " %02x", info->monitor_id[i]); 680 sprintf(&id[i*3], " %02x", info->monitor_id[i]);
683 pr_debug("monitor_id: %s\n", id); 681 pr_debug("monitor_id: %s\n", id);
684 pr_debug("monitor_type: %02x\n", info->monitor_type); 682 pr_debug("monitor_type: %02x\n", info->monitor_type);
685 pr_debug("monitor_name: %.*s\n", (int)sizeof(info->monitor_name), 683 pr_debug("monitor_name: %.*s\n", (int)sizeof(info->monitor_name),
686 info->monitor_name); 684 info->monitor_name);
687 685
688 /* resolution */ 686 /* resolution */
689 pr_debug("resolution_60: bits: %08x native: %08x\n", 687 pr_debug("resolution_60: bits: %08x native: %08x\n",
690 info->res_60.res_bits, info->res_60.native); 688 info->res_60.res_bits, info->res_60.native);
691 pr_debug("resolution_50: bits: %08x native: %08x\n", 689 pr_debug("resolution_50: bits: %08x native: %08x\n",
692 info->res_50.res_bits, info->res_50.native); 690 info->res_50.res_bits, info->res_50.native);
693 pr_debug("resolution_other: bits: %08x native: %08x\n", 691 pr_debug("resolution_other: bits: %08x native: %08x\n",
694 info->res_other.res_bits, info->res_other.native); 692 info->res_other.res_bits, info->res_other.native);
695 pr_debug("resolution_vesa: bits: %08x native: %08x\n", 693 pr_debug("resolution_vesa: bits: %08x native: %08x\n",
696 info->res_vesa.res_bits, info->res_vesa.native); 694 info->res_vesa.res_bits, info->res_vesa.native);
697 695
698 /* color space */ 696 /* color space */
699 pr_debug("color space rgb: %02x\n", info->cs.rgb); 697 pr_debug("color space rgb: %02x\n", info->cs.rgb);
700 pr_debug("color space yuv444: %02x\n", info->cs.yuv444); 698 pr_debug("color space yuv444: %02x\n", info->cs.yuv444);
701 pr_debug("color space yuv422: %02x\n", info->cs.yuv422); 699 pr_debug("color space yuv422: %02x\n", info->cs.yuv422);
702 700
703 /* color info */ 701 /* color info */
704 pr_debug("color info red: X %04x Y %04x\n", info->color.red_x, 702 pr_debug("color info red: X %04x Y %04x\n", info->color.red_x,
705 info->color.red_y); 703 info->color.red_y);
706 pr_debug("color info green: X %04x Y %04x\n", info->color.green_x, 704 pr_debug("color info green: X %04x Y %04x\n", info->color.green_x,
707 info->color.green_y); 705 info->color.green_y);
708 pr_debug("color info blue: X %04x Y %04x\n", info->color.blue_x, 706 pr_debug("color info blue: X %04x Y %04x\n", info->color.blue_x,
709 info->color.blue_y); 707 info->color.blue_y);
710 pr_debug("color info white: X %04x Y %04x\n", info->color.white_x, 708 pr_debug("color info white: X %04x Y %04x\n", info->color.white_x,
711 info->color.white_y); 709 info->color.white_y);
712 pr_debug("color info gamma: %08x\n", info->color.gamma); 710 pr_debug("color info gamma: %08x\n", info->color.gamma);
713 711
714 /* other info */ 712 /* other info */
715 pr_debug("supported_AI: %02x\n", info->supported_ai); 713 pr_debug("supported_AI: %02x\n", info->supported_ai);
716 pr_debug("speaker_info: %02x\n", info->speaker_info); 714 pr_debug("speaker_info: %02x\n", info->speaker_info);
717 pr_debug("num of audio: %02x\n", info->num_of_audio_block); 715 pr_debug("num of audio: %02x\n", info->num_of_audio_block);
718 716
719 /* audio block */ 717 /* audio block */
720 for (i = 0; i < info->num_of_audio_block; i++) { 718 for (i = 0; i < info->num_of_audio_block; i++) {
721 pr_debug("audio[%d] type: %02x max_ch: %02x fs: %02x sbit: " 719 pr_debug("audio[%d] type: %02x max_ch: %02x fs: %02x sbit: "
722 "%02x\n", 720 "%02x\n",
723 i, audio->type, audio->max_num_of_ch, audio->fs, 721 i, audio->type, audio->max_num_of_ch, audio->fs,
724 audio->sbit); 722 audio->sbit);
725 audio++; 723 audio++;
726 } 724 }
727 } 725 }
728 726
729 static const struct ps3av_monitor_quirk { 727 static const struct ps3av_monitor_quirk {
730 const char *monitor_name; 728 const char *monitor_name;
731 u32 clear_60; 729 u32 clear_60;
732 } ps3av_monitor_quirks[] = { 730 } ps3av_monitor_quirks[] = {
733 { 731 {
734 .monitor_name = "DELL 2007WFP", 732 .monitor_name = "DELL 2007WFP",
735 .clear_60 = PS3AV_RESBIT_1920x1080I 733 .clear_60 = PS3AV_RESBIT_1920x1080I
736 }, { 734 }, {
737 .monitor_name = "L226WTQ", 735 .monitor_name = "L226WTQ",
738 .clear_60 = PS3AV_RESBIT_1920x1080I | 736 .clear_60 = PS3AV_RESBIT_1920x1080I |
739 PS3AV_RESBIT_1920x1080P 737 PS3AV_RESBIT_1920x1080P
740 }, { 738 }, {
741 .monitor_name = "SyncMaster", 739 .monitor_name = "SyncMaster",
742 .clear_60 = PS3AV_RESBIT_1920x1080I 740 .clear_60 = PS3AV_RESBIT_1920x1080I
743 } 741 }
744 }; 742 };
745 743
746 static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info) 744 static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info)
747 { 745 {
748 unsigned int i; 746 unsigned int i;
749 const struct ps3av_monitor_quirk *quirk; 747 const struct ps3av_monitor_quirk *quirk;
750 748
751 for (i = 0; i < ARRAY_SIZE(ps3av_monitor_quirks); i++) { 749 for (i = 0; i < ARRAY_SIZE(ps3av_monitor_quirks); i++) {
752 quirk = &ps3av_monitor_quirks[i]; 750 quirk = &ps3av_monitor_quirks[i];
753 if (!strncmp(info->monitor_name, quirk->monitor_name, 751 if (!strncmp(info->monitor_name, quirk->monitor_name,
754 sizeof(info->monitor_name))) { 752 sizeof(info->monitor_name))) {
755 pr_info("%s: Applying quirk for %s\n", __func__, 753 pr_info("%s: Applying quirk for %s\n", __func__,
756 quirk->monitor_name); 754 quirk->monitor_name);
757 info->res_60.res_bits &= ~quirk->clear_60; 755 info->res_60.res_bits &= ~quirk->clear_60;
758 info->res_60.native &= ~quirk->clear_60; 756 info->res_60.native &= ~quirk->clear_60;
759 break; 757 break;
760 } 758 }
761 } 759 }
762 } 760 }
763 761
764 static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf) 762 static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf)
765 { 763 {
766 int i, res, id = 0, dvi = 0, rgb = 0; 764 int i, res, id = 0, dvi = 0, rgb = 0;
767 struct ps3av_pkt_av_get_monitor_info monitor_info; 765 struct ps3av_pkt_av_get_monitor_info monitor_info;
768 struct ps3av_info_monitor *info; 766 struct ps3av_info_monitor *info;
769 767
770 /* get mode id for hdmi */ 768 /* get mode id for hdmi */
771 for (i = 0; i < av_hw_conf->num_of_hdmi && !id; i++) { 769 for (i = 0; i < av_hw_conf->num_of_hdmi && !id; i++) {
772 res = ps3av_cmd_video_get_monitor_info(&monitor_info, 770 res = ps3av_cmd_video_get_monitor_info(&monitor_info,
773 PS3AV_CMD_AVPORT_HDMI_0 + 771 PS3AV_CMD_AVPORT_HDMI_0 +
774 i); 772 i);
775 if (res < 0) 773 if (res < 0)
776 return -1; 774 return -1;
777 775
778 ps3av_monitor_info_dump(&monitor_info); 776 ps3av_monitor_info_dump(&monitor_info);
779 777
780 info = &monitor_info.info; 778 info = &monitor_info.info;
781 ps3av_fixup_monitor_info(info); 779 ps3av_fixup_monitor_info(info);
782 780
783 switch (info->monitor_type) { 781 switch (info->monitor_type) {
784 case PS3AV_MONITOR_TYPE_DVI: 782 case PS3AV_MONITOR_TYPE_DVI:
785 dvi = PS3AV_MODE_DVI; 783 dvi = PS3AV_MODE_DVI;
786 /* fall through */ 784 /* fall through */
787 case PS3AV_MONITOR_TYPE_HDMI: 785 case PS3AV_MONITOR_TYPE_HDMI:
788 id = ps3av_hdmi_get_id(info); 786 id = ps3av_hdmi_get_id(info);
789 break; 787 break;
790 } 788 }
791 } 789 }
792 790
793 if (!id) { 791 if (!id) {
794 /* no HDMI interface or HDMI is off */ 792 /* no HDMI interface or HDMI is off */
795 if (ps3av->region & PS3AV_REGION_60) 793 if (ps3av->region & PS3AV_REGION_60)
796 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60; 794 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60;
797 else 795 else
798 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50; 796 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50;
799 if (ps3av->region & PS3AV_REGION_RGB) 797 if (ps3av->region & PS3AV_REGION_RGB)
800 rgb = PS3AV_MODE_RGB; 798 rgb = PS3AV_MODE_RGB;
801 pr_debug("%s: Using avmulti mode %d\n", __func__, id); 799 pr_debug("%s: Using avmulti mode %d\n", __func__, id);
802 } 800 }
803 801
804 return id | dvi | rgb; 802 return id | dvi | rgb;
805 } 803 }
806 804
807 static int ps3av_get_hw_conf(struct ps3av *ps3av) 805 static int ps3av_get_hw_conf(struct ps3av *ps3av)
808 { 806 {
809 int i, j, k, res; 807 int i, j, k, res;
810 const struct ps3av_pkt_av_get_hw_conf *hw_conf; 808 const struct ps3av_pkt_av_get_hw_conf *hw_conf;
811 809
812 /* get av_hw_conf */ 810 /* get av_hw_conf */
813 res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf); 811 res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf);
814 if (res < 0) 812 if (res < 0)
815 return -1; 813 return -1;
816 814
817 hw_conf = &ps3av->av_hw_conf; 815 hw_conf = &ps3av->av_hw_conf;
818 pr_debug("av_h_conf: num of hdmi: %u\n", hw_conf->num_of_hdmi); 816 pr_debug("av_h_conf: num of hdmi: %u\n", hw_conf->num_of_hdmi);
819 pr_debug("av_h_conf: num of avmulti: %u\n", hw_conf->num_of_avmulti); 817 pr_debug("av_h_conf: num of avmulti: %u\n", hw_conf->num_of_avmulti);
820 pr_debug("av_h_conf: num of spdif: %u\n", hw_conf->num_of_spdif); 818 pr_debug("av_h_conf: num of spdif: %u\n", hw_conf->num_of_spdif);
821 819
822 for (i = 0; i < PS3AV_HEAD_MAX; i++) 820 for (i = 0; i < PS3AV_HEAD_MAX; i++)
823 ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i; 821 ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i;
824 for (i = 0; i < PS3AV_OPT_PORT_MAX; i++) 822 for (i = 0; i < PS3AV_OPT_PORT_MAX; i++)
825 ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i; 823 ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i;
826 for (i = 0; i < hw_conf->num_of_hdmi; i++) 824 for (i = 0; i < hw_conf->num_of_hdmi; i++)
827 ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i; 825 ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i;
828 for (j = 0; j < hw_conf->num_of_avmulti; j++) 826 for (j = 0; j < hw_conf->num_of_avmulti; j++)
829 ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j; 827 ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j;
830 for (k = 0; k < hw_conf->num_of_spdif; k++) 828 for (k = 0; k < hw_conf->num_of_spdif; k++)
831 ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k; 829 ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k;
832 830
833 /* set all audio port */ 831 /* set all audio port */
834 ps3av->audio_port = PS3AV_CMD_AUDIO_PORT_HDMI_0 832 ps3av->audio_port = PS3AV_CMD_AUDIO_PORT_HDMI_0
835 | PS3AV_CMD_AUDIO_PORT_HDMI_1 833 | PS3AV_CMD_AUDIO_PORT_HDMI_1
836 | PS3AV_CMD_AUDIO_PORT_AVMULTI_0 834 | PS3AV_CMD_AUDIO_PORT_AVMULTI_0
837 | PS3AV_CMD_AUDIO_PORT_SPDIF_0 | PS3AV_CMD_AUDIO_PORT_SPDIF_1; 835 | PS3AV_CMD_AUDIO_PORT_SPDIF_0 | PS3AV_CMD_AUDIO_PORT_SPDIF_1;
838 836
839 return 0; 837 return 0;
840 } 838 }
841 839
842 /* set mode using id */ 840 /* set mode using id */
843 int ps3av_set_video_mode(u32 id) 841 int ps3av_set_video_mode(u32 id)
844 { 842 {
845 int size; 843 int size;
846 u32 option; 844 u32 option;
847 845
848 size = ARRAY_SIZE(video_mode_table); 846 size = ARRAY_SIZE(video_mode_table);
849 if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) { 847 if ((id & PS3AV_MODE_MASK) > size - 1 || id < 0) {
850 dev_dbg(&ps3av->dev->core, "%s: error id :%d\n", __func__, id); 848 dev_dbg(&ps3av->dev->core, "%s: error id :%d\n", __func__, id);
851 return -EINVAL; 849 return -EINVAL;
852 } 850 }
853 851
854 /* auto mode */ 852 /* auto mode */
855 option = id & ~PS3AV_MODE_MASK; 853 option = id & ~PS3AV_MODE_MASK;
856 if ((id & PS3AV_MODE_MASK) == PS3AV_MODE_AUTO) { 854 if ((id & PS3AV_MODE_MASK) == PS3AV_MODE_AUTO) {
857 id = ps3av_auto_videomode(&ps3av->av_hw_conf); 855 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
858 if (id < 1) { 856 if (id < 1) {
859 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); 857 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
860 return -EINVAL; 858 return -EINVAL;
861 } 859 }
862 id |= option; 860 id |= option;
863 } 861 }
864 862
865 /* set videomode */ 863 /* set videomode */
866 wait_for_completion(&ps3av->done); 864 wait_for_completion(&ps3av->done);
867 ps3av->ps3av_mode_old = ps3av->ps3av_mode; 865 ps3av->ps3av_mode_old = ps3av->ps3av_mode;
868 ps3av->ps3av_mode = id; 866 ps3av->ps3av_mode = id;
869 if (ps3av_set_videomode()) 867 if (ps3av_set_videomode())
870 ps3av->ps3av_mode = ps3av->ps3av_mode_old; 868 ps3av->ps3av_mode = ps3av->ps3av_mode_old;
871 869
872 return 0; 870 return 0;
873 } 871 }
874 872
875 EXPORT_SYMBOL_GPL(ps3av_set_video_mode); 873 EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
876 874
877 int ps3av_get_auto_mode(void) 875 int ps3av_get_auto_mode(void)
878 { 876 {
879 return ps3av_auto_videomode(&ps3av->av_hw_conf); 877 return ps3av_auto_videomode(&ps3av->av_hw_conf);
880 } 878 }
881 879
882 EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); 880 EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
883 881
884 int ps3av_get_mode(void) 882 int ps3av_get_mode(void)
885 { 883 {
886 return ps3av ? ps3av->ps3av_mode : 0; 884 return ps3av ? ps3av->ps3av_mode : 0;
887 } 885 }
888 886
889 EXPORT_SYMBOL_GPL(ps3av_get_mode); 887 EXPORT_SYMBOL_GPL(ps3av_get_mode);
890 888
891 /* get resolution by video_mode */ 889 /* get resolution by video_mode */
892 int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres) 890 int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres)
893 { 891 {
894 int size; 892 int size;
895 893
896 id = id & PS3AV_MODE_MASK; 894 id = id & PS3AV_MODE_MASK;
897 size = ARRAY_SIZE(video_mode_table); 895 size = ARRAY_SIZE(video_mode_table);
898 if (id > size - 1 || id < 0) { 896 if (id > size - 1 || id < 0) {
899 printk(KERN_ERR "%s: invalid mode %d\n", __func__, id); 897 printk(KERN_ERR "%s: invalid mode %d\n", __func__, id);
900 return -EINVAL; 898 return -EINVAL;
901 } 899 }
902 *xres = video_mode_table[id].x; 900 *xres = video_mode_table[id].x;
903 *yres = video_mode_table[id].y; 901 *yres = video_mode_table[id].y;
904 return 0; 902 return 0;
905 } 903 }
906 904
907 EXPORT_SYMBOL_GPL(ps3av_video_mode2res); 905 EXPORT_SYMBOL_GPL(ps3av_video_mode2res);
908 906
909 /* mute */ 907 /* mute */
910 int ps3av_video_mute(int mute) 908 int ps3av_video_mute(int mute)
911 { 909 {
912 return ps3av_set_av_video_mute(mute ? PS3AV_CMD_MUTE_ON 910 return ps3av_set_av_video_mute(mute ? PS3AV_CMD_MUTE_ON
913 : PS3AV_CMD_MUTE_OFF); 911 : PS3AV_CMD_MUTE_OFF);
914 } 912 }
915 913
916 EXPORT_SYMBOL_GPL(ps3av_video_mute); 914 EXPORT_SYMBOL_GPL(ps3av_video_mute);
917 915
918 /* mute analog output only */ 916 /* mute analog output only */
919 int ps3av_audio_mute_analog(int mute) 917 int ps3av_audio_mute_analog(int mute)
920 { 918 {
921 int i, res; 919 int i, res;
922 920
923 for (i = 0; i < ps3av->av_hw_conf.num_of_avmulti; i++) { 921 for (i = 0; i < ps3av->av_hw_conf.num_of_avmulti; i++) {
924 res = ps3av_cmd_av_audio_mute(1, 922 res = ps3av_cmd_av_audio_mute(1,
925 &ps3av->av_port[i + ps3av->av_hw_conf.num_of_hdmi], 923 &ps3av->av_port[i + ps3av->av_hw_conf.num_of_hdmi],
926 mute); 924 mute);
927 if (res < 0) 925 if (res < 0)
928 return -1; 926 return -1;
929 } 927 }
930 return 0; 928 return 0;
931 } 929 }
932 EXPORT_SYMBOL_GPL(ps3av_audio_mute_analog); 930 EXPORT_SYMBOL_GPL(ps3av_audio_mute_analog);
933 931
934 int ps3av_audio_mute(int mute) 932 int ps3av_audio_mute(int mute)
935 { 933 {
936 return ps3av_set_audio_mute(mute ? PS3AV_CMD_MUTE_ON 934 return ps3av_set_audio_mute(mute ? PS3AV_CMD_MUTE_ON
937 : PS3AV_CMD_MUTE_OFF); 935 : PS3AV_CMD_MUTE_OFF);
938 } 936 }
939 937
940 EXPORT_SYMBOL_GPL(ps3av_audio_mute); 938 EXPORT_SYMBOL_GPL(ps3av_audio_mute);
941
942 void ps3av_register_flip_ctl(void (*flip_ctl)(int on, void *data),
943 void *flip_data)
944 {
945 mutex_lock(&ps3av->mutex);
946 ps3av->flip_ctl = flip_ctl;
947 ps3av->flip_data = flip_data;
948 mutex_unlock(&ps3av->mutex);
949 }
950 EXPORT_SYMBOL_GPL(ps3av_register_flip_ctl);
951
952 void ps3av_flip_ctl(int on)
953 {
954 mutex_lock(&ps3av->mutex);
955 if (ps3av->flip_ctl)
956 ps3av->flip_ctl(on, ps3av->flip_data);
957 mutex_unlock(&ps3av->mutex);
958 }
959 939
960 static int ps3av_probe(struct ps3_system_bus_device *dev) 940 static int ps3av_probe(struct ps3_system_bus_device *dev)
961 { 941 {
962 int res; 942 int res;
963 u32 id; 943 u32 id;
964 944
965 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 945 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
966 dev_dbg(&dev->core, " timeout=%d\n", timeout); 946 dev_dbg(&dev->core, " timeout=%d\n", timeout);
967 947
968 if (ps3av) { 948 if (ps3av) {
969 dev_err(&dev->core, "Only one ps3av device is supported\n"); 949 dev_err(&dev->core, "Only one ps3av device is supported\n");
970 return -EBUSY; 950 return -EBUSY;
971 } 951 }
972 952
973 ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL); 953 ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL);
974 if (!ps3av) 954 if (!ps3av)
975 return -ENOMEM; 955 return -ENOMEM;
976 956
977 mutex_init(&ps3av->mutex); 957 mutex_init(&ps3av->mutex);
978 ps3av->ps3av_mode = PS3AV_MODE_AUTO; 958 ps3av->ps3av_mode = PS3AV_MODE_AUTO;
979 ps3av->dev = dev; 959 ps3av->dev = dev;
980 960
981 INIT_WORK(&ps3av->work, ps3avd); 961 INIT_WORK(&ps3av->work, ps3avd);
982 init_completion(&ps3av->done); 962 init_completion(&ps3av->done);
983 complete(&ps3av->done); 963 complete(&ps3av->done);
984 ps3av->wq = create_singlethread_workqueue("ps3avd"); 964 ps3av->wq = create_singlethread_workqueue("ps3avd");
985 if (!ps3av->wq) 965 if (!ps3av->wq)
986 goto fail; 966 goto fail;
987 967
988 switch (ps3_os_area_get_av_multi_out()) { 968 switch (ps3_os_area_get_av_multi_out()) {
989 case PS3_PARAM_AV_MULTI_OUT_NTSC: 969 case PS3_PARAM_AV_MULTI_OUT_NTSC:
990 ps3av->region = PS3AV_REGION_60; 970 ps3av->region = PS3AV_REGION_60;
991 break; 971 break;
992 case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR: 972 case PS3_PARAM_AV_MULTI_OUT_PAL_YCBCR:
993 case PS3_PARAM_AV_MULTI_OUT_SECAM: 973 case PS3_PARAM_AV_MULTI_OUT_SECAM:
994 ps3av->region = PS3AV_REGION_50; 974 ps3av->region = PS3AV_REGION_50;
995 break; 975 break;
996 case PS3_PARAM_AV_MULTI_OUT_PAL_RGB: 976 case PS3_PARAM_AV_MULTI_OUT_PAL_RGB:
997 ps3av->region = PS3AV_REGION_50 | PS3AV_REGION_RGB; 977 ps3av->region = PS3AV_REGION_50 | PS3AV_REGION_RGB;
998 break; 978 break;
999 default: 979 default:
1000 ps3av->region = PS3AV_REGION_60; 980 ps3av->region = PS3AV_REGION_60;
1001 break; 981 break;
1002 } 982 }
1003 983
1004 /* init avsetting modules */ 984 /* init avsetting modules */
1005 res = ps3av_cmd_init(); 985 res = ps3av_cmd_init();
1006 if (res < 0) 986 if (res < 0)
1007 printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__, 987 printk(KERN_ERR "%s: ps3av_cmd_init failed %d\n", __func__,
1008 res); 988 res);
1009 989
1010 ps3av_get_hw_conf(ps3av); 990 ps3av_get_hw_conf(ps3av);
1011 991
1012 #ifdef CONFIG_FB 992 #ifdef CONFIG_FB
1013 if (fb_mode_option && !strcmp(fb_mode_option, "safe")) 993 if (fb_mode_option && !strcmp(fb_mode_option, "safe"))
1014 safe_mode = 1; 994 safe_mode = 1;
1015 #endif /* CONFIG_FB */ 995 #endif /* CONFIG_FB */
1016 id = ps3av_auto_videomode(&ps3av->av_hw_conf); 996 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
1017 safe_mode = 0; 997 safe_mode = 0;
1018 998
1019 mutex_lock(&ps3av->mutex); 999 mutex_lock(&ps3av->mutex);
1020 ps3av->ps3av_mode = id; 1000 ps3av->ps3av_mode = id;
1021 mutex_unlock(&ps3av->mutex); 1001 mutex_unlock(&ps3av->mutex);
1022 1002
1023 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 1003 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1024 1004
1025 return 0; 1005 return 0;
1026 1006
1027 fail: 1007 fail:
1028 kfree(ps3av); 1008 kfree(ps3av);
1029 ps3av = NULL; 1009 ps3av = NULL;
1030 return -ENOMEM; 1010 return -ENOMEM;
1031 } 1011 }
1032 1012
1033 static int ps3av_remove(struct ps3_system_bus_device *dev) 1013 static int ps3av_remove(struct ps3_system_bus_device *dev)
1034 { 1014 {
1035 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 1015 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1036 if (ps3av) { 1016 if (ps3av) {
1037 ps3av_cmd_fin(); 1017 ps3av_cmd_fin();
1038 if (ps3av->wq) 1018 if (ps3av->wq)
1039 destroy_workqueue(ps3av->wq); 1019 destroy_workqueue(ps3av->wq);
1040 kfree(ps3av); 1020 kfree(ps3av);
1041 ps3av = NULL; 1021 ps3av = NULL;
1042 } 1022 }
1043 1023
1044 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 1024 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1045 return 0; 1025 return 0;
1046 } 1026 }
1047 1027
1048 static void ps3av_shutdown(struct ps3_system_bus_device *dev) 1028 static void ps3av_shutdown(struct ps3_system_bus_device *dev)
1049 { 1029 {
1050 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 1030 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1051 ps3av_remove(dev); 1031 ps3av_remove(dev);
1052 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 1032 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1053 } 1033 }
1054 1034
1055 static struct ps3_vuart_port_driver ps3av_driver = { 1035 static struct ps3_vuart_port_driver ps3av_driver = {
1056 .core.match_id = PS3_MATCH_ID_AV_SETTINGS, 1036 .core.match_id = PS3_MATCH_ID_AV_SETTINGS,
1057 .core.core.name = "ps3_av", 1037 .core.core.name = "ps3_av",
1058 .probe = ps3av_probe, 1038 .probe = ps3av_probe,
1059 .remove = ps3av_remove, 1039 .remove = ps3av_remove,
1060 .shutdown = ps3av_shutdown, 1040 .shutdown = ps3av_shutdown,
1061 }; 1041 };
1062 1042
1063 static int ps3av_module_init(void) 1043 static int ps3av_module_init(void)
1064 { 1044 {
1065 int error; 1045 int error;
1066 1046
1067 if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) 1047 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
1068 return -ENODEV; 1048 return -ENODEV;
1069 1049
1070 pr_debug(" -> %s:%d\n", __func__, __LINE__); 1050 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1071 1051
1072 error = ps3_vuart_port_driver_register(&ps3av_driver); 1052 error = ps3_vuart_port_driver_register(&ps3av_driver);
1073 if (error) { 1053 if (error) {
1074 printk(KERN_ERR 1054 printk(KERN_ERR
1075 "%s: ps3_vuart_port_driver_register failed %d\n", 1055 "%s: ps3_vuart_port_driver_register failed %d\n",
1076 __func__, error); 1056 __func__, error);
1077 return error; 1057 return error;
1078 } 1058 }
1079 1059
1080 pr_debug(" <- %s:%d\n", __func__, __LINE__); 1060 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1081 return error; 1061 return error;
1082 } 1062 }
1083 1063
1084 static void __exit ps3av_module_exit(void) 1064 static void __exit ps3av_module_exit(void)
1085 { 1065 {
1086 pr_debug(" -> %s:%d\n", __func__, __LINE__); 1066 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1087 ps3_vuart_port_driver_unregister(&ps3av_driver); 1067 ps3_vuart_port_driver_unregister(&ps3av_driver);
1088 pr_debug(" <- %s:%d\n", __func__, __LINE__); 1068 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1089 } 1069 }
1090 1070
1091 subsys_initcall(ps3av_module_init); 1071 subsys_initcall(ps3av_module_init);
1092 module_exit(ps3av_module_exit); 1072 module_exit(ps3av_module_exit);
1093 1073
1094 MODULE_LICENSE("GPL v2"); 1074 MODULE_LICENSE("GPL v2");
1095 MODULE_DESCRIPTION("PS3 AV Settings Driver"); 1075 MODULE_DESCRIPTION("PS3 AV Settings Driver");
1096 MODULE_AUTHOR("Sony Computer Entertainment Inc."); 1076 MODULE_AUTHOR("Sony Computer Entertainment Inc.");
1097 MODULE_ALIAS(PS3_MODULE_ALIAS_AV_SETTINGS); 1077 MODULE_ALIAS(PS3_MODULE_ALIAS_AV_SETTINGS);
1098 1078
drivers/ps3/ps3av_cmd.c
1 /* 1 /*
2 * Copyright (C) 2006 Sony Computer Entertainment Inc. 2 * Copyright (C) 2006 Sony Computer Entertainment Inc.
3 * Copyright 2006, 2007 Sony Corporation 3 * Copyright 2006, 2007 Sony Corporation
4 * 4 *
5 * AV backend support for PS3 5 * AV backend support for PS3
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published 8 * under the terms of the GNU General Public License as published
9 * by the Free Software Foundation; version 2 of the License. 9 * by the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but 11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details. 14 * General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along 16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc., 17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */ 19 */
20 20
21 #include <linux/module.h> 21 #include <linux/module.h>
22 #include <linux/kernel.h> 22 #include <linux/kernel.h>
23 #include <linux/delay.h> 23 #include <linux/delay.h>
24 #include <asm/ps3av.h> 24 #include <asm/ps3av.h>
25 #include <asm/ps3fb.h> 25 #include <asm/ps3fb.h>
26 #include <asm/ps3.h> 26 #include <asm/ps3.h>
27 27
28 #include "vuart.h" 28 #include "vuart.h"
29 29
30 static const struct video_fmt { 30 static const struct video_fmt {
31 u32 format; 31 u32 format;
32 u32 order; 32 u32 order;
33 } ps3av_video_fmt_table[] = { 33 } ps3av_video_fmt_table[] = {
34 { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_RGB }, 34 { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_RGB },
35 { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_BGR }, 35 { PS3AV_CMD_VIDEO_FORMAT_ARGB_8BIT, PS3AV_CMD_VIDEO_ORDER_BGR },
36 }; 36 };
37 37
38 static const struct { 38 static const struct {
39 int cs; 39 int cs;
40 u32 av; 40 u32 av;
41 u32 bl; 41 u32 bl;
42 } ps3av_cs_video2av_table[] = { 42 } ps3av_cs_video2av_table[] = {
43 { 43 {
44 .cs = PS3AV_CMD_VIDEO_CS_RGB_8, 44 .cs = PS3AV_CMD_VIDEO_CS_RGB_8,
45 .av = PS3AV_CMD_AV_CS_RGB_8, 45 .av = PS3AV_CMD_AV_CS_RGB_8,
46 .bl = PS3AV_CMD_AV_CS_8 46 .bl = PS3AV_CMD_AV_CS_8
47 }, { 47 }, {
48 .cs = PS3AV_CMD_VIDEO_CS_RGB_10, 48 .cs = PS3AV_CMD_VIDEO_CS_RGB_10,
49 .av = PS3AV_CMD_AV_CS_RGB_8, 49 .av = PS3AV_CMD_AV_CS_RGB_8,
50 .bl = PS3AV_CMD_AV_CS_8 50 .bl = PS3AV_CMD_AV_CS_8
51 }, { 51 }, {
52 .cs = PS3AV_CMD_VIDEO_CS_RGB_12, 52 .cs = PS3AV_CMD_VIDEO_CS_RGB_12,
53 .av = PS3AV_CMD_AV_CS_RGB_8, 53 .av = PS3AV_CMD_AV_CS_RGB_8,
54 .bl = PS3AV_CMD_AV_CS_8 54 .bl = PS3AV_CMD_AV_CS_8
55 }, { 55 }, {
56 .cs = PS3AV_CMD_VIDEO_CS_YUV444_8, 56 .cs = PS3AV_CMD_VIDEO_CS_YUV444_8,
57 .av = PS3AV_CMD_AV_CS_YUV444_8, 57 .av = PS3AV_CMD_AV_CS_YUV444_8,
58 .bl = PS3AV_CMD_AV_CS_8 58 .bl = PS3AV_CMD_AV_CS_8
59 }, { 59 }, {
60 .cs = PS3AV_CMD_VIDEO_CS_YUV444_10, 60 .cs = PS3AV_CMD_VIDEO_CS_YUV444_10,
61 .av = PS3AV_CMD_AV_CS_YUV444_8, 61 .av = PS3AV_CMD_AV_CS_YUV444_8,
62 .bl = PS3AV_CMD_AV_CS_10 62 .bl = PS3AV_CMD_AV_CS_10
63 }, { 63 }, {
64 .cs = PS3AV_CMD_VIDEO_CS_YUV444_12, 64 .cs = PS3AV_CMD_VIDEO_CS_YUV444_12,
65 .av = PS3AV_CMD_AV_CS_YUV444_8, 65 .av = PS3AV_CMD_AV_CS_YUV444_8,
66 .bl = PS3AV_CMD_AV_CS_10 66 .bl = PS3AV_CMD_AV_CS_10
67 }, { 67 }, {
68 .cs = PS3AV_CMD_VIDEO_CS_YUV422_8, 68 .cs = PS3AV_CMD_VIDEO_CS_YUV422_8,
69 .av = PS3AV_CMD_AV_CS_YUV422_8, 69 .av = PS3AV_CMD_AV_CS_YUV422_8,
70 .bl = PS3AV_CMD_AV_CS_10 70 .bl = PS3AV_CMD_AV_CS_10
71 }, { 71 }, {
72 .cs = PS3AV_CMD_VIDEO_CS_YUV422_10, 72 .cs = PS3AV_CMD_VIDEO_CS_YUV422_10,
73 .av = PS3AV_CMD_AV_CS_YUV422_8, 73 .av = PS3AV_CMD_AV_CS_YUV422_8,
74 .bl = PS3AV_CMD_AV_CS_10 74 .bl = PS3AV_CMD_AV_CS_10
75 }, { 75 }, {
76 .cs = PS3AV_CMD_VIDEO_CS_YUV422_12, 76 .cs = PS3AV_CMD_VIDEO_CS_YUV422_12,
77 .av = PS3AV_CMD_AV_CS_YUV422_8, 77 .av = PS3AV_CMD_AV_CS_YUV422_8,
78 .bl = PS3AV_CMD_AV_CS_12 78 .bl = PS3AV_CMD_AV_CS_12
79 }, { 79 }, {
80 .cs = PS3AV_CMD_VIDEO_CS_XVYCC_8, 80 .cs = PS3AV_CMD_VIDEO_CS_XVYCC_8,
81 .av = PS3AV_CMD_AV_CS_XVYCC_8, 81 .av = PS3AV_CMD_AV_CS_XVYCC_8,
82 .bl = PS3AV_CMD_AV_CS_12 82 .bl = PS3AV_CMD_AV_CS_12
83 }, { 83 }, {
84 .cs = PS3AV_CMD_VIDEO_CS_XVYCC_10, 84 .cs = PS3AV_CMD_VIDEO_CS_XVYCC_10,
85 .av = PS3AV_CMD_AV_CS_XVYCC_8, 85 .av = PS3AV_CMD_AV_CS_XVYCC_8,
86 .bl = PS3AV_CMD_AV_CS_12 86 .bl = PS3AV_CMD_AV_CS_12
87 }, { 87 }, {
88 .cs = PS3AV_CMD_VIDEO_CS_XVYCC_12, 88 .cs = PS3AV_CMD_VIDEO_CS_XVYCC_12,
89 .av = PS3AV_CMD_AV_CS_XVYCC_8, 89 .av = PS3AV_CMD_AV_CS_XVYCC_8,
90 .bl = PS3AV_CMD_AV_CS_12 90 .bl = PS3AV_CMD_AV_CS_12
91 } 91 }
92 }; 92 };
93 93
94 static u32 ps3av_cs_video2av(int cs) 94 static u32 ps3av_cs_video2av(int cs)
95 { 95 {
96 unsigned int i; 96 unsigned int i;
97 97
98 for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++) 98 for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++)
99 if (ps3av_cs_video2av_table[i].cs == cs) 99 if (ps3av_cs_video2av_table[i].cs == cs)
100 return ps3av_cs_video2av_table[i].av; 100 return ps3av_cs_video2av_table[i].av;
101 101
102 return PS3AV_CMD_AV_CS_RGB_8; 102 return PS3AV_CMD_AV_CS_RGB_8;
103 } 103 }
104 104
105 static u32 ps3av_cs_video2av_bitlen(int cs) 105 static u32 ps3av_cs_video2av_bitlen(int cs)
106 { 106 {
107 unsigned int i; 107 unsigned int i;
108 108
109 for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++) 109 for (i = 0; i < ARRAY_SIZE(ps3av_cs_video2av_table); i++)
110 if (ps3av_cs_video2av_table[i].cs == cs) 110 if (ps3av_cs_video2av_table[i].cs == cs)
111 return ps3av_cs_video2av_table[i].bl; 111 return ps3av_cs_video2av_table[i].bl;
112 112
113 return PS3AV_CMD_AV_CS_8; 113 return PS3AV_CMD_AV_CS_8;
114 } 114 }
115 115
116 static const struct { 116 static const struct {
117 int vid; 117 int vid;
118 u32 av; 118 u32 av;
119 } ps3av_vid_video2av_table[] = { 119 } ps3av_vid_video2av_table[] = {
120 { PS3AV_CMD_VIDEO_VID_480I, PS3AV_CMD_AV_VID_480I }, 120 { PS3AV_CMD_VIDEO_VID_480I, PS3AV_CMD_AV_VID_480I },
121 { PS3AV_CMD_VIDEO_VID_480P, PS3AV_CMD_AV_VID_480P }, 121 { PS3AV_CMD_VIDEO_VID_480P, PS3AV_CMD_AV_VID_480P },
122 { PS3AV_CMD_VIDEO_VID_576I, PS3AV_CMD_AV_VID_576I }, 122 { PS3AV_CMD_VIDEO_VID_576I, PS3AV_CMD_AV_VID_576I },
123 { PS3AV_CMD_VIDEO_VID_576P, PS3AV_CMD_AV_VID_576P }, 123 { PS3AV_CMD_VIDEO_VID_576P, PS3AV_CMD_AV_VID_576P },
124 { PS3AV_CMD_VIDEO_VID_1080I_60HZ, PS3AV_CMD_AV_VID_1080I_60HZ }, 124 { PS3AV_CMD_VIDEO_VID_1080I_60HZ, PS3AV_CMD_AV_VID_1080I_60HZ },
125 { PS3AV_CMD_VIDEO_VID_720P_60HZ, PS3AV_CMD_AV_VID_720P_60HZ }, 125 { PS3AV_CMD_VIDEO_VID_720P_60HZ, PS3AV_CMD_AV_VID_720P_60HZ },
126 { PS3AV_CMD_VIDEO_VID_1080P_60HZ, PS3AV_CMD_AV_VID_1080P_60HZ }, 126 { PS3AV_CMD_VIDEO_VID_1080P_60HZ, PS3AV_CMD_AV_VID_1080P_60HZ },
127 { PS3AV_CMD_VIDEO_VID_1080I_50HZ, PS3AV_CMD_AV_VID_1080I_50HZ }, 127 { PS3AV_CMD_VIDEO_VID_1080I_50HZ, PS3AV_CMD_AV_VID_1080I_50HZ },
128 { PS3AV_CMD_VIDEO_VID_720P_50HZ, PS3AV_CMD_AV_VID_720P_50HZ }, 128 { PS3AV_CMD_VIDEO_VID_720P_50HZ, PS3AV_CMD_AV_VID_720P_50HZ },
129 { PS3AV_CMD_VIDEO_VID_1080P_50HZ, PS3AV_CMD_AV_VID_1080P_50HZ }, 129 { PS3AV_CMD_VIDEO_VID_1080P_50HZ, PS3AV_CMD_AV_VID_1080P_50HZ },
130 { PS3AV_CMD_VIDEO_VID_WXGA, PS3AV_CMD_AV_VID_WXGA }, 130 { PS3AV_CMD_VIDEO_VID_WXGA, PS3AV_CMD_AV_VID_WXGA },
131 { PS3AV_CMD_VIDEO_VID_SXGA, PS3AV_CMD_AV_VID_SXGA }, 131 { PS3AV_CMD_VIDEO_VID_SXGA, PS3AV_CMD_AV_VID_SXGA },
132 { PS3AV_CMD_VIDEO_VID_WUXGA, PS3AV_CMD_AV_VID_WUXGA } 132 { PS3AV_CMD_VIDEO_VID_WUXGA, PS3AV_CMD_AV_VID_WUXGA }
133 }; 133 };
134 134
135 static u32 ps3av_vid_video2av(int vid) 135 static u32 ps3av_vid_video2av(int vid)
136 { 136 {
137 unsigned int i; 137 unsigned int i;
138 138
139 for (i = 0; i < ARRAY_SIZE(ps3av_vid_video2av_table); i++) 139 for (i = 0; i < ARRAY_SIZE(ps3av_vid_video2av_table); i++)
140 if (ps3av_vid_video2av_table[i].vid == vid) 140 if (ps3av_vid_video2av_table[i].vid == vid)
141 return ps3av_vid_video2av_table[i].av; 141 return ps3av_vid_video2av_table[i].av;
142 142
143 return PS3AV_CMD_AV_VID_480P; 143 return PS3AV_CMD_AV_VID_480P;
144 } 144 }
145 145
146 static int ps3av_hdmi_range(void) 146 static int ps3av_hdmi_range(void)
147 { 147 {
148 if (ps3_compare_firmware_version(1, 8, 0) < 0) 148 if (ps3_compare_firmware_version(1, 8, 0) < 0)
149 return 0; 149 return 0;
150 else 150 else
151 return 1; /* supported */ 151 return 1; /* supported */
152 } 152 }
153 153
154 int ps3av_cmd_init(void) 154 int ps3av_cmd_init(void)
155 { 155 {
156 int res; 156 int res;
157 struct ps3av_pkt_av_init av_init; 157 struct ps3av_pkt_av_init av_init;
158 struct ps3av_pkt_video_init video_init; 158 struct ps3av_pkt_video_init video_init;
159 struct ps3av_pkt_audio_init audio_init; 159 struct ps3av_pkt_audio_init audio_init;
160 160
161 /* video init */ 161 /* video init */
162 memset(&video_init, 0, sizeof(video_init)); 162 memset(&video_init, 0, sizeof(video_init));
163 163
164 res = ps3av_do_pkt(PS3AV_CID_VIDEO_INIT, sizeof(video_init.send_hdr), 164 res = ps3av_do_pkt(PS3AV_CID_VIDEO_INIT, sizeof(video_init.send_hdr),
165 sizeof(video_init), &video_init.send_hdr); 165 sizeof(video_init), &video_init.send_hdr);
166 if (res < 0) 166 if (res < 0)
167 return res; 167 return res;
168 168
169 res = get_status(&video_init); 169 res = get_status(&video_init);
170 if (res) { 170 if (res) {
171 printk(KERN_ERR "PS3AV_CID_VIDEO_INIT: failed %x\n", res); 171 printk(KERN_ERR "PS3AV_CID_VIDEO_INIT: failed %x\n", res);
172 return res; 172 return res;
173 } 173 }
174 174
175 /* audio init */ 175 /* audio init */
176 memset(&audio_init, 0, sizeof(audio_init)); 176 memset(&audio_init, 0, sizeof(audio_init));
177 177
178 res = ps3av_do_pkt(PS3AV_CID_AUDIO_INIT, sizeof(audio_init.send_hdr), 178 res = ps3av_do_pkt(PS3AV_CID_AUDIO_INIT, sizeof(audio_init.send_hdr),
179 sizeof(audio_init), &audio_init.send_hdr); 179 sizeof(audio_init), &audio_init.send_hdr);
180 if (res < 0) 180 if (res < 0)
181 return res; 181 return res;
182 182
183 res = get_status(&audio_init); 183 res = get_status(&audio_init);
184 if (res) { 184 if (res) {
185 printk(KERN_ERR "PS3AV_CID_AUDIO_INIT: failed %x\n", res); 185 printk(KERN_ERR "PS3AV_CID_AUDIO_INIT: failed %x\n", res);
186 return res; 186 return res;
187 } 187 }
188 188
189 /* av init */ 189 /* av init */
190 memset(&av_init, 0, sizeof(av_init)); 190 memset(&av_init, 0, sizeof(av_init));
191 av_init.event_bit = 0; 191 av_init.event_bit = 0;
192 192
193 res = ps3av_do_pkt(PS3AV_CID_AV_INIT, sizeof(av_init), sizeof(av_init), 193 res = ps3av_do_pkt(PS3AV_CID_AV_INIT, sizeof(av_init), sizeof(av_init),
194 &av_init.send_hdr); 194 &av_init.send_hdr);
195 if (res < 0) 195 if (res < 0)
196 return res; 196 return res;
197 197
198 res = get_status(&av_init); 198 res = get_status(&av_init);
199 if (res) 199 if (res)
200 printk(KERN_ERR "PS3AV_CID_AV_INIT: failed %x\n", res); 200 printk(KERN_ERR "PS3AV_CID_AV_INIT: failed %x\n", res);
201 201
202 return res; 202 return res;
203 } 203 }
204 204
205 int ps3av_cmd_fin(void) 205 int ps3av_cmd_fin(void)
206 { 206 {
207 int res; 207 int res;
208 struct ps3av_pkt_av_fin av_fin; 208 struct ps3av_pkt_av_fin av_fin;
209 209
210 memset(&av_fin, 0, sizeof(av_fin)); 210 memset(&av_fin, 0, sizeof(av_fin));
211 211
212 res = ps3av_do_pkt(PS3AV_CID_AV_FIN, sizeof(av_fin.send_hdr), 212 res = ps3av_do_pkt(PS3AV_CID_AV_FIN, sizeof(av_fin.send_hdr),
213 sizeof(av_fin), &av_fin.send_hdr); 213 sizeof(av_fin), &av_fin.send_hdr);
214 if (res < 0) 214 if (res < 0)
215 return res; 215 return res;
216 216
217 res = get_status(&av_fin); 217 res = get_status(&av_fin);
218 if (res) 218 if (res)
219 printk(KERN_ERR "PS3AV_CID_AV_FIN: failed %x\n", res); 219 printk(KERN_ERR "PS3AV_CID_AV_FIN: failed %x\n", res);
220 220
221 return res; 221 return res;
222 } 222 }
223 223
224 int ps3av_cmd_av_video_mute(int num_of_port, u32 *port, u32 mute) 224 int ps3av_cmd_av_video_mute(int num_of_port, u32 *port, u32 mute)
225 { 225 {
226 int i, send_len, res; 226 int i, send_len, res;
227 struct ps3av_pkt_av_video_mute av_video_mute; 227 struct ps3av_pkt_av_video_mute av_video_mute;
228 228
229 if (num_of_port > PS3AV_MUTE_PORT_MAX) 229 if (num_of_port > PS3AV_MUTE_PORT_MAX)
230 return -EINVAL; 230 return -EINVAL;
231 231
232 memset(&av_video_mute, 0, sizeof(av_video_mute)); 232 memset(&av_video_mute, 0, sizeof(av_video_mute));
233 for (i = 0; i < num_of_port; i++) { 233 for (i = 0; i < num_of_port; i++) {
234 av_video_mute.mute[i].avport = port[i]; 234 av_video_mute.mute[i].avport = port[i];
235 av_video_mute.mute[i].mute = mute; 235 av_video_mute.mute[i].mute = mute;
236 } 236 }
237 237
238 send_len = sizeof(av_video_mute.send_hdr) + 238 send_len = sizeof(av_video_mute.send_hdr) +
239 sizeof(struct ps3av_av_mute) * num_of_port; 239 sizeof(struct ps3av_av_mute) * num_of_port;
240 res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_MUTE, send_len, 240 res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_MUTE, send_len,
241 sizeof(av_video_mute), &av_video_mute.send_hdr); 241 sizeof(av_video_mute), &av_video_mute.send_hdr);
242 if (res < 0) 242 if (res < 0)
243 return res; 243 return res;
244 244
245 res = get_status(&av_video_mute); 245 res = get_status(&av_video_mute);
246 if (res) 246 if (res)
247 printk(KERN_ERR "PS3AV_CID_AV_VIDEO_MUTE: failed %x\n", res); 247 printk(KERN_ERR "PS3AV_CID_AV_VIDEO_MUTE: failed %x\n", res);
248 248
249 return res; 249 return res;
250 } 250 }
251 251
252 int ps3av_cmd_av_video_disable_sig(u32 port) 252 int ps3av_cmd_av_video_disable_sig(u32 port)
253 { 253 {
254 int res; 254 int res;
255 struct ps3av_pkt_av_video_disable_sig av_video_sig; 255 struct ps3av_pkt_av_video_disable_sig av_video_sig;
256 256
257 memset(&av_video_sig, 0, sizeof(av_video_sig)); 257 memset(&av_video_sig, 0, sizeof(av_video_sig));
258 av_video_sig.avport = port; 258 av_video_sig.avport = port;
259 259
260 res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_DISABLE_SIG, 260 res = ps3av_do_pkt(PS3AV_CID_AV_VIDEO_DISABLE_SIG,
261 sizeof(av_video_sig), sizeof(av_video_sig), 261 sizeof(av_video_sig), sizeof(av_video_sig),
262 &av_video_sig.send_hdr); 262 &av_video_sig.send_hdr);
263 if (res < 0) 263 if (res < 0)
264 return res; 264 return res;
265 265
266 res = get_status(&av_video_sig); 266 res = get_status(&av_video_sig);
267 if (res) 267 if (res)
268 printk(KERN_ERR 268 printk(KERN_ERR
269 "PS3AV_CID_AV_VIDEO_DISABLE_SIG: failed %x port:%x\n", 269 "PS3AV_CID_AV_VIDEO_DISABLE_SIG: failed %x port:%x\n",
270 res, port); 270 res, port);
271 271
272 return res; 272 return res;
273 } 273 }
274 274
275 int ps3av_cmd_av_tv_mute(u32 avport, u32 mute) 275 int ps3av_cmd_av_tv_mute(u32 avport, u32 mute)
276 { 276 {
277 int res; 277 int res;
278 struct ps3av_pkt_av_tv_mute tv_mute; 278 struct ps3av_pkt_av_tv_mute tv_mute;
279 279
280 memset(&tv_mute, 0, sizeof(tv_mute)); 280 memset(&tv_mute, 0, sizeof(tv_mute));
281 tv_mute.avport = avport; 281 tv_mute.avport = avport;
282 tv_mute.mute = mute; 282 tv_mute.mute = mute;
283 283
284 res = ps3av_do_pkt(PS3AV_CID_AV_TV_MUTE, sizeof(tv_mute), 284 res = ps3av_do_pkt(PS3AV_CID_AV_TV_MUTE, sizeof(tv_mute),
285 sizeof(tv_mute), &tv_mute.send_hdr); 285 sizeof(tv_mute), &tv_mute.send_hdr);
286 if (res < 0) 286 if (res < 0)
287 return res; 287 return res;
288 288
289 res = get_status(&tv_mute); 289 res = get_status(&tv_mute);
290 if (res) 290 if (res)
291 printk(KERN_ERR "PS3AV_CID_AV_TV_MUTE: failed %x port:%x\n", 291 printk(KERN_ERR "PS3AV_CID_AV_TV_MUTE: failed %x port:%x\n",
292 res, avport); 292 res, avport);
293 293
294 return res; 294 return res;
295 } 295 }
296 296
297 int ps3av_cmd_enable_event(void) 297 int ps3av_cmd_enable_event(void)
298 { 298 {
299 int res; 299 int res;
300 struct ps3av_pkt_av_event av_event; 300 struct ps3av_pkt_av_event av_event;
301 301
302 memset(&av_event, 0, sizeof(av_event)); 302 memset(&av_event, 0, sizeof(av_event));
303 av_event.event_bit = PS3AV_CMD_EVENT_BIT_UNPLUGGED | 303 av_event.event_bit = PS3AV_CMD_EVENT_BIT_UNPLUGGED |
304 PS3AV_CMD_EVENT_BIT_PLUGGED | PS3AV_CMD_EVENT_BIT_HDCP_DONE; 304 PS3AV_CMD_EVENT_BIT_PLUGGED | PS3AV_CMD_EVENT_BIT_HDCP_DONE;
305 305
306 res = ps3av_do_pkt(PS3AV_CID_AV_ENABLE_EVENT, sizeof(av_event), 306 res = ps3av_do_pkt(PS3AV_CID_AV_ENABLE_EVENT, sizeof(av_event),
307 sizeof(av_event), &av_event.send_hdr); 307 sizeof(av_event), &av_event.send_hdr);
308 if (res < 0) 308 if (res < 0)
309 return res; 309 return res;
310 310
311 res = get_status(&av_event); 311 res = get_status(&av_event);
312 if (res) 312 if (res)
313 printk(KERN_ERR "PS3AV_CID_AV_ENABLE_EVENT: failed %x\n", res); 313 printk(KERN_ERR "PS3AV_CID_AV_ENABLE_EVENT: failed %x\n", res);
314 314
315 return res; 315 return res;
316 } 316 }
317 317
318 int ps3av_cmd_av_hdmi_mode(u8 mode) 318 int ps3av_cmd_av_hdmi_mode(u8 mode)
319 { 319 {
320 int res; 320 int res;
321 struct ps3av_pkt_av_hdmi_mode hdmi_mode; 321 struct ps3av_pkt_av_hdmi_mode hdmi_mode;
322 322
323 memset(&hdmi_mode, 0, sizeof(hdmi_mode)); 323 memset(&hdmi_mode, 0, sizeof(hdmi_mode));
324 hdmi_mode.mode = mode; 324 hdmi_mode.mode = mode;
325 325
326 res = ps3av_do_pkt(PS3AV_CID_AV_HDMI_MODE, sizeof(hdmi_mode), 326 res = ps3av_do_pkt(PS3AV_CID_AV_HDMI_MODE, sizeof(hdmi_mode),
327 sizeof(hdmi_mode), &hdmi_mode.send_hdr); 327 sizeof(hdmi_mode), &hdmi_mode.send_hdr);
328 if (res < 0) 328 if (res < 0)
329 return res; 329 return res;
330 330
331 res = get_status(&hdmi_mode); 331 res = get_status(&hdmi_mode);
332 if (res && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE) 332 if (res && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
333 printk(KERN_ERR "PS3AV_CID_AV_HDMI_MODE: failed %x\n", res); 333 printk(KERN_ERR "PS3AV_CID_AV_HDMI_MODE: failed %x\n", res);
334 334
335 return res; 335 return res;
336 } 336 }
337 337
338 u32 ps3av_cmd_set_av_video_cs(void *p, u32 avport, int video_vid, int cs_out, 338 u32 ps3av_cmd_set_av_video_cs(void *p, u32 avport, int video_vid, int cs_out,
339 int aspect, u32 id) 339 int aspect, u32 id)
340 { 340 {
341 struct ps3av_pkt_av_video_cs *av_video_cs; 341 struct ps3av_pkt_av_video_cs *av_video_cs;
342 342
343 av_video_cs = (struct ps3av_pkt_av_video_cs *)p; 343 av_video_cs = (struct ps3av_pkt_av_video_cs *)p;
344 if (video_vid == -1) 344 if (video_vid == -1)
345 video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ; 345 video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
346 if (cs_out == -1) 346 if (cs_out == -1)
347 cs_out = PS3AV_CMD_VIDEO_CS_YUV444_8; 347 cs_out = PS3AV_CMD_VIDEO_CS_YUV444_8;
348 if (aspect == -1) 348 if (aspect == -1)
349 aspect = 0; 349 aspect = 0;
350 350
351 memset(av_video_cs, 0, sizeof(*av_video_cs)); 351 memset(av_video_cs, 0, sizeof(*av_video_cs));
352 ps3av_set_hdr(PS3AV_CID_AV_VIDEO_CS, sizeof(*av_video_cs), 352 ps3av_set_hdr(PS3AV_CID_AV_VIDEO_CS, sizeof(*av_video_cs),
353 &av_video_cs->send_hdr); 353 &av_video_cs->send_hdr);
354 av_video_cs->avport = avport; 354 av_video_cs->avport = avport;
355 /* should be same as video_mode.resolution */ 355 /* should be same as video_mode.resolution */
356 av_video_cs->av_vid = ps3av_vid_video2av(video_vid); 356 av_video_cs->av_vid = ps3av_vid_video2av(video_vid);
357 av_video_cs->av_cs_out = ps3av_cs_video2av(cs_out); 357 av_video_cs->av_cs_out = ps3av_cs_video2av(cs_out);
358 /* should be same as video_mode.video_cs_out */ 358 /* should be same as video_mode.video_cs_out */
359 av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8); 359 av_video_cs->av_cs_in = ps3av_cs_video2av(PS3AV_CMD_VIDEO_CS_RGB_8);
360 av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out); 360 av_video_cs->bitlen_out = ps3av_cs_video2av_bitlen(cs_out);
361 if ((id & PS3AV_MODE_WHITE) && ps3av_hdmi_range()) 361 if ((id & PS3AV_MODE_WHITE) && ps3av_hdmi_range())
362 av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_ON; 362 av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_ON;
363 else /* default off */ 363 else /* default off */
364 av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_OFF; 364 av_video_cs->super_white = PS3AV_CMD_AV_SUPER_WHITE_OFF;
365 av_video_cs->aspect = aspect; 365 av_video_cs->aspect = aspect;
366 if (id & PS3AV_MODE_DITHER) { 366 if (id & PS3AV_MODE_DITHER) {
367 av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON 367 av_video_cs->dither = PS3AV_CMD_AV_DITHER_ON
368 | PS3AV_CMD_AV_DITHER_8BIT; 368 | PS3AV_CMD_AV_DITHER_8BIT;
369 } else { 369 } else {
370 /* default off */ 370 /* default off */
371 av_video_cs->dither = PS3AV_CMD_AV_DITHER_OFF; 371 av_video_cs->dither = PS3AV_CMD_AV_DITHER_OFF;
372 } 372 }
373 373
374 return sizeof(*av_video_cs); 374 return sizeof(*av_video_cs);
375 } 375 }
376 376
377 u32 ps3av_cmd_set_video_mode(void *p, u32 head, int video_vid, int video_fmt, 377 u32 ps3av_cmd_set_video_mode(void *p, u32 head, int video_vid, int video_fmt,
378 u32 id) 378 u32 id)
379 { 379 {
380 struct ps3av_pkt_video_mode *video_mode; 380 struct ps3av_pkt_video_mode *video_mode;
381 u32 x, y; 381 u32 x, y;
382 382
383 video_mode = (struct ps3av_pkt_video_mode *)p; 383 video_mode = (struct ps3av_pkt_video_mode *)p;
384 if (video_vid == -1) 384 if (video_vid == -1)
385 video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ; 385 video_vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
386 if (video_fmt == -1) 386 if (video_fmt == -1)
387 video_fmt = PS3AV_CMD_VIDEO_FMT_X8R8G8B8; 387 video_fmt = PS3AV_CMD_VIDEO_FMT_X8R8G8B8;
388 388
389 if (ps3av_video_mode2res(id, &x, &y)) 389 if (ps3av_video_mode2res(id, &x, &y))
390 return 0; 390 return 0;
391 391
392 /* video mode */ 392 /* video mode */
393 memset(video_mode, 0, sizeof(*video_mode)); 393 memset(video_mode, 0, sizeof(*video_mode));
394 ps3av_set_hdr(PS3AV_CID_VIDEO_MODE, sizeof(*video_mode), 394 ps3av_set_hdr(PS3AV_CID_VIDEO_MODE, sizeof(*video_mode),
395 &video_mode->send_hdr); 395 &video_mode->send_hdr);
396 video_mode->video_head = head; 396 video_mode->video_head = head;
397 if (video_vid == PS3AV_CMD_VIDEO_VID_480I 397 if (video_vid == PS3AV_CMD_VIDEO_VID_480I
398 && head == PS3AV_CMD_VIDEO_HEAD_B) 398 && head == PS3AV_CMD_VIDEO_HEAD_B)
399 video_mode->video_vid = PS3AV_CMD_VIDEO_VID_480I_A; 399 video_mode->video_vid = PS3AV_CMD_VIDEO_VID_480I_A;
400 else 400 else
401 video_mode->video_vid = video_vid; 401 video_mode->video_vid = video_vid;
402 video_mode->width = (u16) x; 402 video_mode->width = (u16) x;
403 video_mode->height = (u16) y; 403 video_mode->height = (u16) y;
404 video_mode->pitch = video_mode->width * 4; /* line_length */ 404 video_mode->pitch = video_mode->width * 4; /* line_length */
405 video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT; 405 video_mode->video_out_format = PS3AV_CMD_VIDEO_OUT_FORMAT_RGB_12BIT;
406 video_mode->video_format = ps3av_video_fmt_table[video_fmt].format; 406 video_mode->video_format = ps3av_video_fmt_table[video_fmt].format;
407 if ((id & PS3AV_MODE_COLOR) && ps3av_hdmi_range()) 407 if ((id & PS3AV_MODE_COLOR) && ps3av_hdmi_range())
408 video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT; 408 video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_DISABLE_LUT;
409 else /* default enable */ 409 else /* default enable */
410 video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT; 410 video_mode->video_cl_cnv = PS3AV_CMD_VIDEO_CL_CNV_ENABLE_LUT;
411 video_mode->video_order = ps3av_video_fmt_table[video_fmt].order; 411 video_mode->video_order = ps3av_video_fmt_table[video_fmt].order;
412 412
413 pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n", 413 pr_debug("%s: video_mode:vid:%x width:%d height:%d pitch:%d out_format:%d format:%x order:%x\n",
414 __func__, video_vid, video_mode->width, video_mode->height, 414 __func__, video_vid, video_mode->width, video_mode->height,
415 video_mode->pitch, video_mode->video_out_format, 415 video_mode->pitch, video_mode->video_out_format,
416 video_mode->video_format, video_mode->video_order); 416 video_mode->video_format, video_mode->video_order);
417 return sizeof(*video_mode); 417 return sizeof(*video_mode);
418 } 418 }
419 419
420 int ps3av_cmd_video_format_black(u32 head, u32 video_fmt, u32 mute) 420 int ps3av_cmd_video_format_black(u32 head, u32 video_fmt, u32 mute)
421 { 421 {
422 int res; 422 int res;
423 struct ps3av_pkt_video_format video_format; 423 struct ps3av_pkt_video_format video_format;
424 424
425 memset(&video_format, 0, sizeof(video_format)); 425 memset(&video_format, 0, sizeof(video_format));
426 video_format.video_head = head; 426 video_format.video_head = head;
427 if (mute != PS3AV_CMD_MUTE_OFF) 427 if (mute != PS3AV_CMD_MUTE_OFF)
428 video_format.video_format = PS3AV_CMD_VIDEO_FORMAT_BLACK; 428 video_format.video_format = PS3AV_CMD_VIDEO_FORMAT_BLACK;
429 else 429 else
430 video_format.video_format = 430 video_format.video_format =
431 ps3av_video_fmt_table[video_fmt].format; 431 ps3av_video_fmt_table[video_fmt].format;
432 video_format.video_order = ps3av_video_fmt_table[video_fmt].order; 432 video_format.video_order = ps3av_video_fmt_table[video_fmt].order;
433 433
434 res = ps3av_do_pkt(PS3AV_CID_VIDEO_FORMAT, sizeof(video_format), 434 res = ps3av_do_pkt(PS3AV_CID_VIDEO_FORMAT, sizeof(video_format),
435 sizeof(video_format), &video_format.send_hdr); 435 sizeof(video_format), &video_format.send_hdr);
436 if (res < 0) 436 if (res < 0)
437 return res; 437 return res;
438 438
439 res = get_status(&video_format); 439 res = get_status(&video_format);
440 if (res) 440 if (res)
441 printk(KERN_ERR "PS3AV_CID_VIDEO_FORMAT: failed %x\n", res); 441 printk(KERN_ERR "PS3AV_CID_VIDEO_FORMAT: failed %x\n", res);
442 442
443 return res; 443 return res;
444 } 444 }
445 445
446 446
447 int ps3av_cmd_av_audio_mute(int num_of_port, u32 *port, u32 mute) 447 int ps3av_cmd_av_audio_mute(int num_of_port, u32 *port, u32 mute)
448 { 448 {
449 int i, res; 449 int i, res;
450 struct ps3av_pkt_av_audio_mute av_audio_mute; 450 struct ps3av_pkt_av_audio_mute av_audio_mute;
451 451
452 if (num_of_port > PS3AV_MUTE_PORT_MAX) 452 if (num_of_port > PS3AV_MUTE_PORT_MAX)
453 return -EINVAL; 453 return -EINVAL;
454 454
455 /* audio mute */ 455 /* audio mute */
456 memset(&av_audio_mute, 0, sizeof(av_audio_mute)); 456 memset(&av_audio_mute, 0, sizeof(av_audio_mute));
457 for (i = 0; i < num_of_port; i++) { 457 for (i = 0; i < num_of_port; i++) {
458 av_audio_mute.mute[i].avport = port[i]; 458 av_audio_mute.mute[i].avport = port[i];
459 av_audio_mute.mute[i].mute = mute; 459 av_audio_mute.mute[i].mute = mute;
460 } 460 }
461 461
462 res = ps3av_do_pkt(PS3AV_CID_AV_AUDIO_MUTE, 462 res = ps3av_do_pkt(PS3AV_CID_AV_AUDIO_MUTE,
463 sizeof(av_audio_mute.send_hdr) + 463 sizeof(av_audio_mute.send_hdr) +
464 sizeof(struct ps3av_av_mute) * num_of_port, 464 sizeof(struct ps3av_av_mute) * num_of_port,
465 sizeof(av_audio_mute), &av_audio_mute.send_hdr); 465 sizeof(av_audio_mute), &av_audio_mute.send_hdr);
466 if (res < 0) 466 if (res < 0)
467 return res; 467 return res;
468 468
469 res = get_status(&av_audio_mute); 469 res = get_status(&av_audio_mute);
470 if (res) 470 if (res)
471 printk(KERN_ERR "PS3AV_CID_AV_AUDIO_MUTE: failed %x\n", res); 471 printk(KERN_ERR "PS3AV_CID_AV_AUDIO_MUTE: failed %x\n", res);
472 472
473 return res; 473 return res;
474 } 474 }
475 475
476 static const struct { 476 static const struct {
477 u32 fs; 477 u32 fs;
478 u8 mclk; 478 u8 mclk;
479 } ps3av_cnv_mclk_table[] = { 479 } ps3av_cnv_mclk_table[] = {
480 { PS3AV_CMD_AUDIO_FS_44K, PS3AV_CMD_AV_MCLK_512 }, 480 { PS3AV_CMD_AUDIO_FS_44K, PS3AV_CMD_AV_MCLK_512 },
481 { PS3AV_CMD_AUDIO_FS_48K, PS3AV_CMD_AV_MCLK_512 }, 481 { PS3AV_CMD_AUDIO_FS_48K, PS3AV_CMD_AV_MCLK_512 },
482 { PS3AV_CMD_AUDIO_FS_88K, PS3AV_CMD_AV_MCLK_256 }, 482 { PS3AV_CMD_AUDIO_FS_88K, PS3AV_CMD_AV_MCLK_256 },
483 { PS3AV_CMD_AUDIO_FS_96K, PS3AV_CMD_AV_MCLK_256 }, 483 { PS3AV_CMD_AUDIO_FS_96K, PS3AV_CMD_AV_MCLK_256 },
484 { PS3AV_CMD_AUDIO_FS_176K, PS3AV_CMD_AV_MCLK_128 }, 484 { PS3AV_CMD_AUDIO_FS_176K, PS3AV_CMD_AV_MCLK_128 },
485 { PS3AV_CMD_AUDIO_FS_192K, PS3AV_CMD_AV_MCLK_128 } 485 { PS3AV_CMD_AUDIO_FS_192K, PS3AV_CMD_AV_MCLK_128 }
486 }; 486 };
487 487
488 static u8 ps3av_cnv_mclk(u32 fs) 488 static u8 ps3av_cnv_mclk(u32 fs)
489 { 489 {
490 unsigned int i; 490 unsigned int i;
491 491
492 for (i = 0; i < ARRAY_SIZE(ps3av_cnv_mclk_table); i++) 492 for (i = 0; i < ARRAY_SIZE(ps3av_cnv_mclk_table); i++)
493 if (ps3av_cnv_mclk_table[i].fs == fs) 493 if (ps3av_cnv_mclk_table[i].fs == fs)
494 return ps3av_cnv_mclk_table[i].mclk; 494 return ps3av_cnv_mclk_table[i].mclk;
495 495
496 printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs); 496 printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs);
497 return 0; 497 return 0;
498 } 498 }
499 499
500 #define BASE PS3AV_CMD_AUDIO_FS_44K 500 #define BASE PS3AV_CMD_AUDIO_FS_44K
501 501
502 static const u32 ps3av_ns_table[][5] = { 502 static const u32 ps3av_ns_table[][5] = {
503 /* D1, D2, D3, D4, D5 */ 503 /* D1, D2, D3, D4, D5 */
504 [PS3AV_CMD_AUDIO_FS_44K-BASE] = { 6272, 6272, 17836, 17836, 8918 }, 504 [PS3AV_CMD_AUDIO_FS_44K-BASE] = { 6272, 6272, 17836, 17836, 8918 },
505 [PS3AV_CMD_AUDIO_FS_48K-BASE] = { 6144, 6144, 11648, 11648, 5824 }, 505 [PS3AV_CMD_AUDIO_FS_48K-BASE] = { 6144, 6144, 11648, 11648, 5824 },
506 [PS3AV_CMD_AUDIO_FS_88K-BASE] = { 12544, 12544, 35672, 35672, 17836 }, 506 [PS3AV_CMD_AUDIO_FS_88K-BASE] = { 12544, 12544, 35672, 35672, 17836 },
507 [PS3AV_CMD_AUDIO_FS_96K-BASE] = { 12288, 12288, 23296, 23296, 11648 }, 507 [PS3AV_CMD_AUDIO_FS_96K-BASE] = { 12288, 12288, 23296, 23296, 11648 },
508 [PS3AV_CMD_AUDIO_FS_176K-BASE] = { 25088, 25088, 71344, 71344, 35672 }, 508 [PS3AV_CMD_AUDIO_FS_176K-BASE] = { 25088, 25088, 71344, 71344, 35672 },
509 [PS3AV_CMD_AUDIO_FS_192K-BASE] = { 24576, 24576, 46592, 46592, 23296 } 509 [PS3AV_CMD_AUDIO_FS_192K-BASE] = { 24576, 24576, 46592, 46592, 23296 }
510 }; 510 };
511 511
512 static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid) 512 static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
513 { 513 {
514 u32 av_vid, ns_val; 514 u32 av_vid, ns_val;
515 int d; 515 int d;
516 516
517 d = ns_val = 0; 517 d = ns_val = 0;
518 av_vid = ps3av_vid_video2av(video_vid); 518 av_vid = ps3av_vid_video2av(video_vid);
519 switch (av_vid) { 519 switch (av_vid) {
520 case PS3AV_CMD_AV_VID_480I: 520 case PS3AV_CMD_AV_VID_480I:
521 case PS3AV_CMD_AV_VID_576I: 521 case PS3AV_CMD_AV_VID_576I:
522 d = 0; 522 d = 0;
523 break; 523 break;
524 case PS3AV_CMD_AV_VID_480P: 524 case PS3AV_CMD_AV_VID_480P:
525 case PS3AV_CMD_AV_VID_576P: 525 case PS3AV_CMD_AV_VID_576P:
526 d = 1; 526 d = 1;
527 break; 527 break;
528 case PS3AV_CMD_AV_VID_1080I_60HZ: 528 case PS3AV_CMD_AV_VID_1080I_60HZ:
529 case PS3AV_CMD_AV_VID_1080I_50HZ: 529 case PS3AV_CMD_AV_VID_1080I_50HZ:
530 d = 2; 530 d = 2;
531 break; 531 break;
532 case PS3AV_CMD_AV_VID_720P_60HZ: 532 case PS3AV_CMD_AV_VID_720P_60HZ:
533 case PS3AV_CMD_AV_VID_720P_50HZ: 533 case PS3AV_CMD_AV_VID_720P_50HZ:
534 d = 3; 534 d = 3;
535 break; 535 break;
536 case PS3AV_CMD_AV_VID_1080P_60HZ: 536 case PS3AV_CMD_AV_VID_1080P_60HZ:
537 case PS3AV_CMD_AV_VID_1080P_50HZ: 537 case PS3AV_CMD_AV_VID_1080P_50HZ:
538 case PS3AV_CMD_AV_VID_WXGA: 538 case PS3AV_CMD_AV_VID_WXGA:
539 case PS3AV_CMD_AV_VID_SXGA: 539 case PS3AV_CMD_AV_VID_SXGA:
540 case PS3AV_CMD_AV_VID_WUXGA: 540 case PS3AV_CMD_AV_VID_WUXGA:
541 d = 4; 541 d = 4;
542 break; 542 break;
543 default: 543 default:
544 printk(KERN_ERR "%s failed, vid:%x\n", __func__, video_vid); 544 printk(KERN_ERR "%s failed, vid:%x\n", __func__, video_vid);
545 break; 545 break;
546 } 546 }
547 547
548 if (fs < PS3AV_CMD_AUDIO_FS_44K || fs > PS3AV_CMD_AUDIO_FS_192K) 548 if (fs < PS3AV_CMD_AUDIO_FS_44K || fs > PS3AV_CMD_AUDIO_FS_192K)
549 printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs); 549 printk(KERN_ERR "%s failed, fs:%x\n", __func__, fs);
550 else 550 else
551 ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d]; 551 ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d];
552 552
553 *ns++ = ns_val & 0x000000FF; 553 *ns++ = ns_val & 0x000000FF;
554 *ns++ = (ns_val & 0x0000FF00) >> 8; 554 *ns++ = (ns_val & 0x0000FF00) >> 8;
555 *ns = (ns_val & 0x00FF0000) >> 16; 555 *ns = (ns_val & 0x00FF0000) >> 16;
556 } 556 }
557 557
558 #undef BASE 558 #undef BASE
559 559
560 static u8 ps3av_cnv_enable(u32 source, const u8 *enable) 560 static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
561 { 561 {
562 u8 ret = 0; 562 u8 ret = 0;
563 563
564 if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) { 564 if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) {
565 ret = 0x03; 565 ret = 0x03;
566 } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) { 566 } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) {
567 ret = ((enable[0] << 4) + (enable[1] << 5) + (enable[2] << 6) + 567 ret = ((enable[0] << 4) + (enable[1] << 5) + (enable[2] << 6) +
568 (enable[3] << 7)) | 0x01; 568 (enable[3] << 7)) | 0x01;
569 } else 569 } else
570 printk(KERN_ERR "%s failed, source:%x\n", __func__, source); 570 printk(KERN_ERR "%s failed, source:%x\n", __func__, source);
571 return ret; 571 return ret;
572 } 572 }
573 573
574 static u8 ps3av_cnv_fifomap(const u8 *map) 574 static u8 ps3av_cnv_fifomap(const u8 *map)
575 { 575 {
576 u8 ret = 0; 576 u8 ret = 0;
577 577
578 ret = map[0] + (map[1] << 2) + (map[2] << 4) + (map[3] << 6); 578 ret = map[0] + (map[1] << 2) + (map[2] << 4) + (map[3] << 6);
579 return ret; 579 return ret;
580 } 580 }
581 581
582 static u8 ps3av_cnv_inputlen(u32 word_bits) 582 static u8 ps3av_cnv_inputlen(u32 word_bits)
583 { 583 {
584 u8 ret = 0; 584 u8 ret = 0;
585 585
586 switch (word_bits) { 586 switch (word_bits) {
587 case PS3AV_CMD_AUDIO_WORD_BITS_16: 587 case PS3AV_CMD_AUDIO_WORD_BITS_16:
588 ret = PS3AV_CMD_AV_INPUTLEN_16; 588 ret = PS3AV_CMD_AV_INPUTLEN_16;
589 break; 589 break;
590 case PS3AV_CMD_AUDIO_WORD_BITS_20: 590 case PS3AV_CMD_AUDIO_WORD_BITS_20:
591 ret = PS3AV_CMD_AV_INPUTLEN_20; 591 ret = PS3AV_CMD_AV_INPUTLEN_20;
592 break; 592 break;
593 case PS3AV_CMD_AUDIO_WORD_BITS_24: 593 case PS3AV_CMD_AUDIO_WORD_BITS_24:
594 ret = PS3AV_CMD_AV_INPUTLEN_24; 594 ret = PS3AV_CMD_AV_INPUTLEN_24;
595 break; 595 break;
596 default: 596 default:
597 printk(KERN_ERR "%s failed, word_bits:%x\n", __func__, 597 printk(KERN_ERR "%s failed, word_bits:%x\n", __func__,
598 word_bits); 598 word_bits);
599 break; 599 break;
600 } 600 }
601 return ret; 601 return ret;
602 } 602 }
603 603
604 static u8 ps3av_cnv_layout(u32 num_of_ch) 604 static u8 ps3av_cnv_layout(u32 num_of_ch)
605 { 605 {
606 if (num_of_ch > PS3AV_CMD_AUDIO_NUM_OF_CH_8) { 606 if (num_of_ch > PS3AV_CMD_AUDIO_NUM_OF_CH_8) {
607 printk(KERN_ERR "%s failed, num_of_ch:%x\n", __func__, 607 printk(KERN_ERR "%s failed, num_of_ch:%x\n", __func__,
608 num_of_ch); 608 num_of_ch);
609 return 0; 609 return 0;
610 } 610 }
611 611
612 return num_of_ch == PS3AV_CMD_AUDIO_NUM_OF_CH_2 ? 0x0 : 0x1; 612 return num_of_ch == PS3AV_CMD_AUDIO_NUM_OF_CH_2 ? 0x0 : 0x1;
613 } 613 }
614 614
615 static void ps3av_cnv_info(struct ps3av_audio_info_frame *info, 615 static void ps3av_cnv_info(struct ps3av_audio_info_frame *info,
616 const struct ps3av_pkt_audio_mode *mode) 616 const struct ps3av_pkt_audio_mode *mode)
617 { 617 {
618 info->pb1.cc = mode->audio_num_of_ch + 1; /* CH2:0x01 --- CH8:0x07 */ 618 info->pb1.cc = mode->audio_num_of_ch + 1; /* CH2:0x01 --- CH8:0x07 */
619 info->pb1.ct = 0; 619 info->pb1.ct = 0;
620 info->pb2.sf = 0; 620 info->pb2.sf = 0;
621 info->pb2.ss = 0; 621 info->pb2.ss = 0;
622 622
623 info->pb3 = 0; /* check mode->audio_format ?? */ 623 info->pb3 = 0; /* check mode->audio_format ?? */
624 info->pb4 = mode->audio_layout; 624 info->pb4 = mode->audio_layout;
625 info->pb5.dm = mode->audio_downmix; 625 info->pb5.dm = mode->audio_downmix;
626 info->pb5.lsv = mode->audio_downmix_level; 626 info->pb5.lsv = mode->audio_downmix_level;
627 } 627 }
628 628
629 static void ps3av_cnv_chstat(u8 *chstat, const u8 *cs_info) 629 static void ps3av_cnv_chstat(u8 *chstat, const u8 *cs_info)
630 { 630 {
631 memcpy(chstat, cs_info, 5); 631 memcpy(chstat, cs_info, 5);
632 } 632 }
633 633
634 u32 ps3av_cmd_set_av_audio_param(void *p, u32 port, 634 u32 ps3av_cmd_set_av_audio_param(void *p, u32 port,
635 const struct ps3av_pkt_audio_mode *audio_mode, 635 const struct ps3av_pkt_audio_mode *audio_mode,
636 u32 video_vid) 636 u32 video_vid)
637 { 637 {
638 struct ps3av_pkt_av_audio_param *param; 638 struct ps3av_pkt_av_audio_param *param;
639 639
640 param = (struct ps3av_pkt_av_audio_param *)p; 640 param = (struct ps3av_pkt_av_audio_param *)p;
641 641
642 memset(param, 0, sizeof(*param)); 642 memset(param, 0, sizeof(*param));
643 ps3av_set_hdr(PS3AV_CID_AV_AUDIO_PARAM, sizeof(*param), 643 ps3av_set_hdr(PS3AV_CID_AV_AUDIO_PARAM, sizeof(*param),
644 &param->send_hdr); 644 &param->send_hdr);
645 645
646 param->avport = port; 646 param->avport = port;
647 param->mclk = ps3av_cnv_mclk(audio_mode->audio_fs) | 0x80; 647 param->mclk = ps3av_cnv_mclk(audio_mode->audio_fs) | 0x80;
648 ps3av_cnv_ns(param->ns, audio_mode->audio_fs, video_vid); 648 ps3av_cnv_ns(param->ns, audio_mode->audio_fs, video_vid);
649 param->enable = ps3av_cnv_enable(audio_mode->audio_source, 649 param->enable = ps3av_cnv_enable(audio_mode->audio_source,
650 audio_mode->audio_enable); 650 audio_mode->audio_enable);
651 param->swaplr = 0x09; 651 param->swaplr = 0x09;
652 param->fifomap = ps3av_cnv_fifomap(audio_mode->audio_map); 652 param->fifomap = ps3av_cnv_fifomap(audio_mode->audio_map);
653 param->inputctrl = 0x49; 653 param->inputctrl = 0x49;
654 param->inputlen = ps3av_cnv_inputlen(audio_mode->audio_word_bits); 654 param->inputlen = ps3av_cnv_inputlen(audio_mode->audio_word_bits);
655 param->layout = ps3av_cnv_layout(audio_mode->audio_num_of_ch); 655 param->layout = ps3av_cnv_layout(audio_mode->audio_num_of_ch);
656 ps3av_cnv_info(&param->info, audio_mode); 656 ps3av_cnv_info(&param->info, audio_mode);
657 ps3av_cnv_chstat(param->chstat, audio_mode->audio_cs_info); 657 ps3av_cnv_chstat(param->chstat, audio_mode->audio_cs_info);
658 658
659 return sizeof(*param); 659 return sizeof(*param);
660 } 660 }
661 661
662 /* default cs val */ 662 /* default cs val */
663 u8 ps3av_mode_cs_info[] = { 663 u8 ps3av_mode_cs_info[] = {
664 0x00, 0x09, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00 664 0x00, 0x09, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00
665 }; 665 };
666 EXPORT_SYMBOL_GPL(ps3av_mode_cs_info); 666 EXPORT_SYMBOL_GPL(ps3av_mode_cs_info);
667 667
668 #define CS_44 0x00 668 #define CS_44 0x00
669 #define CS_48 0x02 669 #define CS_48 0x02
670 #define CS_88 0x08 670 #define CS_88 0x08
671 #define CS_96 0x0a 671 #define CS_96 0x0a
672 #define CS_176 0x0c 672 #define CS_176 0x0c
673 #define CS_192 0x0e 673 #define CS_192 0x0e
674 #define CS_MASK 0x0f 674 #define CS_MASK 0x0f
675 #define CS_BIT 0x40 675 #define CS_BIT 0x40
676 676
677 void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport, 677 void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport,
678 u32 ch, u32 fs, u32 word_bits, u32 format, 678 u32 ch, u32 fs, u32 word_bits, u32 format,
679 u32 source) 679 u32 source)
680 { 680 {
681 int spdif_through; 681 int spdif_through;
682 int i; 682 int i;
683 683
684 if (!(ch | fs | format | word_bits | source)) { 684 if (!(ch | fs | format | word_bits | source)) {
685 ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2; 685 ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2;
686 fs = PS3AV_CMD_AUDIO_FS_48K; 686 fs = PS3AV_CMD_AUDIO_FS_48K;
687 word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16; 687 word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16;
688 format = PS3AV_CMD_AUDIO_FORMAT_PCM; 688 format = PS3AV_CMD_AUDIO_FORMAT_PCM;
689 source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; 689 source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
690 } 690 }
691 691
692 /* audio mode */ 692 /* audio mode */
693 memset(audio, 0, sizeof(*audio)); 693 memset(audio, 0, sizeof(*audio));
694 ps3av_set_hdr(PS3AV_CID_AUDIO_MODE, sizeof(*audio), &audio->send_hdr); 694 ps3av_set_hdr(PS3AV_CID_AUDIO_MODE, sizeof(*audio), &audio->send_hdr);
695 695
696 audio->avport = (u8) avport; 696 audio->avport = (u8) avport;
697 audio->mask = 0x0FFF; /* XXX set all */ 697 audio->mask = 0x0FFF; /* XXX set all */
698 audio->audio_num_of_ch = ch; 698 audio->audio_num_of_ch = ch;
699 audio->audio_fs = fs; 699 audio->audio_fs = fs;
700 audio->audio_word_bits = word_bits; 700 audio->audio_word_bits = word_bits;
701 audio->audio_format = format; 701 audio->audio_format = format;
702 audio->audio_source = source; 702 audio->audio_source = source;
703 703
704 switch (ch) { 704 switch (ch) {
705 case PS3AV_CMD_AUDIO_NUM_OF_CH_8: 705 case PS3AV_CMD_AUDIO_NUM_OF_CH_8:
706 audio->audio_enable[3] = 1; 706 audio->audio_enable[3] = 1;
707 /* fall through */ 707 /* fall through */
708 case PS3AV_CMD_AUDIO_NUM_OF_CH_6: 708 case PS3AV_CMD_AUDIO_NUM_OF_CH_6:
709 audio->audio_enable[2] = 1; 709 audio->audio_enable[2] = 1;
710 audio->audio_enable[1] = 1; 710 audio->audio_enable[1] = 1;
711 /* fall through */ 711 /* fall through */
712 case PS3AV_CMD_AUDIO_NUM_OF_CH_2: 712 case PS3AV_CMD_AUDIO_NUM_OF_CH_2:
713 default: 713 default:
714 audio->audio_enable[0] = 1; 714 audio->audio_enable[0] = 1;
715 } 715 }
716 716
717 /* audio swap L/R */ 717 /* audio swap L/R */
718 for (i = 0; i < 4; i++) 718 for (i = 0; i < 4; i++)
719 audio->audio_swap[i] = PS3AV_CMD_AUDIO_SWAP_0; /* no swap */ 719 audio->audio_swap[i] = PS3AV_CMD_AUDIO_SWAP_0; /* no swap */
720 720
721 /* audio serial input mapping */ 721 /* audio serial input mapping */
722 audio->audio_map[0] = PS3AV_CMD_AUDIO_MAP_OUTPUT_0; 722 audio->audio_map[0] = PS3AV_CMD_AUDIO_MAP_OUTPUT_0;
723 audio->audio_map[1] = PS3AV_CMD_AUDIO_MAP_OUTPUT_1; 723 audio->audio_map[1] = PS3AV_CMD_AUDIO_MAP_OUTPUT_1;
724 audio->audio_map[2] = PS3AV_CMD_AUDIO_MAP_OUTPUT_2; 724 audio->audio_map[2] = PS3AV_CMD_AUDIO_MAP_OUTPUT_2;
725 audio->audio_map[3] = PS3AV_CMD_AUDIO_MAP_OUTPUT_3; 725 audio->audio_map[3] = PS3AV_CMD_AUDIO_MAP_OUTPUT_3;
726 726
727 /* audio speaker layout */ 727 /* audio speaker layout */
728 if (avport == PS3AV_CMD_AVPORT_HDMI_0 || 728 if (avport == PS3AV_CMD_AVPORT_HDMI_0 ||
729 avport == PS3AV_CMD_AVPORT_HDMI_1) { 729 avport == PS3AV_CMD_AVPORT_HDMI_1) {
730 switch (ch) { 730 switch (ch) {
731 case PS3AV_CMD_AUDIO_NUM_OF_CH_8: 731 case PS3AV_CMD_AUDIO_NUM_OF_CH_8:
732 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_8CH; 732 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_8CH;
733 break; 733 break;
734 case PS3AV_CMD_AUDIO_NUM_OF_CH_6: 734 case PS3AV_CMD_AUDIO_NUM_OF_CH_6:
735 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_6CH; 735 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_6CH;
736 break; 736 break;
737 case PS3AV_CMD_AUDIO_NUM_OF_CH_2: 737 case PS3AV_CMD_AUDIO_NUM_OF_CH_2:
738 default: 738 default:
739 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH; 739 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH;
740 break; 740 break;
741 } 741 }
742 } else { 742 } else {
743 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH; 743 audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH;
744 } 744 }
745 745
746 /* audio downmix permission */ 746 /* audio downmix permission */
747 audio->audio_downmix = PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED; 747 audio->audio_downmix = PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED;
748 /* audio downmix level shift (0:0dB to 15:15dB) */ 748 /* audio downmix level shift (0:0dB to 15:15dB) */
749 audio->audio_downmix_level = 0; /* 0dB */ 749 audio->audio_downmix_level = 0; /* 0dB */
750 750
751 /* set ch status */ 751 /* set ch status */
752 for (i = 0; i < 8; i++) 752 for (i = 0; i < 8; i++)
753 audio->audio_cs_info[i] = ps3av_mode_cs_info[i]; 753 audio->audio_cs_info[i] = ps3av_mode_cs_info[i];
754 754
755 switch (fs) { 755 switch (fs) {
756 case PS3AV_CMD_AUDIO_FS_44K: 756 case PS3AV_CMD_AUDIO_FS_44K:
757 audio->audio_cs_info[3] &= ~CS_MASK; 757 audio->audio_cs_info[3] &= ~CS_MASK;
758 audio->audio_cs_info[3] |= CS_44; 758 audio->audio_cs_info[3] |= CS_44;
759 break; 759 break;
760 case PS3AV_CMD_AUDIO_FS_88K: 760 case PS3AV_CMD_AUDIO_FS_88K:
761 audio->audio_cs_info[3] &= ~CS_MASK; 761 audio->audio_cs_info[3] &= ~CS_MASK;
762 audio->audio_cs_info[3] |= CS_88; 762 audio->audio_cs_info[3] |= CS_88;
763 break; 763 break;
764 case PS3AV_CMD_AUDIO_FS_96K: 764 case PS3AV_CMD_AUDIO_FS_96K:
765 audio->audio_cs_info[3] &= ~CS_MASK; 765 audio->audio_cs_info[3] &= ~CS_MASK;
766 audio->audio_cs_info[3] |= CS_96; 766 audio->audio_cs_info[3] |= CS_96;
767 break; 767 break;
768 case PS3AV_CMD_AUDIO_FS_176K: 768 case PS3AV_CMD_AUDIO_FS_176K:
769 audio->audio_cs_info[3] &= ~CS_MASK; 769 audio->audio_cs_info[3] &= ~CS_MASK;
770 audio->audio_cs_info[3] |= CS_176; 770 audio->audio_cs_info[3] |= CS_176;
771 break; 771 break;
772 case PS3AV_CMD_AUDIO_FS_192K: 772 case PS3AV_CMD_AUDIO_FS_192K:
773 audio->audio_cs_info[3] &= ~CS_MASK; 773 audio->audio_cs_info[3] &= ~CS_MASK;
774 audio->audio_cs_info[3] |= CS_192; 774 audio->audio_cs_info[3] |= CS_192;
775 break; 775 break;
776 default: 776 default:
777 break; 777 break;
778 } 778 }
779 779
780 /* non-audio bit */ 780 /* non-audio bit */
781 spdif_through = audio->audio_cs_info[0] & 0x02; 781 spdif_through = audio->audio_cs_info[0] & 0x02;
782 782
783 /* pass through setting */ 783 /* pass through setting */
784 if (spdif_through && 784 if (spdif_through &&
785 (avport == PS3AV_CMD_AVPORT_SPDIF_0 || 785 (avport == PS3AV_CMD_AVPORT_SPDIF_0 ||
786 avport == PS3AV_CMD_AVPORT_SPDIF_1 || 786 avport == PS3AV_CMD_AVPORT_SPDIF_1 ||
787 avport == PS3AV_CMD_AVPORT_HDMI_0 || 787 avport == PS3AV_CMD_AVPORT_HDMI_0 ||
788 avport == PS3AV_CMD_AVPORT_HDMI_1)) { 788 avport == PS3AV_CMD_AVPORT_HDMI_1)) {
789 audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16; 789 audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16;
790 audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM; 790 audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM;
791 } 791 }
792 } 792 }
793 793
794 int ps3av_cmd_audio_mode(struct ps3av_pkt_audio_mode *audio_mode) 794 int ps3av_cmd_audio_mode(struct ps3av_pkt_audio_mode *audio_mode)
795 { 795 {
796 int res; 796 int res;
797 797
798 res = ps3av_do_pkt(PS3AV_CID_AUDIO_MODE, sizeof(*audio_mode), 798 res = ps3av_do_pkt(PS3AV_CID_AUDIO_MODE, sizeof(*audio_mode),
799 sizeof(*audio_mode), &audio_mode->send_hdr); 799 sizeof(*audio_mode), &audio_mode->send_hdr);
800 if (res < 0) 800 if (res < 0)
801 return res; 801 return res;
802 802
803 res = get_status(audio_mode); 803 res = get_status(audio_mode);
804 if (res) 804 if (res)
805 printk(KERN_ERR "PS3AV_CID_AUDIO_MODE: failed %x\n", res); 805 printk(KERN_ERR "PS3AV_CID_AUDIO_MODE: failed %x\n", res);
806 806
807 return res; 807 return res;
808 } 808 }
809 809
810 int ps3av_cmd_audio_mute(int num_of_port, u32 *port, u32 mute) 810 int ps3av_cmd_audio_mute(int num_of_port, u32 *port, u32 mute)
811 { 811 {
812 int i, res; 812 int i, res;
813 struct ps3av_pkt_audio_mute audio_mute; 813 struct ps3av_pkt_audio_mute audio_mute;
814 814
815 if (num_of_port > PS3AV_OPT_PORT_MAX) 815 if (num_of_port > PS3AV_OPT_PORT_MAX)
816 return -EINVAL; 816 return -EINVAL;
817 817
818 /* audio mute */ 818 /* audio mute */
819 memset(&audio_mute, 0, sizeof(audio_mute)); 819 memset(&audio_mute, 0, sizeof(audio_mute));
820 for (i = 0; i < num_of_port; i++) { 820 for (i = 0; i < num_of_port; i++) {
821 audio_mute.mute[i].avport = port[i]; 821 audio_mute.mute[i].avport = port[i];
822 audio_mute.mute[i].mute = mute; 822 audio_mute.mute[i].mute = mute;
823 } 823 }
824 824
825 res = ps3av_do_pkt(PS3AV_CID_AUDIO_MUTE, 825 res = ps3av_do_pkt(PS3AV_CID_AUDIO_MUTE,
826 sizeof(audio_mute.send_hdr) + 826 sizeof(audio_mute.send_hdr) +
827 sizeof(struct ps3av_audio_mute) * num_of_port, 827 sizeof(struct ps3av_audio_mute) * num_of_port,
828 sizeof(audio_mute), &audio_mute.send_hdr); 828 sizeof(audio_mute), &audio_mute.send_hdr);
829 if (res < 0) 829 if (res < 0)
830 return res; 830 return res;
831 831
832 res = get_status(&audio_mute); 832 res = get_status(&audio_mute);
833 if (res) 833 if (res)
834 printk(KERN_ERR "PS3AV_CID_AUDIO_MUTE: failed %x\n", res); 834 printk(KERN_ERR "PS3AV_CID_AUDIO_MUTE: failed %x\n", res);
835 835
836 return res; 836 return res;
837 } 837 }
838 838
839 int ps3av_cmd_audio_active(int active, u32 port) 839 int ps3av_cmd_audio_active(int active, u32 port)
840 { 840 {
841 int res; 841 int res;
842 struct ps3av_pkt_audio_active audio_active; 842 struct ps3av_pkt_audio_active audio_active;
843 u32 cid; 843 u32 cid;
844 844
845 /* audio active */ 845 /* audio active */
846 memset(&audio_active, 0, sizeof(audio_active)); 846 memset(&audio_active, 0, sizeof(audio_active));
847 audio_active.audio_port = port; 847 audio_active.audio_port = port;
848 cid = active ? PS3AV_CID_AUDIO_ACTIVE : PS3AV_CID_AUDIO_INACTIVE; 848 cid = active ? PS3AV_CID_AUDIO_ACTIVE : PS3AV_CID_AUDIO_INACTIVE;
849 849
850 res = ps3av_do_pkt(cid, sizeof(audio_active), sizeof(audio_active), 850 res = ps3av_do_pkt(cid, sizeof(audio_active), sizeof(audio_active),
851 &audio_active.send_hdr); 851 &audio_active.send_hdr);
852 if (res < 0) 852 if (res < 0)
853 return res; 853 return res;
854 854
855 res = get_status(&audio_active); 855 res = get_status(&audio_active);
856 if (res) 856 if (res)
857 printk(KERN_ERR "PS3AV_CID_AUDIO_ACTIVE:%x failed %x\n", cid, 857 printk(KERN_ERR "PS3AV_CID_AUDIO_ACTIVE:%x failed %x\n", cid,
858 res); 858 res);
859 859
860 return res; 860 return res;
861 } 861 }
862 862
863 int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len) 863 int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *avb, u32 send_len)
864 { 864 {
865 int res; 865 int res;
866 866
867 ps3av_flip_ctl(0); /* flip off */ 867 mutex_lock(&ps3_gpu_mutex);
868 868
869 /* avb packet */ 869 /* avb packet */
870 res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb), 870 res = ps3av_do_pkt(PS3AV_CID_AVB_PARAM, send_len, sizeof(*avb),
871 &avb->send_hdr); 871 &avb->send_hdr);
872 if (res < 0) 872 if (res < 0)
873 goto out; 873 goto out;
874 874
875 res = get_status(avb); 875 res = get_status(avb);
876 if (res) 876 if (res)
877 pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __func__, 877 pr_debug("%s: PS3AV_CID_AVB_PARAM: failed %x\n", __func__,
878 res); 878 res);
879 879
880 out: 880 out:
881 ps3av_flip_ctl(1); /* flip on */ 881 mutex_unlock(&ps3_gpu_mutex);
882 return res; 882 return res;
883 } 883 }
884 884
885 int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *hw_conf) 885 int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *hw_conf)
886 { 886 {
887 int res; 887 int res;
888 888
889 memset(hw_conf, 0, sizeof(*hw_conf)); 889 memset(hw_conf, 0, sizeof(*hw_conf));
890 890
891 res = ps3av_do_pkt(PS3AV_CID_AV_GET_HW_CONF, sizeof(hw_conf->send_hdr), 891 res = ps3av_do_pkt(PS3AV_CID_AV_GET_HW_CONF, sizeof(hw_conf->send_hdr),
892 sizeof(*hw_conf), &hw_conf->send_hdr); 892 sizeof(*hw_conf), &hw_conf->send_hdr);
893 if (res < 0) 893 if (res < 0)
894 return res; 894 return res;
895 895
896 res = get_status(hw_conf); 896 res = get_status(hw_conf);
897 if (res) 897 if (res)
898 printk(KERN_ERR "PS3AV_CID_AV_GET_HW_CONF: failed %x\n", res); 898 printk(KERN_ERR "PS3AV_CID_AV_GET_HW_CONF: failed %x\n", res);
899 899
900 return res; 900 return res;
901 } 901 }
902 902
903 int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *info, 903 int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *info,
904 u32 avport) 904 u32 avport)
905 { 905 {
906 int res; 906 int res;
907 907
908 memset(info, 0, sizeof(*info)); 908 memset(info, 0, sizeof(*info));
909 info->avport = avport; 909 info->avport = avport;
910 910
911 res = ps3av_do_pkt(PS3AV_CID_AV_GET_MONITOR_INFO, 911 res = ps3av_do_pkt(PS3AV_CID_AV_GET_MONITOR_INFO,
912 sizeof(info->send_hdr) + sizeof(info->avport) + 912 sizeof(info->send_hdr) + sizeof(info->avport) +
913 sizeof(info->reserved), 913 sizeof(info->reserved),
914 sizeof(*info), &info->send_hdr); 914 sizeof(*info), &info->send_hdr);
915 if (res < 0) 915 if (res < 0)
916 return res; 916 return res;
917 917
918 res = get_status(info); 918 res = get_status(info);
919 if (res) 919 if (res)
920 printk(KERN_ERR "PS3AV_CID_AV_GET_MONITOR_INFO: failed %x\n", 920 printk(KERN_ERR "PS3AV_CID_AV_GET_MONITOR_INFO: failed %x\n",
921 res); 921 res);
922 922
923 return res; 923 return res;
924 } 924 }
925 925
926 #define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \ 926 #define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \
927 | PS3AV_CMD_AV_LAYOUT_44 \ 927 | PS3AV_CMD_AV_LAYOUT_44 \
928 | PS3AV_CMD_AV_LAYOUT_48) 928 | PS3AV_CMD_AV_LAYOUT_48)
929 929
930 #define PS3AV_AV_LAYOUT_1 (PS3AV_AV_LAYOUT_0 \ 930 #define PS3AV_AV_LAYOUT_1 (PS3AV_AV_LAYOUT_0 \
931 | PS3AV_CMD_AV_LAYOUT_88 \ 931 | PS3AV_CMD_AV_LAYOUT_88 \
932 | PS3AV_CMD_AV_LAYOUT_96 \ 932 | PS3AV_CMD_AV_LAYOUT_96 \
933 | PS3AV_CMD_AV_LAYOUT_176 \ 933 | PS3AV_CMD_AV_LAYOUT_176 \
934 | PS3AV_CMD_AV_LAYOUT_192) 934 | PS3AV_CMD_AV_LAYOUT_192)
935 935
936 936
drivers/video/ps3fb.c
1 /* 1 /*
2 * linux/drivers/video/ps3fb.c -- PS3 GPU frame buffer device 2 * linux/drivers/video/ps3fb.c -- PS3 GPU frame buffer device
3 * 3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc. 4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006, 2007 Sony Corporation 5 * Copyright 2006, 2007 Sony Corporation
6 * 6 *
7 * This file is based on : 7 * This file is based on :
8 * 8 *
9 * linux/drivers/video/vfb.c -- Virtual frame buffer device 9 * linux/drivers/video/vfb.c -- Virtual frame buffer device
10 * 10 *
11 * Copyright (C) 2002 James Simmons 11 * Copyright (C) 2002 James Simmons
12 * 12 *
13 * Copyright (C) 1997 Geert Uytterhoeven 13 * Copyright (C) 1997 Geert Uytterhoeven
14 * 14 *
15 * This file is subject to the terms and conditions of the GNU General Public 15 * This file is subject to the terms and conditions of the GNU General Public
16 * License. See the file COPYING in the main directory of this archive for 16 * License. See the file COPYING in the main directory of this archive for
17 * more details. 17 * more details.
18 */ 18 */
19 19
20 #include <linux/module.h> 20 #include <linux/module.h>
21 #include <linux/kernel.h> 21 #include <linux/kernel.h>
22 #include <linux/errno.h> 22 #include <linux/errno.h>
23 #include <linux/string.h> 23 #include <linux/string.h>
24 #include <linux/mm.h> 24 #include <linux/mm.h>
25 #include <linux/interrupt.h> 25 #include <linux/interrupt.h>
26 #include <linux/console.h> 26 #include <linux/console.h>
27 #include <linux/ioctl.h> 27 #include <linux/ioctl.h>
28 #include <linux/kthread.h> 28 #include <linux/kthread.h>
29 #include <linux/freezer.h> 29 #include <linux/freezer.h>
30 #include <linux/uaccess.h> 30 #include <linux/uaccess.h>
31 #include <linux/fb.h> 31 #include <linux/fb.h>
32 #include <linux/init.h> 32 #include <linux/init.h>
33 33
34 #include <asm/abs_addr.h> 34 #include <asm/abs_addr.h>
35 #include <asm/lv1call.h> 35 #include <asm/lv1call.h>
36 #include <asm/ps3av.h> 36 #include <asm/ps3av.h>
37 #include <asm/ps3fb.h> 37 #include <asm/ps3fb.h>
38 #include <asm/ps3.h> 38 #include <asm/ps3.h>
39 39
40 40
41 #define DEVICE_NAME "ps3fb" 41 #define DEVICE_NAME "ps3fb"
42 42
43 #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101 43 #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
44 #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102 44 #define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
45 #define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600 45 #define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
46 #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 46 #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
47 #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602 47 #define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602
48 48
49 #define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32) 49 #define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32)
50 50
51 #define L1GPU_DISPLAY_SYNC_HSYNC 1 51 #define L1GPU_DISPLAY_SYNC_HSYNC 1
52 #define L1GPU_DISPLAY_SYNC_VSYNC 2 52 #define L1GPU_DISPLAY_SYNC_VSYNC 2
53 53
54 #define GPU_CMD_BUF_SIZE (2 * 1024 * 1024) 54 #define GPU_CMD_BUF_SIZE (2 * 1024 * 1024)
55 #define GPU_FB_START (64 * 1024) 55 #define GPU_FB_START (64 * 1024)
56 #define GPU_IOIF (0x0d000000UL) 56 #define GPU_IOIF (0x0d000000UL)
57 #define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64) 57 #define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
58 #define GPU_MAX_LINE_LENGTH (65536 - 64) 58 #define GPU_MAX_LINE_LENGTH (65536 - 64)
59 59
60 #define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */ 60 #define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */
61 #define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */ 61 #define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */
62 #define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */ 62 #define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */
63 #define GPU_INTR_STATUS_FLIP_1 4 /* flip head B */ 63 #define GPU_INTR_STATUS_FLIP_1 4 /* flip head B */
64 #define GPU_INTR_STATUS_QUEUE_0 5 /* queue head A */ 64 #define GPU_INTR_STATUS_QUEUE_0 5 /* queue head A */
65 #define GPU_INTR_STATUS_QUEUE_1 6 /* queue head B */ 65 #define GPU_INTR_STATUS_QUEUE_1 6 /* queue head B */
66 66
67 #define GPU_DRIVER_INFO_VERSION 0x211 67 #define GPU_DRIVER_INFO_VERSION 0x211
68 68
69 /* gpu internals */ 69 /* gpu internals */
70 struct display_head { 70 struct display_head {
71 u64 be_time_stamp; 71 u64 be_time_stamp;
72 u32 status; 72 u32 status;
73 u32 offset; 73 u32 offset;
74 u32 res1; 74 u32 res1;
75 u32 res2; 75 u32 res2;
76 u32 field; 76 u32 field;
77 u32 reserved1; 77 u32 reserved1;
78 78
79 u64 res3; 79 u64 res3;
80 u32 raster; 80 u32 raster;
81 81
82 u64 vblank_count; 82 u64 vblank_count;
83 u32 field_vsync; 83 u32 field_vsync;
84 u32 reserved2; 84 u32 reserved2;
85 }; 85 };
86 86
87 struct gpu_irq { 87 struct gpu_irq {
88 u32 irq_outlet; 88 u32 irq_outlet;
89 u32 status; 89 u32 status;
90 u32 mask; 90 u32 mask;
91 u32 video_cause; 91 u32 video_cause;
92 u32 graph_cause; 92 u32 graph_cause;
93 u32 user_cause; 93 u32 user_cause;
94 94
95 u32 res1; 95 u32 res1;
96 u64 res2; 96 u64 res2;
97 97
98 u32 reserved[4]; 98 u32 reserved[4];
99 }; 99 };
100 100
101 struct gpu_driver_info { 101 struct gpu_driver_info {
102 u32 version_driver; 102 u32 version_driver;
103 u32 version_gpu; 103 u32 version_gpu;
104 u32 memory_size; 104 u32 memory_size;
105 u32 hardware_channel; 105 u32 hardware_channel;
106 106
107 u32 nvcore_frequency; 107 u32 nvcore_frequency;
108 u32 memory_frequency; 108 u32 memory_frequency;
109 109
110 u32 reserved[1063]; 110 u32 reserved[1063];
111 struct display_head display_head[8]; 111 struct display_head display_head[8];
112 struct gpu_irq irq; 112 struct gpu_irq irq;
113 }; 113 };
114 114
115 struct ps3fb_priv { 115 struct ps3fb_priv {
116 unsigned int irq_no; 116 unsigned int irq_no;
117 117
118 u64 context_handle, memory_handle; 118 u64 context_handle, memory_handle;
119 struct gpu_driver_info *dinfo; 119 struct gpu_driver_info *dinfo;
120 120
121 u64 vblank_count; /* frame count */ 121 u64 vblank_count; /* frame count */
122 wait_queue_head_t wait_vsync; 122 wait_queue_head_t wait_vsync;
123 123
124 atomic_t ext_flip; /* on/off flip with vsync */ 124 atomic_t ext_flip; /* on/off flip with vsync */
125 atomic_t f_count; /* fb_open count */ 125 atomic_t f_count; /* fb_open count */
126 int is_blanked; 126 int is_blanked;
127 int is_kicked; 127 int is_kicked;
128 struct task_struct *task; 128 struct task_struct *task;
129 }; 129 };
130 static struct ps3fb_priv ps3fb; 130 static struct ps3fb_priv ps3fb;
131 131
132 struct ps3fb_par { 132 struct ps3fb_par {
133 u32 pseudo_palette[16]; 133 u32 pseudo_palette[16];
134 int mode_id, new_mode_id; 134 int mode_id, new_mode_id;
135 unsigned int num_frames; /* num of frame buffers */ 135 unsigned int num_frames; /* num of frame buffers */
136 unsigned int width; 136 unsigned int width;
137 unsigned int height; 137 unsigned int height;
138 unsigned int ddr_line_length; 138 unsigned int ddr_line_length;
139 unsigned int ddr_frame_size; 139 unsigned int ddr_frame_size;
140 unsigned int xdr_frame_size; 140 unsigned int xdr_frame_size;
141 unsigned int full_offset; /* start of fullscreen DDR fb */ 141 unsigned int full_offset; /* start of fullscreen DDR fb */
142 unsigned int fb_offset; /* start of actual DDR fb */ 142 unsigned int fb_offset; /* start of actual DDR fb */
143 unsigned int pan_offset; 143 unsigned int pan_offset;
144 }; 144 };
145 145
146 146
147 #define FIRST_NATIVE_MODE_INDEX 10 147 #define FIRST_NATIVE_MODE_INDEX 10
148 148
149 static const struct fb_videomode ps3fb_modedb[] = { 149 static const struct fb_videomode ps3fb_modedb[] = {
150 /* 60 Hz broadcast modes (modes "1" to "5") */ 150 /* 60 Hz broadcast modes (modes "1" to "5") */
151 { 151 {
152 /* 480i */ 152 /* 480i */
153 "480i", 60, 576, 384, 74074, 130, 89, 78, 57, 63, 6, 153 "480i", 60, 576, 384, 74074, 130, 89, 78, 57, 63, 6,
154 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 154 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
155 }, { 155 }, {
156 /* 480p */ 156 /* 480p */
157 "480p", 60, 576, 384, 37037, 130, 89, 78, 57, 63, 6, 157 "480p", 60, 576, 384, 37037, 130, 89, 78, 57, 63, 6,
158 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 158 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
159 }, { 159 }, {
160 /* 720p */ 160 /* 720p */
161 "720p", 60, 1124, 644, 13481, 298, 148, 57, 44, 80, 5, 161 "720p", 60, 1124, 644, 13481, 298, 148, 57, 44, 80, 5,
162 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 162 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
163 }, { 163 }, {
164 /* 1080i */ 164 /* 1080i */
165 "1080i", 60, 1688, 964, 13481, 264, 160, 94, 62, 88, 5, 165 "1080i", 60, 1688, 964, 13481, 264, 160, 94, 62, 88, 5,
166 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 166 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
167 }, { 167 }, {
168 /* 1080p */ 168 /* 1080p */
169 "1080p", 60, 1688, 964, 6741, 264, 160, 94, 62, 88, 5, 169 "1080p", 60, 1688, 964, 6741, 264, 160, 94, 62, 88, 5,
170 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 170 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
171 }, 171 },
172 172
173 /* 50 Hz broadcast modes (modes "6" to "10") */ 173 /* 50 Hz broadcast modes (modes "6" to "10") */
174 { 174 {
175 /* 576i */ 175 /* 576i */
176 "576i", 50, 576, 460, 74074, 142, 83, 97, 63, 63, 5, 176 "576i", 50, 576, 460, 74074, 142, 83, 97, 63, 63, 5,
177 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 177 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
178 }, { 178 }, {
179 /* 576p */ 179 /* 576p */
180 "576p", 50, 576, 460, 37037, 142, 83, 97, 63, 63, 5, 180 "576p", 50, 576, 460, 37037, 142, 83, 97, 63, 63, 5,
181 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 181 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
182 }, { 182 }, {
183 /* 720p */ 183 /* 720p */
184 "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5, 184 "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5,
185 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 185 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
186 }, { 186 }, {
187 /* 1080i */ 187 /* 1080i */
188 "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5, 188 "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5,
189 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 189 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
190 }, { 190 }, {
191 /* 1080p */ 191 /* 1080p */
192 "1080p", 50, 1688, 964, 6734, 264, 600, 94, 62, 88, 5, 192 "1080p", 50, 1688, 964, 6734, 264, 600, 94, 62, 88, 5,
193 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 193 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
194 }, 194 },
195 195
196 [FIRST_NATIVE_MODE_INDEX] = 196 [FIRST_NATIVE_MODE_INDEX] =
197 /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */ 197 /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */
198 { 198 {
199 /* 480if */ 199 /* 480if */
200 "480if", 60, 720, 480, 74074, 58, 17, 30, 9, 63, 6, 200 "480if", 60, 720, 480, 74074, 58, 17, 30, 9, 63, 6,
201 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 201 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
202 }, { 202 }, {
203 /* 480pf */ 203 /* 480pf */
204 "480pf", 60, 720, 480, 37037, 58, 17, 30, 9, 63, 6, 204 "480pf", 60, 720, 480, 37037, 58, 17, 30, 9, 63, 6,
205 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 205 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
206 }, { 206 }, {
207 /* 720pf */ 207 /* 720pf */
208 "720pf", 60, 1280, 720, 13481, 220, 70, 19, 6, 80, 5, 208 "720pf", 60, 1280, 720, 13481, 220, 70, 19, 6, 80, 5,
209 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 209 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
210 }, { 210 }, {
211 /* 1080if */ 211 /* 1080if */
212 "1080if", 60, 1920, 1080, 13481, 148, 44, 36, 4, 88, 5, 212 "1080if", 60, 1920, 1080, 13481, 148, 44, 36, 4, 88, 5,
213 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 213 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
214 }, { 214 }, {
215 /* 1080pf */ 215 /* 1080pf */
216 "1080pf", 60, 1920, 1080, 6741, 148, 44, 36, 4, 88, 5, 216 "1080pf", 60, 1920, 1080, 6741, 148, 44, 36, 4, 88, 5,
217 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 217 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
218 }, 218 },
219 219
220 /* 50 Hz broadcast modes (full resolution versions of modes "6" to "10") */ 220 /* 50 Hz broadcast modes (full resolution versions of modes "6" to "10") */
221 { 221 {
222 /* 576if */ 222 /* 576if */
223 "576if", 50, 720, 576, 74074, 70, 11, 39, 5, 63, 5, 223 "576if", 50, 720, 576, 74074, 70, 11, 39, 5, 63, 5,
224 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 224 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
225 }, { 225 }, {
226 /* 576pf */ 226 /* 576pf */
227 "576pf", 50, 720, 576, 37037, 70, 11, 39, 5, 63, 5, 227 "576pf", 50, 720, 576, 37037, 70, 11, 39, 5, 63, 5,
228 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 228 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
229 }, { 229 }, {
230 /* 720pf */ 230 /* 720pf */
231 "720pf", 50, 1280, 720, 13468, 220, 400, 19, 6, 80, 5, 231 "720pf", 50, 1280, 720, 13468, 220, 400, 19, 6, 80, 5,
232 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 232 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
233 }, { 233 }, {
234 /* 1080if */ 234 /* 1080if */
235 "1080if", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5, 235 "1080if", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5,
236 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED 236 FB_SYNC_BROADCAST, FB_VMODE_INTERLACED
237 }, { 237 }, {
238 /* 1080pf */ 238 /* 1080pf */
239 "1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5, 239 "1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5,
240 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED 240 FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
241 }, 241 },
242 242
243 /* VESA modes (modes "11" to "13") */ 243 /* VESA modes (modes "11" to "13") */
244 { 244 {
245 /* WXGA */ 245 /* WXGA */
246 "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6, 246 "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
247 0, FB_VMODE_NONINTERLACED, 247 0, FB_VMODE_NONINTERLACED,
248 FB_MODE_IS_VESA 248 FB_MODE_IS_VESA
249 }, { 249 }, {
250 /* SXGA */ 250 /* SXGA */
251 "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, 251 "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, 252 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
253 FB_MODE_IS_VESA 253 FB_MODE_IS_VESA
254 }, { 254 }, {
255 /* WUXGA */ 255 /* WUXGA */
256 "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6, 256 "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
257 FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, 257 FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
258 FB_MODE_IS_VESA 258 FB_MODE_IS_VESA
259 } 259 }
260 }; 260 };
261 261
262 262
263 #define HEAD_A 263 #define HEAD_A
264 #define HEAD_B 264 #define HEAD_B
265 265
266 #define BPP 4 /* number of bytes per pixel */ 266 #define BPP 4 /* number of bytes per pixel */
267 267
268 268
269 static int ps3fb_mode; 269 static int ps3fb_mode;
270 module_param(ps3fb_mode, int, 0); 270 module_param(ps3fb_mode, int, 0);
271 271
272 static char *mode_option __devinitdata; 272 static char *mode_option __devinitdata;
273 273
274 static int ps3fb_cmp_mode(const struct fb_videomode *vmode, 274 static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
275 const struct fb_var_screeninfo *var) 275 const struct fb_var_screeninfo *var)
276 { 276 {
277 long xres, yres, left_margin, right_margin, upper_margin, lower_margin; 277 long xres, yres, left_margin, right_margin, upper_margin, lower_margin;
278 long dx, dy; 278 long dx, dy;
279 279
280 /* maximum values */ 280 /* maximum values */
281 if (var->xres > vmode->xres || var->yres > vmode->yres || 281 if (var->xres > vmode->xres || var->yres > vmode->yres ||
282 var->pixclock > vmode->pixclock || 282 var->pixclock > vmode->pixclock ||
283 var->hsync_len > vmode->hsync_len || 283 var->hsync_len > vmode->hsync_len ||
284 var->vsync_len > vmode->vsync_len) 284 var->vsync_len > vmode->vsync_len)
285 return -1; 285 return -1;
286 286
287 /* progressive/interlaced must match */ 287 /* progressive/interlaced must match */
288 if ((var->vmode & FB_VMODE_MASK) != vmode->vmode) 288 if ((var->vmode & FB_VMODE_MASK) != vmode->vmode)
289 return -1; 289 return -1;
290 290
291 /* minimum resolution */ 291 /* minimum resolution */
292 xres = max(var->xres, 1U); 292 xres = max(var->xres, 1U);
293 yres = max(var->yres, 1U); 293 yres = max(var->yres, 1U);
294 294
295 /* minimum margins */ 295 /* minimum margins */
296 left_margin = max(var->left_margin, vmode->left_margin); 296 left_margin = max(var->left_margin, vmode->left_margin);
297 right_margin = max(var->right_margin, vmode->right_margin); 297 right_margin = max(var->right_margin, vmode->right_margin);
298 upper_margin = max(var->upper_margin, vmode->upper_margin); 298 upper_margin = max(var->upper_margin, vmode->upper_margin);
299 lower_margin = max(var->lower_margin, vmode->lower_margin); 299 lower_margin = max(var->lower_margin, vmode->lower_margin);
300 300
301 /* resolution + margins may not exceed native parameters */ 301 /* resolution + margins may not exceed native parameters */
302 dx = ((long)vmode->left_margin + (long)vmode->xres + 302 dx = ((long)vmode->left_margin + (long)vmode->xres +
303 (long)vmode->right_margin) - 303 (long)vmode->right_margin) -
304 (left_margin + xres + right_margin); 304 (left_margin + xres + right_margin);
305 if (dx < 0) 305 if (dx < 0)
306 return -1; 306 return -1;
307 307
308 dy = ((long)vmode->upper_margin + (long)vmode->yres + 308 dy = ((long)vmode->upper_margin + (long)vmode->yres +
309 (long)vmode->lower_margin) - 309 (long)vmode->lower_margin) -
310 (upper_margin + yres + lower_margin); 310 (upper_margin + yres + lower_margin);
311 if (dy < 0) 311 if (dy < 0)
312 return -1; 312 return -1;
313 313
314 /* exact match */ 314 /* exact match */
315 if (!dx && !dy) 315 if (!dx && !dy)
316 return 0; 316 return 0;
317 317
318 /* resolution difference */ 318 /* resolution difference */
319 return (vmode->xres - xres) * (vmode->yres - yres); 319 return (vmode->xres - xres) * (vmode->yres - yres);
320 } 320 }
321 321
322 static const struct fb_videomode *ps3fb_native_vmode(enum ps3av_mode_num id) 322 static const struct fb_videomode *ps3fb_native_vmode(enum ps3av_mode_num id)
323 { 323 {
324 return &ps3fb_modedb[FIRST_NATIVE_MODE_INDEX + id - 1]; 324 return &ps3fb_modedb[FIRST_NATIVE_MODE_INDEX + id - 1];
325 } 325 }
326 326
327 static const struct fb_videomode *ps3fb_vmode(int id) 327 static const struct fb_videomode *ps3fb_vmode(int id)
328 { 328 {
329 u32 mode = id & PS3AV_MODE_MASK; 329 u32 mode = id & PS3AV_MODE_MASK;
330 330
331 if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA) 331 if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA)
332 return NULL; 332 return NULL;
333 333
334 if (mode <= PS3AV_MODE_1080P50 && !(id & PS3AV_MODE_FULL)) { 334 if (mode <= PS3AV_MODE_1080P50 && !(id & PS3AV_MODE_FULL)) {
335 /* Non-fullscreen broadcast mode */ 335 /* Non-fullscreen broadcast mode */
336 return &ps3fb_modedb[mode - 1]; 336 return &ps3fb_modedb[mode - 1];
337 } 337 }
338 338
339 return ps3fb_native_vmode(mode); 339 return ps3fb_native_vmode(mode);
340 } 340 }
341 341
342 static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var, 342 static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var,
343 u32 *ddr_line_length, u32 *xdr_line_length) 343 u32 *ddr_line_length, u32 *xdr_line_length)
344 { 344 {
345 unsigned int id, best_id; 345 unsigned int id, best_id;
346 int diff, best_diff; 346 int diff, best_diff;
347 const struct fb_videomode *vmode; 347 const struct fb_videomode *vmode;
348 long gap; 348 long gap;
349 349
350 best_id = 0; 350 best_id = 0;
351 best_diff = INT_MAX; 351 best_diff = INT_MAX;
352 pr_debug("%s: wanted %u [%u] %u x %u [%u] %u\n", __func__, 352 pr_debug("%s: wanted %u [%u] %u x %u [%u] %u\n", __func__,
353 var->left_margin, var->xres, var->right_margin, 353 var->left_margin, var->xres, var->right_margin,
354 var->upper_margin, var->yres, var->lower_margin); 354 var->upper_margin, var->yres, var->lower_margin);
355 for (id = PS3AV_MODE_480I; id <= PS3AV_MODE_WUXGA; id++) { 355 for (id = PS3AV_MODE_480I; id <= PS3AV_MODE_WUXGA; id++) {
356 vmode = ps3fb_native_vmode(id); 356 vmode = ps3fb_native_vmode(id);
357 diff = ps3fb_cmp_mode(vmode, var); 357 diff = ps3fb_cmp_mode(vmode, var);
358 pr_debug("%s: mode %u: %u [%u] %u x %u [%u] %u: diff = %d\n", 358 pr_debug("%s: mode %u: %u [%u] %u x %u [%u] %u: diff = %d\n",
359 __func__, id, vmode->left_margin, vmode->xres, 359 __func__, id, vmode->left_margin, vmode->xres,
360 vmode->right_margin, vmode->upper_margin, 360 vmode->right_margin, vmode->upper_margin,
361 vmode->yres, vmode->lower_margin, diff); 361 vmode->yres, vmode->lower_margin, diff);
362 if (diff < 0) 362 if (diff < 0)
363 continue; 363 continue;
364 if (diff < best_diff) { 364 if (diff < best_diff) {
365 best_id = id; 365 best_id = id;
366 if (!diff) 366 if (!diff)
367 break; 367 break;
368 best_diff = diff; 368 best_diff = diff;
369 } 369 }
370 } 370 }
371 371
372 if (!best_id) { 372 if (!best_id) {
373 pr_debug("%s: no suitable mode found\n", __func__); 373 pr_debug("%s: no suitable mode found\n", __func__);
374 return 0; 374 return 0;
375 } 375 }
376 376
377 id = best_id; 377 id = best_id;
378 vmode = ps3fb_native_vmode(id); 378 vmode = ps3fb_native_vmode(id);
379 379
380 *ddr_line_length = vmode->xres * BPP; 380 *ddr_line_length = vmode->xres * BPP;
381 381
382 /* minimum resolution */ 382 /* minimum resolution */
383 if (!var->xres) 383 if (!var->xres)
384 var->xres = 1; 384 var->xres = 1;
385 if (!var->yres) 385 if (!var->yres)
386 var->yres = 1; 386 var->yres = 1;
387 387
388 /* minimum virtual resolution */ 388 /* minimum virtual resolution */
389 if (var->xres_virtual < var->xres) 389 if (var->xres_virtual < var->xres)
390 var->xres_virtual = var->xres; 390 var->xres_virtual = var->xres;
391 if (var->yres_virtual < var->yres) 391 if (var->yres_virtual < var->yres)
392 var->yres_virtual = var->yres; 392 var->yres_virtual = var->yres;
393 393
394 /* minimum margins */ 394 /* minimum margins */
395 if (var->left_margin < vmode->left_margin) 395 if (var->left_margin < vmode->left_margin)
396 var->left_margin = vmode->left_margin; 396 var->left_margin = vmode->left_margin;
397 if (var->right_margin < vmode->right_margin) 397 if (var->right_margin < vmode->right_margin)
398 var->right_margin = vmode->right_margin; 398 var->right_margin = vmode->right_margin;
399 if (var->upper_margin < vmode->upper_margin) 399 if (var->upper_margin < vmode->upper_margin)
400 var->upper_margin = vmode->upper_margin; 400 var->upper_margin = vmode->upper_margin;
401 if (var->lower_margin < vmode->lower_margin) 401 if (var->lower_margin < vmode->lower_margin)
402 var->lower_margin = vmode->lower_margin; 402 var->lower_margin = vmode->lower_margin;
403 403
404 /* extra margins */ 404 /* extra margins */
405 gap = ((long)vmode->left_margin + (long)vmode->xres + 405 gap = ((long)vmode->left_margin + (long)vmode->xres +
406 (long)vmode->right_margin) - 406 (long)vmode->right_margin) -
407 ((long)var->left_margin + (long)var->xres + 407 ((long)var->left_margin + (long)var->xres +
408 (long)var->right_margin); 408 (long)var->right_margin);
409 if (gap > 0) { 409 if (gap > 0) {
410 var->left_margin += gap/2; 410 var->left_margin += gap/2;
411 var->right_margin += (gap+1)/2; 411 var->right_margin += (gap+1)/2;
412 pr_debug("%s: rounded up H to %u [%u] %u\n", __func__, 412 pr_debug("%s: rounded up H to %u [%u] %u\n", __func__,
413 var->left_margin, var->xres, var->right_margin); 413 var->left_margin, var->xres, var->right_margin);
414 } 414 }
415 415
416 gap = ((long)vmode->upper_margin + (long)vmode->yres + 416 gap = ((long)vmode->upper_margin + (long)vmode->yres +
417 (long)vmode->lower_margin) - 417 (long)vmode->lower_margin) -
418 ((long)var->upper_margin + (long)var->yres + 418 ((long)var->upper_margin + (long)var->yres +
419 (long)var->lower_margin); 419 (long)var->lower_margin);
420 if (gap > 0) { 420 if (gap > 0) {
421 var->upper_margin += gap/2; 421 var->upper_margin += gap/2;
422 var->lower_margin += (gap+1)/2; 422 var->lower_margin += (gap+1)/2;
423 pr_debug("%s: rounded up V to %u [%u] %u\n", __func__, 423 pr_debug("%s: rounded up V to %u [%u] %u\n", __func__,
424 var->upper_margin, var->yres, var->lower_margin); 424 var->upper_margin, var->yres, var->lower_margin);
425 } 425 }
426 426
427 /* fixed fields */ 427 /* fixed fields */
428 var->pixclock = vmode->pixclock; 428 var->pixclock = vmode->pixclock;
429 var->hsync_len = vmode->hsync_len; 429 var->hsync_len = vmode->hsync_len;
430 var->vsync_len = vmode->vsync_len; 430 var->vsync_len = vmode->vsync_len;
431 var->sync = vmode->sync; 431 var->sync = vmode->sync;
432 432
433 if (ps3_compare_firmware_version(1, 9, 0) >= 0) { 433 if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
434 *xdr_line_length = GPU_ALIGN_UP(var->xres_virtual * BPP); 434 *xdr_line_length = GPU_ALIGN_UP(var->xres_virtual * BPP);
435 if (*xdr_line_length > GPU_MAX_LINE_LENGTH) 435 if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
436 *xdr_line_length = GPU_MAX_LINE_LENGTH; 436 *xdr_line_length = GPU_MAX_LINE_LENGTH;
437 } else 437 } else
438 *xdr_line_length = *ddr_line_length; 438 *xdr_line_length = *ddr_line_length;
439 439
440 if (vmode->sync & FB_SYNC_BROADCAST) { 440 if (vmode->sync & FB_SYNC_BROADCAST) {
441 /* Full broadcast modes have the full mode bit set */ 441 /* Full broadcast modes have the full mode bit set */
442 if (vmode->xres == var->xres && vmode->yres == var->yres) 442 if (vmode->xres == var->xres && vmode->yres == var->yres)
443 id |= PS3AV_MODE_FULL; 443 id |= PS3AV_MODE_FULL;
444 } 444 }
445 445
446 pr_debug("%s: mode %u\n", __func__, id); 446 pr_debug("%s: mode %u\n", __func__, id);
447 return id; 447 return id;
448 } 448 }
449 449
450 static void ps3fb_sync_image(struct device *dev, u64 frame_offset, 450 static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
451 u64 dst_offset, u64 src_offset, u32 width, 451 u64 dst_offset, u64 src_offset, u32 width,
452 u32 height, u32 dst_line_length, 452 u32 height, u32 dst_line_length,
453 u32 src_line_length) 453 u32 src_line_length)
454 { 454 {
455 int status; 455 int status;
456 u64 line_length; 456 u64 line_length;
457 457
458 line_length = dst_line_length; 458 line_length = dst_line_length;
459 if (src_line_length != dst_line_length) 459 if (src_line_length != dst_line_length)
460 line_length |= (u64)src_line_length << 32; 460 line_length |= (u64)src_line_length << 32;
461 461
462 src_offset += GPU_FB_START; 462 src_offset += GPU_FB_START;
463
464 mutex_lock(&ps3_gpu_mutex);
463 status = lv1_gpu_context_attribute(ps3fb.context_handle, 465 status = lv1_gpu_context_attribute(ps3fb.context_handle,
464 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 466 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
465 dst_offset, GPU_IOIF + src_offset, 467 dst_offset, GPU_IOIF + src_offset,
466 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | 468 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
467 (width << 16) | height, 469 (width << 16) | height,
468 line_length); 470 line_length);
471 mutex_unlock(&ps3_gpu_mutex);
472
469 if (status) 473 if (status)
470 dev_err(dev, 474 dev_err(dev,
471 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", 475 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
472 __func__, status); 476 __func__, status);
473 #ifdef HEAD_A 477 #ifdef HEAD_A
474 status = lv1_gpu_context_attribute(ps3fb.context_handle, 478 status = lv1_gpu_context_attribute(ps3fb.context_handle,
475 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 479 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
476 0, frame_offset, 0, 0); 480 0, frame_offset, 0, 0);
477 if (status) 481 if (status)
478 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 482 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
479 __func__, status); 483 __func__, status);
480 #endif 484 #endif
481 #ifdef HEAD_B 485 #ifdef HEAD_B
482 status = lv1_gpu_context_attribute(ps3fb.context_handle, 486 status = lv1_gpu_context_attribute(ps3fb.context_handle,
483 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 487 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
484 1, frame_offset, 0, 0); 488 1, frame_offset, 0, 0);
485 if (status) 489 if (status)
486 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 490 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
487 __func__, status); 491 __func__, status);
488 #endif 492 #endif
489 } 493 }
490 494
491 static int ps3fb_sync(struct fb_info *info, u32 frame) 495 static int ps3fb_sync(struct fb_info *info, u32 frame)
492 { 496 {
493 struct ps3fb_par *par = info->par; 497 struct ps3fb_par *par = info->par;
494 int error = 0; 498 int error = 0;
495 u64 ddr_base, xdr_base; 499 u64 ddr_base, xdr_base;
496 500
497 if (frame > par->num_frames - 1) { 501 if (frame > par->num_frames - 1) {
498 dev_dbg(info->device, "%s: invalid frame number (%u)\n", 502 dev_dbg(info->device, "%s: invalid frame number (%u)\n",
499 __func__, frame); 503 __func__, frame);
500 error = -EINVAL; 504 error = -EINVAL;
501 goto out; 505 goto out;
502 } 506 }
503 507
504 xdr_base = frame * par->xdr_frame_size; 508 xdr_base = frame * par->xdr_frame_size;
505 ddr_base = frame * par->ddr_frame_size; 509 ddr_base = frame * par->ddr_frame_size;
506 510
507 ps3fb_sync_image(info->device, ddr_base + par->full_offset, 511 ps3fb_sync_image(info->device, ddr_base + par->full_offset,
508 ddr_base + par->fb_offset, xdr_base + par->pan_offset, 512 ddr_base + par->fb_offset, xdr_base + par->pan_offset,
509 par->width, par->height, par->ddr_line_length, 513 par->width, par->height, par->ddr_line_length,
510 info->fix.line_length); 514 info->fix.line_length);
511 515
512 out: 516 out:
513 return error; 517 return error;
514 } 518 }
515 519
516 static int ps3fb_open(struct fb_info *info, int user) 520 static int ps3fb_open(struct fb_info *info, int user)
517 { 521 {
518 atomic_inc(&ps3fb.f_count); 522 atomic_inc(&ps3fb.f_count);
519 return 0; 523 return 0;
520 } 524 }
521 525
522 static int ps3fb_release(struct fb_info *info, int user) 526 static int ps3fb_release(struct fb_info *info, int user)
523 { 527 {
524 if (atomic_dec_and_test(&ps3fb.f_count)) { 528 if (atomic_dec_and_test(&ps3fb.f_count)) {
525 if (atomic_read(&ps3fb.ext_flip)) { 529 if (atomic_read(&ps3fb.ext_flip)) {
526 atomic_set(&ps3fb.ext_flip, 0); 530 atomic_set(&ps3fb.ext_flip, 0);
527 if (!try_acquire_console_sem()) { 531 if (!try_acquire_console_sem()) {
528 ps3fb_sync(info, 0); /* single buffer */ 532 ps3fb_sync(info, 0); /* single buffer */
529 release_console_sem(); 533 release_console_sem();
530 } 534 }
531 } 535 }
532 } 536 }
533 return 0; 537 return 0;
534 } 538 }
535 539
536 /* 540 /*
537 * Setting the video mode has been split into two parts. 541 * Setting the video mode has been split into two parts.
538 * First part, xxxfb_check_var, must not write anything 542 * First part, xxxfb_check_var, must not write anything
539 * to hardware, it should only verify and adjust var. 543 * to hardware, it should only verify and adjust var.
540 * This means it doesn't alter par but it does use hardware 544 * This means it doesn't alter par but it does use hardware
541 * data from it to check this var. 545 * data from it to check this var.
542 */ 546 */
543 547
544 static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 548 static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
545 { 549 {
546 u32 xdr_line_length, ddr_line_length; 550 u32 xdr_line_length, ddr_line_length;
547 int mode; 551 int mode;
548 552
549 mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length); 553 mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
550 if (!mode) 554 if (!mode)
551 return -EINVAL; 555 return -EINVAL;
552 556
553 /* Virtual screen */ 557 /* Virtual screen */
554 if (var->xres_virtual > xdr_line_length / BPP) { 558 if (var->xres_virtual > xdr_line_length / BPP) {
555 dev_dbg(info->device, 559 dev_dbg(info->device,
556 "Horizontal virtual screen size too large\n"); 560 "Horizontal virtual screen size too large\n");
557 return -EINVAL; 561 return -EINVAL;
558 } 562 }
559 563
560 if (var->xoffset + var->xres > var->xres_virtual || 564 if (var->xoffset + var->xres > var->xres_virtual ||
561 var->yoffset + var->yres > var->yres_virtual) { 565 var->yoffset + var->yres > var->yres_virtual) {
562 dev_dbg(info->device, "panning out-of-range\n"); 566 dev_dbg(info->device, "panning out-of-range\n");
563 return -EINVAL; 567 return -EINVAL;
564 } 568 }
565 569
566 /* We support ARGB8888 only */ 570 /* We support ARGB8888 only */
567 if (var->bits_per_pixel > 32 || var->grayscale || 571 if (var->bits_per_pixel > 32 || var->grayscale ||
568 var->red.offset > 16 || var->green.offset > 8 || 572 var->red.offset > 16 || var->green.offset > 8 ||
569 var->blue.offset > 0 || var->transp.offset > 24 || 573 var->blue.offset > 0 || var->transp.offset > 24 ||
570 var->red.length > 8 || var->green.length > 8 || 574 var->red.length > 8 || var->green.length > 8 ||
571 var->blue.length > 8 || var->transp.length > 8 || 575 var->blue.length > 8 || var->transp.length > 8 ||
572 var->red.msb_right || var->green.msb_right || 576 var->red.msb_right || var->green.msb_right ||
573 var->blue.msb_right || var->transp.msb_right || var->nonstd) { 577 var->blue.msb_right || var->transp.msb_right || var->nonstd) {
574 dev_dbg(info->device, "We support ARGB8888 only\n"); 578 dev_dbg(info->device, "We support ARGB8888 only\n");
575 return -EINVAL; 579 return -EINVAL;
576 } 580 }
577 581
578 var->bits_per_pixel = 32; 582 var->bits_per_pixel = 32;
579 var->red.offset = 16; 583 var->red.offset = 16;
580 var->green.offset = 8; 584 var->green.offset = 8;
581 var->blue.offset = 0; 585 var->blue.offset = 0;
582 var->transp.offset = 24; 586 var->transp.offset = 24;
583 var->red.length = 8; 587 var->red.length = 8;
584 var->green.length = 8; 588 var->green.length = 8;
585 var->blue.length = 8; 589 var->blue.length = 8;
586 var->transp.length = 8; 590 var->transp.length = 8;
587 var->red.msb_right = 0; 591 var->red.msb_right = 0;
588 var->green.msb_right = 0; 592 var->green.msb_right = 0;
589 var->blue.msb_right = 0; 593 var->blue.msb_right = 0;
590 var->transp.msb_right = 0; 594 var->transp.msb_right = 0;
591 595
592 /* Rotation is not supported */ 596 /* Rotation is not supported */
593 if (var->rotate) { 597 if (var->rotate) {
594 dev_dbg(info->device, "Rotation is not supported\n"); 598 dev_dbg(info->device, "Rotation is not supported\n");
595 return -EINVAL; 599 return -EINVAL;
596 } 600 }
597 601
598 /* Memory limit */ 602 /* Memory limit */
599 if (var->yres_virtual * xdr_line_length > info->fix.smem_len) { 603 if (var->yres_virtual * xdr_line_length > info->fix.smem_len) {
600 dev_dbg(info->device, "Not enough memory\n"); 604 dev_dbg(info->device, "Not enough memory\n");
601 return -ENOMEM; 605 return -ENOMEM;
602 } 606 }
603 607
604 var->height = -1; 608 var->height = -1;
605 var->width = -1; 609 var->width = -1;
606 610
607 return 0; 611 return 0;
608 } 612 }
609 613
610 /* 614 /*
611 * This routine actually sets the video mode. 615 * This routine actually sets the video mode.
612 */ 616 */
613 617
614 static int ps3fb_set_par(struct fb_info *info) 618 static int ps3fb_set_par(struct fb_info *info)
615 { 619 {
616 struct ps3fb_par *par = info->par; 620 struct ps3fb_par *par = info->par;
617 unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines; 621 unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
618 unsigned int ddr_xoff, ddr_yoff, offset; 622 unsigned int ddr_xoff, ddr_yoff, offset;
619 const struct fb_videomode *vmode; 623 const struct fb_videomode *vmode;
620 u64 dst; 624 u64 dst;
621 625
622 mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length); 626 mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
623 if (!mode) 627 if (!mode)
624 return -EINVAL; 628 return -EINVAL;
625 629
626 vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK); 630 vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK);
627 631
628 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; 632 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
629 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; 633 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
630 info->fix.line_length = xdr_line_length; 634 info->fix.line_length = xdr_line_length;
631 635
632 par->ddr_line_length = ddr_line_length; 636 par->ddr_line_length = ddr_line_length;
633 par->ddr_frame_size = vmode->yres * ddr_line_length; 637 par->ddr_frame_size = vmode->yres * ddr_line_length;
634 par->xdr_frame_size = info->var.yres_virtual * xdr_line_length; 638 par->xdr_frame_size = info->var.yres_virtual * xdr_line_length;
635 639
636 par->num_frames = info->fix.smem_len / 640 par->num_frames = info->fix.smem_len /
637 max(par->ddr_frame_size, par->xdr_frame_size); 641 max(par->ddr_frame_size, par->xdr_frame_size);
638 642
639 /* Keep the special bits we cannot set using fb_var_screeninfo */ 643 /* Keep the special bits we cannot set using fb_var_screeninfo */
640 par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode; 644 par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
641 645
642 par->width = info->var.xres; 646 par->width = info->var.xres;
643 par->height = info->var.yres; 647 par->height = info->var.yres;
644 648
645 /* Start of the virtual frame buffer (relative to fullscreen) */ 649 /* Start of the virtual frame buffer (relative to fullscreen) */
646 ddr_xoff = info->var.left_margin - vmode->left_margin; 650 ddr_xoff = info->var.left_margin - vmode->left_margin;
647 ddr_yoff = info->var.upper_margin - vmode->upper_margin; 651 ddr_yoff = info->var.upper_margin - vmode->upper_margin;
648 offset = ddr_yoff * ddr_line_length + ddr_xoff * BPP; 652 offset = ddr_yoff * ddr_line_length + ddr_xoff * BPP;
649 653
650 par->fb_offset = GPU_ALIGN_UP(offset); 654 par->fb_offset = GPU_ALIGN_UP(offset);
651 par->full_offset = par->fb_offset - offset; 655 par->full_offset = par->fb_offset - offset;
652 par->pan_offset = info->var.yoffset * xdr_line_length + 656 par->pan_offset = info->var.yoffset * xdr_line_length +
653 info->var.xoffset * BPP; 657 info->var.xoffset * BPP;
654 658
655 if (par->new_mode_id != par->mode_id) { 659 if (par->new_mode_id != par->mode_id) {
656 if (ps3av_set_video_mode(par->new_mode_id)) { 660 if (ps3av_set_video_mode(par->new_mode_id)) {
657 par->new_mode_id = par->mode_id; 661 par->new_mode_id = par->mode_id;
658 return -EINVAL; 662 return -EINVAL;
659 } 663 }
660 par->mode_id = par->new_mode_id; 664 par->mode_id = par->new_mode_id;
661 } 665 }
662 666
663 /* Clear XDR frame buffer memory */ 667 /* Clear XDR frame buffer memory */
664 memset((void __force *)info->screen_base, 0, info->fix.smem_len); 668 memset((void __force *)info->screen_base, 0, info->fix.smem_len);
665 669
666 /* Clear DDR frame buffer memory */ 670 /* Clear DDR frame buffer memory */
667 lines = vmode->yres * par->num_frames; 671 lines = vmode->yres * par->num_frames;
668 if (par->full_offset) 672 if (par->full_offset)
669 lines++; 673 lines++;
670 maxlines = info->fix.smem_len / ddr_line_length; 674 maxlines = info->fix.smem_len / ddr_line_length;
671 for (dst = 0; lines; dst += maxlines * ddr_line_length) { 675 for (dst = 0; lines; dst += maxlines * ddr_line_length) {
672 unsigned int l = min(lines, maxlines); 676 unsigned int l = min(lines, maxlines);
673 ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l, 677 ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l,
674 ddr_line_length, ddr_line_length); 678 ddr_line_length, ddr_line_length);
675 lines -= l; 679 lines -= l;
676 } 680 }
677 681
678 return 0; 682 return 0;
679 } 683 }
680 684
681 /* 685 /*
682 * Set a single color register. The values supplied are already 686 * Set a single color register. The values supplied are already
683 * rounded down to the hardware's capabilities (according to the 687 * rounded down to the hardware's capabilities (according to the
684 * entries in the var structure). Return != 0 for invalid regno. 688 * entries in the var structure). Return != 0 for invalid regno.
685 */ 689 */
686 690
687 static int ps3fb_setcolreg(unsigned int regno, unsigned int red, 691 static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
688 unsigned int green, unsigned int blue, 692 unsigned int green, unsigned int blue,
689 unsigned int transp, struct fb_info *info) 693 unsigned int transp, struct fb_info *info)
690 { 694 {
691 if (regno >= 16) 695 if (regno >= 16)
692 return 1; 696 return 1;
693 697
694 red >>= 8; 698 red >>= 8;
695 green >>= 8; 699 green >>= 8;
696 blue >>= 8; 700 blue >>= 8;
697 transp >>= 8; 701 transp >>= 8;
698 702
699 ((u32 *)info->pseudo_palette)[regno] = transp << 24 | red << 16 | 703 ((u32 *)info->pseudo_palette)[regno] = transp << 24 | red << 16 |
700 green << 8 | blue; 704 green << 8 | blue;
701 return 0; 705 return 0;
702 } 706 }
703 707
704 static int ps3fb_pan_display(struct fb_var_screeninfo *var, 708 static int ps3fb_pan_display(struct fb_var_screeninfo *var,
705 struct fb_info *info) 709 struct fb_info *info)
706 { 710 {
707 struct ps3fb_par *par = info->par; 711 struct ps3fb_par *par = info->par;
708 712
709 par->pan_offset = var->yoffset * info->fix.line_length + 713 par->pan_offset = var->yoffset * info->fix.line_length +
710 var->xoffset * BPP; 714 var->xoffset * BPP;
711 return 0; 715 return 0;
712 } 716 }
713 717
714 /* 718 /*
715 * As we have a virtual frame buffer, we need our own mmap function 719 * As we have a virtual frame buffer, we need our own mmap function
716 */ 720 */
717 721
718 static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 722 static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
719 { 723 {
720 unsigned long size, offset; 724 unsigned long size, offset;
721 725
722 size = vma->vm_end - vma->vm_start; 726 size = vma->vm_end - vma->vm_start;
723 offset = vma->vm_pgoff << PAGE_SHIFT; 727 offset = vma->vm_pgoff << PAGE_SHIFT;
724 if (offset + size > info->fix.smem_len) 728 if (offset + size > info->fix.smem_len)
725 return -EINVAL; 729 return -EINVAL;
726 730
727 offset += info->fix.smem_start; 731 offset += info->fix.smem_start;
728 if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, 732 if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
729 size, vma->vm_page_prot)) 733 size, vma->vm_page_prot))
730 return -EAGAIN; 734 return -EAGAIN;
731 735
732 dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", 736 dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
733 offset, vma->vm_start); 737 offset, vma->vm_start);
734 return 0; 738 return 0;
735 } 739 }
736 740
737 /* 741 /*
738 * Blank the display 742 * Blank the display
739 */ 743 */
740 744
741 static int ps3fb_blank(int blank, struct fb_info *info) 745 static int ps3fb_blank(int blank, struct fb_info *info)
742 { 746 {
743 int retval; 747 int retval;
744 748
745 dev_dbg(info->device, "%s: blank:%d\n", __func__, blank); 749 dev_dbg(info->device, "%s: blank:%d\n", __func__, blank);
746 switch (blank) { 750 switch (blank) {
747 case FB_BLANK_POWERDOWN: 751 case FB_BLANK_POWERDOWN:
748 case FB_BLANK_HSYNC_SUSPEND: 752 case FB_BLANK_HSYNC_SUSPEND:
749 case FB_BLANK_VSYNC_SUSPEND: 753 case FB_BLANK_VSYNC_SUSPEND:
750 case FB_BLANK_NORMAL: 754 case FB_BLANK_NORMAL:
751 retval = ps3av_video_mute(1); /* mute on */ 755 retval = ps3av_video_mute(1); /* mute on */
752 if (!retval) 756 if (!retval)
753 ps3fb.is_blanked = 1; 757 ps3fb.is_blanked = 1;
754 break; 758 break;
755 759
756 default: /* unblank */ 760 default: /* unblank */
757 retval = ps3av_video_mute(0); /* mute off */ 761 retval = ps3av_video_mute(0); /* mute off */
758 if (!retval) 762 if (!retval)
759 ps3fb.is_blanked = 0; 763 ps3fb.is_blanked = 0;
760 break; 764 break;
761 } 765 }
762 return retval; 766 return retval;
763 } 767 }
764 768
765 static int ps3fb_get_vblank(struct fb_vblank *vblank) 769 static int ps3fb_get_vblank(struct fb_vblank *vblank)
766 { 770 {
767 memset(vblank, 0, sizeof(*vblank)); 771 memset(vblank, 0, sizeof(*vblank));
768 vblank->flags = FB_VBLANK_HAVE_VSYNC; 772 vblank->flags = FB_VBLANK_HAVE_VSYNC;
769 return 0; 773 return 0;
770 } 774 }
771 775
772 static int ps3fb_wait_for_vsync(u32 crtc) 776 static int ps3fb_wait_for_vsync(u32 crtc)
773 { 777 {
774 int ret; 778 int ret;
775 u64 count; 779 u64 count;
776 780
777 count = ps3fb.vblank_count; 781 count = ps3fb.vblank_count;
778 ret = wait_event_interruptible_timeout(ps3fb.wait_vsync, 782 ret = wait_event_interruptible_timeout(ps3fb.wait_vsync,
779 count != ps3fb.vblank_count, 783 count != ps3fb.vblank_count,
780 HZ / 10); 784 HZ / 10);
781 if (!ret) 785 if (!ret)
782 return -ETIMEDOUT; 786 return -ETIMEDOUT;
783 787
784 return 0; 788 return 0;
785 } 789 }
786 790
787 static void ps3fb_flip_ctl(int on, void *data)
788 {
789 struct ps3fb_priv *priv = data;
790 if (on)
791 atomic_dec_if_positive(&priv->ext_flip);
792 else
793 atomic_inc(&priv->ext_flip);
794 }
795 791
796
797 /* 792 /*
798 * ioctl 793 * ioctl
799 */ 794 */
800 795
801 static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, 796 static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
802 unsigned long arg) 797 unsigned long arg)
803 { 798 {
804 void __user *argp = (void __user *)arg; 799 void __user *argp = (void __user *)arg;
805 u32 val; 800 u32 val;
806 int retval = -EFAULT; 801 int retval = -EFAULT;
807 802
808 switch (cmd) { 803 switch (cmd) {
809 case FBIOGET_VBLANK: 804 case FBIOGET_VBLANK:
810 { 805 {
811 struct fb_vblank vblank; 806 struct fb_vblank vblank;
812 dev_dbg(info->device, "FBIOGET_VBLANK:\n"); 807 dev_dbg(info->device, "FBIOGET_VBLANK:\n");
813 retval = ps3fb_get_vblank(&vblank); 808 retval = ps3fb_get_vblank(&vblank);
814 if (retval) 809 if (retval)
815 break; 810 break;
816 811
817 if (copy_to_user(argp, &vblank, sizeof(vblank))) 812 if (copy_to_user(argp, &vblank, sizeof(vblank)))
818 retval = -EFAULT; 813 retval = -EFAULT;
819 break; 814 break;
820 } 815 }
821 816
822 case FBIO_WAITFORVSYNC: 817 case FBIO_WAITFORVSYNC:
823 { 818 {
824 u32 crt; 819 u32 crt;
825 dev_dbg(info->device, "FBIO_WAITFORVSYNC:\n"); 820 dev_dbg(info->device, "FBIO_WAITFORVSYNC:\n");
826 if (get_user(crt, (u32 __user *) arg)) 821 if (get_user(crt, (u32 __user *) arg))
827 break; 822 break;
828 823
829 retval = ps3fb_wait_for_vsync(crt); 824 retval = ps3fb_wait_for_vsync(crt);
830 break; 825 break;
831 } 826 }
832 827
833 case PS3FB_IOCTL_SETMODE: 828 case PS3FB_IOCTL_SETMODE:
834 { 829 {
835 struct ps3fb_par *par = info->par; 830 struct ps3fb_par *par = info->par;
836 const struct fb_videomode *vmode; 831 const struct fb_videomode *vmode;
837 struct fb_var_screeninfo var; 832 struct fb_var_screeninfo var;
838 833
839 if (copy_from_user(&val, argp, sizeof(val))) 834 if (copy_from_user(&val, argp, sizeof(val)))
840 break; 835 break;
841 836
842 if (!(val & PS3AV_MODE_MASK)) { 837 if (!(val & PS3AV_MODE_MASK)) {
843 u32 id = ps3av_get_auto_mode(); 838 u32 id = ps3av_get_auto_mode();
844 if (id > 0) 839 if (id > 0)
845 val = (val & ~PS3AV_MODE_MASK) | id; 840 val = (val & ~PS3AV_MODE_MASK) | id;
846 } 841 }
847 dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val); 842 dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
848 retval = -EINVAL; 843 retval = -EINVAL;
849 vmode = ps3fb_vmode(val); 844 vmode = ps3fb_vmode(val);
850 if (vmode) { 845 if (vmode) {
851 var = info->var; 846 var = info->var;
852 fb_videomode_to_var(&var, vmode); 847 fb_videomode_to_var(&var, vmode);
853 acquire_console_sem(); 848 acquire_console_sem();
854 info->flags |= FBINFO_MISC_USEREVENT; 849 info->flags |= FBINFO_MISC_USEREVENT;
855 /* Force, in case only special bits changed */ 850 /* Force, in case only special bits changed */
856 var.activate |= FB_ACTIVATE_FORCE; 851 var.activate |= FB_ACTIVATE_FORCE;
857 par->new_mode_id = val; 852 par->new_mode_id = val;
858 retval = fb_set_var(info, &var); 853 retval = fb_set_var(info, &var);
859 info->flags &= ~FBINFO_MISC_USEREVENT; 854 info->flags &= ~FBINFO_MISC_USEREVENT;
860 release_console_sem(); 855 release_console_sem();
861 } 856 }
862 break; 857 break;
863 } 858 }
864 859
865 case PS3FB_IOCTL_GETMODE: 860 case PS3FB_IOCTL_GETMODE:
866 val = ps3av_get_mode(); 861 val = ps3av_get_mode();
867 dev_dbg(info->device, "PS3FB_IOCTL_GETMODE:%x\n", val); 862 dev_dbg(info->device, "PS3FB_IOCTL_GETMODE:%x\n", val);
868 if (!copy_to_user(argp, &val, sizeof(val))) 863 if (!copy_to_user(argp, &val, sizeof(val)))
869 retval = 0; 864 retval = 0;
870 break; 865 break;
871 866
872 case PS3FB_IOCTL_SCREENINFO: 867 case PS3FB_IOCTL_SCREENINFO:
873 { 868 {
874 struct ps3fb_par *par = info->par; 869 struct ps3fb_par *par = info->par;
875 struct ps3fb_ioctl_res res; 870 struct ps3fb_ioctl_res res;
876 dev_dbg(info->device, "PS3FB_IOCTL_SCREENINFO:\n"); 871 dev_dbg(info->device, "PS3FB_IOCTL_SCREENINFO:\n");
877 res.xres = info->fix.line_length / BPP; 872 res.xres = info->fix.line_length / BPP;
878 res.yres = info->var.yres_virtual; 873 res.yres = info->var.yres_virtual;
879 res.xoff = (res.xres - info->var.xres) / 2; 874 res.xoff = (res.xres - info->var.xres) / 2;
880 res.yoff = (res.yres - info->var.yres) / 2; 875 res.yoff = (res.yres - info->var.yres) / 2;
881 res.num_frames = par->num_frames; 876 res.num_frames = par->num_frames;
882 if (!copy_to_user(argp, &res, sizeof(res))) 877 if (!copy_to_user(argp, &res, sizeof(res)))
883 retval = 0; 878 retval = 0;
884 break; 879 break;
885 } 880 }
886 881
887 case PS3FB_IOCTL_ON: 882 case PS3FB_IOCTL_ON:
888 dev_dbg(info->device, "PS3FB_IOCTL_ON:\n"); 883 dev_dbg(info->device, "PS3FB_IOCTL_ON:\n");
889 atomic_inc(&ps3fb.ext_flip); 884 atomic_inc(&ps3fb.ext_flip);
890 retval = 0; 885 retval = 0;
891 break; 886 break;
892 887
893 case PS3FB_IOCTL_OFF: 888 case PS3FB_IOCTL_OFF:
894 dev_dbg(info->device, "PS3FB_IOCTL_OFF:\n"); 889 dev_dbg(info->device, "PS3FB_IOCTL_OFF:\n");
895 atomic_dec_if_positive(&ps3fb.ext_flip); 890 atomic_dec_if_positive(&ps3fb.ext_flip);
896 retval = 0; 891 retval = 0;
897 break; 892 break;
898 893
899 case PS3FB_IOCTL_FSEL: 894 case PS3FB_IOCTL_FSEL:
900 if (copy_from_user(&val, argp, sizeof(val))) 895 if (copy_from_user(&val, argp, sizeof(val)))
901 break; 896 break;
902 897
903 dev_dbg(info->device, "PS3FB_IOCTL_FSEL:%d\n", val); 898 dev_dbg(info->device, "PS3FB_IOCTL_FSEL:%d\n", val);
904 acquire_console_sem(); 899 acquire_console_sem();
905 retval = ps3fb_sync(info, val); 900 retval = ps3fb_sync(info, val);
906 release_console_sem(); 901 release_console_sem();
907 break; 902 break;
908 903
909 default: 904 default:
910 retval = -ENOIOCTLCMD; 905 retval = -ENOIOCTLCMD;
911 break; 906 break;
912 } 907 }
913 return retval; 908 return retval;
914 } 909 }
915 910
916 static int ps3fbd(void *arg) 911 static int ps3fbd(void *arg)
917 { 912 {
918 struct fb_info *info = arg; 913 struct fb_info *info = arg;
919 914
920 set_freezable(); 915 set_freezable();
921 while (!kthread_should_stop()) { 916 while (!kthread_should_stop()) {
922 try_to_freeze(); 917 try_to_freeze();
923 set_current_state(TASK_INTERRUPTIBLE); 918 set_current_state(TASK_INTERRUPTIBLE);
924 if (ps3fb.is_kicked) { 919 if (ps3fb.is_kicked) {
925 ps3fb.is_kicked = 0; 920 ps3fb.is_kicked = 0;
926 acquire_console_sem(); 921 acquire_console_sem();
927 ps3fb_sync(info, 0); /* single buffer */ 922 ps3fb_sync(info, 0); /* single buffer */
928 release_console_sem(); 923 release_console_sem();
929 } 924 }
930 schedule(); 925 schedule();
931 } 926 }
932 return 0; 927 return 0;
933 } 928 }
934 929
935 static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr) 930 static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
936 { 931 {
937 struct device *dev = ptr; 932 struct device *dev = ptr;
938 u64 v1; 933 u64 v1;
939 int status; 934 int status;
940 struct display_head *head = &ps3fb.dinfo->display_head[1]; 935 struct display_head *head = &ps3fb.dinfo->display_head[1];
941 936
942 status = lv1_gpu_context_intr(ps3fb.context_handle, &v1); 937 status = lv1_gpu_context_intr(ps3fb.context_handle, &v1);
943 if (status) { 938 if (status) {
944 dev_err(dev, "%s: lv1_gpu_context_intr failed: %d\n", __func__, 939 dev_err(dev, "%s: lv1_gpu_context_intr failed: %d\n", __func__,
945 status); 940 status);
946 return IRQ_NONE; 941 return IRQ_NONE;
947 } 942 }
948 943
949 if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) { 944 if (v1 & (1 << GPU_INTR_STATUS_VSYNC_1)) {
950 /* VSYNC */ 945 /* VSYNC */
951 ps3fb.vblank_count = head->vblank_count; 946 ps3fb.vblank_count = head->vblank_count;
952 if (ps3fb.task && !ps3fb.is_blanked && 947 if (ps3fb.task && !ps3fb.is_blanked &&
953 !atomic_read(&ps3fb.ext_flip)) { 948 !atomic_read(&ps3fb.ext_flip)) {
954 ps3fb.is_kicked = 1; 949 ps3fb.is_kicked = 1;
955 wake_up_process(ps3fb.task); 950 wake_up_process(ps3fb.task);
956 } 951 }
957 wake_up_interruptible(&ps3fb.wait_vsync); 952 wake_up_interruptible(&ps3fb.wait_vsync);
958 } 953 }
959 954
960 return IRQ_HANDLED; 955 return IRQ_HANDLED;
961 } 956 }
962 957
963 958
964 static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, 959 static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
965 struct device *dev) 960 struct device *dev)
966 { 961 {
967 int error; 962 int error;
968 963
969 dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver); 964 dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver);
970 dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet); 965 dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet);
971 dev_dbg(dev, 966 dev_dbg(dev,
972 "version_gpu: %x memory_size: %x ch: %x core_freq: %d " 967 "version_gpu: %x memory_size: %x ch: %x core_freq: %d "
973 "mem_freq:%d\n", 968 "mem_freq:%d\n",
974 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel, 969 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
975 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000); 970 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
976 971
977 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) { 972 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
978 dev_err(dev, "%s: version_driver err:%x\n", __func__, 973 dev_err(dev, "%s: version_driver err:%x\n", __func__,
979 dinfo->version_driver); 974 dinfo->version_driver);
980 return -EINVAL; 975 return -EINVAL;
981 } 976 }
982 977
983 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, 978 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
984 &ps3fb.irq_no); 979 &ps3fb.irq_no);
985 if (error) { 980 if (error) {
986 dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error); 981 dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error);
987 return error; 982 return error;
988 } 983 }
989 984
990 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED, 985 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
991 DEVICE_NAME, dev); 986 DEVICE_NAME, dev);
992 if (error) { 987 if (error) {
993 dev_err(dev, "%s: request_irq failed %d\n", __func__, error); 988 dev_err(dev, "%s: request_irq failed %d\n", __func__, error);
994 ps3_irq_plug_destroy(ps3fb.irq_no); 989 ps3_irq_plug_destroy(ps3fb.irq_no);
995 return error; 990 return error;
996 } 991 }
997 992
998 dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) | 993 dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
999 (1 << GPU_INTR_STATUS_FLIP_1); 994 (1 << GPU_INTR_STATUS_FLIP_1);
1000 return 0; 995 return 0;
1001 } 996 }
1002 997
1003 static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev) 998 static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
1004 { 999 {
1005 int status; 1000 int status;
1006 1001
1007 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, 1002 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
1008 xdr_lpar, ps3fb_videomemory.size, 0); 1003 xdr_lpar, ps3fb_videomemory.size, 0);
1009 if (status) { 1004 if (status) {
1010 dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n", 1005 dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n",
1011 __func__, status); 1006 __func__, status);
1012 return -ENXIO; 1007 return -ENXIO;
1013 } 1008 }
1014 dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n", 1009 dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n",
1015 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar, 1010 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
1016 ps3fb_videomemory.size); 1011 ps3fb_videomemory.size);
1017 1012
1018 status = lv1_gpu_context_attribute(ps3fb.context_handle, 1013 status = lv1_gpu_context_attribute(ps3fb.context_handle,
1019 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, 1014 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
1020 xdr_lpar, GPU_CMD_BUF_SIZE, 1015 xdr_lpar, GPU_CMD_BUF_SIZE,
1021 GPU_IOIF, 0); 1016 GPU_IOIF, 0);
1022 if (status) { 1017 if (status) {
1023 dev_err(dev, 1018 dev_err(dev,
1024 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n", 1019 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
1025 __func__, status); 1020 __func__, status);
1026 return -ENXIO; 1021 return -ENXIO;
1027 } 1022 }
1028 return 0; 1023 return 0;
1029 } 1024 }
1030 1025
1031 static struct fb_ops ps3fb_ops = { 1026 static struct fb_ops ps3fb_ops = {
1032 .fb_open = ps3fb_open, 1027 .fb_open = ps3fb_open,
1033 .fb_release = ps3fb_release, 1028 .fb_release = ps3fb_release,
1034 .fb_read = fb_sys_read, 1029 .fb_read = fb_sys_read,
1035 .fb_write = fb_sys_write, 1030 .fb_write = fb_sys_write,
1036 .fb_check_var = ps3fb_check_var, 1031 .fb_check_var = ps3fb_check_var,
1037 .fb_set_par = ps3fb_set_par, 1032 .fb_set_par = ps3fb_set_par,
1038 .fb_setcolreg = ps3fb_setcolreg, 1033 .fb_setcolreg = ps3fb_setcolreg,
1039 .fb_pan_display = ps3fb_pan_display, 1034 .fb_pan_display = ps3fb_pan_display,
1040 .fb_fillrect = sys_fillrect, 1035 .fb_fillrect = sys_fillrect,
1041 .fb_copyarea = sys_copyarea, 1036 .fb_copyarea = sys_copyarea,
1042 .fb_imageblit = sys_imageblit, 1037 .fb_imageblit = sys_imageblit,
1043 .fb_mmap = ps3fb_mmap, 1038 .fb_mmap = ps3fb_mmap,
1044 .fb_blank = ps3fb_blank, 1039 .fb_blank = ps3fb_blank,
1045 .fb_ioctl = ps3fb_ioctl, 1040 .fb_ioctl = ps3fb_ioctl,
1046 .fb_compat_ioctl = ps3fb_ioctl 1041 .fb_compat_ioctl = ps3fb_ioctl
1047 }; 1042 };
1048 1043
1049 static struct fb_fix_screeninfo ps3fb_fix __initdata = { 1044 static struct fb_fix_screeninfo ps3fb_fix __initdata = {
1050 .id = DEVICE_NAME, 1045 .id = DEVICE_NAME,
1051 .type = FB_TYPE_PACKED_PIXELS, 1046 .type = FB_TYPE_PACKED_PIXELS,
1052 .visual = FB_VISUAL_TRUECOLOR, 1047 .visual = FB_VISUAL_TRUECOLOR,
1053 .accel = FB_ACCEL_NONE, 1048 .accel = FB_ACCEL_NONE,
1054 }; 1049 };
1055 1050
1056 static int ps3fb_set_sync(struct device *dev) 1051 static int ps3fb_set_sync(struct device *dev)
1057 { 1052 {
1058 int status; 1053 int status;
1059 1054
1060 #ifdef HEAD_A 1055 #ifdef HEAD_A
1061 status = lv1_gpu_context_attribute(0x0, 1056 status = lv1_gpu_context_attribute(0x0,
1062 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 1057 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1063 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); 1058 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1064 if (status) { 1059 if (status) {
1065 dev_err(dev, 1060 dev_err(dev,
1066 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: " 1061 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1067 "%d\n", 1062 "%d\n",
1068 __func__, status); 1063 __func__, status);
1069 return -1; 1064 return -1;
1070 } 1065 }
1071 #endif 1066 #endif
1072 #ifdef HEAD_B 1067 #ifdef HEAD_B
1073 status = lv1_gpu_context_attribute(0x0, 1068 status = lv1_gpu_context_attribute(0x0,
1074 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 1069 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1075 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); 1070 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1076 1071
1077 if (status) { 1072 if (status) {
1078 dev_err(dev, 1073 dev_err(dev,
1079 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: " 1074 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1080 "%d\n", 1075 "%d\n",
1081 __func__, status); 1076 __func__, status);
1082 return -1; 1077 return -1;
1083 } 1078 }
1084 #endif 1079 #endif
1085 return 0; 1080 return 0;
1086 } 1081 }
1087 1082
1088 static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) 1083 static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1089 { 1084 {
1090 struct fb_info *info; 1085 struct fb_info *info;
1091 struct ps3fb_par *par; 1086 struct ps3fb_par *par;
1092 int retval = -ENOMEM; 1087 int retval = -ENOMEM;
1093 u64 ddr_lpar = 0; 1088 u64 ddr_lpar = 0;
1094 u64 lpar_dma_control = 0; 1089 u64 lpar_dma_control = 0;
1095 u64 lpar_driver_info = 0; 1090 u64 lpar_driver_info = 0;
1096 u64 lpar_reports = 0; 1091 u64 lpar_reports = 0;
1097 u64 lpar_reports_size = 0; 1092 u64 lpar_reports_size = 0;
1098 u64 xdr_lpar; 1093 u64 xdr_lpar;
1099 void *fb_start; 1094 void *fb_start;
1100 int status; 1095 int status;
1101 struct task_struct *task; 1096 struct task_struct *task;
1102 unsigned long max_ps3fb_size; 1097 unsigned long max_ps3fb_size;
1103 1098
1104 if (ps3fb_videomemory.size < GPU_CMD_BUF_SIZE) { 1099 if (ps3fb_videomemory.size < GPU_CMD_BUF_SIZE) {
1105 dev_err(&dev->core, "%s: Not enough video memory\n", __func__); 1100 dev_err(&dev->core, "%s: Not enough video memory\n", __func__);
1106 return -ENOMEM; 1101 return -ENOMEM;
1107 } 1102 }
1108 1103
1109 status = ps3_open_hv_device(dev); 1104 status = ps3_open_hv_device(dev);
1110 if (status) { 1105 if (status) {
1111 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n", 1106 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n",
1112 __func__); 1107 __func__);
1113 goto err; 1108 goto err;
1114 } 1109 }
1115 1110
1116 if (!ps3fb_mode) 1111 if (!ps3fb_mode)
1117 ps3fb_mode = ps3av_get_mode(); 1112 ps3fb_mode = ps3av_get_mode();
1118 dev_dbg(&dev->core, "ps3fb_mode: %d\n", ps3fb_mode); 1113 dev_dbg(&dev->core, "ps3fb_mode: %d\n", ps3fb_mode);
1119 1114
1120 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ 1115 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
1121 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1116 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
1122 init_waitqueue_head(&ps3fb.wait_vsync); 1117 init_waitqueue_head(&ps3fb.wait_vsync);
1123 1118
1124 ps3fb_set_sync(&dev->core); 1119 ps3fb_set_sync(&dev->core);
1125 1120
1126 max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF; 1121 max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
1127 if (ps3fb_videomemory.size > max_ps3fb_size) { 1122 if (ps3fb_videomemory.size > max_ps3fb_size) {
1128 dev_info(&dev->core, "Limiting ps3fb mem size to %lu bytes\n", 1123 dev_info(&dev->core, "Limiting ps3fb mem size to %lu bytes\n",
1129 max_ps3fb_size); 1124 max_ps3fb_size);
1130 ps3fb_videomemory.size = max_ps3fb_size; 1125 ps3fb_videomemory.size = max_ps3fb_size;
1131 } 1126 }
1132 1127
1133 /* get gpu context handle */ 1128 /* get gpu context handle */
1134 status = lv1_gpu_memory_allocate(ps3fb_videomemory.size, 0, 0, 0, 0, 1129 status = lv1_gpu_memory_allocate(ps3fb_videomemory.size, 0, 0, 0, 0,
1135 &ps3fb.memory_handle, &ddr_lpar); 1130 &ps3fb.memory_handle, &ddr_lpar);
1136 if (status) { 1131 if (status) {
1137 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n", 1132 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
1138 __func__, status); 1133 __func__, status);
1139 goto err; 1134 goto err;
1140 } 1135 }
1141 dev_dbg(&dev->core, "ddr:lpar:0x%lx\n", ddr_lpar); 1136 dev_dbg(&dev->core, "ddr:lpar:0x%lx\n", ddr_lpar);
1142 1137
1143 status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0, 1138 status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0,
1144 &ps3fb.context_handle, 1139 &ps3fb.context_handle,
1145 &lpar_dma_control, &lpar_driver_info, 1140 &lpar_dma_control, &lpar_driver_info,
1146 &lpar_reports, &lpar_reports_size); 1141 &lpar_reports, &lpar_reports_size);
1147 if (status) { 1142 if (status) {
1148 dev_err(&dev->core, 1143 dev_err(&dev->core,
1149 "%s: lv1_gpu_context_attribute failed: %d\n", __func__, 1144 "%s: lv1_gpu_context_attribute failed: %d\n", __func__,
1150 status); 1145 status);
1151 goto err_gpu_memory_free; 1146 goto err_gpu_memory_free;
1152 } 1147 }
1153 1148
1154 /* vsync interrupt */ 1149 /* vsync interrupt */
1155 ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024); 1150 ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
1156 if (!ps3fb.dinfo) { 1151 if (!ps3fb.dinfo) {
1157 dev_err(&dev->core, "%s: ioremap failed\n", __func__); 1152 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
1158 goto err_gpu_context_free; 1153 goto err_gpu_context_free;
1159 } 1154 }
1160 1155
1161 retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core); 1156 retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core);
1162 if (retval) 1157 if (retval)
1163 goto err_iounmap_dinfo; 1158 goto err_iounmap_dinfo;
1164 1159
1165 /* Clear memory to prevent kernel info leakage into userspace */ 1160 /* Clear memory to prevent kernel info leakage into userspace */
1166 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size); 1161 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size);
1167 1162
1168 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address)); 1163 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
1169 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); 1164 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
1170 if (retval) 1165 if (retval)
1171 goto err_free_irq; 1166 goto err_free_irq;
1172 1167
1173 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core); 1168 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
1174 if (!info) 1169 if (!info)
1175 goto err_free_irq; 1170 goto err_free_irq;
1176 1171
1177 par = info->par; 1172 par = info->par;
1178 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ 1173 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
1179 par->new_mode_id = ps3fb_mode; 1174 par->new_mode_id = ps3fb_mode;
1180 par->num_frames = 1; 1175 par->num_frames = 1;
1181 1176
1182 info->fbops = &ps3fb_ops; 1177 info->fbops = &ps3fb_ops;
1183 info->fix = ps3fb_fix; 1178 info->fix = ps3fb_fix;
1184 1179
1185 /* 1180 /*
1186 * The GPU command buffer is at the start of video memory 1181 * The GPU command buffer is at the start of video memory
1187 * As we don't use the full command buffer, we can put the actual 1182 * As we don't use the full command buffer, we can put the actual
1188 * frame buffer at offset GPU_FB_START and save some precious XDR 1183 * frame buffer at offset GPU_FB_START and save some precious XDR
1189 * memory 1184 * memory
1190 */ 1185 */
1191 fb_start = ps3fb_videomemory.address + GPU_FB_START; 1186 fb_start = ps3fb_videomemory.address + GPU_FB_START;
1192 info->screen_base = (char __force __iomem *)fb_start; 1187 info->screen_base = (char __force __iomem *)fb_start;
1193 info->fix.smem_start = virt_to_abs(fb_start); 1188 info->fix.smem_start = virt_to_abs(fb_start);
1194 info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START; 1189 info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
1195 1190
1196 info->pseudo_palette = par->pseudo_palette; 1191 info->pseudo_palette = par->pseudo_palette;
1197 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST | 1192 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
1198 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; 1193 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
1199 1194
1200 retval = fb_alloc_cmap(&info->cmap, 256, 0); 1195 retval = fb_alloc_cmap(&info->cmap, 256, 0);
1201 if (retval < 0) 1196 if (retval < 0)
1202 goto err_framebuffer_release; 1197 goto err_framebuffer_release;
1203 1198
1204 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb, 1199 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
1205 ARRAY_SIZE(ps3fb_modedb), 1200 ARRAY_SIZE(ps3fb_modedb),
1206 ps3fb_vmode(par->new_mode_id), 32)) { 1201 ps3fb_vmode(par->new_mode_id), 32)) {
1207 retval = -EINVAL; 1202 retval = -EINVAL;
1208 goto err_fb_dealloc; 1203 goto err_fb_dealloc;
1209 } 1204 }
1210 1205
1211 fb_videomode_to_modelist(ps3fb_modedb, ARRAY_SIZE(ps3fb_modedb), 1206 fb_videomode_to_modelist(ps3fb_modedb, ARRAY_SIZE(ps3fb_modedb),
1212 &info->modelist); 1207 &info->modelist);
1213 1208
1214 retval = register_framebuffer(info); 1209 retval = register_framebuffer(info);
1215 if (retval < 0) 1210 if (retval < 0)
1216 goto err_fb_dealloc; 1211 goto err_fb_dealloc;
1217 1212
1218 dev->core.driver_data = info; 1213 dev->core.driver_data = info;
1219 1214
1220 dev_info(info->device, "%s %s, using %u KiB of video memory\n", 1215 dev_info(info->device, "%s %s, using %u KiB of video memory\n",
1221 dev_driver_string(info->dev), info->dev->bus_id, 1216 dev_driver_string(info->dev), info->dev->bus_id,
1222 info->fix.smem_len >> 10); 1217 info->fix.smem_len >> 10);
1223 1218
1224 task = kthread_run(ps3fbd, info, DEVICE_NAME); 1219 task = kthread_run(ps3fbd, info, DEVICE_NAME);
1225 if (IS_ERR(task)) { 1220 if (IS_ERR(task)) {
1226 retval = PTR_ERR(task); 1221 retval = PTR_ERR(task);
1227 goto err_unregister_framebuffer; 1222 goto err_unregister_framebuffer;
1228 } 1223 }
1229 1224
1230 ps3fb.task = task; 1225 ps3fb.task = task;
1231 ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb);
1232 1226
1233 return 0; 1227 return 0;
1234 1228
1235 err_unregister_framebuffer: 1229 err_unregister_framebuffer:
1236 unregister_framebuffer(info); 1230 unregister_framebuffer(info);
1237 err_fb_dealloc: 1231 err_fb_dealloc:
1238 fb_dealloc_cmap(&info->cmap); 1232 fb_dealloc_cmap(&info->cmap);
1239 err_framebuffer_release: 1233 err_framebuffer_release:
1240 framebuffer_release(info); 1234 framebuffer_release(info);
1241 err_free_irq: 1235 err_free_irq:
1242 free_irq(ps3fb.irq_no, &dev->core); 1236 free_irq(ps3fb.irq_no, &dev->core);
1243 ps3_irq_plug_destroy(ps3fb.irq_no); 1237 ps3_irq_plug_destroy(ps3fb.irq_no);
1244 err_iounmap_dinfo: 1238 err_iounmap_dinfo:
1245 iounmap((u8 __force __iomem *)ps3fb.dinfo); 1239 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1246 err_gpu_context_free: 1240 err_gpu_context_free:
1247 lv1_gpu_context_free(ps3fb.context_handle); 1241 lv1_gpu_context_free(ps3fb.context_handle);
1248 err_gpu_memory_free: 1242 err_gpu_memory_free:
1249 lv1_gpu_memory_free(ps3fb.memory_handle); 1243 lv1_gpu_memory_free(ps3fb.memory_handle);
1250 err: 1244 err:
1251 return retval; 1245 return retval;
1252 } 1246 }
1253 1247
1254 static int ps3fb_shutdown(struct ps3_system_bus_device *dev) 1248 static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1255 { 1249 {
1256 int status; 1250 int status;
1257 struct fb_info *info = dev->core.driver_data; 1251 struct fb_info *info = dev->core.driver_data;
1258 1252
1259 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 1253 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1260 1254
1261 ps3fb_flip_ctl(0, &ps3fb); /* flip off */ 1255 atomic_inc(&ps3fb.ext_flip); /* flip off */
1262 ps3fb.dinfo->irq.mask = 0; 1256 ps3fb.dinfo->irq.mask = 0;
1263 1257
1264 ps3av_register_flip_ctl(NULL, NULL);
1265 if (ps3fb.task) { 1258 if (ps3fb.task) {
1266 struct task_struct *task = ps3fb.task; 1259 struct task_struct *task = ps3fb.task;
1267 ps3fb.task = NULL; 1260 ps3fb.task = NULL;
1268 kthread_stop(task); 1261 kthread_stop(task);
1269 } 1262 }
1270 if (ps3fb.irq_no) { 1263 if (ps3fb.irq_no) {
1271 free_irq(ps3fb.irq_no, &dev->core); 1264 free_irq(ps3fb.irq_no, &dev->core);
1272 ps3_irq_plug_destroy(ps3fb.irq_no); 1265 ps3_irq_plug_destroy(ps3fb.irq_no);
1273 } 1266 }
1274 if (info) { 1267 if (info) {
1275 unregister_framebuffer(info); 1268 unregister_framebuffer(info);
1276 fb_dealloc_cmap(&info->cmap); 1269 fb_dealloc_cmap(&info->cmap);
1277 framebuffer_release(info); 1270 framebuffer_release(info);
1278 info = dev->core.driver_data = NULL; 1271 info = dev->core.driver_data = NULL;
1279 } 1272 }
1280 iounmap((u8 __force __iomem *)ps3fb.dinfo); 1273 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1281 1274
1282 status = lv1_gpu_context_free(ps3fb.context_handle); 1275 status = lv1_gpu_context_free(ps3fb.context_handle);
1283 if (status) 1276 if (status)
1284 dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n", 1277 dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n",
1285 status); 1278 status);
1286 1279
1287 status = lv1_gpu_memory_free(ps3fb.memory_handle); 1280 status = lv1_gpu_memory_free(ps3fb.memory_handle);
1288 if (status) 1281 if (status)
1289 dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n", 1282 dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n",
1290 status); 1283 status);
1291 1284
1292 ps3_close_hv_device(dev); 1285 ps3_close_hv_device(dev);
1293 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 1286 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1294 1287
1295 return 0; 1288 return 0;
1296 } 1289 }
1297 1290
1298 static struct ps3_system_bus_driver ps3fb_driver = { 1291 static struct ps3_system_bus_driver ps3fb_driver = {
1299 .match_id = PS3_MATCH_ID_GRAPHICS, 1292 .match_id = PS3_MATCH_ID_GRAPHICS,
1300 .match_sub_id = PS3_MATCH_SUB_ID_FB, 1293 .match_sub_id = PS3_MATCH_SUB_ID_FB,
1301 .core.name = DEVICE_NAME, 1294 .core.name = DEVICE_NAME,
1302 .core.owner = THIS_MODULE, 1295 .core.owner = THIS_MODULE,
1303 .probe = ps3fb_probe, 1296 .probe = ps3fb_probe,
1304 .remove = ps3fb_shutdown, 1297 .remove = ps3fb_shutdown,
1305 .shutdown = ps3fb_shutdown, 1298 .shutdown = ps3fb_shutdown,
1306 }; 1299 };
1307 1300
1308 static int __init ps3fb_setup(void) 1301 static int __init ps3fb_setup(void)
1309 { 1302 {
1310 char *options; 1303 char *options;
1311 1304
1312 #ifdef MODULE 1305 #ifdef MODULE
1313 return 0; 1306 return 0;
1314 #endif 1307 #endif
1315 1308
1316 if (fb_get_options(DEVICE_NAME, &options)) 1309 if (fb_get_options(DEVICE_NAME, &options))
1317 return -ENXIO; 1310 return -ENXIO;
1318 1311
1319 if (!options || !*options) 1312 if (!options || !*options)
1320 return 0; 1313 return 0;
1321 1314
1322 while (1) { 1315 while (1) {
1323 char *this_opt = strsep(&options, ","); 1316 char *this_opt = strsep(&options, ",");
1324 1317
1325 if (!this_opt) 1318 if (!this_opt)
1326 break; 1319 break;
1327 if (!*this_opt) 1320 if (!*this_opt)
1328 continue; 1321 continue;
1329 if (!strncmp(this_opt, "mode:", 5)) 1322 if (!strncmp(this_opt, "mode:", 5))
1330 ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0); 1323 ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
1331 else 1324 else
1332 mode_option = this_opt; 1325 mode_option = this_opt;
1333 } 1326 }
1334 return 0; 1327 return 0;
1335 } 1328 }
1336 1329
1337 static int __init ps3fb_init(void) 1330 static int __init ps3fb_init(void)
1338 { 1331 {
1339 if (!ps3fb_videomemory.address || ps3fb_setup()) 1332 if (!ps3fb_videomemory.address || ps3fb_setup())
1340 return -ENXIO; 1333 return -ENXIO;
1341 1334
1342 return ps3_system_bus_driver_register(&ps3fb_driver); 1335 return ps3_system_bus_driver_register(&ps3fb_driver);
1343 } 1336 }
1344 1337
1345 static void __exit ps3fb_exit(void) 1338 static void __exit ps3fb_exit(void)
1346 { 1339 {
1347 pr_debug(" -> %s:%d\n", __func__, __LINE__); 1340 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1348 ps3_system_bus_driver_unregister(&ps3fb_driver); 1341 ps3_system_bus_driver_unregister(&ps3fb_driver);
1349 pr_debug(" <- %s:%d\n", __func__, __LINE__); 1342 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1350 } 1343 }
1351 1344
1352 module_init(ps3fb_init); 1345 module_init(ps3fb_init);
1353 module_exit(ps3fb_exit); 1346 module_exit(ps3fb_exit);
1354 1347
1355 MODULE_LICENSE("GPL"); 1348 MODULE_LICENSE("GPL");