Re: [Intel-gfx] [PATCH v2 2/3] drm/i915: Nuke aux regs from intel_dp

2018-02-22 Thread Pandiyan, Dhinakaran



On Thu, 2018-02-22 at 14:43 +0200, Ville Syrjälä wrote:
> On Thu, Feb 22, 2018 at 07:16:07AM +, Pandiyan, Dhinakaran wrote:
> > 
> > On Tue, 2018-02-20 at 21:00 +0200, Ville Syrjala wrote:
> > > From: Ville Syrjälä 
> > > 
> > > Just store function pointers that give us the correct register offsets
> > > instead of storing the register offsets themselves. Slightly less
> > > efficient perhaps but saves a few bytes and better matches how we do
> > > things elsewhere.
> > > 
> > > v2: Keep a local array of data registers (Chris)
> > > 
> > Intriguing, why bother storing register offsets in one go if it's okay
> > to make these additional function calls for every aux transaction.
> > 
> > What am I missing here?
> 
> Slight optimization to do them only once per aux transfer instead of
> potentially multiple times on account of the retry loops.
> 

Yeah, that optimization intrigued me because the additional function
calls this patch introduces make the existing code suboptimal. :)
That's enough bikeshed I suppose, thanks for your answer.


> > 
> > 
> > 
> > > Reviewed-by: Chris Wilson 
> > > Signed-off-by: Ville Syrjälä 
> > > ---
> > >  drivers/gpu/drm/i915/intel_dp.c  | 85 
> > > 
> > >  drivers/gpu/drm/i915/intel_drv.h |  5 ++-
> > >  2 files changed, 45 insertions(+), 45 deletions(-)
> > > 
> > > diff --git a/drivers/gpu/drm/i915/intel_dp.c 
> > > b/drivers/gpu/drm/i915/intel_dp.c
> > > index eeb8a026fd08..b0c273b5b2a9 100644
> > > --- a/drivers/gpu/drm/i915/intel_dp.c
> > > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > > @@ -936,7 +936,7 @@ static uint32_t
> > >  intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
> > >  {
> > >   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> > > - i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
> > > + i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
> > >   uint32_t status;
> > >   bool done;
> > >  
> > > @@ -1089,7 +1089,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > >   struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> > >   struct drm_i915_private *dev_priv =
> > >   to_i915(intel_dig_port->base.base.dev);
> > > - i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
> > > + i915_reg_t ch_ctl, ch_data[5];
> > >   uint32_t aux_clock_divider;
> > >   int i, ret, recv_bytes;
> > >   uint32_t status;
> > > @@ -1097,6 +1097,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > >   bool has_aux_irq = HAS_AUX_IRQ(dev_priv);
> > >   bool vdd;
> > >  
> > > + ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
> > > + for (i = 0; i < ARRAY_SIZE(ch_data); i++)
> > > +  ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i);
> > > +
> > >   pps_lock(intel_dp);
> > >  
> > >   /*
> > > @@ -1154,7 +1158,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > >   for (try = 0; try < 5; try++) {
> > >   /* Load the send data into the aux channel data 
> > > registers */
> > >   for (i = 0; i < send_bytes; i += 4)
> > > - I915_WRITE(intel_dp->aux_ch_data_reg[i >> 2],
> > > + I915_WRITE(ch_data[i >> 2],
> > >  intel_dp_pack_aux(send + i,
> > >send_bytes - i));
> > >  
> > > @@ -1239,7 +1243,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > >   recv_bytes = recv_size;
> > >  
> > >   for (i = 0; i < recv_bytes; i += 4)
> > > - intel_dp_unpack_aux(I915_READ(intel_dp->aux_ch_data_reg[i >> 
> > > 2]),
> > > + intel_dp_unpack_aux(I915_READ(ch_data[i >> 2]),
> > >   recv + i, recv_bytes - i);
> > >  
> > >   ret = recv_bytes;
> > > @@ -1396,9 +1400,11 @@ intel_aux_power_domain(struct intel_dp *intel_dp)
> > >   }
> > >  }
> > >  
> > > -static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
> > > -   enum aux_ch aux_ch)
> > > +static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp)
> > >  {
> > > + struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> > > + enum aux_ch aux_ch = intel_dp->aux_ch;
> > > +
> > >   switch (aux_ch) {
> > >   case AUX_CH_B:
> > >   case AUX_CH_C:
> > > @@ -1410,9 +1416,11 @@ static i915_reg_t g4x_aux_ctl_reg(struct 
> > > drm_i915_private *dev_priv,
> > >   }
> > >  }
> > >  
> > > -static i915_reg_t g4x_aux_data_reg(struct drm_i915_private *dev_priv,
> > > -enum aux_ch aux_ch, int index)
> > > +static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index)
> > >  {
> > > + struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> > > + enum aux_ch aux_ch = intel_dp->aux_ch;
> > > +
> > >   switch (aux_ch) {
> > >   case AUX_CH_B:
> > >   case AUX_CH_C:
> > > @@ -1424,9 +1432,11 @@ static i915_reg_t 

Re: [Intel-gfx] [PATCH v2 2/3] drm/i915: Nuke aux regs from intel_dp

2018-02-22 Thread Ville Syrjälä
On Thu, Feb 22, 2018 at 07:16:07AM +, Pandiyan, Dhinakaran wrote:
> 
> On Tue, 2018-02-20 at 21:00 +0200, Ville Syrjala wrote:
> > From: Ville Syrjälä 
> > 
> > Just store function pointers that give us the correct register offsets
> > instead of storing the register offsets themselves. Slightly less
> > efficient perhaps but saves a few bytes and better matches how we do
> > things elsewhere.
> > 
> > v2: Keep a local array of data registers (Chris)
> > 
> Intriguing, why bother storing register offsets in one go if it's okay
> to make these additional function calls for every aux transaction.
> 
> What am I missing here?

Slight optimization to do them only once per aux transfer instead of
potentially multiple times on account of the retry loops.

> 
> 
> 
> > Reviewed-by: Chris Wilson 
> > Signed-off-by: Ville Syrjälä 
> > ---
> >  drivers/gpu/drm/i915/intel_dp.c  | 85 
> > 
> >  drivers/gpu/drm/i915/intel_drv.h |  5 ++-
> >  2 files changed, 45 insertions(+), 45 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_dp.c 
> > b/drivers/gpu/drm/i915/intel_dp.c
> > index eeb8a026fd08..b0c273b5b2a9 100644
> > --- a/drivers/gpu/drm/i915/intel_dp.c
> > +++ b/drivers/gpu/drm/i915/intel_dp.c
> > @@ -936,7 +936,7 @@ static uint32_t
> >  intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
> >  {
> > struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> > -   i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
> > +   i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
> > uint32_t status;
> > bool done;
> >  
> > @@ -1089,7 +1089,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
> > struct drm_i915_private *dev_priv =
> > to_i915(intel_dig_port->base.base.dev);
> > -   i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
> > +   i915_reg_t ch_ctl, ch_data[5];
> > uint32_t aux_clock_divider;
> > int i, ret, recv_bytes;
> > uint32_t status;
> > @@ -1097,6 +1097,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > bool has_aux_irq = HAS_AUX_IRQ(dev_priv);
> > bool vdd;
> >  
> > +   ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
> > +   for (i = 0; i < ARRAY_SIZE(ch_data); i++)
> > +ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i);
> > +
> > pps_lock(intel_dp);
> >  
> > /*
> > @@ -1154,7 +1158,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > for (try = 0; try < 5; try++) {
> > /* Load the send data into the aux channel data 
> > registers */
> > for (i = 0; i < send_bytes; i += 4)
> > -   I915_WRITE(intel_dp->aux_ch_data_reg[i >> 2],
> > +   I915_WRITE(ch_data[i >> 2],
> >intel_dp_pack_aux(send + i,
> >  send_bytes - i));
> >  
> > @@ -1239,7 +1243,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
> > recv_bytes = recv_size;
> >  
> > for (i = 0; i < recv_bytes; i += 4)
> > -   intel_dp_unpack_aux(I915_READ(intel_dp->aux_ch_data_reg[i >> 
> > 2]),
> > +   intel_dp_unpack_aux(I915_READ(ch_data[i >> 2]),
> > recv + i, recv_bytes - i);
> >  
> > ret = recv_bytes;
> > @@ -1396,9 +1400,11 @@ intel_aux_power_domain(struct intel_dp *intel_dp)
> > }
> >  }
> >  
> > -static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
> > - enum aux_ch aux_ch)
> > +static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp)
> >  {
> > +   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> > +   enum aux_ch aux_ch = intel_dp->aux_ch;
> > +
> > switch (aux_ch) {
> > case AUX_CH_B:
> > case AUX_CH_C:
> > @@ -1410,9 +1416,11 @@ static i915_reg_t g4x_aux_ctl_reg(struct 
> > drm_i915_private *dev_priv,
> > }
> >  }
> >  
> > -static i915_reg_t g4x_aux_data_reg(struct drm_i915_private *dev_priv,
> > -  enum aux_ch aux_ch, int index)
> > +static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index)
> >  {
> > +   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> > +   enum aux_ch aux_ch = intel_dp->aux_ch;
> > +
> > switch (aux_ch) {
> > case AUX_CH_B:
> > case AUX_CH_C:
> > @@ -1424,9 +1432,11 @@ static i915_reg_t g4x_aux_data_reg(struct 
> > drm_i915_private *dev_priv,
> > }
> >  }
> >  
> > -static i915_reg_t ilk_aux_ctl_reg(struct drm_i915_private *dev_priv,
> > - enum aux_ch aux_ch)
> > +static i915_reg_t ilk_aux_ctl_reg(struct intel_dp *intel_dp)
> >  {
> > +   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> > +   enum aux_ch aux_ch = 

Re: [Intel-gfx] [PATCH v2 2/3] drm/i915: Nuke aux regs from intel_dp

2018-02-21 Thread Pandiyan, Dhinakaran

On Tue, 2018-02-20 at 21:00 +0200, Ville Syrjala wrote:
> From: Ville Syrjälä 
> 
> Just store function pointers that give us the correct register offsets
> instead of storing the register offsets themselves. Slightly less
> efficient perhaps but saves a few bytes and better matches how we do
> things elsewhere.
> 
> v2: Keep a local array of data registers (Chris)
> 
Intriguing, why bother storing register offsets in one go if it's okay
to make these additional function calls for every aux transaction.

What am I missing here?



> Reviewed-by: Chris Wilson 
> Signed-off-by: Ville Syrjälä 
> ---
>  drivers/gpu/drm/i915/intel_dp.c  | 85 
> 
>  drivers/gpu/drm/i915/intel_drv.h |  5 ++-
>  2 files changed, 45 insertions(+), 45 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
> index eeb8a026fd08..b0c273b5b2a9 100644
> --- a/drivers/gpu/drm/i915/intel_dp.c
> +++ b/drivers/gpu/drm/i915/intel_dp.c
> @@ -936,7 +936,7 @@ static uint32_t
>  intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
>  {
>   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> - i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
> + i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
>   uint32_t status;
>   bool done;
>  
> @@ -1089,7 +1089,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
>   struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
>   struct drm_i915_private *dev_priv =
>   to_i915(intel_dig_port->base.base.dev);
> - i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
> + i915_reg_t ch_ctl, ch_data[5];
>   uint32_t aux_clock_divider;
>   int i, ret, recv_bytes;
>   uint32_t status;
> @@ -1097,6 +1097,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
>   bool has_aux_irq = HAS_AUX_IRQ(dev_priv);
>   bool vdd;
>  
> + ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
> + for (i = 0; i < ARRAY_SIZE(ch_data); i++)
> +  ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i);
> +
>   pps_lock(intel_dp);
>  
>   /*
> @@ -1154,7 +1158,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
>   for (try = 0; try < 5; try++) {
>   /* Load the send data into the aux channel data 
> registers */
>   for (i = 0; i < send_bytes; i += 4)
> - I915_WRITE(intel_dp->aux_ch_data_reg[i >> 2],
> + I915_WRITE(ch_data[i >> 2],
>  intel_dp_pack_aux(send + i,
>send_bytes - i));
>  
> @@ -1239,7 +1243,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
>   recv_bytes = recv_size;
>  
>   for (i = 0; i < recv_bytes; i += 4)
> - intel_dp_unpack_aux(I915_READ(intel_dp->aux_ch_data_reg[i >> 
> 2]),
> + intel_dp_unpack_aux(I915_READ(ch_data[i >> 2]),
>   recv + i, recv_bytes - i);
>  
>   ret = recv_bytes;
> @@ -1396,9 +1400,11 @@ intel_aux_power_domain(struct intel_dp *intel_dp)
>   }
>  }
>  
> -static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
> -   enum aux_ch aux_ch)
> +static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp)
>  {
> + struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> + enum aux_ch aux_ch = intel_dp->aux_ch;
> +
>   switch (aux_ch) {
>   case AUX_CH_B:
>   case AUX_CH_C:
> @@ -1410,9 +1416,11 @@ static i915_reg_t g4x_aux_ctl_reg(struct 
> drm_i915_private *dev_priv,
>   }
>  }
>  
> -static i915_reg_t g4x_aux_data_reg(struct drm_i915_private *dev_priv,
> -enum aux_ch aux_ch, int index)
> +static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index)
>  {
> + struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> + enum aux_ch aux_ch = intel_dp->aux_ch;
> +
>   switch (aux_ch) {
>   case AUX_CH_B:
>   case AUX_CH_C:
> @@ -1424,9 +1432,11 @@ static i915_reg_t g4x_aux_data_reg(struct 
> drm_i915_private *dev_priv,
>   }
>  }
>  
> -static i915_reg_t ilk_aux_ctl_reg(struct drm_i915_private *dev_priv,
> -   enum aux_ch aux_ch)
> +static i915_reg_t ilk_aux_ctl_reg(struct intel_dp *intel_dp)
>  {
> + struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
> + enum aux_ch aux_ch = intel_dp->aux_ch;
> +
>   switch (aux_ch) {
>   case AUX_CH_A:
>   return DP_AUX_CH_CTL(aux_ch);
> @@ -1440,9 +1450,11 @@ static i915_reg_t ilk_aux_ctl_reg(struct 
> drm_i915_private *dev_priv,
>   }
>  }
>  
> -static i915_reg_t ilk_aux_data_reg(struct drm_i915_private *dev_priv,
> -enum 

[Intel-gfx] [PATCH v2 2/3] drm/i915: Nuke aux regs from intel_dp

2018-02-20 Thread Ville Syrjala
From: Ville Syrjälä 

Just store function pointers that give us the correct register offsets
instead of storing the register offsets themselves. Slightly less
efficient perhaps but saves a few bytes and better matches how we do
things elsewhere.

v2: Keep a local array of data registers (Chris)

Reviewed-by: Chris Wilson 
Signed-off-by: Ville Syrjälä 
---
 drivers/gpu/drm/i915/intel_dp.c  | 85 
 drivers/gpu/drm/i915/intel_drv.h |  5 ++-
 2 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index eeb8a026fd08..b0c273b5b2a9 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -936,7 +936,7 @@ static uint32_t
 intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq)
 {
struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
-   i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
+   i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
uint32_t status;
bool done;
 
@@ -1089,7 +1089,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv =
to_i915(intel_dig_port->base.base.dev);
-   i915_reg_t ch_ctl = intel_dp->aux_ch_ctl_reg;
+   i915_reg_t ch_ctl, ch_data[5];
uint32_t aux_clock_divider;
int i, ret, recv_bytes;
uint32_t status;
@@ -1097,6 +1097,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
bool has_aux_irq = HAS_AUX_IRQ(dev_priv);
bool vdd;
 
+   ch_ctl = intel_dp->aux_ch_ctl_reg(intel_dp);
+   for (i = 0; i < ARRAY_SIZE(ch_data); i++)
+ch_data[i] = intel_dp->aux_ch_data_reg(intel_dp, i);
+
pps_lock(intel_dp);
 
/*
@@ -1154,7 +1158,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
for (try = 0; try < 5; try++) {
/* Load the send data into the aux channel data 
registers */
for (i = 0; i < send_bytes; i += 4)
-   I915_WRITE(intel_dp->aux_ch_data_reg[i >> 2],
+   I915_WRITE(ch_data[i >> 2],
   intel_dp_pack_aux(send + i,
 send_bytes - i));
 
@@ -1239,7 +1243,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
recv_bytes = recv_size;
 
for (i = 0; i < recv_bytes; i += 4)
-   intel_dp_unpack_aux(I915_READ(intel_dp->aux_ch_data_reg[i >> 
2]),
+   intel_dp_unpack_aux(I915_READ(ch_data[i >> 2]),
recv + i, recv_bytes - i);
 
ret = recv_bytes;
@@ -1396,9 +1400,11 @@ intel_aux_power_domain(struct intel_dp *intel_dp)
}
 }
 
-static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
- enum aux_ch aux_ch)
+static i915_reg_t g4x_aux_ctl_reg(struct intel_dp *intel_dp)
 {
+   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+   enum aux_ch aux_ch = intel_dp->aux_ch;
+
switch (aux_ch) {
case AUX_CH_B:
case AUX_CH_C:
@@ -1410,9 +1416,11 @@ static i915_reg_t g4x_aux_ctl_reg(struct 
drm_i915_private *dev_priv,
}
 }
 
-static i915_reg_t g4x_aux_data_reg(struct drm_i915_private *dev_priv,
-  enum aux_ch aux_ch, int index)
+static i915_reg_t g4x_aux_data_reg(struct intel_dp *intel_dp, int index)
 {
+   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+   enum aux_ch aux_ch = intel_dp->aux_ch;
+
switch (aux_ch) {
case AUX_CH_B:
case AUX_CH_C:
@@ -1424,9 +1432,11 @@ static i915_reg_t g4x_aux_data_reg(struct 
drm_i915_private *dev_priv,
}
 }
 
-static i915_reg_t ilk_aux_ctl_reg(struct drm_i915_private *dev_priv,
- enum aux_ch aux_ch)
+static i915_reg_t ilk_aux_ctl_reg(struct intel_dp *intel_dp)
 {
+   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+   enum aux_ch aux_ch = intel_dp->aux_ch;
+
switch (aux_ch) {
case AUX_CH_A:
return DP_AUX_CH_CTL(aux_ch);
@@ -1440,9 +1450,11 @@ static i915_reg_t ilk_aux_ctl_reg(struct 
drm_i915_private *dev_priv,
}
 }
 
-static i915_reg_t ilk_aux_data_reg(struct drm_i915_private *dev_priv,
-  enum aux_ch aux_ch, int index)
+static i915_reg_t ilk_aux_data_reg(struct intel_dp *intel_dp, int index)
 {
+   struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+   enum aux_ch aux_ch = intel_dp->aux_ch;
+
switch (aux_ch) {
case AUX_CH_A:
return DP_AUX_CH_DATA(aux_ch, index);
@@ -1456,9 +1468,11