[RFC v2 PATCH] mipi-dsi-bus: add MIPI DSI bus support

Thierry Reding thierry.reding at gmail.com
Thu Dec 12 04:19:42 PST 2013


On Tue, Dec 10, 2013 at 11:19:54AM +0200, Tomi Valkeinen wrote:
> On 2013-12-09 18:10, Thierry Reding wrote:
> 
> Btw, about single linux device handling multiple VC IDs: I noticed that
> the DSI spec has an example, in which a DSI peripheral receives
> interlaced video, and the video packets containing even field have VC ID
> 0 and packets for odd field have VC ID 1. I'm not sure how relevant
> interlaced video is, but I think there's an example where having
> separate linux devices for each VC ID would be somewhat clumsy.

Ugh... that's pretty bad.

> >> That call would go to the DSI hub driver. It knows how it routes the
> >> packets (the routing configuration is either hardcoded or passed via DT
> >> data), and then calls dsi_transmit op on SoC DSI, with VC number 2 and
> >> the packet data.
> > 
> > So it is the DSI hub driver that translates VC 0 to VC 2? How does it
> > know that VC 0 should be VC 2 but not VC 3? Does the panel 2 driver pass
> > in a different VC as panel 1?
> 
> I'm not sure what you mean. The routing information is passed via DT
> data and then configured to the hub HW, or is hardcoded in the hub hardware.

Okay, that's what I meant.

> > It's really the same thing. If you define VC IDs in a link local manner
> > you don't need them at all. What's the point in having them if you can
> > only reach a single device anyway.
> 
> You have to define the VC IDs somewhere in link-local manner for the HW
> to work. The panels in my example respond to VC ID 0, even if from SW
> (DSI host's) point of view they are addressed with VC ID 2 or 3. Both VC
> ID 0 and VC IDs 2 and 3 need to be programmed to the hub and possibly to
> the panel.

In that case I think maybe a better thing to do would be to dynamically
assign the VC ID's perhaps using some enumeration algorithm.

Or perhaps DSI devices are assigned fixed numbers as defined by software
(DT) and these are then used to program hubs.

> > From a software perspective we can always only describe devices from the
> > viewpoint where things leave software control. In this case the last
> > point of control is the DSI host. Therefore if we want to send a packet
> > to any device connected to the DSI host (whether directly or through a
> > hub), we need to pass some VC ID to the DSI host as a destination. That
> > number needs to be known up front.
> > 
> > So either you hide that information in some software framework, such as
> > you seem to be doing given your example above, and make the panel driver
> > call into the hub driver and have the hub driver translate the VC ID to
> > a different one.
> > 
> > The alternative would be to pass the correct address to the DSI host
> > directly. Either way, though, whatever is written into the registers of
> > the DSI host will end up the same, won't it?
> 
> Yes.
> 
> > You always address peripherals from the DSI host's viewpoint.
> 
> Yes. Except, of course, if the hub can be accessed with i2c also, in
> which case you need some other addressing mechanism.

Well, you address DSI peripherals from the DSI host's viewpoint. If they
have an additional I2C configuration interface then that isn't directly
related to DSI. Even if both devices are physically the same, the Linux
representation is a logical one, so you can very well have two types of
logical devices referring to the same physical device.

> >> The panels here should should be inside the hub node for DSI case. They
> >> are connected to the hub, not the SoC's DSI, and need the hub to be
> >> powered up and configured to work. And the hub should contain two output
> >> DSI busses, each having one panel with VC ID 0. Probably something like:
> >>
> >> dsi {
> >> 	hub at 0 {
> >> 		dsi at 0 {
> >> 			panel at 0 {
> >> 			};
> >> 		};
> >>
> >> 		dsi at 1 {
> >> 			panel at 0 {
> >> 			};
> >> 		};
> >> 	};
> >> };
> >>
> >> That kind of ruins the idea of representing the panels as DSI devices
> >> with VC IDs of 2 and 3. I don't know how that should be managed then...
> > 
> > Why does that ruin it? You still address panel at 0 using VC 2 and panel at 1
> > using VC 3, don't you? Therefore I see no reason why they shouldn't be
> > represented as DSI devices with their respective VC IDs.
> 
> The DT data should reflect the hardware. In this case both panels are
> addressed by the DSI hub with VC ID 0. That information has to be
> somewhere, and logical place for it is to define the panels as having VC
> ID 0.

It seems to me like for these cases we'd need some sort of automatic
enumeration (as I mentioned above) or some mechanism to translate from
lower busses to upper busses.

Perhaps something like this would work:

	dsi {
		hub at 0 {
			/*
			 * means the hub has VC ID 0 on the primary bus
			 * which translates to global VC ID 0
			 */
			 reg = <0>;

			panel at 0 {
				reg = <0>; /* link-local */
				assigned-addresses = <2>;
			};

			panel at 1 {
				reg = <1>; /* link-local */
				assigned-addresses = <3>;
			};
		};
	};

Where the assigned-addresses property is even somewhat standardized and
used within the PCI DT bindings.

That way a hub could easily use the reg property to find out about the
local port that it needs to map the assigned VC ID to. The assigned VC
ID is of course read from the assigned-addresses property.

> > What you say above could only be done if the hub actually had the
> > possibility to initiate transactions of its own. But in that case it
> > becomes a DSI host itself, rather than a simple hub.
> 
> Well, what is a "DSI host"? From HW perspective, the hub is a DSI host.
> Or actually two DSI hosts, one for each panel. It buffers the packets it
> receives from the SoC, which can come via DSI, i2c, or any other means,
> and then sends them forward.

Can it initiate transactions itself? Based on I2C messages that it
receives? If so I think that would qualify it as a DSI host. If on the
other hand it only routes DSI packets to downstream ports based on
registers configured via I2C, then it is not a DSI host, because it
cannot create DSI packets itself.

> >> It is normal to have multiple i2c devices on a bus. It's rare (never
> >> seen such) to have multiple DSI devices behind one DSI connector.
> > 
> > But you can have repeaters and such for I2C as well. Either way, I don't
> > see how the physical connections are related to whether DSI should or
> > should not be modeled as a Linux bus. PCI is modeled as a bus and can
> > easily originate from a single root complex.
> 
> True.
> 
> So, how would a hub be modeled? We'd still need to model the real
> hardware topology, right? That's what PCI does also, if I'm not mistaken.

