Hi Wolfgang,

+void fpga_set_reg(unsigned int fpga, u16 reg, u16 data)
+{
+       int res;
+ struct ihs_fpga *fpga_0 = (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(0);
+
+       switch (fpga) {
+       case 0:
+               out_le16((u16 *)fpga_0 + reg / sizeof(u16), data);
+               break;
+       default:
+               res = mclink_send(fpga - 1, reg, data);
+               if (res < 0)
+                       printf("mclink_send reg %02x data %04x returned %d\n",
+                              reg, data, res);
+               break;
+       }
+}

So no memory mapping here. That's the reason for all this fuzz.

OK - but I don't see why mclink_send() could not be used in the same
way, i. e. taking a struct member as argument?

Certainly it *can* be used using *pointers* to struct members as argument.

What I stated yesterday was:
"We have FPGAs that are memory mapped and others that are not. They must be accessed by the same drivers. So the alternative would be to create FPGA instances at address NULL and getting the register offesets by casting pointers to u16. Not very nice either."


Apparently all your FPGA accesses are for  u16  data only?  Then you
could rewrite fpga_set_reg() similar to this:

        int fpga_set_reg(u32 fpga, u16 *addr, u16 data)

With
  struct ihs_fpga {
        u16 reflection_low;     /* 0x0000 */
        u16 versions;           /* 0x0002 */
        ...
  };
and
  void fpga_set_reg(unsigned int fpga, u16 reg, u16 data)
the call looks like
  fpga_set_reg(k, REG(reflection_low), REFLECTION_TESTPATTERN);


To use
  int fpga_set_reg(u32 fpga, u16 *addr, u16 data)
we need something like
  struct ihs_fpga system_fpgas[] = {
        (struct ihs_fpga *)CONFIG_SYS_FPGA_BASE(0),
        (struct ihs_fpga *)NULL,
        (struct ihs_fpga *)NULL,
        (struct ihs_fpga *)NULL,
  };
and
fpga_set_reg(k, system_fpgas[k].reflection_low, REFLECTION_TESTPATTERN);

In fpga_set_reg() it would look like
  mclink_send(fpga - 1, (u16)addr, data);

I personally dislike all this NULL-pointer passing and casting. But YMMV. If that's the u-boot-way I will be happy to change it.

And voila, no need to move away from the C structs.

Note 1: You print an error message if mclink_send() returns an error;
        I think this error should propagate, i. e. this function
        should not return  void.

Yep. Happy were the days when accessing FPGA registers could not fail :(

Note 2: I changed the type of the first arg into "u32" so it is
        consistent with the other args. Mixing native types (unsigned
        int) here and defined types (as u16 instead of unsigned
        short) looks weird to me.

I wanted to express the 16 bit io-implementation of our address/data busses, while the fpga index is simply a number. Maybe that is information overkill :)

Cheers
Dirk
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to