Message ID | 1376924669-28873-4-git-send-email-m.szyprowski@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > This patch adds device tree support for contiguous and reserved memory > regions defined in device tree. > diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt > +*** Reserved memory regions *** > + > +In /memory/reserved-memory node one can create additional nodes s/additional/child/ or s/additional/sub/ would make it clearer where the "additional" nodes should be placed. > +compatible: "linux,contiguous-memory-region" - enables binding of this > + region to Contiguous Memory Allocator (special region for > + contiguous memory allocations, shared with movable system > + memory, Linux kernel-specific), alternatively if > + "reserved-memory-region" - compatibility is defined, given > + region is assigned for exclusive usage for by the respective > + devices "alternatively" makes it sound like the two compatible values are mutually-exclusive. Perhaps make this a list, like: ---------- compatible: One or more of: - "linux,contiguous-memory-region" - enables binding of this region to Contiguous Memory Allocator (special region for contiguous memory allocations, shared with movable system memory, Linux kernel-specific). - "reserved-memory-region" - compatibility is defined, given region is assigned for exclusive usage for by the respective devices. ---------- "linux,contiguous-memory-region" is already long enough, but I'd slightly bikeshed towards "linux,contiguous-memory-allocator-region", or perhaps "linux,cma-region" since it's not really describing whether the memory is contiguous (at the level of /memory, each chunk of memory is contiguous...) > +*** Device node's properties *** > + > +Once regions in the /memory/reserved-memory node have been defined, they > +can be assigned to device nodes to enable respective device drivers to > +access them. The following properties are defined: > + > +memory-region = <&phandle_to_defined_region>; I think the naming of that property should more obviously match this binding and/or compatible value; perhaps cma-region or contiguous-memory-region?
Hi Stephen, On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: > On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > > This patch adds device tree support for contiguous and reserved memory > > regions defined in device tree. > > > > diff --git a/Documentation/devicetree/bindings/memory.txt > > b/Documentation/devicetree/bindings/memory.txt > > > > +*** Reserved memory regions *** > > + > > +In /memory/reserved-memory node one can create additional nodes > > s/additional/child/ or s/additional/sub/ would make it clearer where the > "additional" nodes should be placed. > > > +compatible: "linux,contiguous-memory-region" - enables binding of > > this > > + region to Contiguous Memory Allocator (special region for > > + contiguous memory allocations, shared with movable system > > + memory, Linux kernel-specific), alternatively if > > + "reserved-memory-region" - compatibility is defined, given > > + region is assigned for exclusive usage for by the respective > > + devices > > "alternatively" makes it sound like the two compatible values are > mutually-exclusive. Perhaps make this a list, like: > > ---------- > compatible: One or more of: > > - "linux,contiguous-memory-region" - enables binding of this > region to Contiguous Memory Allocator (special region for > contiguous memory allocations, shared with movable system > memory, Linux kernel-specific). > - "reserved-memory-region" - compatibility is defined, given > region is assigned for exclusive usage for by the respective > devices. > ---------- > > "linux,contiguous-memory-region" is already long enough, but I'd > slightly bikeshed towards "linux,contiguous-memory-allocator-region", or > perhaps "linux,cma-region" since it's not really describing whether the > memory is contiguous (at the level of /memory, each chunk of memory is > contiguous...) I'm not really sure if we need the "linux" prefix for "contiguous-memory- region". The concept of contiguous memory region is rather OS independent and tells us that memory allocated from this region will be contiguous. IMHO any OS is free to implement its own contiguous memory allocation method, without being limited to Linux CMA. Keep in mind that rationale behind those contiguous regions was that there are devices that require buffers contiguous in memory to operate correctly. But this is just nitpicking and I don't really have any strong opinion on this. > > +*** Device node's properties *** > > + > > +Once regions in the /memory/reserved-memory node have been defined, > > they +can be assigned to device nodes to enable respective device > > drivers to +access them. The following properties are defined: > > + > > +memory-region = <&phandle_to_defined_region>; > > I think the naming of that property should more obviously match this > binding and/or compatible value; perhaps cma-region or > contiguous-memory-region? This property is not CMA-specific. Any memory region can be given using the memory-region property and used to allocate buffers for particular device. Best regards, Tomasz
On 08/19/2013 04:02 PM, Tomasz Figa wrote: > Hi Stephen, > > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: >>> This patch adds device tree support for contiguous and reserved memory >>> regions defined in device tree. >>> >>> diff --git a/Documentation/devicetree/bindings/memory.txt >>> b/Documentation/devicetree/bindings/memory.txt >>> >>> +*** Reserved memory regions *** >>> + >>> +In /memory/reserved-memory node one can create additional nodes >> >> s/additional/child/ or s/additional/sub/ would make it clearer where the >> "additional" nodes should be placed. >> >>> +compatible: "linux,contiguous-memory-region" - enables binding > of >>> this >>> + region to Contiguous Memory Allocator (special region for >>> + contiguous memory allocations, shared with movable system >>> + memory, Linux kernel-specific), alternatively if >>> + "reserved-memory-region" - compatibility is defined, given >>> + region is assigned for exclusive usage for by the > respective >>> + devices >> >> "alternatively" makes it sound like the two compatible values are >> mutually-exclusive. Perhaps make this a list, like: >> >> ---------- >> compatible: One or more of: >> >> - "linux,contiguous-memory-region" - enables binding of this >> region to Contiguous Memory Allocator (special region for >> contiguous memory allocations, shared with movable system >> memory, Linux kernel-specific). >> - "reserved-memory-region" - compatibility is defined, given >> region is assigned for exclusive usage for by the respective >> devices. >> ---------- >> >> "linux,contiguous-memory-region" is already long enough, but I'd >> slightly bikeshed towards "linux,contiguous-memory-allocator-region", or >> perhaps "linux,cma-region" since it's not really describing whether the >> memory is contiguous (at the level of /memory, each chunk of memory is >> contiguous...) > > I'm not really sure if we need the "linux" prefix for "contiguous-memory- > region". The concept of contiguous memory region is rather OS independent > and tells us that memory allocated from this region will be contiguous. > IMHO any OS is free to implement its own contiguous memory allocation > method, without being limited to Linux CMA. > > Keep in mind that rationale behind those contiguous regions was that there > are devices that require buffers contiguous in memory to operate > correctly. > > But this is just nitpicking and I don't really have any strong opinion on > this. > >>> +*** Device node's properties *** >>> + >>> +Once regions in the /memory/reserved-memory node have been defined, >>> they +can be assigned to device nodes to enable respective device >>> drivers to +access them. The following properties are defined: >>> + >>> +memory-region = <&phandle_to_defined_region>; >> >> I think the naming of that property should more obviously match this >> binding and/or compatible value; perhaps cma-region or >> contiguous-memory-region? > > This property is not CMA-specific. Any memory region can be given using > the memory-region property and used to allocate buffers for particular > device. OK, that makes sense. What I'm looking for is some way to make it obvious that when you see a "memory-region" property in a node, you go look at the "memory.txt" rather than the DT binding for the node where that property appears. Right now, it doesn't seem that obvious to me. I think the real issue here is that my brief reading of memory.txt implies that arbitrary device nodes can include the memory-region property without the node's own binding having to document it; the property name is essentially "forced into" all other bindings. I think instead, memory.txt should say: ---------- ** Device node's properties *** Once regions in the /memory/reserved-memory node have been defined, they may be referenced by other device nodes. Bindings that wish to reference memory regions should explicitly document their use of the following property: memory-region = <&phandle_to_defined_region>; This property indicates that the device driver should use the memory region pointed by the given phandle. ---------- Also, what if a device needs multiple separate memory regions? Perhaps a GPU is forced to allocate displayable surfaces from addresses 0..32M and textures/off-screen-render-targets from 256M..384M or something whacky like that. In that case, we could either: a) Adjust memory.txt to allow multiple entries in memory-regions, and add an associated memory-region-names property. or: b) Adjust memory.txt not to mention any specific property names, but simply mention that other DT nodes can refer to define memory regions by phandle, and leave it up to individual bindings to define which property they use to reference the memory regions, perhaps with memory.txt providing a recommendation of memory-region for the simple case, but perhaps also allowing a custom case, e.g.: display-memory-region = <&phandl1e1>; texture-memory-region = <&phahndle2>;
On Monday 19 of August 2013 16:17:30 Stephen Warren wrote: > On 08/19/2013 04:02 PM, Tomasz Figa wrote: > > Hi Stephen, > > > > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: > >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > >>> This patch adds device tree support for contiguous and reserved > >>> memory > >>> regions defined in device tree. > >>> > >>> diff --git a/Documentation/devicetree/bindings/memory.txt > >>> b/Documentation/devicetree/bindings/memory.txt > >>> > >>> +*** Reserved memory regions *** > >>> + > >>> +In /memory/reserved-memory node one can create additional nodes > >> > >> s/additional/child/ or s/additional/sub/ would make it clearer where > >> the "additional" nodes should be placed. > >> > >>> +compatible: "linux,contiguous-memory-region" - enables binding > > > > of > > > >>> this > >>> + region to Contiguous Memory Allocator (special region for > >>> + contiguous memory allocations, shared with movable system > >>> + memory, Linux kernel-specific), alternatively if > >>> + "reserved-memory-region" - compatibility is defined, given > >>> + region is assigned for exclusive usage for by the > > > > respective > > > >>> + devices > >> > >> "alternatively" makes it sound like the two compatible values are > >> mutually-exclusive. Perhaps make this a list, like: > >> > >> ---------- > >> > >> compatible: One or more of: > >> - "linux,contiguous-memory-region" - enables binding of this > >> > >> region to Contiguous Memory Allocator (special region for > >> contiguous memory allocations, shared with movable system > >> memory, Linux kernel-specific). > >> > >> - "reserved-memory-region" - compatibility is defined, given > >> > >> region is assigned for exclusive usage for by the respective > >> devices. > >> > >> ---------- > >> > >> "linux,contiguous-memory-region" is already long enough, but I'd > >> slightly bikeshed towards "linux,contiguous-memory-allocator-region", > >> or perhaps "linux,cma-region" since it's not really describing > >> whether the memory is contiguous (at the level of /memory, each > >> chunk of memory is contiguous...) > > > > I'm not really sure if we need the "linux" prefix for > > "contiguous-memory- region". The concept of contiguous memory region > > is rather OS independent and tells us that memory allocated from this > > region will be contiguous. IMHO any OS is free to implement its own > > contiguous memory allocation method, without being limited to Linux > > CMA. > > > > Keep in mind that rationale behind those contiguous regions was that > > there are devices that require buffers contiguous in memory to > > operate correctly. > > > > But this is just nitpicking and I don't really have any strong opinion > > on this. > > > >>> +*** Device node's properties *** > >>> + > >>> +Once regions in the /memory/reserved-memory node have been defined, > >>> they +can be assigned to device nodes to enable respective device > >>> drivers to +access them. The following properties are defined: > >>> + > >>> +memory-region = <&phandle_to_defined_region>; > >> > >> I think the naming of that property should more obviously match this > >> binding and/or compatible value; perhaps cma-region or > >> contiguous-memory-region? > > > > This property is not CMA-specific. Any memory region can be given > > using > > the memory-region property and used to allocate buffers for particular > > device. > > OK, that makes sense. > > What I'm looking for is some way to make it obvious that when you see a > "memory-region" property in a node, you go look at the "memory.txt" > rather than the DT binding for the node where that property appears. > Right now, it doesn't seem that obvious to me. > > I think the real issue here is that my brief reading of memory.txt > implies that arbitrary device nodes can include the memory-region > property without the node's own binding having to document it; the > property name is essentially "forced into" all other bindings. > > I think instead, memory.txt should say: > > ---------- > ** Device node's properties *** > > Once regions in the /memory/reserved-memory node have been defined, they > may be referenced by other device nodes. Bindings that wish to > reference memory regions should explicitly document their use of the > following property: > > memory-region = <&phandle_to_defined_region>; > > This property indicates that the device driver should use the memory > region pointed by the given phandle. > ---------- > > Also, what if a device needs multiple separate memory regions? Perhaps a > GPU is forced to allocate displayable surfaces from addresses 0..32M > and textures/off-screen-render-targets from 256M..384M or something > whacky like that. In that case, we could either: > > a) Adjust memory.txt to allow multiple entries in memory-regions, and > add an associated memory-region-names property. > > or: > > b) Adjust memory.txt not to mention any specific property names, but > simply mention that other DT nodes can refer to define memory regions by > phandle, and leave it up to individual bindings to define which > property they use to reference the memory regions, perhaps with > memory.txt providing a recommendation of memory-region for the simple > case, but perhaps also allowing a custom case, e.g.: > > display-memory-region = <&phandl1e1>; > texture-memory-region = <&phahndle2>; Well, such setup simply cannot be handled by Linux today, as one device (aka one struct device) can only have one memory region bound to it. So this is not something we can implement today. I agree that the device tree should be able to describe such configurations, though, but I'm not sure if this should be done from this side. IMHO the concept of memport (or bus master) can be used to represent cases when multiple parts of an IP have different requirements for memory they work with. This is what Marek's patches adjusting MFC bindings to use memory-regions are also about. Best regards, Tomasz
On 08/19/2013 04:24 PM, Tomasz Figa wrote: > On Monday 19 of August 2013 16:17:30 Stephen Warren wrote: >> On 08/19/2013 04:02 PM, Tomasz Figa wrote: >>> Hi Stephen, >>> >>> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: >>>> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: >>>>> This patch adds device tree support for contiguous and reserved >>>>> memory >>>>> regions defined in device tree. >>>>> >>>>> diff --git a/Documentation/devicetree/bindings/memory.txt >>>>> b/Documentation/devicetree/bindings/memory.txt >>>>> >>>>> +*** Reserved memory regions *** >>>>> + >>>>> +In /memory/reserved-memory node one can create additional nodes >>>> >>>> s/additional/child/ or s/additional/sub/ would make it clearer where >>>> the "additional" nodes should be placed. >>>> >>>>> +compatible: "linux,contiguous-memory-region" - enables binding >>> >>> of >>> >>>>> this >>>>> + region to Contiguous Memory Allocator (special region for >>>>> + contiguous memory allocations, shared with movable system >>>>> + memory, Linux kernel-specific), alternatively if >>>>> + "reserved-memory-region" - compatibility is defined, given >>>>> + region is assigned for exclusive usage for by the >>> >>> respective >>> >>>>> + devices >>>> >>>> "alternatively" makes it sound like the two compatible values are >>>> mutually-exclusive. Perhaps make this a list, like: >>>> >>>> ---------- >>>> >>>> compatible: One or more of: >>>> - "linux,contiguous-memory-region" - enables binding of this >>>> >>>> region to Contiguous Memory Allocator (special region for >>>> contiguous memory allocations, shared with movable system >>>> memory, Linux kernel-specific). >>>> >>>> - "reserved-memory-region" - compatibility is defined, given >>>> >>>> region is assigned for exclusive usage for by the respective >>>> devices. >>>> >>>> ---------- >>>> >>>> "linux,contiguous-memory-region" is already long enough, but I'd >>>> slightly bikeshed towards "linux,contiguous-memory-allocator-region", >>>> or perhaps "linux,cma-region" since it's not really describing >>>> whether the memory is contiguous (at the level of /memory, each >>>> chunk of memory is contiguous...) >>> >>> I'm not really sure if we need the "linux" prefix for >>> "contiguous-memory- region". The concept of contiguous memory region >>> is rather OS independent and tells us that memory allocated from this >>> region will be contiguous. IMHO any OS is free to implement its own >>> contiguous memory allocation method, without being limited to Linux >>> CMA. >>> >>> Keep in mind that rationale behind those contiguous regions was that >>> there are devices that require buffers contiguous in memory to >>> operate correctly. >>> >>> But this is just nitpicking and I don't really have any strong opinion >>> on this. >>> >>>>> +*** Device node's properties *** >>>>> + >>>>> +Once regions in the /memory/reserved-memory node have been defined, >>>>> they +can be assigned to device nodes to enable respective device >>>>> drivers to +access them. The following properties are defined: >>>>> + >>>>> +memory-region = <&phandle_to_defined_region>; >>>> >>>> I think the naming of that property should more obviously match this >>>> binding and/or compatible value; perhaps cma-region or >>>> contiguous-memory-region? >>> >>> This property is not CMA-specific. Any memory region can be given >>> using >>> the memory-region property and used to allocate buffers for particular >>> device. >> >> OK, that makes sense. >> >> What I'm looking for is some way to make it obvious that when you see a >> "memory-region" property in a node, you go look at the "memory.txt" >> rather than the DT binding for the node where that property appears. >> Right now, it doesn't seem that obvious to me. >> >> I think the real issue here is that my brief reading of memory.txt >> implies that arbitrary device nodes can include the memory-region >> property without the node's own binding having to document it; the >> property name is essentially "forced into" all other bindings. >> >> I think instead, memory.txt should say: >> >> ---------- >> ** Device node's properties *** >> >> Once regions in the /memory/reserved-memory node have been defined, they >> may be referenced by other device nodes. Bindings that wish to >> reference memory regions should explicitly document their use of the >> following property: >> >> memory-region = <&phandle_to_defined_region>; >> >> This property indicates that the device driver should use the memory >> region pointed by the given phandle. >> ---------- >> >> Also, what if a device needs multiple separate memory regions? Perhaps a >> GPU is forced to allocate displayable surfaces from addresses 0..32M >> and textures/off-screen-render-targets from 256M..384M or something >> whacky like that. In that case, we could either: >> >> a) Adjust memory.txt to allow multiple entries in memory-regions, and >> add an associated memory-region-names property. >> >> or: >> >> b) Adjust memory.txt not to mention any specific property names, but >> simply mention that other DT nodes can refer to define memory regions by >> phandle, and leave it up to individual bindings to define which >> property they use to reference the memory regions, perhaps with >> memory.txt providing a recommendation of memory-region for the simple >> case, but perhaps also allowing a custom case, e.g.: >> >> display-memory-region = <&phandl1e1>; >> texture-memory-region = <&phahndle2>; > > Well, such setup simply cannot be handled by Linux today, as one device > (aka one struct device) can only have one memory region bound to it. So > this is not something we can implement today. Don't you just create "fake" struct devices to make this work, so that the top-level struct device is instantiated from DT, and the others created manually in the top-level device's probe routine, and the memory regions get attached to those "fake" child devices? Seems pretty conceptually easy. > I agree that the device tree should be able to describe such > configurations, good:-) > though, but I'm not sure if this should be done from this side. I'm not sure what "from this side" means. It seems pretty simple to adjust this patch to allow such HW to be represented, so shouldn't we just do it and be done with the question?
On Monday 19 of August 2013 16:27:14 Stephen Warren wrote: > On 08/19/2013 04:24 PM, Tomasz Figa wrote: > > On Monday 19 of August 2013 16:17:30 Stephen Warren wrote: > >> On 08/19/2013 04:02 PM, Tomasz Figa wrote: > >>> Hi Stephen, > >>> > >>> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: > >>>> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > >>>>> This patch adds device tree support for contiguous and reserved > >>>>> memory > >>>>> regions defined in device tree. > >>>>> > >>>>> diff --git a/Documentation/devicetree/bindings/memory.txt > >>>>> b/Documentation/devicetree/bindings/memory.txt > >>>>> > >>>>> +*** Reserved memory regions *** > >>>>> + > >>>>> +In /memory/reserved-memory node one can create additional nodes > >>>> > >>>> s/additional/child/ or s/additional/sub/ would make it clearer > >>>> where > >>>> the "additional" nodes should be placed. > >>>> > >>>>> +compatible: "linux,contiguous-memory-region" - enables binding > >>> > >>> of > >>> > >>>>> this > >>>>> + region to Contiguous Memory Allocator (special region for > >>>>> + contiguous memory allocations, shared with movable system > >>>>> + memory, Linux kernel-specific), alternatively if > >>>>> + "reserved-memory-region" - compatibility is defined, given > >>>>> + region is assigned for exclusive usage for by the > >>> > >>> respective > >>> > >>>>> + devices > >>>> > >>>> "alternatively" makes it sound like the two compatible values are > >>>> mutually-exclusive. Perhaps make this a list, like: > >>>> > >>>> ---------- > >>>> > >>>> compatible: One or more of: > >>>> - "linux,contiguous-memory-region" - enables binding of this > >>>> > >>>> region to Contiguous Memory Allocator (special region for > >>>> contiguous memory allocations, shared with movable system > >>>> memory, Linux kernel-specific). > >>>> > >>>> - "reserved-memory-region" - compatibility is defined, given > >>>> > >>>> region is assigned for exclusive usage for by the respective > >>>> devices. > >>>> > >>>> ---------- > >>>> > >>>> "linux,contiguous-memory-region" is already long enough, but I'd > >>>> slightly bikeshed towards > >>>> "linux,contiguous-memory-allocator-region", > >>>> or perhaps "linux,cma-region" since it's not really describing > >>>> whether the memory is contiguous (at the level of /memory, each > >>>> chunk of memory is contiguous...) > >>> > >>> I'm not really sure if we need the "linux" prefix for > >>> "contiguous-memory- region". The concept of contiguous memory region > >>> is rather OS independent and tells us that memory allocated from > >>> this > >>> region will be contiguous. IMHO any OS is free to implement its own > >>> contiguous memory allocation method, without being limited to Linux > >>> CMA. > >>> > >>> Keep in mind that rationale behind those contiguous regions was that > >>> there are devices that require buffers contiguous in memory to > >>> operate correctly. > >>> > >>> But this is just nitpicking and I don't really have any strong > >>> opinion > >>> on this. > >>> > >>>>> +*** Device node's properties *** > >>>>> + > >>>>> +Once regions in the /memory/reserved-memory node have been > >>>>> defined, > >>>>> they +can be assigned to device nodes to enable respective device > >>>>> drivers to +access them. The following properties are defined: > >>>>> + > >>>>> +memory-region = <&phandle_to_defined_region>; > >>>> > >>>> I think the naming of that property should more obviously match > >>>> this > >>>> binding and/or compatible value; perhaps cma-region or > >>>> contiguous-memory-region? > >>> > >>> This property is not CMA-specific. Any memory region can be given > >>> using > >>> the memory-region property and used to allocate buffers for > >>> particular > >>> device. > >> > >> OK, that makes sense. > >> > >> What I'm looking for is some way to make it obvious that when you see > >> a > >> "memory-region" property in a node, you go look at the "memory.txt" > >> rather than the DT binding for the node where that property appears. > >> Right now, it doesn't seem that obvious to me. > >> > >> I think the real issue here is that my brief reading of memory.txt > >> implies that arbitrary device nodes can include the memory-region > >> property without the node's own binding having to document it; the > >> property name is essentially "forced into" all other bindings. > >> > >> I think instead, memory.txt should say: > >> > >> ---------- > >> ** Device node's properties *** > >> > >> Once regions in the /memory/reserved-memory node have been defined, > >> they may be referenced by other device nodes. Bindings that wish to > >> reference memory regions should explicitly document their use of the > >> following property: > >> > >> memory-region = <&phandle_to_defined_region>; > >> > >> This property indicates that the device driver should use the memory > >> region pointed by the given phandle. > >> ---------- > >> > >> Also, what if a device needs multiple separate memory regions? > >> Perhaps a GPU is forced to allocate displayable surfaces from > >> addresses 0..32M and textures/off-screen-render-targets from > >> 256M..384M or something whacky like that. In that case, we could > >> either: > >> > >> a) Adjust memory.txt to allow multiple entries in memory-regions, and > >> add an associated memory-region-names property. > >> > >> or: > >> > >> b) Adjust memory.txt not to mention any specific property names, but > >> simply mention that other DT nodes can refer to define memory regions > >> by phandle, and leave it up to individual bindings to define which > >> property they use to reference the memory regions, perhaps with > >> memory.txt providing a recommendation of memory-region for the > >> simple case, but perhaps also allowing a custom case, e.g.: > >> > >> display-memory-region = <&phandl1e1>; > >> texture-memory-region = <&phahndle2>; > > > > Well, such setup simply cannot be handled by Linux today, as one > > device > > (aka one struct device) can only have one memory region bound to it. > > So > > this is not something we can implement today. > > Don't you just create "fake" struct devices to make this work, so that > the top-level struct device is instantiated from DT, and the others > created manually in the top-level device's probe routine, and the memory > regions get attached to those "fake" child devices? Seems pretty > conceptually easy. Correct. However you need those fake struct devices to be attached to some memory region and often other things like IOMMU. In fact, they aren't entirely fake, as they usually represent real bus masters of the IP. > > I agree that the device tree should be able to describe such > > configurations, > > good:-) > > > though, but I'm not sure if this should be done from this side. > > I'm not sure what "from this side" means. It seems pretty simple to > adjust this patch to allow such HW to be represented, so shouldn't we > just do it and be done with the question? Well, if it's just about modifying the binding to support such cases, but without actually adding support for them in Linux, then I guess it's fine. Otherwise a lot of memory management code (mostly the DMA mapping API and a lot of its users) would have to be almost completely reworked, which wouldn't be an easy task. Best regards, Tomasz
On 08/19/2013 04:40 PM, Tomasz Figa wrote: > On Monday 19 of August 2013 16:27:14 Stephen Warren wrote: >> On 08/19/2013 04:24 PM, Tomasz Figa wrote: >>> On Monday 19 of August 2013 16:17:30 Stephen Warren wrote: >>>> On 08/19/2013 04:02 PM, Tomasz Figa wrote: >>>>> Hi Stephen, >>>>> >>>>> On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: >>>>>> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: >>>>>>> This patch adds device tree support for contiguous and reserved >>>>>>> memory regions defined in device tree. >>>>>>> >>>>>>> diff --git a/Documentation/devicetree/bindings/memory.txt >>>>>>> b/Documentation/devicetree/bindings/memory.txt ... >>>> Also, what if a device needs multiple separate memory regions? >>>> Perhaps a GPU is forced to allocate displayable surfaces from >>>> addresses 0..32M and textures/off-screen-render-targets from >>>> 256M..384M or something whacky like that. In that case, we could >>>> either: >>>> >>>> a) Adjust memory.txt to allow multiple entries in memory-regions, and >>>> add an associated memory-region-names property. >>>> >>>> or: >>>> >>>> b) Adjust memory.txt not to mention any specific property names, but >>>> simply mention that other DT nodes can refer to define memory regions >>>> by phandle, and leave it up to individual bindings to define which >>>> property they use to reference the memory regions, perhaps with >>>> memory.txt providing a recommendation of memory-region for the >>>> simple case, but perhaps also allowing a custom case, e.g.: >>>> >>>> display-memory-region = <&phandl1e1>; >>>> texture-memory-region = <&phahndle2>; >>> >>> Well, such setup simply cannot be handled by Linux today, as one ... >>> I agree that the device tree should be able to describe such >>> configurations, ... > Well, if it's just about modifying the binding to support such cases, but > without actually adding support for them in Linux, then I guess it's fine. Yes. I don't care so much if the SW won't work (yet?), but I want to make sure the binding isn't going to need semantic changes.
Hello, On 8/20/2013 12:17 AM, Stephen Warren wrote: > On 08/19/2013 04:02 PM, Tomasz Figa wrote: > > Hi Stephen, > > > > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: > >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > >>> This patch adds device tree support for contiguous and reserved memory > >>> regions defined in device tree. > >>> > >>> diff --git a/Documentation/devicetree/bindings/memory.txt > >>> b/Documentation/devicetree/bindings/memory.txt > >>> > >>> +*** Reserved memory regions *** > >>> + > >>> +In /memory/reserved-memory node one can create additional nodes > >> > >> s/additional/child/ or s/additional/sub/ would make it clearer where the > >> "additional" nodes should be placed. > >> > >>> +compatible: "linux,contiguous-memory-region" - enables binding > > of > >>> this > >>> + region to Contiguous Memory Allocator (special region for > >>> + contiguous memory allocations, shared with movable system > >>> + memory, Linux kernel-specific), alternatively if > >>> + "reserved-memory-region" - compatibility is defined, given > >>> + region is assigned for exclusive usage for by the > > respective > >>> + devices > >> > >> "alternatively" makes it sound like the two compatible values are > >> mutually-exclusive. Perhaps make this a list, like: > >> > >> ---------- > >> compatible: One or more of: > >> > >> - "linux,contiguous-memory-region" - enables binding of this > >> region to Contiguous Memory Allocator (special region for > >> contiguous memory allocations, shared with movable system > >> memory, Linux kernel-specific). > >> - "reserved-memory-region" - compatibility is defined, given > >> region is assigned for exclusive usage for by the respective > >> devices. > >> ---------- > >> > >> "linux,contiguous-memory-region" is already long enough, but I'd > >> slightly bikeshed towards "linux,contiguous-memory-allocator-region", or > >> perhaps "linux,cma-region" since it's not really describing whether the > >> memory is contiguous (at the level of /memory, each chunk of memory is > >> contiguous...) > > > > I'm not really sure if we need the "linux" prefix for "contiguous-memory- > > region". The concept of contiguous memory region is rather OS independent > > and tells us that memory allocated from this region will be contiguous. > > IMHO any OS is free to implement its own contiguous memory allocation > > method, without being limited to Linux CMA. > > > > Keep in mind that rationale behind those contiguous regions was that there > > are devices that require buffers contiguous in memory to operate > > correctly. > > > > But this is just nitpicking and I don't really have any strong opinion on > > this. > > > >>> +*** Device node's properties *** > >>> + > >>> +Once regions in the /memory/reserved-memory node have been defined, > >>> they +can be assigned to device nodes to enable respective device > >>> drivers to +access them. The following properties are defined: > >>> + > >>> +memory-region = <&phandle_to_defined_region>; > >> > >> I think the naming of that property should more obviously match this > >> binding and/or compatible value; perhaps cma-region or > >> contiguous-memory-region? > > > > This property is not CMA-specific. Any memory region can be given using > > the memory-region property and used to allocate buffers for particular > > device. > > OK, that makes sense. > > What I'm looking for is some way to make it obvious that when you see a > "memory-region" property in a node, you go look at the "memory.txt" > rather than the DT binding for the node where that property appears. > Right now, it doesn't seem that obvious to me. > > I think the real issue here is that my brief reading of memory.txt > implies that arbitrary device nodes can include the memory-region > property without the node's own binding having to document it; the > property name is essentially "forced into" all other bindings. > > I think instead, memory.txt should say: > > ---------- > ** Device node's properties *** > > Once regions in the /memory/reserved-memory node have been defined, they > may be referenced by other device nodes. Bindings that wish to reference > memory regions should explicitly document their use of the following > property: > > memory-region = <&phandle_to_defined_region>; > > This property indicates that the device driver should use the memory > region pointed by the given phandle. > ---------- > > Also, what if a device needs multiple separate memory regions? Perhaps a > GPU is forced to allocate displayable surfaces from addresses 0..32M and > textures/off-screen-render-targets from 256M..384M or something whacky > like that. In that case, we could either: > > a) Adjust memory.txt to allow multiple entries in memory-regions, and > add an associated memory-region-names property. > > or: > > b) Adjust memory.txt not to mention any specific property names, but > simply mention that other DT nodes can refer to define memory regions by > phandle, and leave it up to individual bindings to define which property > they use to reference the memory regions, perhaps with memory.txt > providing a recommendation of memory-region for the simple case, but > perhaps also allowing a custom case, e.g.: > > display-memory-region = <&phandl1e1>; > texture-memory-region = <&phahndle2>; Support for multiple regions is something that need to be discussed separately. In case of Exynos hardware it is also related to iommu bindings and configuration, because each busmuster on the internal memory bus has separate iommu controller. Having each busmaster defined as a separate node, enables to put there the associated memory region and/or iommu controller as well as dma window properties (in case of limited dma window). However right now I would like to focus on the simple case (1 device, 1 memory region) and define bindings which can be extended later. I hope that my current proposal covers this (I will send updated binding documentation asap) and the initial support for reserved memory can be merged to -next soon. Best regards
On 08/20/2013 04:57 AM, Marek Szyprowski wrote: > Hello, > > On 8/20/2013 12:17 AM, Stephen Warren wrote: >> On 08/19/2013 04:02 PM, Tomasz Figa wrote: >> > Hi Stephen, >> > >> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: >> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: >> >>> This patch adds device tree support for contiguous and reserved >> memory >> >>> regions defined in device tree. >> >>> >> >>> diff --git a/Documentation/devicetree/bindings/memory.txt >> >>> b/Documentation/devicetree/bindings/memory.txt >> >>> >> >>> +*** Reserved memory regions *** >> >>> + >> >>> +In /memory/reserved-memory node one can create additional nodes >> >> >> >> s/additional/child/ or s/additional/sub/ would make it clearer >> where the >> >> "additional" nodes should be placed. >> >> >> >>> +compatible: "linux,contiguous-memory-region" - enables binding >> > of >> >>> this >> >>> + region to Contiguous Memory Allocator (special region for >> >>> + contiguous memory allocations, shared with movable system >> >>> + memory, Linux kernel-specific), alternatively if >> >>> + "reserved-memory-region" - compatibility is defined, given >> >>> + region is assigned for exclusive usage for by the >> > respective >> >>> + devices >> >> >> >> "alternatively" makes it sound like the two compatible values are >> >> mutually-exclusive. Perhaps make this a list, like: >> >> >> >> ---------- >> >> compatible: One or more of: >> >> >> >> - "linux,contiguous-memory-region" - enables binding of this >> >> region to Contiguous Memory Allocator (special region for >> >> contiguous memory allocations, shared with movable system >> >> memory, Linux kernel-specific). >> >> - "reserved-memory-region" - compatibility is defined, given >> >> region is assigned for exclusive usage for by the respective >> >> devices. >> >> ---------- >> >> >> >> "linux,contiguous-memory-region" is already long enough, but I'd >> >> slightly bikeshed towards >> "linux,contiguous-memory-allocator-region", or >> >> perhaps "linux,cma-region" since it's not really describing whether >> the >> >> memory is contiguous (at the level of /memory, each chunk of memory is >> >> contiguous...) >> > >> > I'm not really sure if we need the "linux" prefix for >> "contiguous-memory- >> > region". The concept of contiguous memory region is rather OS >> independent >> > and tells us that memory allocated from this region will be contiguous. >> > IMHO any OS is free to implement its own contiguous memory allocation >> > method, without being limited to Linux CMA. >> > >> > Keep in mind that rationale behind those contiguous regions was that >> there >> > are devices that require buffers contiguous in memory to operate >> > correctly. >> > >> > But this is just nitpicking and I don't really have any strong >> opinion on >> > this. >> > >> >>> +*** Device node's properties *** >> >>> + >> >>> +Once regions in the /memory/reserved-memory node have been defined, >> >>> they +can be assigned to device nodes to enable respective device >> >>> drivers to +access them. The following properties are defined: >> >>> + >> >>> +memory-region = <&phandle_to_defined_region>; >> >> >> >> I think the naming of that property should more obviously match this >> >> binding and/or compatible value; perhaps cma-region or >> >> contiguous-memory-region? >> > >> > This property is not CMA-specific. Any memory region can be given using >> > the memory-region property and used to allocate buffers for particular >> > device. >> >> OK, that makes sense. >> >> What I'm looking for is some way to make it obvious that when you see a >> "memory-region" property in a node, you go look at the "memory.txt" >> rather than the DT binding for the node where that property appears. >> Right now, it doesn't seem that obvious to me. >> >> I think the real issue here is that my brief reading of memory.txt >> implies that arbitrary device nodes can include the memory-region >> property without the node's own binding having to document it; the >> property name is essentially "forced into" all other bindings. >> >> I think instead, memory.txt should say: >> >> ---------- >> ** Device node's properties *** >> >> Once regions in the /memory/reserved-memory node have been defined, they >> may be referenced by other device nodes. Bindings that wish to reference >> memory regions should explicitly document their use of the following >> property: >> >> memory-region = <&phandle_to_defined_region>; >> >> This property indicates that the device driver should use the memory >> region pointed by the given phandle. >> ---------- >> >> Also, what if a device needs multiple separate memory regions? Perhaps a >> GPU is forced to allocate displayable surfaces from addresses 0..32M and >> textures/off-screen-render-targets from 256M..384M or something whacky >> like that. In that case, we could either: >> >> a) Adjust memory.txt to allow multiple entries in memory-regions, and >> add an associated memory-region-names property. >> >> or: >> >> b) Adjust memory.txt not to mention any specific property names, but >> simply mention that other DT nodes can refer to define memory regions by >> phandle, and leave it up to individual bindings to define which property >> they use to reference the memory regions, perhaps with memory.txt >> providing a recommendation of memory-region for the simple case, but >> perhaps also allowing a custom case, e.g.: >> >> display-memory-region = <&phandl1e1>; >> texture-memory-region = <&phahndle2>; > > Support for multiple regions is something that need to be discussed > separately. In case of Exynos hardware it is also related to iommu bindings > and configuration, because each busmuster on the internal memory bus has > separate iommu controller. Having each busmaster defined as a separate > node, > enables to put there the associated memory region and/or iommu > controller as > well as dma window properties (in case of limited dma window). > > However right now I would like to focus on the simple case (1 device, > 1 memory region) and define bindings which can be extended later. > I hope that my current proposal covers this (I will send updated binding > documentation asap) and the initial support for reserved memory can be > merged to -next soon. I don't believe that's a good approach unless you have at least a partial idea of how the current bindings will be extended to support multiple memory regions. Without a clear idea how that will eventually work, you run a real risk of not being able to extend the bindings in a 100% backwards-compatible way, and hence wishing to break DT ABI.
Hello, On 8/20/2013 6:35 PM, Stephen Warren wrote: > On 08/20/2013 04:57 AM, Marek Szyprowski wrote: > > Hello, > > > > On 8/20/2013 12:17 AM, Stephen Warren wrote: > >> On 08/19/2013 04:02 PM, Tomasz Figa wrote: > >> > Hi Stephen, > >> > > >> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: > >> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > >> >>> This patch adds device tree support for contiguous and reserved > >> memory > >> >>> regions defined in device tree. > >> >>> > >> >>> diff --git a/Documentation/devicetree/bindings/memory.txt > >> >>> b/Documentation/devicetree/bindings/memory.txt > >> >>> > >> >>> +*** Reserved memory regions *** > >> >>> + > >> >>> +In /memory/reserved-memory node one can create additional nodes > >> >> > >> >> s/additional/child/ or s/additional/sub/ would make it clearer > >> where the > >> >> "additional" nodes should be placed. > >> >> > >> >>> +compatible: "linux,contiguous-memory-region" - enables binding > >> > of > >> >>> this > >> >>> + region to Contiguous Memory Allocator (special region for > >> >>> + contiguous memory allocations, shared with movable system > >> >>> + memory, Linux kernel-specific), alternatively if > >> >>> + "reserved-memory-region" - compatibility is defined, given > >> >>> + region is assigned for exclusive usage for by the > >> > respective > >> >>> + devices > >> >> > >> >> "alternatively" makes it sound like the two compatible values are > >> >> mutually-exclusive. Perhaps make this a list, like: > >> >> > >> >> ---------- > >> >> compatible: One or more of: > >> >> > >> >> - "linux,contiguous-memory-region" - enables binding of this > >> >> region to Contiguous Memory Allocator (special region for > >> >> contiguous memory allocations, shared with movable system > >> >> memory, Linux kernel-specific). > >> >> - "reserved-memory-region" - compatibility is defined, given > >> >> region is assigned for exclusive usage for by the respective > >> >> devices. > >> >> ---------- > >> >> > >> >> "linux,contiguous-memory-region" is already long enough, but I'd > >> >> slightly bikeshed towards > >> "linux,contiguous-memory-allocator-region", or > >> >> perhaps "linux,cma-region" since it's not really describing whether > >> the > >> >> memory is contiguous (at the level of /memory, each chunk of memory is > >> >> contiguous...) > >> > > >> > I'm not really sure if we need the "linux" prefix for > >> "contiguous-memory- > >> > region". The concept of contiguous memory region is rather OS > >> independent > >> > and tells us that memory allocated from this region will be contiguous. > >> > IMHO any OS is free to implement its own contiguous memory allocation > >> > method, without being limited to Linux CMA. > >> > > >> > Keep in mind that rationale behind those contiguous regions was that > >> there > >> > are devices that require buffers contiguous in memory to operate > >> > correctly. > >> > > >> > But this is just nitpicking and I don't really have any strong > >> opinion on > >> > this. > >> > > >> >>> +*** Device node's properties *** > >> >>> + > >> >>> +Once regions in the /memory/reserved-memory node have been defined, > >> >>> they +can be assigned to device nodes to enable respective device > >> >>> drivers to +access them. The following properties are defined: > >> >>> + > >> >>> +memory-region = <&phandle_to_defined_region>; > >> >> > >> >> I think the naming of that property should more obviously match this > >> >> binding and/or compatible value; perhaps cma-region or > >> >> contiguous-memory-region? > >> > > >> > This property is not CMA-specific. Any memory region can be given using > >> > the memory-region property and used to allocate buffers for particular > >> > device. > >> > >> OK, that makes sense. > >> > >> What I'm looking for is some way to make it obvious that when you see a > >> "memory-region" property in a node, you go look at the "memory.txt" > >> rather than the DT binding for the node where that property appears. > >> Right now, it doesn't seem that obvious to me. > >> > >> I think the real issue here is that my brief reading of memory.txt > >> implies that arbitrary device nodes can include the memory-region > >> property without the node's own binding having to document it; the > >> property name is essentially "forced into" all other bindings. > >> > >> I think instead, memory.txt should say: > >> > >> ---------- > >> ** Device node's properties *** > >> > >> Once regions in the /memory/reserved-memory node have been defined, they > >> may be referenced by other device nodes. Bindings that wish to reference > >> memory regions should explicitly document their use of the following > >> property: > >> > >> memory-region = <&phandle_to_defined_region>; > >> > >> This property indicates that the device driver should use the memory > >> region pointed by the given phandle. > >> ---------- > >> > >> Also, what if a device needs multiple separate memory regions? Perhaps a > >> GPU is forced to allocate displayable surfaces from addresses 0..32M and > >> textures/off-screen-render-targets from 256M..384M or something whacky > >> like that. In that case, we could either: > >> > >> a) Adjust memory.txt to allow multiple entries in memory-regions, and > >> add an associated memory-region-names property. > >> > >> or: > >> > >> b) Adjust memory.txt not to mention any specific property names, but > >> simply mention that other DT nodes can refer to define memory regions by > >> phandle, and leave it up to individual bindings to define which property > >> they use to reference the memory regions, perhaps with memory.txt > >> providing a recommendation of memory-region for the simple case, but > >> perhaps also allowing a custom case, e.g.: > >> > >> display-memory-region = <&phandl1e1>; > >> texture-memory-region = <&phahndle2>; > > > > Support for multiple regions is something that need to be discussed > > separately. In case of Exynos hardware it is also related to iommu bindings > > and configuration, because each busmuster on the internal memory bus has > > separate iommu controller. Having each busmaster defined as a separate > > node, > > enables to put there the associated memory region and/or iommu > > controller as > > well as dma window properties (in case of limited dma window). > > > > However right now I would like to focus on the simple case (1 device, > > 1 memory region) and define bindings which can be extended later. > > I hope that my current proposal covers this (I will send updated binding > > documentation asap) and the initial support for reserved memory can be > > merged to -next soon. > > I don't believe that's a good approach unless you have at least a > partial idea of how the current bindings will be extended to support > multiple memory regions. > > Without a clear idea how that will eventually work, you run a real risk > of not being able to extend the bindings in a 100% backwards-compatible > way, and hence wishing to break DT ABI. Both already proposed approaches for extending them to support multiple memory regions are compatible with the 'single memory region' approach defined in my patches. Adding additional property with region names is probably the simplest way from binding perspective, while adding additional child nodes for each bus master or memory interface gives much more flexibility in describing hardware properties. Besides memory region, one can assign iommu controller or dma window properties to each such node. Best regards
On Tuesday 20 of August 2013 10:35:51 Stephen Warren wrote: > On 08/20/2013 04:57 AM, Marek Szyprowski wrote: > > Hello, > > > > On 8/20/2013 12:17 AM, Stephen Warren wrote: > >> On 08/19/2013 04:02 PM, Tomasz Figa wrote: > >> > Hi Stephen, > >> > > >> > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: > >> >> On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > >> >>> This patch adds device tree support for contiguous and reserved > >> > >> memory > >> > >> >>> regions defined in device tree. > >> >>> > >> >>> diff --git a/Documentation/devicetree/bindings/memory.txt > >> >>> b/Documentation/devicetree/bindings/memory.txt > >> >>> > >> >>> +*** Reserved memory regions *** > >> >>> + > >> >>> +In /memory/reserved-memory node one can create additional nodes > >> >> > >> >> s/additional/child/ or s/additional/sub/ would make it clearer > >> > >> where the > >> > >> >> "additional" nodes should be placed. > >> >> > >> >>> +compatible: "linux,contiguous-memory-region" - enables binding > >> > > >> > of > >> > > >> >>> this > >> >>> + region to Contiguous Memory Allocator (special region for > >> >>> + contiguous memory allocations, shared with movable system > >> >>> + memory, Linux kernel-specific), alternatively if > >> >>> + "reserved-memory-region" - compatibility is defined, > >> >>> given > >> >>> + region is assigned for exclusive usage for by the > >> > > >> > respective > >> > > >> >>> + devices > >> >> > >> >> "alternatively" makes it sound like the two compatible values are > >> >> mutually-exclusive. Perhaps make this a list, like: > >> >> > >> >> ---------- > >> >> > >> >> compatible: One or more of: > >> >> - "linux,contiguous-memory-region" - enables binding of this > >> >> > >> >> region to Contiguous Memory Allocator (special region for > >> >> contiguous memory allocations, shared with movable system > >> >> memory, Linux kernel-specific). > >> >> > >> >> - "reserved-memory-region" - compatibility is defined, given > >> >> > >> >> region is assigned for exclusive usage for by the respective > >> >> devices. > >> >> > >> >> ---------- > >> >> > >> >> "linux,contiguous-memory-region" is already long enough, but I'd > >> >> slightly bikeshed towards > >> > >> "linux,contiguous-memory-allocator-region", or > >> > >> >> perhaps "linux,cma-region" since it's not really describing whether > >> > >> the > >> > >> >> memory is contiguous (at the level of /memory, each chunk of memory > >> >> is > >> >> contiguous...) > >> > > >> > I'm not really sure if we need the "linux" prefix for > >> > >> "contiguous-memory- > >> > >> > region". The concept of contiguous memory region is rather OS > >> > >> independent > >> > >> > and tells us that memory allocated from this region will be > >> > contiguous. > >> > IMHO any OS is free to implement its own contiguous memory > >> > allocation > >> > method, without being limited to Linux CMA. > >> > > >> > Keep in mind that rationale behind those contiguous regions was that > >> > >> there > >> > >> > are devices that require buffers contiguous in memory to operate > >> > correctly. > >> > > >> > But this is just nitpicking and I don't really have any strong > >> > >> opinion on > >> > >> > this. > >> > > >> >>> +*** Device node's properties *** > >> >>> + > >> >>> +Once regions in the /memory/reserved-memory node have been > >> >>> defined, > >> >>> they +can be assigned to device nodes to enable respective device > >> >>> drivers to +access them. The following properties are defined: > >> >>> + > >> >>> +memory-region = <&phandle_to_defined_region>; > >> >> > >> >> I think the naming of that property should more obviously match > >> >> this > >> >> binding and/or compatible value; perhaps cma-region or > >> >> contiguous-memory-region? > >> > > >> > This property is not CMA-specific. Any memory region can be given > >> > using > >> > the memory-region property and used to allocate buffers for > >> > particular > >> > device. > >> > >> OK, that makes sense. > >> > >> What I'm looking for is some way to make it obvious that when you see > >> a > >> "memory-region" property in a node, you go look at the "memory.txt" > >> rather than the DT binding for the node where that property appears. > >> Right now, it doesn't seem that obvious to me. > >> > >> I think the real issue here is that my brief reading of memory.txt > >> implies that arbitrary device nodes can include the memory-region > >> property without the node's own binding having to document it; the > >> property name is essentially "forced into" all other bindings. > >> > >> I think instead, memory.txt should say: > >> > >> ---------- > >> ** Device node's properties *** > >> > >> Once regions in the /memory/reserved-memory node have been defined, > >> they > >> may be referenced by other device nodes. Bindings that wish to > >> reference > >> memory regions should explicitly document their use of the following > >> property: > >> > >> memory-region = <&phandle_to_defined_region>; > >> > >> This property indicates that the device driver should use the memory > >> region pointed by the given phandle. > >> ---------- > >> > >> Also, what if a device needs multiple separate memory regions? Perhaps > >> a > >> GPU is forced to allocate displayable surfaces from addresses 0..32M > >> and > >> textures/off-screen-render-targets from 256M..384M or something whacky > >> like that. In that case, we could either: > >> > >> a) Adjust memory.txt to allow multiple entries in memory-regions, and > >> add an associated memory-region-names property. > >> > >> or: > >> > >> b) Adjust memory.txt not to mention any specific property names, but > >> simply mention that other DT nodes can refer to define memory regions > >> by > >> phandle, and leave it up to individual bindings to define which > >> property > >> they use to reference the memory regions, perhaps with memory.txt > >> providing a recommendation of memory-region for the simple case, but > >> perhaps also allowing a custom case, e.g.: > >> > >> display-memory-region = <&phandl1e1>; > >> texture-memory-region = <&phahndle2>; > > > > Support for multiple regions is something that need to be discussed > > separately. In case of Exynos hardware it is also related to iommu > > bindings and configuration, because each busmuster on the internal > > memory bus has separate iommu controller. Having each busmaster > > defined as a separate node, > > enables to put there the associated memory region and/or iommu > > controller as > > well as dma window properties (in case of limited dma window). > > > > However right now I would like to focus on the simple case (1 device, > > 1 memory region) and define bindings which can be extended later. > > I hope that my current proposal covers this (I will send updated > > binding > > documentation asap) and the initial support for reserved memory can be > > merged to -next soon. > > I don't believe that's a good approach unless you have at least a > partial idea of how the current bindings will be extended to support > multiple memory regions. I believe that at least three "at least partial" ideas have been brought in this thread. Moreover, I don't think that defining the simple binding now would stop us from extending it according to any of those ideas in any way. > Without a clear idea how that will eventually work, you run a real risk > of not being able to extend the bindings in a 100% backwards-compatible > way, and hence wishing to break DT ABI. As a fallback you can always define a new binding, while keeping support for old one. Of course this is the last resort, but it is not that simple to find a case that couldn't be supported without breaking the ABI. Best regards, Tomasz
I have a suggestion here. I recall that CHRP had a reserved node definition which essentially, since it was not a lot more than a definition of the bare minimum node that can describe a memory region, acted as a way to carve out peripheral addresses. In this case, the device_type would be "reserved" and a property to mark it as for the Linux contiguous memory allocator would be prudent here. This way nothing new is being defined except the property. In the case you want default regions and supplemental regions, give the linux,contiguous-memory-region property a value. In the case of the reserved node, the name could be "default" though and CMA could special-case this. It doesn't even need to be called reserved-memory or be a child node of it's own, then, but I also guess this would mean duplicating #address-cells and #size-cells in every node (that said.. isn't there a case for a 32-bit system having a >32-bit memory map somewhere that the kernel somehow needs to know about? On PowerPC I've seen 8GB hooked up to it on CPUs that didn't have 36-bit addressing, and therefore could not do anything with that amount of memory. But the DMA controllers in this case were designed around 36-bit addressing and could easily access the upper 4GB.. it would have come in handy for a kind of DMA-assisted buffering whereby you wanted to put all your network or "graphics" stuff in a safe place and copy it in and out as needed, or even as 4GB of magical swap space driven by a custom DMA driver) The naming of nodes is not really "important" in device-tree, in this case it might make sense in the same way the regulator guys specify regulators. In any case where the "default" name does not exist, then the first parsed becomes the default, but this does mean we'd be kind of restricting the namespace for everyone based on a Linux kernel behavior.. If you can search for the device_type = "memory" node you can also search for all nodes matching device_type = "reserved" under the memory node, with the appropriate property in place to bundle them up for adding to CMA, and just carve it out. In fact, this would work without needing to be in the /memory node at all. Hooray for device_type, long live device_type? :D -- Matt On Mon, Aug 19, 2013 at 10:04 AM, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > This patch adds device tree support for contiguous and reserved memory > regions defined in device tree. > > Large memory blocks can be reliably reserved only during early boot. > This must happen before the whole memory management subsystem is > initialized, because we need to ensure that the given contiguous blocks > are not yet allocated by kernel. Also it must happen before kernel > mappings for the whole low memory are created, to ensure that there will > be no mappings (for reserved blocks) or mapping with special properties > can be created (for CMA blocks). This all happens before device tree > structures are unflattened, so we need to get reserved memory layout > directly from fdt. > > Later, those reserved memory regions are assigned to devices on each > device structure initialization. > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> > Acked-by: Kyungmin Park <kyungmin.park@samsung.com> > Acked-by: Michal Nazarewicz <mina86@mina86.com> > Acked-by: Tomasz Figa <t.figa@samsung.com> > --- > Documentation/devicetree/bindings/memory.txt | 166 ++++++++++++++++++++++++ > drivers/of/Kconfig | 6 + > drivers/of/Makefile | 1 + > drivers/of/of_reserved_mem.c | 175 ++++++++++++++++++++++++++ > drivers/of/platform.c | 5 + > include/linux/of_reserved_mem.h | 14 +++ > 6 files changed, 367 insertions(+) > create mode 100644 Documentation/devicetree/bindings/memory.txt > create mode 100644 drivers/of/of_reserved_mem.c > create mode 100644 include/linux/of_reserved_mem.h > > diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt > new file mode 100644 > index 0000000..90e96278 > --- /dev/null > +++ b/Documentation/devicetree/bindings/memory.txt > @@ -0,0 +1,166 @@ > +*** Memory binding *** > + > +The /memory node provides basic information about the address and size > +of the physical memory. This node is usually filled or updated by the > +bootloader, depending on the actual memory configuration of the given > +hardware. > + > +The memory layout is described by the following node: > + > +/ { > + #address-cells = <(n)>; > + #size-cells = <(m)>; > + memory { > + device_type = "memory"; > + reg = <(baseaddr1) (size1) > + (baseaddr2) (size2) > + ... > + (baseaddrN) (sizeN)>; > + }; > + ... > +}; > + > +A memory node follows the typical device tree rules for "reg" property: > +n: number of cells used to store base address value > +m: number of cells used to store size value > +baseaddrX: defines a base address of the defined memory bank > +sizeX: the size of the defined memory bank > + > + > +More than one memory bank can be defined. > + > + > +*** Reserved memory regions *** > + > +In /memory/reserved-memory node one can create additional nodes > +describing particular reserved (excluded from normal use) memory > +regions. Such memory regions are usually designed for the special usage > +by various device drivers. A good example are contiguous memory > +allocations or memory sharing with other operating system on the same > +hardware board. Those special memory regions might depend on the board > +configuration and devices used on the target system. > + > +Parameters for each memory region can be encoded into the device tree > +with the following convention: > + > +[(label):] (name) { > + compatible = "linux,contiguous-memory-region", "reserved-memory-region"; > + reg = <(address) (size)>; > + (linux,default-contiguous-region); > +}; > + > +compatible: "linux,contiguous-memory-region" - enables binding of this > + region to Contiguous Memory Allocator (special region for > + contiguous memory allocations, shared with movable system > + memory, Linux kernel-specific), alternatively if > + "reserved-memory-region" - compatibility is defined, given > + region is assigned for exclusive usage for by the respective > + devices > + > +reg: standard property defining the base address and size of > + the memory region > + > +linux,default-contiguous-region: property indicating that the region > + is the default region for all contiguous memory > + allocations, Linux specific (optional) > + > +It is optional to specify the base address, so if one wants to use > +autoconfiguration of the base address, '0' can be specified as a base > +address in the 'reg' property. > + > +The /memory/reserved-memory node must contain the same #address-cells > +and #size-cells value as the root node. > + > + > +*** Device node's properties *** > + > +Once regions in the /memory/reserved-memory node have been defined, they > +can be assigned to device nodes to enable respective device drivers to > +access them. The following properties are defined: > + > +memory-region = <&phandle_to_defined_region>; > + > +This property indicates that the device driver should use the memory > +region pointed by the given phandle. > + > + > +*** Example *** > + > +This example defines a memory consisting of 4 memory banks. 3 contiguous > +regions are defined for Linux kernel, one default of all device drivers > +(named contig_mem, placed at 0x72000000, 64MiB), one dedicated to the > +framebuffer device (labelled display_mem, placed at 0x78000000, 8MiB) > +and one for multimedia processing (labelled multimedia_mem, placed at > +0x77000000, 64MiB). 'display_mem' region is then assigned to fb@12300000 > +device for DMA memory allocations (Linux kernel drivers will use CMA is > +available or dma-exclusive usage otherwise). 'multimedia_mem' is > +assigned to scaler@12500000 and codec@12600000 devices for contiguous > +memory allocations when CMA driver is enabled. > + > +The reason for creating a separate region for framebuffer device is to > +match the framebuffer base address to the one configured by bootloader, > +so once Linux kernel drivers starts no glitches on the displayed boot > +logo appears. Scaller and codec drivers should share the memory > +allocations. > + > +/ { > + #address-cells = <1>; > + #size-cells = <1>; > + > + /* ... */ > + > + memory { > + reg = <0x40000000 0x10000000 > + 0x50000000 0x10000000 > + 0x60000000 0x10000000 > + 0x70000000 0x10000000>; > + > + reserved-memory { > + #address-cells = <1>; > + #size-cells = <1>; > + > + /* > + * global autoconfigured region for contiguous allocations > + * (used only with Contiguous Memory Allocator) > + */ > + contig_region@0 { > + compatible = "linux,contiguous-memory-region"; > + reg = <0x0 0x4000000>; > + linux,default-contiguous-region; > + }; > + > + /* > + * special region for framebuffer > + */ > + display_mem: region@78000000 { > + compatible = "linux,contiguous-memory-region", "reserved-memory-region"; > + reg = <0x78000000 0x800000>; > + }; > + > + /* > + * special region for multimedia processing devices > + */ > + multimedia_mem: region@77000000 { > + compatible = "linux,contiguous-memory-region"; > + reg = <0x77000000 0x4000000>; > + }; > + }; > + }; > + > + /* ... */ > + > + fb0: fb@12300000 { > + status = "okay"; > + memory-region = <&display_mem>; > + }; > + > + scaler: scaler@12500000 { > + status = "okay"; > + memory-region = <&multimedia_mem>; > + }; > + > + codec: codec@12600000 { > + status = "okay"; > + memory-region = <&multimedia_mem>; > + }; > +}; > diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig > index 80e5c13..a83ab43 100644 > --- a/drivers/of/Kconfig > +++ b/drivers/of/Kconfig > @@ -80,4 +80,10 @@ config OF_MTD > depends on MTD > def_bool y > > +config OF_RESERVED_MEM > + depends on CMA || (HAVE_GENERIC_DMA_COHERENT && HAVE_MEMBLOCK) > + def_bool y > + help > + Initialization code for DMA reserved memory > + > endmenu # OF > diff --git a/drivers/of/Makefile b/drivers/of/Makefile > index 1f9c0c4..e7e3322 100644 > --- a/drivers/of/Makefile > +++ b/drivers/of/Makefile > @@ -10,3 +10,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o > obj-$(CONFIG_OF_PCI) += of_pci.o > obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o > obj-$(CONFIG_OF_MTD) += of_mtd.o > +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o > diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c > new file mode 100644 > index 0000000..95563d33 > --- /dev/null > +++ b/drivers/of/of_reserved_mem.c > @@ -0,0 +1,175 @@ > +/* > + * Device tree based initialization code for reserved memory. > + * > + * Copyright (c) 2013 Samsung Electronics Co., Ltd. > + * http://www.samsung.com > + * Author: Marek Szyprowski <m.szyprowski@samsung.com> > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation; either version 2 of the > + * License or (at your optional) any later version of the license. > + */ > + > +#include <asm/dma-contiguous.h> > + > +#include <linux/memblock.h> > +#include <linux/err.h> > +#include <linux/of.h> > +#include <linux/of_fdt.h> > +#include <linux/of_platform.h> > +#include <linux/mm.h> > +#include <linux/sizes.h> > +#include <linux/mm_types.h> > +#include <linux/dma-contiguous.h> > +#include <linux/dma-mapping.h> > +#include <linux/of_reserved_mem.h> > + > +#define MAX_RESERVED_REGIONS 16 > +struct reserved_mem { > + phys_addr_t base; > + unsigned long size; > + struct cma *cma; > + char name[32]; > +}; > +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; > +static int reserved_mem_count; > + > +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname, > + int depth, void *data) > +{ > + struct reserved_mem *rmem = &reserved_mem[reserved_mem_count]; > + phys_addr_t base, size; > + int is_cma, is_reserved; > + unsigned long len; > + const char *status; > + __be32 *prop; > + > + is_cma = IS_ENABLED(CONFIG_CMA) && > + of_flat_dt_is_compatible(node, "linux,contiguous-memory-region"); > + is_reserved = of_flat_dt_is_compatible(node, "reserved-memory-region"); > + > + if (!is_reserved && !is_cma) { > + /* ignore node and scan next one */ > + return 0; > + } > + > + status = of_get_flat_dt_prop(node, "status", &len); > + if (status && strcmp(status, "okay") != 0) { > + /* ignore disabled node nad scan next one */ > + return 0; > + } > + > + prop = of_get_flat_dt_prop(node, "reg", &len); > + if (!prop || (len < (dt_root_size_cells + dt_root_addr_cells) * > + sizeof(__be32))) { > + pr_err("Reserved mem: node %s, incorrect \"reg\" property\n", > + uname); > + /* ignore node and scan next one */ > + return 0; > + } > + base = dt_mem_next_cell(dt_root_addr_cells, &prop); > + size = dt_mem_next_cell(dt_root_size_cells, &prop); > + > + if (!size) { > + /* ignore node and scan next one */ > + return 0; > + } > + > + pr_info("Reserved mem: found %s, memory base %lx, size %ld MiB\n", > + uname, (unsigned long)base, (unsigned long)size / SZ_1M); > + > + if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) > + return -ENOSPC; > + > + rmem->base = base; > + rmem->size = size; > + strlcpy(rmem->name, uname, sizeof(rmem->name)); > + > + if (is_cma) { > + struct cma *cma; > + if (dma_contiguous_reserve_area(size, base, 0, &cma) == 0) { > + rmem->cma = cma; > + reserved_mem_count++; > + if (of_get_flat_dt_prop(node, > + "linux,default-contiguous-region", > + NULL)) > + dma_contiguous_default_area = cma; > + } > + } else if (is_reserved) { > + if (memblock_remove(base, size) == 0) > + reserved_mem_count++; > + else > + pr_err("Failed to reserve memory for %s\n", uname); > + } > + > + return 0; > +} > + > +static struct reserved_mem *get_dma_memory_region(struct device *dev) > +{ > + struct device_node *node; > + const char *name; > + int i; > + > + node = of_parse_phandle(dev->of_node, "memory-region", 0); > + if (!node) > + return NULL; > + > + name = kbasename(node->full_name); > + for (i = 0; i < reserved_mem_count; i++) > + if (strcmp(name, reserved_mem[i].name) == 0) > + return &reserved_mem[i]; > + return NULL; > +} > + > +/** > + * of_reserved_mem_device_init() - assign reserved memory region to given device > + * > + * This function assign memory region pointed by "memory-region" device tree > + * property to the given device. > + */ > +void of_reserved_mem_device_init(struct device *dev) > +{ > + struct reserved_mem *region = get_dma_memory_region(dev); > + if (!region) > + return; > + > + if (region->cma) { > + dev_set_cma_area(dev, region->cma); > + pr_info("Assigned CMA %s to %s device\n", region->name, > + dev_name(dev)); > + } else { > + if (dma_declare_coherent_memory(dev, region->base, region->base, > + region->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) != 0) > + pr_info("Declared reserved memory %s to %s device\n", > + region->name, dev_name(dev)); > + } > +} > + > +/** > + * of_reserved_mem_device_release() - release reserved memory device structures > + * > + * This function releases structures allocated for memory region handling for > + * the given device. > + */ > +void of_reserved_mem_device_release(struct device *dev) > +{ > + struct reserved_mem *region = get_dma_memory_region(dev); > + if (!region && !region->cma) > + dma_release_declared_memory(dev); > +} > + > +/** > + * early_init_dt_scan_reserved_mem() - create reserved memory regions > + * > + * This function grabs memory from early allocator for device exclusive use > + * defined in device tree structures. It should be called by arch specific code > + * once the early allocator (memblock) has been activated and all other > + * subsystems have already allocated/reserved memory. > + */ > +void __init early_init_dt_scan_reserved_mem(void) > +{ > + of_scan_flat_dt_by_path("/memory/reserved-memory", > + fdt_scan_reserved_mem, NULL); > +} > diff --git a/drivers/of/platform.c b/drivers/of/platform.c > index e0a6514..1e4e91d 100644 > --- a/drivers/of/platform.c > +++ b/drivers/of/platform.c > @@ -21,6 +21,7 @@ > #include <linux/of_device.h> > #include <linux/of_irq.h> > #include <linux/of_platform.h> > +#include <linux/of_reserved_mem.h> > #include <linux/platform_device.h> > > const struct of_device_id of_default_bus_match_table[] = { > @@ -196,6 +197,7 @@ EXPORT_SYMBOL(of_device_alloc); > * Returns pointer to created platform device, or NULL if a device was not > * registered. Unavailable devices will not get registered. > */ > + > struct platform_device *of_platform_device_create_pdata( > struct device_node *np, > const char *bus_id, > @@ -218,6 +220,8 @@ struct platform_device *of_platform_device_create_pdata( > dev->dev.bus = &platform_bus_type; > dev->dev.platform_data = platform_data; > > + of_reserved_mem_device_init(&dev->dev); > + > /* We do not fill the DMA ops for platform devices by default. > * This is currently the responsibility of the platform code > * to do such, possibly using a device notifier > @@ -225,6 +229,7 @@ struct platform_device *of_platform_device_create_pdata( > > if (of_device_add(dev) != 0) { > platform_device_put(dev); > + of_reserved_mem_device_release(&dev->dev); > return NULL; > } > > diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h > new file mode 100644 > index 0000000..c841282 > --- /dev/null > +++ b/include/linux/of_reserved_mem.h > @@ -0,0 +1,14 @@ > +#ifndef __OF_RESERVED_MEM_H > +#define __OF_RESERVED_MEM_H > + > +#ifdef CONFIG_OF_RESERVED_MEM > +void of_reserved_mem_device_init(struct device *dev); > +void of_reserved_mem_device_release(struct device *dev); > +void early_init_dt_scan_reserved_mem(void); > +#else > +static inline void of_reserved_mem_device_init(struct device *dev) { } > +static inline void of_reserved_mem_device_release(struct device *dev) { } > +static inline void early_init_dt_scan_reserved_mem(void) { } > +#endif > + > +#endif /* __OF_RESERVED_MEM_H */ > -- > 1.7.9.5 > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
On 08/21/2013 08:38 AM, Marek Szyprowski wrote: ... >> >> b) Adjust memory.txt not to mention any specific property names, but >> >> simply mention that other DT nodes can refer to define memory regions by >> >> phandle, and leave it up to individual bindings to define which property >> >> they use to reference the memory regions, perhaps with memory.txt >> >> providing a recommendation of memory-region for the simple case I think if we just make that change to the binding doc, it'll be fine. It's obvious how to extend the binding then.
On 08/23/2013 02:39 AM, wrote: > From: Marek Szyprowski <m.szyprowski@samsung.com> > > This patch adds device tree support for contiguous and reserved memory > regions defined in device tree. > > Large memory blocks can be reliably reserved only during early boot. > This must happen before the whole memory management subsystem is > initialized, because we need to ensure that the given contiguous blocks > are not yet allocated by kernel. Also it must happen before kernel > mappings for the whole low memory are created, to ensure that there will > be no mappings (for reserved blocks) or mapping with special properties > can be created (for CMA blocks). This all happens before device tree > structures are unflattened, so we need to get reserved memory layout > directly from fdt. > > Later, those reserved memory regions are assigned to devices on each > device structure initialization. I think the binding looks OK now; just a couple minor comments below. > diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt > +*** Reserved memory regions *** > +compatible: one or more of: > + - "linux,contiguous-memory-region" - enables binding of this > + region to Contiguous Memory Allocator (special region for > + contiguous memory allocations, shared with movable system > + memory, Linux kernel-specific). > + - "reserved-memory-region" - compatibility is defined, given > + region is assigned for exclusive usage for by the respective > + devices. I'm slightly hesitant to agree with "linux" in the name here, since it seems like the concept of a memory region where DMA buffers/... should be allocated is pretty OS-independant. Similar for: > +linux,default-contiguous-region: property indicating that the region > + is the default region for all contiguous memory > + allocations, Linux specific (optional) But, I guess there's nothing stopping any other OS from parsing this same property, so I suppose it's OK. What do other DT maintainers think? > +*** Example *** > + reserved-memory { ... > + contig_region@0 { ... > + display_mem: region@78000000 { ... > + multimedia_mem: region@77000000 { Nit: I think all 3 of those nodes should be called region, but it's probably fine as-is. So, the binding, Acked-by: Stephen Warren <swarren@nvidia.com>
On Mon, Aug 19, 2013 at 10:04 AM, Marek Szyprowski <m.szyprowski@samsung.com> wrote: > This patch adds device tree support for contiguous and reserved memory > regions defined in device tree. > > Large memory blocks can be reliably reserved only during early boot. > This must happen before the whole memory management subsystem is > initialized, because we need to ensure that the given contiguous blocks > are not yet allocated by kernel. Also it must happen before kernel > mappings for the whole low memory are created, to ensure that there will > be no mappings (for reserved blocks) or mapping with special properties > can be created (for CMA blocks). This all happens before device tree > structures are unflattened, so we need to get reserved memory layout > directly from fdt. > > Later, those reserved memory regions are assigned to devices on each > device structure initialization. > > Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com> > Acked-by: Kyungmin Park <kyungmin.park@samsung.com> > Acked-by: Michal Nazarewicz <mina86@mina86.com> > Acked-by: Tomasz Figa <t.figa@samsung.com> Reviewed-by: Rob Herring <rob.herring@calxeda.com>
On Tue, 20 Aug 2013 00:02:37 +0200, Tomasz Figa <tomasz.figa@gmail.com> wrote: > Hi Stephen, > > On Monday 19 of August 2013 15:49:20 Stephen Warren wrote: > > On 08/19/2013 09:04 AM, Marek Szyprowski wrote: > > > This patch adds device tree support for contiguous and reserved memory > > > regions defined in device tree. > > > > > > diff --git a/Documentation/devicetree/bindings/memory.txt > > > b/Documentation/devicetree/bindings/memory.txt > > > > > > +*** Reserved memory regions *** > > > + > > > +In /memory/reserved-memory node one can create additional nodes > > > > s/additional/child/ or s/additional/sub/ would make it clearer where the > > "additional" nodes should be placed. > > > > > +compatible: "linux,contiguous-memory-region" - enables binding > of > > > this > > > + region to Contiguous Memory Allocator (special region for > > > + contiguous memory allocations, shared with movable system > > > + memory, Linux kernel-specific), alternatively if > > > + "reserved-memory-region" - compatibility is defined, given > > > + region is assigned for exclusive usage for by the > respective > > > + devices > > > > "alternatively" makes it sound like the two compatible values are > > mutually-exclusive. Perhaps make this a list, like: > > > > ---------- > > compatible: One or more of: > > > > - "linux,contiguous-memory-region" - enables binding of this > > region to Contiguous Memory Allocator (special region for > > contiguous memory allocations, shared with movable system > > memory, Linux kernel-specific). > > - "reserved-memory-region" - compatibility is defined, given > > region is assigned for exclusive usage for by the respective > > devices. > > ---------- > > > > "linux,contiguous-memory-region" is already long enough, but I'd > > slightly bikeshed towards "linux,contiguous-memory-allocator-region", or > > perhaps "linux,cma-region" since it's not really describing whether the > > memory is contiguous (at the level of /memory, each chunk of memory is > > contiguous...) > > I'm not really sure if we need the "linux" prefix for "contiguous-memory- > region". The concept of contiguous memory region is rather OS independent > and tells us that memory allocated from this region will be contiguous. > IMHO any OS is free to implement its own contiguous memory allocation > method, without being limited to Linux CMA. > > Keep in mind that rationale behind those contiguous regions was that there > are devices that require buffers contiguous in memory to operate > correctly. > > But this is just nitpicking and I don't really have any strong opinion on > this. Actually, I think this is important. It is something that describes the expected usage of the hardware (flicker-free framebuffer is a really good example) and isn't really linux-specific from that perspective. I think you can drop the 'linux,' prefix string. g.
On Wed, 21 Aug 2013 17:39:48 +0200, Tomasz Figa <t.figa@samsung.com> wrote: > On Tuesday 20 of August 2013 10:35:51 Stephen Warren wrote: > > >> a) Adjust memory.txt to allow multiple entries in memory-regions, and > > >> add an associated memory-region-names property. > > >> > > I don't believe that's a good approach unless you have at least a > > partial idea of how the current bindings will be extended to support > > multiple memory regions. > > I believe that at least three "at least partial" ideas have been brought in > this thread. Moreover, I don't think that defining the simple binding now > would stop us from extending it according to any of those ideas in any way. I would plan on extending later with suggestion 'a)' above. Making the memory-region an array of phandles is a better match with how most of the core bindings work. I actually regret the *-gpio properties that were defined earlier becasue it makes it harder for software to look at a tree and determine if there are any gpio references. It of course doesn't need to be done immediately, only when it becomes required. g.
diff --git a/Documentation/devicetree/bindings/memory.txt b/Documentation/devicetree/bindings/memory.txt new file mode 100644 index 0000000..90e96278 --- /dev/null +++ b/Documentation/devicetree/bindings/memory.txt @@ -0,0 +1,166 @@ +*** Memory binding *** + +The /memory node provides basic information about the address and size +of the physical memory. This node is usually filled or updated by the +bootloader, depending on the actual memory configuration of the given +hardware. + +The memory layout is described by the following node: + +/ { + #address-cells = <(n)>; + #size-cells = <(m)>; + memory { + device_type = "memory"; + reg = <(baseaddr1) (size1) + (baseaddr2) (size2) + ... + (baseaddrN) (sizeN)>; + }; + ... +}; + +A memory node follows the typical device tree rules for "reg" property: +n: number of cells used to store base address value +m: number of cells used to store size value +baseaddrX: defines a base address of the defined memory bank +sizeX: the size of the defined memory bank + + +More than one memory bank can be defined. + + +*** Reserved memory regions *** + +In /memory/reserved-memory node one can create additional nodes +describing particular reserved (excluded from normal use) memory +regions. Such memory regions are usually designed for the special usage +by various device drivers. A good example are contiguous memory +allocations or memory sharing with other operating system on the same +hardware board. Those special memory regions might depend on the board +configuration and devices used on the target system. + +Parameters for each memory region can be encoded into the device tree +with the following convention: + +[(label):] (name) { + compatible = "linux,contiguous-memory-region", "reserved-memory-region"; + reg = <(address) (size)>; + (linux,default-contiguous-region); +}; + +compatible: "linux,contiguous-memory-region" - enables binding of this + region to Contiguous Memory Allocator (special region for + contiguous memory allocations, shared with movable system + memory, Linux kernel-specific), alternatively if + "reserved-memory-region" - compatibility is defined, given + region is assigned for exclusive usage for by the respective + devices + +reg: standard property defining the base address and size of + the memory region + +linux,default-contiguous-region: property indicating that the region + is the default region for all contiguous memory + allocations, Linux specific (optional) + +It is optional to specify the base address, so if one wants to use +autoconfiguration of the base address, '0' can be specified as a base +address in the 'reg' property. + +The /memory/reserved-memory node must contain the same #address-cells +and #size-cells value as the root node. + + +*** Device node's properties *** + +Once regions in the /memory/reserved-memory node have been defined, they +can be assigned to device nodes to enable respective device drivers to +access them. The following properties are defined: + +memory-region = <&phandle_to_defined_region>; + +This property indicates that the device driver should use the memory +region pointed by the given phandle. + + +*** Example *** + +This example defines a memory consisting of 4 memory banks. 3 contiguous +regions are defined for Linux kernel, one default of all device drivers +(named contig_mem, placed at 0x72000000, 64MiB), one dedicated to the +framebuffer device (labelled display_mem, placed at 0x78000000, 8MiB) +and one for multimedia processing (labelled multimedia_mem, placed at +0x77000000, 64MiB). 'display_mem' region is then assigned to fb@12300000 +device for DMA memory allocations (Linux kernel drivers will use CMA is +available or dma-exclusive usage otherwise). 'multimedia_mem' is +assigned to scaler@12500000 and codec@12600000 devices for contiguous +memory allocations when CMA driver is enabled. + +The reason for creating a separate region for framebuffer device is to +match the framebuffer base address to the one configured by bootloader, +so once Linux kernel drivers starts no glitches on the displayed boot +logo appears. Scaller and codec drivers should share the memory +allocations. + +/ { + #address-cells = <1>; + #size-cells = <1>; + + /* ... */ + + memory { + reg = <0x40000000 0x10000000 + 0x50000000 0x10000000 + 0x60000000 0x10000000 + 0x70000000 0x10000000>; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + + /* + * global autoconfigured region for contiguous allocations + * (used only with Contiguous Memory Allocator) + */ + contig_region@0 { + compatible = "linux,contiguous-memory-region"; + reg = <0x0 0x4000000>; + linux,default-contiguous-region; + }; + + /* + * special region for framebuffer + */ + display_mem: region@78000000 { + compatible = "linux,contiguous-memory-region", "reserved-memory-region"; + reg = <0x78000000 0x800000>; + }; + + /* + * special region for multimedia processing devices + */ + multimedia_mem: region@77000000 { + compatible = "linux,contiguous-memory-region"; + reg = <0x77000000 0x4000000>; + }; + }; + }; + + /* ... */ + + fb0: fb@12300000 { + status = "okay"; + memory-region = <&display_mem>; + }; + + scaler: scaler@12500000 { + status = "okay"; + memory-region = <&multimedia_mem>; + }; + + codec: codec@12600000 { + status = "okay"; + memory-region = <&multimedia_mem>; + }; +}; diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 80e5c13..a83ab43 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -80,4 +80,10 @@ config OF_MTD depends on MTD def_bool y +config OF_RESERVED_MEM + depends on CMA || (HAVE_GENERIC_DMA_COHERENT && HAVE_MEMBLOCK) + def_bool y + help + Initialization code for DMA reserved memory + endmenu # OF diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 1f9c0c4..e7e3322 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -10,3 +10,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_PCI) += of_pci.o obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o obj-$(CONFIG_OF_MTD) += of_mtd.o +obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c new file mode 100644 index 0000000..95563d33 --- /dev/null +++ b/drivers/of/of_reserved_mem.c @@ -0,0 +1,175 @@ +/* + * Device tree based initialization code for reserved memory. + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * Author: Marek Szyprowski <m.szyprowski@samsung.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License or (at your optional) any later version of the license. + */ + +#include <asm/dma-contiguous.h> + +#include <linux/memblock.h> +#include <linux/err.h> +#include <linux/of.h> +#include <linux/of_fdt.h> +#include <linux/of_platform.h> +#include <linux/mm.h> +#include <linux/sizes.h> +#include <linux/mm_types.h> +#include <linux/dma-contiguous.h> +#include <linux/dma-mapping.h> +#include <linux/of_reserved_mem.h> + +#define MAX_RESERVED_REGIONS 16 +struct reserved_mem { + phys_addr_t base; + unsigned long size; + struct cma *cma; + char name[32]; +}; +static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS]; +static int reserved_mem_count; + +static int __init fdt_scan_reserved_mem(unsigned long node, const char *uname, + int depth, void *data) +{ + struct reserved_mem *rmem = &reserved_mem[reserved_mem_count]; + phys_addr_t base, size; + int is_cma, is_reserved; + unsigned long len; + const char *status; + __be32 *prop; + + is_cma = IS_ENABLED(CONFIG_CMA) && + of_flat_dt_is_compatible(node, "linux,contiguous-memory-region"); + is_reserved = of_flat_dt_is_compatible(node, "reserved-memory-region"); + + if (!is_reserved && !is_cma) { + /* ignore node and scan next one */ + return 0; + } + + status = of_get_flat_dt_prop(node, "status", &len); + if (status && strcmp(status, "okay") != 0) { + /* ignore disabled node nad scan next one */ + return 0; + } + + prop = of_get_flat_dt_prop(node, "reg", &len); + if (!prop || (len < (dt_root_size_cells + dt_root_addr_cells) * + sizeof(__be32))) { + pr_err("Reserved mem: node %s, incorrect \"reg\" property\n", + uname); + /* ignore node and scan next one */ + return 0; + } + base = dt_mem_next_cell(dt_root_addr_cells, &prop); + size = dt_mem_next_cell(dt_root_size_cells, &prop); + + if (!size) { + /* ignore node and scan next one */ + return 0; + } + + pr_info("Reserved mem: found %s, memory base %lx, size %ld MiB\n", + uname, (unsigned long)base, (unsigned long)size / SZ_1M); + + if (reserved_mem_count == ARRAY_SIZE(reserved_mem)) + return -ENOSPC; + + rmem->base = base; + rmem->size = size; + strlcpy(rmem->name, uname, sizeof(rmem->name)); + + if (is_cma) { + struct cma *cma; + if (dma_contiguous_reserve_area(size, base, 0, &cma) == 0) { + rmem->cma = cma; + reserved_mem_count++; + if (of_get_flat_dt_prop(node, + "linux,default-contiguous-region", + NULL)) + dma_contiguous_default_area = cma; + } + } else if (is_reserved) { + if (memblock_remove(base, size) == 0) + reserved_mem_count++; + else + pr_err("Failed to reserve memory for %s\n", uname); + } + + return 0; +} + +static struct reserved_mem *get_dma_memory_region(struct device *dev) +{ + struct device_node *node; + const char *name; + int i; + + node = of_parse_phandle(dev->of_node, "memory-region", 0); + if (!node) + return NULL; + + name = kbasename(node->full_name); + for (i = 0; i < reserved_mem_count; i++) + if (strcmp(name, reserved_mem[i].name) == 0) + return &reserved_mem[i]; + return NULL; +} + +/** + * of_reserved_mem_device_init() - assign reserved memory region to given device + * + * This function assign memory region pointed by "memory-region" device tree + * property to the given device. + */ +void of_reserved_mem_device_init(struct device *dev) +{ + struct reserved_mem *region = get_dma_memory_region(dev); + if (!region) + return; + + if (region->cma) { + dev_set_cma_area(dev, region->cma); + pr_info("Assigned CMA %s to %s device\n", region->name, + dev_name(dev)); + } else { + if (dma_declare_coherent_memory(dev, region->base, region->base, + region->size, DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) != 0) + pr_info("Declared reserved memory %s to %s device\n", + region->name, dev_name(dev)); + } +} + +/** + * of_reserved_mem_device_release() - release reserved memory device structures + * + * This function releases structures allocated for memory region handling for + * the given device. + */ +void of_reserved_mem_device_release(struct device *dev) +{ + struct reserved_mem *region = get_dma_memory_region(dev); + if (!region && !region->cma) + dma_release_declared_memory(dev); +} + +/** + * early_init_dt_scan_reserved_mem() - create reserved memory regions + * + * This function grabs memory from early allocator for device exclusive use + * defined in device tree structures. It should be called by arch specific code + * once the early allocator (memblock) has been activated and all other + * subsystems have already allocated/reserved memory. + */ +void __init early_init_dt_scan_reserved_mem(void) +{ + of_scan_flat_dt_by_path("/memory/reserved-memory", + fdt_scan_reserved_mem, NULL); +} diff --git a/drivers/of/platform.c b/drivers/of/platform.c index e0a6514..1e4e91d 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -21,6 +21,7 @@ #include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/of_platform.h> +#include <linux/of_reserved_mem.h> #include <linux/platform_device.h> const struct of_device_id of_default_bus_match_table[] = { @@ -196,6 +197,7 @@ EXPORT_SYMBOL(of_device_alloc); * Returns pointer to created platform device, or NULL if a device was not * registered. Unavailable devices will not get registered. */ + struct platform_device *of_platform_device_create_pdata( struct device_node *np, const char *bus_id, @@ -218,6 +220,8 @@ struct platform_device *of_platform_device_create_pdata( dev->dev.bus = &platform_bus_type; dev->dev.platform_data = platform_data; + of_reserved_mem_device_init(&dev->dev); + /* We do not fill the DMA ops for platform devices by default. * This is currently the responsibility of the platform code * to do such, possibly using a device notifier @@ -225,6 +229,7 @@ struct platform_device *of_platform_device_create_pdata( if (of_device_add(dev) != 0) { platform_device_put(dev); + of_reserved_mem_device_release(&dev->dev); return NULL; } diff --git a/include/linux/of_reserved_mem.h b/include/linux/of_reserved_mem.h new file mode 100644 index 0000000..c841282 --- /dev/null +++ b/include/linux/of_reserved_mem.h @@ -0,0 +1,14 @@ +#ifndef __OF_RESERVED_MEM_H +#define __OF_RESERVED_MEM_H + +#ifdef CONFIG_OF_RESERVED_MEM +void of_reserved_mem_device_init(struct device *dev); +void of_reserved_mem_device_release(struct device *dev); +void early_init_dt_scan_reserved_mem(void); +#else +static inline void of_reserved_mem_device_init(struct device *dev) { } +static inline void of_reserved_mem_device_release(struct device *dev) { } +static inline void early_init_dt_scan_reserved_mem(void) { } +#endif + +#endif /* __OF_RESERVED_MEM_H */