Well, with PCI you have a whole lot more address space that can actually
reflect the topology. That's completely absent in DSI, so I don't think
we can really describe it accurately.

> Would we have one DSI bus for each DSI master on the SoC? And the hub
> would be a device on that bus, and the panels would be children of that
> hub device?
> 
> How are the logical VC ID (i.e. from SW perspective) and real VC ID (HW
> perspective) present there?

I think the above example should clarify this.

> Then, how does it work if we have an external DSI encoder, which uses
> i2c for control and DPI for input video data, and outputs DSI to a
> panel? Do we have a DSI bus somewhere? If we don't, how does the DSI
> panel driver, connected to that DSI encoder, work?

In that case I think the external DSI encoder would have to be
considered the DSI host, since it will be the one who initiates
transactions. A panel connected to it will be a simple DSI peripheral on
that host's bus.

> I guess in that case the external encoder driver would register a DSI
> bus. So generally speaking, an external encoder that outputs DSI would
> register a DSI bus except if it is a DSI receiver itself, and it can
> route DSI packets.

Yes. Although I think in the latter case it will typically only route
but not create packets of its own. Doing both seems to me like it would
be rather difficult to implement.

> >> If there was a simple way to have a single Linux device sitting on two
> >> buses (DSI and I2C), I think it could make sense to have a Linux DSI bus
> >> and Linux DSI device. But afaik it's not simple, and as we anyway have a
> >> video "link" for DSI which can easily used for the control side,
> > 
> > But how do we have that? How is it represented? There is no generic
> > framework that allows this. It's specifically what this patch series is
> > all about. We need a way to instantiate a device and have it hooked up
> > to a DSI host such that drivers can use the DSI host to send commands to
> > the peripherals.
> > 
> > Perhaps you have that in omapdss, the rest of us don't have that. We can
> > obviously duplicate what you've done to a large extent, but the goal was
> > to come up with something generic. If generic means that it'll take
> > endless amounts of discussions, I don't think I want generic for now.
> > I'd rather focus on something that works for my use-cases and get back
> > to generic later on.
> 
> As I said, I'm not nacking the patch. If it works for you, it's fine.
> 
> I just want to raise the issues I have encountered and though about. If
> we ever want to support all kinds of DSI configurations, my opinion is
> that this kind of bus approach is difficult, whereas a simpler model as
> used by omapdss works. Both can be generic code.
> 
> Then again, I've not worked much with linux buses, so I may be missing
> something and it's actually easy to support different DSI scenarios with
> a linux bus.

Okay, so we've talked about many of these issues now and I appreciate
you providing all that feedback. In an attempt to move things forward
can I propose that we start off with something simple so we can get
started and gather some experience with the matter.

The most difficult part will be the DT bindings. I've sent a proposal a
while ago[0]. It's explicitly very terse and I don't think it would
prevent any of the more advanced setups involving hubs in the future.
Basically it says you can have a DSI host and up to four children
attached to it. And it describes that you use the reg property to
describe the VC ID. If we don't have a hub in there, then the global and
link-local VC IDs will be the same anyway, so it should be safe from
that point of view. If we ever get something that's more complicated we
will have to revise the binding documentation and formalize much of what
we have discussed in this thread.

