--- /dev/null
+#ifndef __HW_DVISAMPLER_H
+#define __HW_DVISAMPLER_H
+
+#include <hw/common.h>
+#include <csrbase.h>
+
+#define DVISAMPLER0_CSR(x) MMPTR(DVISAMPLER0_BASE+(x))
+
+#define CSR_DVISAMPLER0_PLL_RESET DVISAMPLER0_CSR(0x00)
+#define CSR_DVISAMPLER0_PLL_LOCKED DVISAMPLER0_CSR(0x04)
+
+#define CSR_DVISAMPLER0_D0_DELAY_CTL DVISAMPLER0_CSR(0x08)
+#define CSR_DVISAMPLER0_D0_DELAY_BUSY DVISAMPLER0_CSR(0x0C)
+#define CSR_DVISAMPLER0_D0_PHASE DVISAMPLER0_CSR(0x10)
+#define CSR_DVISAMPLER0_D0_PHASE_RESET DVISAMPLER0_CSR(0x14)
+
+#define CSR_DVISAMPLER0_D1_DELAY_CTL DVISAMPLER0_CSR(0x18)
+#define CSR_DVISAMPLER0_D1_DELAY_BUSY DVISAMPLER0_CSR(0x1C)
+#define CSR_DVISAMPLER0_D1_PHASE DVISAMPLER0_CSR(0x20)
+#define CSR_DVISAMPLER0_D1_PHASE_RESET DVISAMPLER0_CSR(0x24)
+
+#define CSR_DVISAMPLER0_D2_DELAY_CTL DVISAMPLER0_CSR(0x28)
+#define CSR_DVISAMPLER0_D2_DELAY_BUSY DVISAMPLER0_CSR(0x2C)
+#define CSR_DVISAMPLER0_D2_PHASE DVISAMPLER0_CSR(0x30)
+#define CSR_DVISAMPLER0_D2_PHASE_RESET DVISAMPLER0_CSR(0x34)
+
+#define DVISAMPLER_DELAY_CAL 0x01
+#define DVISAMPLER_DELAY_RST 0x02
+#define DVISAMPLER_DELAY_INC 0x04
+#define DVISAMPLER_DELAY_DEC 0x08
+
+#define DVISAMPLER_TOO_LATE 0x01
+#define DVISAMPLER_TOO_EARLY 0x02
+
+#endif /* __HW_DVISAMPLER_H */
#include <irq.h>
#include <uart.h>
+#include <hw/dvisampler.h>
+
+static int d0, d1, d2;
+
+static void calibrate_delays(void)
+{
+ CSR_DVISAMPLER0_D0_DELAY_CTL = DVISAMPLER_DELAY_CAL;
+ CSR_DVISAMPLER0_D1_DELAY_CTL = DVISAMPLER_DELAY_CAL;
+ CSR_DVISAMPLER0_D2_DELAY_CTL = DVISAMPLER_DELAY_CAL;
+ while(CSR_DVISAMPLER0_D0_DELAY_BUSY || CSR_DVISAMPLER0_D1_DELAY_BUSY || CSR_DVISAMPLER0_D2_DELAY_BUSY);
+ CSR_DVISAMPLER0_D0_DELAY_CTL = DVISAMPLER_DELAY_RST;
+ CSR_DVISAMPLER0_D1_DELAY_CTL = DVISAMPLER_DELAY_RST;
+ CSR_DVISAMPLER0_D2_DELAY_CTL = DVISAMPLER_DELAY_RST;
+ CSR_DVISAMPLER0_D0_PHASE_RESET = 1;
+ CSR_DVISAMPLER0_D1_PHASE_RESET = 1;
+ CSR_DVISAMPLER0_D2_PHASE_RESET = 1;
+ d0 = d1 = d2 = 0;
+ printf("Delays calibrated\n");
+}
+
+static void adjust_phase(void)
+{
+ switch(CSR_DVISAMPLER0_D0_PHASE) {
+ case DVISAMPLER_TOO_LATE:
+ CSR_DVISAMPLER0_D0_DELAY_CTL = DVISAMPLER_DELAY_DEC;
+ d0--;
+ CSR_DVISAMPLER0_D0_PHASE_RESET = 1;
+ break;
+ case DVISAMPLER_TOO_EARLY:
+ CSR_DVISAMPLER0_D0_DELAY_CTL = DVISAMPLER_DELAY_INC;
+ d0++;
+ CSR_DVISAMPLER0_D0_PHASE_RESET = 1;
+ break;
+ }
+ switch(CSR_DVISAMPLER0_D1_PHASE) {
+ case DVISAMPLER_TOO_LATE:
+ CSR_DVISAMPLER0_D1_DELAY_CTL = DVISAMPLER_DELAY_DEC;
+ d1--;
+ CSR_DVISAMPLER0_D1_PHASE_RESET = 1;
+ break;
+ case DVISAMPLER_TOO_EARLY:
+ CSR_DVISAMPLER0_D1_DELAY_CTL = DVISAMPLER_DELAY_INC;
+ d1++;
+ CSR_DVISAMPLER0_D1_PHASE_RESET = 1;
+ break;
+ }
+ switch(CSR_DVISAMPLER0_D2_PHASE) {
+ case DVISAMPLER_TOO_LATE:
+ CSR_DVISAMPLER0_D2_DELAY_CTL = DVISAMPLER_DELAY_DEC;
+ d2--;
+ CSR_DVISAMPLER0_D2_PHASE_RESET = 1;
+ break;
+ case DVISAMPLER_TOO_EARLY:
+ CSR_DVISAMPLER0_D2_DELAY_CTL = DVISAMPLER_DELAY_INC;
+ d2++;
+ CSR_DVISAMPLER0_D2_PHASE_RESET = 1;
+ break;
+ }
+ //printf("Ph: %4d %4d %4d\n", d0, d1, d2);
+}
+
+static void vmix(void)
+{
+ unsigned int counter;
+
+ while(1) {
+ while(!CSR_DVISAMPLER0_PLL_LOCKED);
+ printf("PLL locked\n");
+ calibrate_delays();
+ adjust_phase();
+
+ counter = 0;
+ while(CSR_DVISAMPLER0_PLL_LOCKED) {
+ counter++;
+ if(counter == 200000) {
+ adjust_phase();
+ counter = 0;
+ }
+ }
+ printf("PLL unlocked\n");
+ }
+}
int main(void)
{
puts("Minimal video mixer software built "__DATE__" "__TIME__"\n");
- while(1);
+ vmix();
return 0;
}