2018-05-22 19:34:53 +03:00
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright ( c ) 2018 BayLibre , SAS .
* Author : Jerome Brunet < jbrunet @ baylibre . com >
*/
# include <linux/clk-provider.h>
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 15:58:41 +03:00
# include <linux/module.h>
# include "clk-regmap.h"
# include "clk-phase.h"
2018-05-22 19:34:53 +03:00
# define phase_step(_width) (360 / (1 << (_width)))
static inline struct meson_clk_phase_data *
meson_clk_phase_data ( struct clk_regmap * clk )
{
return ( struct meson_clk_phase_data * ) clk - > data ;
}
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 15:58:41 +03:00
static int meson_clk_degrees_from_val ( unsigned int val , unsigned int width )
2018-05-22 19:34:53 +03:00
{
return phase_step ( width ) * val ;
}
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 15:58:41 +03:00
static unsigned int meson_clk_degrees_to_val ( int degrees , unsigned int width )
2018-05-22 19:34:53 +03:00
{
unsigned int val = DIV_ROUND_CLOSEST ( degrees , phase_step ( width ) ) ;
/*
* This last calculation is here for cases when degrees is rounded
* to 360 , in which case val = = ( 1 < < width ) .
*/
return val % ( 1 < < width ) ;
}
static int meson_clk_phase_get_phase ( struct clk_hw * hw )
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_clk_phase_data * phase = meson_clk_phase_data ( clk ) ;
unsigned int val ;
val = meson_parm_read ( clk - > map , & phase - > ph ) ;
return meson_clk_degrees_from_val ( val , phase - > ph . width ) ;
}
static int meson_clk_phase_set_phase ( struct clk_hw * hw , int degrees )
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_clk_phase_data * phase = meson_clk_phase_data ( clk ) ;
unsigned int val ;
val = meson_clk_degrees_to_val ( degrees , phase - > ph . width ) ;
meson_parm_write ( clk - > map , & phase - > ph , val ) ;
return 0 ;
}
const struct clk_ops meson_clk_phase_ops = {
. get_phase = meson_clk_phase_get_phase ,
. set_phase = meson_clk_phase_set_phase ,
} ;
EXPORT_SYMBOL_GPL ( meson_clk_phase_ops ) ;
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 15:58:41 +03:00
/*
* This is a special clock for the audio controller .
* The phase of mst_sclk clock output can be controlled independently
* for the outside world ( ph0 ) , the tdmout ( ph1 ) and tdmin ( ph2 ) .
* Controlling these 3 phases as just one makes things simpler and
* give the same clock view to all the element on the i2s bus .
* If necessary , we can still control the phase in the tdm block
* which makes these independent control redundant .
*/
static inline struct meson_clk_triphase_data *
meson_clk_triphase_data ( struct clk_regmap * clk )
{
return ( struct meson_clk_triphase_data * ) clk - > data ;
}
2019-09-24 15:39:53 +03:00
static int meson_clk_triphase_sync ( struct clk_hw * hw )
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 15:58:41 +03:00
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_clk_triphase_data * tph = meson_clk_triphase_data ( clk ) ;
unsigned int val ;
/* Get phase 0 and sync it to phase 1 and 2 */
val = meson_parm_read ( clk - > map , & tph - > ph0 ) ;
meson_parm_write ( clk - > map , & tph - > ph1 , val ) ;
meson_parm_write ( clk - > map , & tph - > ph2 , val ) ;
2019-09-24 15:39:53 +03:00
return 0 ;
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 15:58:41 +03:00
}
static int meson_clk_triphase_get_phase ( struct clk_hw * hw )
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_clk_triphase_data * tph = meson_clk_triphase_data ( clk ) ;
unsigned int val ;
/* Phase are in sync, reading phase 0 is enough */
val = meson_parm_read ( clk - > map , & tph - > ph0 ) ;
return meson_clk_degrees_from_val ( val , tph - > ph0 . width ) ;
}
static int meson_clk_triphase_set_phase ( struct clk_hw * hw , int degrees )
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_clk_triphase_data * tph = meson_clk_triphase_data ( clk ) ;
unsigned int val ;
val = meson_clk_degrees_to_val ( degrees , tph - > ph0 . width ) ;
meson_parm_write ( clk - > map , & tph - > ph0 , val ) ;
meson_parm_write ( clk - > map , & tph - > ph1 , val ) ;
meson_parm_write ( clk - > map , & tph - > ph2 , val ) ;
return 0 ;
}
const struct clk_ops meson_clk_triphase_ops = {
. init = meson_clk_triphase_sync ,
. get_phase = meson_clk_triphase_get_phase ,
. set_phase = meson_clk_triphase_set_phase ,
} ;
EXPORT_SYMBOL_GPL ( meson_clk_triphase_ops ) ;
2020-07-29 18:43:57 +03:00
/*
* This is a special clock for the audio controller .
* This drive a bit clock inverter for which the
* opposite value of the inverter bit needs to be manually
* set into another bit
*/
static inline struct meson_sclk_ws_inv_data *
meson_sclk_ws_inv_data ( struct clk_regmap * clk )
{
return ( struct meson_sclk_ws_inv_data * ) clk - > data ;
}
static int meson_sclk_ws_inv_sync ( struct clk_hw * hw )
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_sclk_ws_inv_data * tph = meson_sclk_ws_inv_data ( clk ) ;
unsigned int val ;
/* Get phase and sync the inverted value to ws */
val = meson_parm_read ( clk - > map , & tph - > ph ) ;
meson_parm_write ( clk - > map , & tph - > ws , val ? 0 : 1 ) ;
return 0 ;
}
static int meson_sclk_ws_inv_get_phase ( struct clk_hw * hw )
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_sclk_ws_inv_data * tph = meson_sclk_ws_inv_data ( clk ) ;
unsigned int val ;
val = meson_parm_read ( clk - > map , & tph - > ph ) ;
return meson_clk_degrees_from_val ( val , tph - > ph . width ) ;
}
static int meson_sclk_ws_inv_set_phase ( struct clk_hw * hw , int degrees )
{
struct clk_regmap * clk = to_clk_regmap ( hw ) ;
struct meson_sclk_ws_inv_data * tph = meson_sclk_ws_inv_data ( clk ) ;
unsigned int val ;
val = meson_clk_degrees_to_val ( degrees , tph - > ph . width ) ;
meson_parm_write ( clk - > map , & tph - > ph , val ) ;
meson_parm_write ( clk - > map , & tph - > ws , val ? 0 : 1 ) ;
return 0 ;
}
const struct clk_ops meson_sclk_ws_inv_ops = {
. init = meson_sclk_ws_inv_sync ,
. get_phase = meson_sclk_ws_inv_get_phase ,
. set_phase = meson_sclk_ws_inv_set_phase ,
} ;
EXPORT_SYMBOL_GPL ( meson_sclk_ws_inv_ops ) ;
clk: meson: rework and clean drivers dependencies
Initially, the meson clock directory only hosted 2 controllers drivers,
for meson8 and gxbb. At the time, both used the same set of clock drivers
so managing the dependencies was not a big concern.
Since this ancient time, entropy did its job, controllers with different
requirement and specific clock drivers have been added. Unfortunately, we
did not do a great job at managing the dependencies between the
controllers and the different clock drivers. Some drivers, such as
clk-phase or vid-pll-div, are compiled even if they are useless on the
target (meson8). As we are adding new controllers, we need to be able to
pick a driver w/o pulling the whole thing.
The patch aims to clean things up by:
* providing a dedicated CONFIG_ for each clock drivers
* allowing clock drivers to be compiled as a modules, if possible
* stating explicitly which drivers are required by each controller.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20190201125841.26785-5-jbrunet@baylibre.com
2019-02-01 15:58:41 +03:00
MODULE_DESCRIPTION ( " Amlogic phase driver " ) ;
MODULE_AUTHOR ( " Jerome Brunet <jbrunet@baylibre.com> " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;