File indexing completed on 2025-05-11 08:23:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
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(
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 }