21 #include <linux/errno.h>
22 #include <linux/sched.h>
23 #include <linux/kernel.h>
25 #include <linux/poll.h>
27 #include <linux/stddef.h>
34 #include <asm/mmu_context.h>
39 struct spu *spu = ctx->
spu;
40 struct spu_problem
__iomem *prob = spu->problem;
44 spin_lock_irq(&spu->register_lock);
45 mbox_stat =
in_be32(&prob->mb_stat_R);
46 if (mbox_stat & 0x0000ff) {
47 *data =
in_be32(&prob->pu_mb_R);
50 spin_unlock_irq(&spu->register_lock);
59 static unsigned int spu_hw_mbox_stat_poll(
struct spu_context *ctx,
62 struct spu *spu = ctx->
spu;
66 spin_lock_irq(&spu->register_lock);
67 stat =
in_be32(&spu->problem->mb_stat_R);
78 spu_int_stat_clear(spu, 2, CLASS2_MAILBOX_INTR);
79 spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
86 spu_int_stat_clear(spu, 2,
87 CLASS2_MAILBOX_THRESHOLD_INTR);
88 spu_int_mask_or(spu, 2,
89 CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR);
92 spin_unlock_irq(&spu->register_lock);
98 struct spu *spu = ctx->
spu;
99 struct spu_problem
__iomem *prob = spu->problem;
100 struct spu_priv2
__iomem *priv2 = spu->priv2;
103 spin_lock_irq(&spu->register_lock);
104 if (
in_be32(&prob->mb_stat_R) & 0xff0000) {
106 *data = in_be64(&priv2->puint_mb_R);
110 spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
113 spin_unlock_irq(&spu->register_lock);
119 struct spu *spu = ctx->
spu;
120 struct spu_problem
__iomem *prob = spu->problem;
123 spin_lock_irq(&spu->register_lock);
124 if (
in_be32(&prob->mb_stat_R) & 0x00ff00) {
131 spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR);
134 spin_unlock_irq(&spu->register_lock);
138 static void spu_hw_signal1_write(
struct spu_context *ctx,
u32 data)
140 out_be32(&ctx->
spu->problem->signal_notify1, data);
143 static void spu_hw_signal2_write(
struct spu_context *ctx,
u32 data)
145 out_be32(&ctx->
spu->problem->signal_notify2, data);
150 struct spu *spu = ctx->
spu;
151 struct spu_priv2
__iomem *priv2 = spu->priv2;
154 spin_lock_irq(&spu->register_lock);
155 tmp = in_be64(&priv2->spu_cfg_RW);
160 out_be64(&priv2->spu_cfg_RW, tmp);
161 spin_unlock_irq(&spu->register_lock);
166 return ((in_be64(&ctx->
spu->priv2->spu_cfg_RW) & 1) != 0);
169 static void spu_hw_signal2_type_set(
struct spu_context *ctx,
u64 val)
171 struct spu *spu = ctx->
spu;
172 struct spu_priv2
__iomem *priv2 = spu->priv2;
175 spin_lock_irq(&spu->register_lock);
176 tmp = in_be64(&priv2->spu_cfg_RW);
181 out_be64(&priv2->spu_cfg_RW, tmp);
182 spin_unlock_irq(&spu->register_lock);
187 return ((in_be64(&ctx->
spu->priv2->spu_cfg_RW) & 2) != 0);
192 return in_be32(&ctx->
spu->problem->spu_npc_RW);
202 return in_be32(&ctx->
spu->problem->spu_status_R);
205 static char *spu_hw_get_ls(
struct spu_context *ctx)
207 return ctx->
spu->local_store;
210 static void spu_hw_privcntl_write(
struct spu_context *ctx,
u64 val)
212 out_be64(&ctx->
spu->priv2->spu_privcntl_RW, val);
217 return in_be32(&ctx->
spu->problem->spu_runcntl_RW);
220 static void spu_hw_runcntl_write(
struct spu_context *ctx,
u32 val)
222 spin_lock_irq(&ctx->
spu->register_lock);
223 if (val & SPU_RUNCNTL_ISOLATE)
224 spu_hw_privcntl_write(ctx,
225 SPU_PRIVCNT_LOAD_REQUEST_ENABLE_MASK);
227 spin_unlock_irq(&ctx->
spu->register_lock);
230 static void spu_hw_runcntl_stop(
struct spu_context *ctx)
232 spin_lock_irq(&ctx->
spu->register_lock);
233 out_be32(&ctx->
spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
234 while (
in_be32(&ctx->
spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
236 spin_unlock_irq(&ctx->
spu->register_lock);
239 static void spu_hw_master_start(
struct spu_context *ctx)
241 struct spu *spu = ctx->
spu;
244 spin_lock_irq(&spu->register_lock);
245 sr1 = spu_mfc_sr1_get(spu) | MFC_STATE1_MASTER_RUN_CONTROL_MASK;
246 spu_mfc_sr1_set(spu, sr1);
247 spin_unlock_irq(&spu->register_lock);
250 static void spu_hw_master_stop(
struct spu_context *ctx)
252 struct spu *spu = ctx->
spu;
255 spin_lock_irq(&spu->register_lock);
256 sr1 = spu_mfc_sr1_get(spu) & ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
257 spu_mfc_sr1_set(spu, sr1);
258 spin_unlock_irq(&spu->register_lock);
263 struct spu_problem
__iomem *prob = ctx->
spu->problem;
266 spin_lock_irq(&ctx->
spu->register_lock);
268 if (
in_be32(&prob->dma_querytype_RW))
271 out_be32(&prob->dma_querymask_RW, mask);
272 out_be32(&prob->dma_querytype_RW, mode);
274 spin_unlock_irq(&ctx->
spu->register_lock);
280 return in_be32(&ctx->
spu->problem->dma_tagstatus_R);
285 return in_be32(&ctx->
spu->problem->dma_qstatus_R);
288 static int spu_hw_send_mfc_command(
struct spu_context *ctx,
292 struct spu_problem
__iomem *prob = ctx->
spu->problem;
294 spin_lock_irq(&ctx->
spu->register_lock);
296 out_be64(&prob->mfc_ea_W, cmd->
ea);
297 out_be32(&prob->mfc_union_W.by32.mfc_size_tag32,
299 out_be32(&prob->mfc_union_W.by32.mfc_class_cmd32,
301 status =
in_be32(&prob->mfc_union_W.by32.mfc_class_cmd32);
302 spin_unlock_irq(&ctx->
spu->register_lock);
304 switch (status & 0xffff) {
314 static void spu_hw_restart_dma(
struct spu_context *ctx)
316 struct spu_priv2
__iomem *priv2 = ctx->
spu->priv2;
318 if (!
test_bit(SPU_CONTEXT_SWITCH_PENDING, &ctx->
spu->flags))
319 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
323 .mbox_read = spu_hw_mbox_read,
324 .mbox_stat_read = spu_hw_mbox_stat_read,
325 .mbox_stat_poll = spu_hw_mbox_stat_poll,
326 .ibox_read = spu_hw_ibox_read,
327 .wbox_write = spu_hw_wbox_write,
328 .signal1_write = spu_hw_signal1_write,
329 .signal2_write = spu_hw_signal2_write,
330 .signal1_type_set = spu_hw_signal1_type_set,
331 .signal1_type_get = spu_hw_signal1_type_get,
332 .signal2_type_set = spu_hw_signal2_type_set,
333 .signal2_type_get = spu_hw_signal2_type_get,
334 .npc_read = spu_hw_npc_read,
335 .npc_write = spu_hw_npc_write,
336 .status_read = spu_hw_status_read,
337 .get_ls = spu_hw_get_ls,
338 .privcntl_write = spu_hw_privcntl_write,
339 .runcntl_read = spu_hw_runcntl_read,
340 .runcntl_write = spu_hw_runcntl_write,
341 .runcntl_stop = spu_hw_runcntl_stop,
342 .master_start = spu_hw_master_start,
343 .master_stop = spu_hw_master_stop,
344 .set_mfc_query = spu_hw_set_mfc_query,
345 .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus,
346 .get_mfc_free_elements = spu_hw_get_mfc_free_elements,
347 .send_mfc_command = spu_hw_send_mfc_command,
348 .restart_dma = spu_hw_restart_dma,