It would be great if you could have a look and see if you have any
concerns with it.

As for the code, I suggest we proceed with what Andrzej has proposed for
now. I know that you don't see this as a good solution, but I don't
think we'll find a common ground here and now, so we may as well proceed
with what we have. If it really turns out to cause problems later on I'm
sure we can rework it to meet everyone's needs. The infrastructure in
Andrzej's patch is only a kernel internal API, so we can change it in
whatever way we want if there's a need.

[0]: http://lists.freedesktop.org/archives/dri-devel/2013-December/049934.html

> >> it much simpler not to have the DSI bus at all. Especially as the DSI
> >> bus would have just one device anyway.
> > 
> > You keep saying that, and at the same time you keep bringing forth
> > arguments why it's important to support things such as DSI hubs. Can we
> > settle on one way or another?
> 
> Well, I keep saying that because I've been thinking that in the case we
> have a DSI hub, we would have multiple Linux DSI buses. One for SoC, and
> more for the DSI hub. If so, each of the buses have just one device.
> 
> If we can have one logical DSI bus, then it's different.

Yes, I think we should have a single logical bus per DSI host. All the
link-local aspects should be hidden within drivers. I'm thinking that
perhaps a DSI hub could be a special type of peripheral, much like a
bridge in PCI, with a means to instantiate children of its own (yet
still make them children of the DSI host bus) and providing a way to
translate between link-local (physical) and logical VC IDs.

> And I haven't said it's important to support DSI hubs. I've said I have
> not seen such in production, possibly because they are very difficult to
> use well and not worth the trouble. I wouldn't be surprised if there
> never will such a device supported in Linux kernel. (that's purely
> subjective, of course, and no, I make no guarantees that tomorrow
> somebody won't be asking for DSI hub support).

Okay, I like that mindset very much. No need to address something that
we're not sure we'll ever even have to support. We should be careful not
to make it impossible to support in the future, but given that in-kernel
APIs are allowed to change when needed, we only need to make sure the DT
is good enough to start with.

> My opinion is that as long as the DT data is good enough, we could as
> well forget the hubs and multiple devices on the Linux driver side, and
> consider DSI as a point-to-point video data link. If the DT is fine, we
> could later extend the drivers if there's need for hubs.

I think the binding that I've posted doesn't preclude extension for
things such as hubs. Again, it'd be of great help if you could take a
look and raise any concerns you have about it.

> >>> But it will obviously be some work to move to a generic "framework", if
> >>> you can call it that. The driver will likely need some major rewrite,
> >>> which I think will be the case anyway because this will be a DRM API and
> >>> you'll have to move to DRM to use it.
> >>
> >> Yep. I think the most important part is to have somewhat sane DT data
> >> with all the relevant information. It'd be nice to see an example of
> >> that kind of data there would be used with this patch.
> > 
> > Well the simplest case, which I think will probably cover about 99% of
> > use-cases would look something like this:
> > 
> > 	/* DSI host */
> > 	dsi at 54300000 {
> > 		#address-cells = <1>;
> > 		#size-cells = <0>;
> > 
> > 		/* DSI peripheral */
> > 		panel at 0 {
> > 			reg = <0>;
> > 		};
> > 	};
> 
> Yes, I think this looks fine. What I have in omapdss's current DT work
> tree is basically the same, except I use the V4L2 style video ports, so
> that I can construct longer video pipelines. If longer pipelines are not
> needed, the port information is not needed as it can be deduced from the
> above data (if it's ever needed).

Okay, good. That's actually a less abstract example from the DT binding,
so I'm hopeful we can at least agree on that. =)

> > Which in that case has a hard-coded VC 0 for the panel. Other more
> > complex use-cases could look like this:
> > 
> > 	dsi at 54300000 {
> > 		#address-cells = <1>;
> > 		#size-cells = <0>;
> > 
> > 		hub at 0 {
> > 			panel at 2 {
> > 				reg = <2>;
> > 			};
> > 
> > 			panel at 3 {
> > 				reg = <3>;
> > 			};
> > 		};
> > 	};
> > 
> > Shouldn't that be able to cover pretty much any scenario in existence?
> 
> This I think needs more information, as the routing needs to be defined.
> But I think we can ignore the hub side, no one is using those at the moment.

Okay. Let's continue that discussion when somebody comes up with a setup
that actually uses hubs.

Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/dri-devel/attachments/20131212/59427e00/attachment.pgp>


More information about the dri-devel mailing list