Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:44

0001 /*  tmu.c
0002  *
0003  *  Milkymist TMU driver for RTEMS
0004  *
0005  *  The license and distribution terms for this file may be
0006  *  found in the file LICENSE in this distribution or at
0007  *  http://www.rtems.org/license/LICENSE.
0008  *
0009  *  COPYRIGHT (c) 2010, 2011 Sebastien Bourdeauducq
0010  */
0011 
0012 #define RTEMS_STATUS_CHECKS_USE_PRINTK
0013 
0014 #include <stdlib.h>
0015 #include <stdio.h>
0016 #include <errno.h>
0017 #include <sys/types.h>
0018 #include <rtems.h>
0019 #include <bsp.h>
0020 #include <bsp/irq-generic.h>
0021 #include <rtems/libio.h>
0022 #include <rtems/status-checks.h>
0023 #include "../include/system_conf.h"
0024 #include <bsp/milkymist_tmu.h>
0025 
0026 #define DEVICE_NAME "/dev/tmu"
0027 
0028 static rtems_id done_sem;
0029 
0030 static rtems_isr done_handler(rtems_vector_number n)
0031 {
0032   rtems_semaphore_release(done_sem);
0033   lm32_interrupt_ack(1 << MM_IRQ_TMU);
0034 }
0035 
0036 rtems_device_driver tmu_initialize(
0037   rtems_device_major_number major,
0038   rtems_device_minor_number minor,
0039   void *arg
0040 )
0041 {
0042   rtems_status_code sc;
0043   rtems_isr_entry dummy;
0044 
0045   sc = rtems_io_register_name(DEVICE_NAME, major, 0);
0046   RTEMS_CHECK_SC(sc, "create TMU device");
0047 
0048   sc = rtems_semaphore_create(
0049     rtems_build_name('T', 'M', 'U', ' '),
0050     0,
0051     RTEMS_SIMPLE_BINARY_SEMAPHORE,
0052     0,
0053     &done_sem
0054   );
0055   RTEMS_CHECK_SC(sc, "create TMU done semaphore");
0056 
0057   rtems_interrupt_catch(done_handler, MM_IRQ_TMU, &dummy);
0058   bsp_interrupt_vector_enable(MM_IRQ_TMU);
0059 
0060   return RTEMS_SUCCESSFUL;
0061 }
0062 
0063 static void invalidate_l2(void)
0064 {
0065   volatile char *flushbase = (char *)FMLBRG_FLUSH_BASE;
0066   int i, offset;
0067 
0068   offset = 0;
0069   for (i=0;i<FMLBRG_LINE_COUNT;i++) {
0070     flushbase[offset] = 0;
0071     offset += FMLBRG_LINE_LENGTH;
0072   }
0073 }
0074 
0075 static bool invalidate_after;
0076 
0077 static void tmu_start(struct tmu_td *td)
0078 {
0079   if (td->invalidate_before)
0080     invalidate_l2();
0081 
0082   MM_WRITE(MM_TMU_HMESHLAST, td->hmeshlast);
0083   MM_WRITE(MM_TMU_VMESHLAST, td->vmeshlast);
0084   MM_WRITE(MM_TMU_BRIGHTNESS, td->brightness);
0085   MM_WRITE(MM_TMU_CHROMAKEY, td->chromakey);
0086 
0087   MM_WRITE(MM_TMU_VERTICESADR, (unsigned int)td->vertices);
0088   MM_WRITE(MM_TMU_TEXFBUF, (unsigned int)td->texfbuf);
0089   MM_WRITE(MM_TMU_TEXHRES, td->texhres);
0090   MM_WRITE(MM_TMU_TEXVRES, td->texvres);
0091   MM_WRITE(MM_TMU_TEXHMASK, td->texhmask);
0092   MM_WRITE(MM_TMU_TEXVMASK, td->texvmask);
0093 
0094   MM_WRITE(MM_TMU_DSTFBUF, (unsigned int)td->dstfbuf);
0095   MM_WRITE(MM_TMU_DSTHRES, td->dsthres);
0096   MM_WRITE(MM_TMU_DSTVRES, td->dstvres);
0097   MM_WRITE(MM_TMU_DSTHOFFSET, td->dsthoffset);
0098   MM_WRITE(MM_TMU_DSTVOFFSET, td->dstvoffset);
0099   MM_WRITE(MM_TMU_DSTSQUAREW, td->dstsquarew);
0100   MM_WRITE(MM_TMU_DSTSQUAREH, td->dstsquareh);
0101 
0102   MM_WRITE(MM_TMU_ALPHA, td->alpha);
0103 
0104   MM_WRITE(MM_TMU_CTL, td->flags|TMU_CTL_START);
0105 
0106   invalidate_after = td->invalidate_after;
0107 }
0108 
0109 static rtems_status_code tmu_finalize(void)
0110 {
0111   rtems_status_code sc;
0112 
0113   sc = rtems_semaphore_obtain(done_sem, RTEMS_WAIT, 100);
0114   if (sc != RTEMS_SUCCESSFUL)
0115     return sc;
0116 
0117   if (invalidate_after) {
0118     invalidate_l2();
0119     __asm__ volatile( /* Invalidate Level-1 data cache */
0120       "wcsr DCC, r0\n"
0121       "nop\n"
0122     );
0123   }
0124 
0125   return RTEMS_SUCCESSFUL;
0126 }
0127 
0128 rtems_device_driver tmu_control(
0129   rtems_device_major_number major,
0130   rtems_device_minor_number minor,
0131   void *arg
0132 )
0133 {
0134   rtems_libio_ioctl_args_t *args = arg;
0135   struct tmu_td *td = (struct tmu_td *)args->buffer;
0136   rtems_status_code sc;
0137 
0138   switch (args->command) {
0139     case TMU_EXECUTE:
0140       tmu_start(td);
0141       sc = tmu_finalize();
0142       break;
0143     case TMU_EXECUTE_NONBLOCK:
0144       tmu_start(td);
0145       sc = RTEMS_SUCCESSFUL;
0146       break;
0147     case TMU_EXECUTE_WAIT:
0148       sc = tmu_finalize();
0149       break;
0150     default:
0151       sc = RTEMS_UNSATISFIED;
0152       break;
0153   }
0154 
0155   if (sc == RTEMS_SUCCESSFUL)
0156     args->ioctl_return = 0;
0157   else
0158     args->ioctl_return = -1;
0159 
0160   return sc;
0161 }