drm/sti: fix dvo data_enable signal
authorBich Hemon <bich.hemon@st.com>
Wed, 10 Feb 2016 09:56:47 +0000 (10:56 +0100)
committerVincent Abriou <vincent.abriou@st.com>
Fri, 26 Feb 2016 09:06:18 +0000 (10:06 +0100)
Modify AWG algorithm in order to handle more than 1023 lines

Signed-off-by: Bich Hemon <bich.hemon@st.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Reviewed-by: Vincent Abriou <vincent.abriou@st.com>
drivers/gpu/drm/sti/sti_awg_utils.c

index 2378b939290704689561c65a937f5807e9f70dfd..a516eb869f6fe81c71b8b77106a9b6a13777105b 100644 (file)
@@ -7,6 +7,7 @@
 #include "sti_awg_utils.h"
 
 #define AWG_OPCODE_OFFSET 10
+#define AWG_MAX_ARG       0x3ff
 
 enum opcode {
        SET,
@@ -67,7 +68,7 @@ static int awg_generate_instr(enum opcode opcode,
 
                        mux = 0;
                        data_enable = 0;
-                       arg &= (0x3ff);
+                       arg &= AWG_MAX_ARG;
                        break;
                case REPEAT:
                case REPLAY:
@@ -78,13 +79,13 @@ static int awg_generate_instr(enum opcode opcode,
 
                        mux = 0;
                        data_enable = 0;
-                       arg &= (0x3ff);
+                       arg &= AWG_MAX_ARG;
                        break;
                case JUMP:
                        mux = 0;
                        data_enable = 0;
                        arg |= 0x40; /* for jump instruction 7th bit is 1 */
-                       arg &= 0x3ff;
+                       arg &= AWG_MAX_ARG;
                        break;
                case STOP:
                        arg = 0;
@@ -112,22 +113,13 @@ static int awg_generate_instr(enum opcode opcode,
        return 0;
 }
 
-int sti_awg_generate_code_data_enable_mode(
+static int awg_generate_line_signal(
                struct awg_code_generation_params *fwparams,
                struct awg_timing *timing)
 {
        long int val;
        int ret = 0;
 
-       if (timing->trailing_lines > 0) {
-               /* skip trailing lines */
-               val = timing->blanking_level;
-               ret |= awg_generate_instr(RPLSET, val, 0, 0, fwparams);
-
-               val = timing->trailing_lines - 1;
-               ret |= awg_generate_instr(REPLAY, val, 0, 0, fwparams);
-       }
-
        if (timing->trailing_pixels > 0) {
                /* skip trailing pixel */
                val = timing->blanking_level;
@@ -152,9 +144,36 @@ int sti_awg_generate_code_data_enable_mode(
                ret |= awg_generate_instr(SET, val, 0, 0, fwparams);
        }
 
-       /* replay the sequence as many active lines defined */
-       val = timing->active_lines - 1;
-       ret |= awg_generate_instr(REPLAY, val, 0, 0, fwparams);
+       return ret;
+}
+
+int sti_awg_generate_code_data_enable_mode(
+               struct awg_code_generation_params *fwparams,
+               struct awg_timing *timing)
+{
+       long int val, tmp_val;
+       int ret = 0;
+
+       if (timing->trailing_lines > 0) {
+               /* skip trailing lines */
+               val = timing->blanking_level;
+               ret |= awg_generate_instr(RPLSET, val, 0, 0, fwparams);
+
+               val = timing->trailing_lines - 1;
+               ret |= awg_generate_instr(REPLAY, val, 0, 0, fwparams);
+       }
+
+       tmp_val = timing->active_lines - 1;
+
+       while (tmp_val > 0) {
+               /* generate DE signal for each line */
+               ret |= awg_generate_line_signal(fwparams, timing);
+               /* replay the sequence as many active lines defined */
+               ret |= awg_generate_instr(REPLAY,
+                                         min_t(int, AWG_MAX_ARG, tmp_val),
+                                         0, 0, fwparams);
+               tmp_val -= AWG_MAX_ARG;
+       }
 
        if (timing->blanking_lines > 0) {
                /* skip blanking lines */